summaryrefslogtreecommitdiff
path: root/gnu/dist/diffutils
diff options
context:
space:
mode:
authortv <tv@NetBSD.org>1999-02-12 12:27:03 +0000
committertv <tv@NetBSD.org>1999-02-12 12:27:03 +0000
commitf598822c56272f3d89f5aa2baed15845a4425246 (patch)
tree0407a6b8daaab17d3eb35e65c52545100583a035 /gnu/dist/diffutils
parentd84dcf29f14246bc986209827fa085a48b8ae378 (diff)
Use dist layout for diffutils, for easier upgrades and texinfo doc.
Diffstat (limited to 'gnu/dist/diffutils')
-rw-r--r--gnu/dist/diffutils/COPYING339
-rw-r--r--gnu/dist/diffutils/ChangeLog1766
-rw-r--r--gnu/dist/diffutils/INSTALL179
-rw-r--r--gnu/dist/diffutils/Makefile.in198
-rw-r--r--gnu/dist/diffutils/NEWS126
-rw-r--r--gnu/dist/diffutils/README9
-rw-r--r--gnu/dist/diffutils/alloca.c492
-rw-r--r--gnu/dist/diffutils/analyze.c1084
-rw-r--r--gnu/dist/diffutils/cmp.c568
-rw-r--r--gnu/dist/diffutils/cmpbuf.c40
-rw-r--r--gnu/dist/diffutils/cmpbuf.h20
-rw-r--r--gnu/dist/diffutils/config.hin117
-rwxr-xr-xgnu/dist/diffutils/configure2149
-rw-r--r--gnu/dist/diffutils/configure.in26
-rw-r--r--gnu/dist/diffutils/context.c468
-rw-r--r--gnu/dist/diffutils/diagmeet.note71
-rw-r--r--gnu/dist/diffutils/diff.c1106
-rw-r--r--gnu/dist/diffutils/diff.h340
-rw-r--r--gnu/dist/diffutils/diff.info128
-rw-r--r--gnu/dist/diffutils/diff.info-11211
-rw-r--r--gnu/dist/diffutils/diff.info-21312
-rw-r--r--gnu/dist/diffutils/diff.info-31327
-rw-r--r--gnu/dist/diffutils/diff.info-4152
-rw-r--r--gnu/dist/diffutils/diff.texi3916
-rw-r--r--gnu/dist/diffutils/diff3.c1778
-rw-r--r--gnu/dist/diffutils/dir.c216
-rw-r--r--gnu/dist/diffutils/ed.c200
-rw-r--r--gnu/dist/diffutils/error.c111
-rw-r--r--gnu/dist/diffutils/fnmatch.c209
-rw-r--r--gnu/dist/diffutils/fnmatch.h69
-rw-r--r--gnu/dist/diffutils/getopt.c748
-rw-r--r--gnu/dist/diffutils/getopt.h129
-rw-r--r--gnu/dist/diffutils/getopt1.c180
-rw-r--r--gnu/dist/diffutils/ifdef.c428
-rw-r--r--gnu/dist/diffutils/install-sh238
-rw-r--r--gnu/dist/diffutils/io.c714
-rw-r--r--gnu/dist/diffutils/memchr.c19
-rw-r--r--gnu/dist/diffutils/mkinstalldirs32
-rw-r--r--gnu/dist/diffutils/normal.c71
-rw-r--r--gnu/dist/diffutils/regex.c5248
-rw-r--r--gnu/dist/diffutils/regex.h490
-rw-r--r--gnu/dist/diffutils/sdiff.c1180
-rw-r--r--gnu/dist/diffutils/side.c284
-rw-r--r--gnu/dist/diffutils/stamp-h.in1
-rw-r--r--gnu/dist/diffutils/system.h267
-rw-r--r--gnu/dist/diffutils/texinfo.tex4344
-rw-r--r--gnu/dist/diffutils/util.c754
-rw-r--r--gnu/dist/diffutils/version.c5
-rw-r--r--gnu/dist/diffutils/waitpid.c68
-rw-r--r--gnu/dist/diffutils/xmalloc.c81
50 files changed, 35008 insertions, 0 deletions
diff --git a/gnu/dist/diffutils/COPYING b/gnu/dist/diffutils/COPYING
new file mode 100644
index 00000000000..a43ea2126fb
--- /dev/null
+++ b/gnu/dist/diffutils/COPYING
@@ -0,0 +1,339 @@
+ 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.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 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.
+
+ <signature of Ty Coon>, 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/dist/diffutils/ChangeLog b/gnu/dist/diffutils/ChangeLog
new file mode 100644
index 00000000000..6cfc7791adb
--- /dev/null
+++ b/gnu/dist/diffutils/ChangeLog
@@ -0,0 +1,1766 @@
+Sat Oct 1 05:24:19 1994 Paul Eggert <eggert@twinsun.com>
+
+ * Version 2.7 released.
+
+ * configure.in (AC_HEADER_SYS_WAIT): Add.
+ (AC_CHECK_HEADERS): Remove sys/wait.h.
+ (AC_CHECK_FUNCS): Add tmpnam.
+ * system.h (<sys/wait.h>, WEXITSTATUS): Use simpler scheme
+ now that HAVE_SYS_WAIT_H is not set on hosts
+ that are incompatible with Posix applications.
+
+ * util.c (dir_file_pathname): Use filename_lastdirchar not strrchr.
+ * sdiff.c (expand_name): Likewise.
+ (private_tempnam): Use tmpnam if HAVE_TMPNAM; this simplifies porting.
+ (exists, letters): Omit if HAVE_TMPNAM.
+
+ * diff3.c (read_diff): If STAT_BLOCKSIZE yields zero,
+ adjust it to a more reasonable value.
+
+Sat Sep 24 20:36:40 1994 Paul Eggert <eggert@twinsun.com>
+
+ * sdiff.c (exists, private_tempname): Adopt latest GNU libc algorithm.
+ (private_tempnam): Specialize for sdiff to avoid portability problems.
+
+Thu Sep 22 16:47:00 1994 Paul Eggert <eggert@twinsun.com>
+
+ * configure.in (AC_ARG_PROGRAM): Added.
+ (AC_OUTPUT): Add [date > stamp-h].
+
+ * Makefile.in (DEFAULT_EDITOR_PROGRAM, DIFF_PROGRAM, LIBOBJS,
+ NULL_DEVICE, PR_PROGRAM, PROGRAMS): New variables.
+ (check, stamp-h.in, cmp.o, util.o): New targets.
+ (edit_program_name): New variable; replaces old binprefix method.
+ (install, uninstall): Use it.
+ (binprefix): Removed.
+ (distfiles): Add stamp-h.in.
+ (clean): Clean stamp-h.
+ (config.hin, config.h): Use time stamp files.
+ (cmp_o): Add $(LIBOBJS).
+ (install): Install info files from srcdir if they're not in `.'.
+
+ * cmp.c, io.c (word): Don't define if already defined.
+
+ * comp.c (main): Use setmode, not open(..., O_BINARY); this gets stdin.
+ Use NULL_DEVICE instead of "/dev/null".
+ (cmp): Use %lu instead of %ld when it is more likely to be right.
+
+ * diff.h (PR_FILE_NAME): Rename to PR_PROGRAM and move to Makefile.in,
+ util.c.
+
+ * diff3.c (main): Give proper diagnostic if too many labels were given.
+ (read_diff): Use SYSTEM_QUOTE_ARG.
+
+ * system.h: <string.h>: Include if HAVE_STRING_H, too.
+ <ctype.h>: Include here. All includers changed.
+ (CTYPE_DOMAIN, ISDIGIT, ISPRINT, ISSPACE, ISUPPER): New macros that
+ work around common <ctype.h> problems.
+ (O_BINARY): Remove.
+ (SYSTEM_QUOTE_ARG): New macros.
+
+ * diff.c: Add comment.
+
+ * util.c (PR_PROGRAM): Moved here from diff.h.
+ (begin_output): Use SYSTEM_QUOTE_ARG.
+
+ * io.c (read_files): Set mode to binary before returning 1.
+
+ * sdiff.c (TMPDIR_ENV): New macro.
+ (DEFAULT_EDITOR_PROGRAM): Renamed from DEFAULT_EDITOR for consistency.
+ (expand_name): Change `isdir' to `is_dir' to avoid theoretical ctype
+ namespace contamination.
+ (main): Use SYSTEM_QUOTE_ARG.
+ (private_tempnam): Don't access "/tmp" directly; use PVT_tmpdir.
+
+Tue Sep 13 18:46:43 1994 Paul Eggert <eggert@twinsun.com>
+
+ * configure.in (AC_FUNC_MEMCHR): Remove. Autoconf didn't adopt this,
+ since we need not worry about an old experimental library
+ where memchr didn't work.
+ (AC_FUNC_MEMCMP): Not needed, since we only test for equality.
+ (AC_REPLACE_FUNCS): Add test for memchr.
+ (AC_CHECK_FUNCS): Check for memchr, not memcpy, since it'll be cached.
+ (AC_CHECK_HEADERS): Add string.h; regex.c uses on some old hosts.
+
+ * system.h (memcmp): Define in terms of bcmp.
+ Use HAVE_MEMCHR to test for all mem* routines.
+
+ * Makefile.in (srcs): Remove memcmp.c.
+ We use bcmp if memcmp doesn't work, since we only test for equality.
+
+Mon Sep 12 15:52:22 1994 Paul Eggert <eggert@twinsun.com>
+
+ * configure.in (AC_CONFIG_HEADER): Rename config.h.in to config.hin.
+ (AC_ISC_POSIX, AC_MINIX): Go back to these old names for Autoconf 2.
+ (AC_CHECK_HEADERS): Remove now-redundant check for <string.h>.
+ (AC_CHECK_FUNCS): Check for strchr.
+ (AC_FUNC_MEMCHR, AC_FUNC_MEMCMP, AC_CHECK_FUNCS): Use special-purpose
+ macros when suitable.
+ * memcmp.c: New file.
+ * Makefile.in (CPPFLAGS, DEFS, CFLAGS, LDFLAGS, prefix, exec_prefix):
+ Default to autoconf-specified strings.
+ (COMPILE): Use the defaults.
+ (srcs): Add memcmp.c.
+ (distfiles): Rename config.h.in->config.hin, install.sh->install-sh.
+ (Makefile, config.h, config.hin, config.status): Rework for
+ compatibility with Autoconf 2.
+ * io.c (binary_file_p): Assume non-broken memchr.
+ * memchr.c: Assume compiler understands void *; otherwise
+ we don't match GCC's internal declaration of memchr.
+ * system.h: Use more modern autoconf approach to standard C headers.
+ * version.c: Include <config.h>, not "config.h".
+
+ * diff.c, diff.h (ignore_some_line_changes):
+ New variable; replaces `length_varies'.
+ (line_end_char): Replace with '\n'; it wasn't being used consistently.
+
+ * io.c (find_and_hash_each_line): Fix inconsistencies with -b -w -i and
+ incomplete lines. Put incomplete lines into their own bucket.
+ This means line_cmp no longer needs line length arguments,
+ and equivalence classes' line lengths no longer need to include \n.
+ Invoke line_cmp only if ignore_some_line_changes.
+ (prepare_text_end): -B no longer ignores missing newlines.
+ (read_files): Allocate another bucket for incomplete lines.
+
+ * util.c (line_cmp): Now takes just two arguments. No longer
+ optimizes for common case of exact equality; the caller does that
+ optimization now. The caller is changed accordingly.
+ Optimize for the common case of mostly equality.
+ Use isupper+tolower instead of islower+toupper, for consistency.
+
+ * waitpid.c (waitpid): Fix typo with internal scoping.
+
+Thu Sep 8 08:23:15 1994 Paul Eggert <eggert@twinsun.com>
+
+ * configure.in: Revamp for Autoconf 2.
+ * memchr.c, waitpid.c: New source files for substitute functions.
+ * Makefile.in (diff_o, diff3_o, sdiff_o): Add $(LIBOBJS).
+ (srcs): Add memchr.c, waitpid.c.
+ (distfiles): Add install.sh, memchr.c, waitpid.c, install.sh.
+ * system.h: Use Autoconf 2 style HAVE_DIRENT_H etc. macros for dirs.
+ * dir.c (dir_sort): Prefer NAMLEN (p) to strlen (p->d_name).
+ Change VOID_CLOSEDIR to CLOSEDIR_VOID for Autoconf 2.
+ * sdiff.c, util.c (memchr, waitpid): Remove; use new substitutes.
+ * diff3.c (read_diff): Use new waitpid substitute.
+
+ * cmp.c, diff.c, diff3.c, sdiff.c (check_stdout, try_help): New fns.
+ (usage): Just print more detailed usage message; let caller exit.
+ * diff.c (option_help): New variable.
+ (filetype): Add Posix.1b file types.
+
+Fri Sep 2 16:01:49 1994 Paul Eggert <eggert@twinsun.com>
+
+ * configure.in: Switch to new autoconf names. Add sys/file.h test.
+ * Makefile.in (distclean): Clean config.cache, config.log
+ (used by new autoconf).
+
+ * diff.c, diff3.c, (main), sdiff.c (trapsigs): If we'll have children,
+ make sure SIGCHLD isn't ignored.
+
+ * diff3.c (DIFF_CHUNK_SIZE): Removed. Get size from STAT_BLOCKSIZE.
+ (INT_STRLEN_BOUND): New macro.
+
+ * ifdef.c (format_group, groups_letter_value):
+ Use * instead of [] in prototypes.
+
+ * system.h: Include <sys/file.h> only if HAVE_SYS_FILE_H.
+ (S_IXGRP, S_IXOTH, S_IXUSR): Remove unused macros.
+
+ * util.c (begin_output): Check fdopen result.
+
+ The following changes simplify porting to non-Posix environments.
+ * cmp.c, diff.c, diff3.c, sdiff.c, (main): Call initialize_main first.
+ * diff.c (binary_I_O): New variable for --binary option.
+ (main, usage, compare_files): Support --binary option.
+ (compare_files): Use filename_lastdirchar to find last
+ directory char in a file name.
+ * cmp.c (main), diff.c (compare_files), dir.c (compare_names,
+ diff_dirs): Use filename_cmp to compare file names.
+ Use same_file to determine whether two files are the same.
+ * context.c (print_context_label): Check whether ctime yields 0.
+ * diff3.c (read_diff), sdiff.c (cleanup, main, waitpid),
+ util.c (begin_output): Use popen+pclose if !HAVE_FORK.
+ * io.c (sip): If HAVE_SETMODE, test for binary files in O_BINARY mode.
+ * sdiff.c (ck_fdopen): Function removed.
+ (edit): Use system if !HAVE_FORK.
+ (execdiff): Now assumes caller has pushed all args, plus trailing 0.
+ All callers changed.
+ (private_tempnam): Try TMP if TMPDIR isn't defined.
+ Fit temporary filenames into 8.3 limit.
+ * system.h (STAT_BLOCKSIZE): Don't define if already defined.
+ (min, max): Undef if already defined.
+ (filename_cmp, filename_lastdirchar, HAVE_FORK, HAVE_SETMODE,
+ initialize_main O_BINARY, same_file): New macros.
+
+Fri Jun 17 11:23:53 1994 David J. MacKenzie (djm@geech.gnu.ai.mit.edu)
+
+ * Makefile.in (info, dvi, diff.dvi): New targets.
+ (clean): Remove TeX output files.
+
+Fri Jun 17 05:37:52 1994 Paul Eggert (eggert@twinsun.com)
+
+ * cmp.c, io.c (word): Change from typedef to #define, to avoid
+ collision with Unicos 8.0 <sys/types.h>, which also typedefs `word'.
+
+Thu Apr 15 00:53:01 1994 Paul Eggert (eggert@twinsun.com)
+
+ * diff3.c (scan_diff_line), util.c (print_number_range): Don't
+ rely on promotion to make the old-style parameter type agree
+ with the prototype parameter type; this doesn't work on
+ Apollos running bsd4.3.
+
+Mon Jan 3 02:05:51 1994 Paul Eggert (eggert@twinsun.com)
+
+ * Makefile.in (LDFLAGS): Remove -g. Change all link commands
+ to use both $(CFLAGS) and $(LDFLAGS).
+
+Mon Dec 13 12:23:27 1993 Paul Eggert (eggert@twinsun.com)
+
+ * system.h: Don't assume dirent.h exists just because
+ _POSIX_VERSION is defined.
+
+Fri Dec 3 18:39:39 1993 Paul Eggert (eggert@twinsun.com)
+
+ * diff.c (main): allow -pu.
+
+Tue Nov 23 03:51:08 1993 Paul Eggert (eggert@twinsun.com)
+
+ * Makefile.in (distclean): Remove config.h.
+
+Wed Nov 10 00:28:27 1993 Paul Eggert (eggert@twinsun.com)
+
+ * Version 2.6 released.
+
+ * analyze.c (too_expensive): New variable, for heuristic to
+ limit the worst-case cost to O(N**1.5 log N) at the price of
+ producing suboptimal output for large inputs with many differences.
+ (diff_2_files): Initialize it.
+ (struct partition): New type.
+ (SNAKE_LIMIT): New macro; merely documents already-used number 20.
+ (diag): New `minimal' arg; all callers changed. Put results into
+ struct partition. Apply `too_expensive' heuristic. Tune.
+ (compareseq): New `minimal' arg; all callers changed. Tune.
+ (shift_boundaries): Improve heuristic to also coalesce adjacent runs
+ of changes more often.
+
+ * diff.c (long_options, main, usage): Add `--help'.
+ (main): Send version number to stdout, not stderr.
+ (usage): Send usage to stdout, not stderr.
+ (compare_files): Initialize `inf' properly.
+
+ * io.c (word): Change to `int'; it makes a big difference on x86.
+ (sip, slurp): Put off allocating room to hold the whole file until we
+ have to read the whole file. This wins if the file turns out
+ to be binary.
+
+ * util.c (xmalloc, xrealloc): "virtual memory" -> "memory"
+ (primes): Omit large primes if INT_MAX is small.
+
+ * sdiff.c (usage): Send usage to stdout, not stderr.
+ (long_options, main, usage): Add `--help'.
+ (main): Send version number to stdout, not stderr. Exit afterwards.
+
+ * diff3.c (usage): Send usage to stdout, not stderr.
+ (long_options, main, usage): Add `--help'.
+ (read_diff): Detect integer overflow in buffer size calculations.
+
+ * cmp.c (word): New type. All uses of `long' for
+ word-at-a-time comparisons changed to `word'.
+ (long_options, main, usage): Add `--help'.
+ (usage): Send usage to stdout, not stderr.
+ (main): Add `-v'. Send version number to stdout, not stderr.
+
+ * configure.in (AC_HAVE_HEADERS): Add unistd.h; remove AC_UNISTD_H.
+
+Mon Sep 27 07:20:24 1993 Paul Eggert (eggert@twinsun.com)
+
+ * diff.c (add_exclude_file): Cast memchr to (char *)
+ to suppress bogus warnings on some nonstandard hosts.
+
+ * Makefile.in (cmp): Add version.o.
+
+ * analyze.c (diff_2_files): Work around memcmp bug with size=0.
+
+ * cmp.c (main, usage, version_string): Add --version option.
+
+ * system.h (malloc, realloc): Declare only if !HAVE_STDLIB_H.
+ (memchr): Declare only if !HAVE_MEMCHR. These changes are
+ needed to keep some nonstandard hosts happy.
+
+ * util.c (memchr): Make first arg char const *
+ to match standard.
+ (xmalloc, xrealloc): Cast malloc, realloc
+ to (VOID *) to suppress bogus warnings on some nonstandard hosts.
+
+ * diff3.c (xmalloc, xrealloc): Cast malloc, realloc
+ to (VOID *) to suppress bogus warnings on some nonstandard hosts.
+
+ * sdiff.c (xmalloc, xrealloc): Cast malloc, realloc
+ to (VOID *) to suppress bogus warnings on some nonstandard hosts.
+ (lf_copy, lf_skip, lf_snarf): Cast memchr to (char *)
+ to suppress bogus warnings on some nonstandard hosts.
+ (memchr): Make first arg char const *
+ to match standard.
+
+Mon Sep 27 00:23:37 1993 Paul Eggert (eggert@twinsun.com)
+
+ * Version 2.5 released.
+
+ * analyze.c (diff_2_files): Work around memcmp bug with size=0.
+
+ * cmp.c (main, usage, version_string): Add --version option.
+ * Makefile.in (cmp): Add version.o.
+
+ * diff.c (add_exclude_file): Cast memchr to (char *)
+ to suppress bogus warnings on some nonstandard hosts.
+ * sdiff.c (lf_copy, lf_skip, lf_snarf): Likewise.
+
+ * diff3.c, sdiff.c, util.c (xmalloc, xrealloc): Cast malloc, realloc
+ to (VOID *) to suppress bogus warnings on some nonstandard hosts.
+
+ * sdiff.c, util.c (memchr): Make first arg char const *
+ to match standard.
+
+ * system.h (malloc, realloc): Declare only if !HAVE_STDLIB_H.
+ (memchr): Declare only if !HAVE_MEMCHR. These changes are
+ needed to keep some nonstandard hosts happy.
+
+ * xmalloc.c: Include <sys/types.h> always; some nonstandard hosts
+ need it for size_t even if STDC_HEADERS.
+
+Sat Sep 18 01:33:07 1993 Paul Eggert (eggert@twinsun.com)
+
+ * configure.in (AC_STAT_MACROS_BROKEN): Add.
+ * system.h (S_IS{BLK,CHR,DIR,FIFO,REG,SOCK}): Fix defns if
+ STAT_MACROS_BROKEN.
+
+ * Makefile.in (diff3, sdiff, cmp): Do not link $(ALLOCA).
+
+ * analyze.c (discard_confusing_lines): Make defn static, like decl.
+ * sdiff.c (xmalloc): Likewise.
+
+ * ifdef.c (format_group): Ensure isdigit argument isn't < 0.
+
+ * side.c (print_half_line): Use isprint, since some hosts lack isgraph.
+ * util.c (output_1_line): Likewise. Ensure its argument isn't < 0.
+ (xmalloc, xrealloc): Remove needless casts.
+
+ * system.h (volatile, const):
+ Define these before including any system headers,
+ so that they're used consistently in all system includes.
+ (getenv, malloc, realloc): Declare even if HAVE_STDLIB_H, since some
+ <stdlib.h>s don't declare them.
+ (memchr): Likewise for <string.h>.
+
+ * cmp.c, diff3.c, diff.h, sdiff.c: Include "system.h" first.
+ * diff.c: Remove redundant "system.h" inclusion.
+
+ * diff3.c (xmalloc): Now static.
+ (xmalloc, realloc): Remove needless casts.
+ (READNUM): Ensure isdigit argument isn't negative.
+
+Wed Sep 14 07:14:15 1993 Paul Eggert (eggert@twinsun.com)
+
+ * Version 2.4 released.
+
+ * ifdef.c (scan_char_literal): New function, for new %c'x' and
+ %c'\ooo' format specs.
+ (format_group, print_ifdef_lines): Use it. Remove %0 format spec.
+
+ * cmp.c (cmp): Don't try to read past end of file; this doesn't
+ work on ttys.
+
+ * system.h, version.c: #include <config.h>, not "config.h", to allow
+ configuring in a separate directory when the source directory has
+ already been configured.
+ * Makefile.in (COMPILE): New defn, with proper -I options so that
+ `#include <config.h>' works.
+ (.c.o, diff3.o, sdiff.o): Use it.
+
+Mon Sep 13 06:45:43 1993 Paul Eggert (eggert@twinsun.com)
+
+ * diff.c (main, longopts): Add --line-format=FORMAT option.
+ (specify_format): Args no longer const pointers. All callers changed.
+
+ * ifdef.c: Add support for %?c, %(A=B?T:E), PRINTF_SPECn formats.
+ (struct group): New struct.
+ (print_ifdef_lines): Use it to simplify argument passing.
+ Remove the convention that last arg -1 signifies that the lines
+ from file 2 are the same as the lines from file 1; this
+ convention no longer works, now that line numbers might be
+ printed out, since the line numbers may differ.
+ Add first FILE * argument to output to. All callers changed.
+ Use a faster test for the single-fwrite optimization.
+ (format_group, scan_printf_spec, groups_letter_value): New functions.
+
+ * diff.h (group_format, line_format): No longer const pointers.
+ (format_ifdef): 1st arg is no longer const pointer.
+
+ * configure.in: Configure HAVE_LIMITS_H, HAVE_STDLIB_H.
+ * system.h <limits.h>, <stdlib.h>, <string.h>:
+ Include only if HAVE_LIMITS_H etc.
+
+ * system.h (memcmp, memcpy, strchr, strrchr, struct dirent): Prefer
+ these standard names to the traditional names (bcmp, bcpy, index,
+ rindex, struct direct). All callers changed.
+
+ * system.h (PARAMS, VOID):
+ Define earlier so that malloc decl can use VOID.
+ (STAT_BLOCKSIZE): Simplify ersatz defn; just use 8K.
+
+Fri Sep 3 00:21:02 1993 Paul Eggert (eggert@twinsun.com)
+
+ * diff.c (compare_files): Two files with the same name must be
+ the same file; avoid a needless `stat' in that case.
+
+Fri Aug 27 06:59:03 1993 Paul Eggert (eggert@twinsun.com)
+
+ * Pervasive changes for portability to 64-bit hosts:
+ Add prototypes to function declarations.
+ Use size_t, not int, when needed.
+
+ * Other pervasive changes:
+ Use `const' more often.
+ Use STD{IN,OUT,ERR}_FILENO instead of [012].
+ Use 0, not NULL, for portability to broken hosts.
+
+ * Makefile.in: (srcs, objs, distfiles, cmp): New files cmpbuf.[ch].
+ (distfiles): New files config.h.in, mkinstalldirs.
+ (.c.o): Add -DHAVE_CONFIG_H.
+
+ * analyze.c: (diag): Pacify `gcc -Wall' with a useless assignment.
+ (diff_2_files): Use l.c.m., not max, of files' buffer sizes.
+
+ * cmp.c: Make globals static when possible.
+
+ (file): Now a 2-element array; replaces `file1' and `file2'.
+ (file_desc, buffer): Likewise, for file[12]_desc and buf[12].
+ (main): Likewise, for stat_buf[12]. Index these variables with `i'.
+
+ (ignore_initial): New var.
+ (long_options): Now const. Add `--ignore-initial'.
+ (usage): Sort options and add `--ignore-initial'.
+ (main, cmp): Add `--ignore-initial' support.
+
+ (main): `cmp - -' now succeeds.
+ When comparing standard input to a file, and using a shortcut (e.g.
+ looking at file sizes or inode numbers), take the lseek offset into
+ account before deciding whether the files are identical.
+ Avoid mentioning `dev_t', `ino_t' for portability to nonstandard hosts.
+ Use l.c.m. of files' buffer sizes, not 8 * 1024.
+ ferror (stdout) does not imply errno has a useful value.
+ If 2nd file is "-", treat it first, in case stdin is closed.
+
+ (cmp): Always compute `char_number', `smaller' for speed and simplicity.
+ Say `cmp: EOF on input', not `/usr/gnu/bin/cmp: EOF on input',
+ as per Posix.2.
+
+ (block_compare_and_count): Increment line_number argument.
+ Remove end_char argument; it's always '\n'. All callers changed.
+ Do not assume sizeof(long) == 4; this isn't true on some 64-bit hosts.
+ (block_compare): Minimize differences with block_compare_and_count.
+
+ (block_read): Coalesce `bp += nread's.
+
+ (printc): Remove `FILE *' arg; output to stdout. All callers changed.
+
+ * configure.in: Configure HAVE_SIGACTION, RETSIGTYPE, HAVE_VPRINTF.
+ Configure into config.h.
+
+ * context.c (print_context_label):
+ Standard input's st_mtime is no longer a special case
+ here, since `compare_files' now sets it to the current time.
+
+ * diff.c (usage): Sort options.
+ (filetype): New function.
+ (compare_files): Set stdin's st_mtime to be the current time.
+ Leave its name "-" instead of changing it to "Standard Input";
+ to test whether a file is stdin, we must compare its name to "-" instead
+ of its desc to 0, since if it's closed other file descs may be 0.
+ When comparing standard input to a file, and using a shortcut (e.g.
+ looking at file sizes or inode numbers), take the lseek offset into
+ account before deciding whether the files are identical.
+ Pretend that nonexistent files have the same filetype as existing files.
+ Rename `errorcount' to `failed', since it's boolean.
+ In directory comparisons, if a file is neither a regular file nor a
+ directory, just print its type and the other file's type.
+
+ * diff.h (Is_space, textchar): Remove.
+ (struct msg, msg_chain, msg_chain_end): Move to util.c.
+ (VOID): Move to system.h.
+ (line_cmp, version_string, change_letter, print_number_range,
+ find_change): New decls.
+
+ * diff.texi:
+ whitespace -> white space. It now stands for whatever isspace yields.
+ Add --ignore-initial.
+
+ * diff3.c (VOID): Move to system.h.
+ (version_string): Now char[].
+ (usage): Sort options.
+ (process_diff): Pacify `gcc -Wall' with a useless assignment.
+ (read_diff): pid is of type pid_t, not int. Use waitpid if available.
+ (output_diff3): Simplify test for `\ No newline at end of file' message.
+
+ * dir.c (struct dirdata): Rename `files' to `names' to avoid confusion
+ with external struct file_data `files'.
+
+ * io.c (line_cmp): Move declaration to diff.h.
+ (textchar): Remove.
+ (find_and_hash_each_line): Use locale's definition of white space
+ instead of using one hardwired defn for -b and another for -w.
+
+ * normal.c (change_letter, print_number_range, find_change):
+ Move decls to diff.h.
+ (print_normal_hunk): Now static.
+
+ * sdiff.c (SEEK_SET): Move to system.h.
+ (version_string): Now char[], not char*.
+ (private_tempnam): Remove hardcoded limit on temporary file names.
+ (exiterr, perror_fatal, main): When exiting because of a signal,
+ exit with that signal's status.
+ (lf_refill, main, skip_white, edit, interact): Check for signal.
+ (ignore_SIGINT): Renamed from `ignore_signals'.
+ (NUM_SIGS, initial_handler): New macros.
+ (initial_action, signal_received, sigs_trapped): New vars.
+ (catchsig, trapsigs): Use sigaction if possible, since this closes the
+ windows of vulnerability that `signal' has. Use RETSIGTYPE not void.
+ When a signal comes in, just set a global variable; this is safer.
+ (checksigs, untrapsig): New functions.
+ (edit): Pacify `gcc -Wall' with a useless assignment.
+ Respond to each empty line with help, not to every other empty line.
+ (private_tempnam): Remove hardcoded limit on temporary file name length.
+ Don't assume sizeof (pid_t) <= sizeof (int).
+
+ * system.h: (S_IXOTH, S_IXGRP, S_IXUSR,
+ SEEK_SET, SEEK_CUR,
+ STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO):
+ New macros, if system doesn't define them.
+ (volatile): Don't define if already defined.
+ (PARAMS): New macro.
+ (VOID): Move here from diff.h.
+
+ * util.c (struct msg, msg_chain, msg_chain_end): Moved here from diff.h.
+ (message5): New function.
+ (pr_pid): New var.
+ (begin_output): Allocate `name' more precisely.
+ Put child pid into pr_pid, so that we can wait for it later.
+ Don't check execl's return value, since any return must be an error.
+ (finish_output): Detect and report output errors.
+ Use waitpid if available. Check pr exit status.
+ (line_cmp): Use locale's definition of white space
+ instead of using one hardwired defn for -b and another for -w.
+ (analyze_cmp): Avoid double negation with `! nontrivial'.
+ Pacify `gcc -Wall' be rewriting for-loop into do-while-loop.
+ (dir_file_pathname): New function.
+
+ * version.c (version_string): Now char[], not char*.
+
+Thu Jul 29 20:44:30 1993 David J. MacKenzie (djm@wookumz.gnu.ai.mit.edu)
+
+ * Makefile.in (config.status): Run config.status --recheck, not
+ configure, to get the right args passed.
+
+Thu Jul 22 10:46:30 1993 Paul Eggert (eggert@twinsun.com)
+
+ * Makefile.in (dist): Replace `if [ ! TEST ]; then ACTION; fi'
+ with `[ TEST ] || ACTION || exit' so that the containing for-loop exits
+ with proper status for `make'.
+
+Thu Jul 8 19:47:22 1993 David J. MacKenzie (djm@goldman.gnu.ai.mit.edu)
+
+ * Makefile.in (installdirs): New target.
+ (install): Use it.
+ (Makefile, config.status, configure): New targets.
+
+Sat Jun 5 23:10:40 1993 Paul Eggert (eggert@twinsun.com)
+
+ * Makefile.in (dist): Switch from .z to .gz.
+
+Wed May 26 17:16:02 1993 Paul Eggert (eggert@twinsun.com)
+
+ * diff.c (main): Cast args to compare_files, for traditional C.
+ * side.c (print_sdiff_common_lines_print_sdiff_hunk): Likewise.
+ * analyze.c, diff3.c, sdiff.c, util.c: Don't assume NULL is defined
+ properly.
+
+Tue May 25 14:54:05 1993 Paul Eggert (eggert@twinsun.com)
+
+ * analyze.c (diff_2_files): With -q, do not report that files differ
+ if all their differences are ignored.
+ (briefly_report): New function.
+ * diff.h (ignore_some_changes): New variable.
+ * diff.c (compare_files): Don't use the file size shortcut if
+ ignore_some_changes is nonzero, since the file size may differ
+ merely due to ignored changes.
+ (main): Set ignore_some_changes if we might ignore some changes.
+ Remove unsystematic assignment of 0 to static vars.
+ * io.c (read_files): New argument PRETEND_BINARY says whether to
+ pretend the files are binary.
+
+ * diff3.c (tab_align_flag): New variable, for new -T option.
+ (main, usage, output_diff3): Add support for -T.
+
+Sun May 23 15:25:29 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu)
+
+ * dir.c (dir_sort): Always init `data' to avoid GCC warning.
+
+Sat May 22 15:35:02 1993 Paul Eggert (eggert@twinsun.com)
+
+ * Makefile.in (dist): Change name of package from diff to diffutils.
+ Don't bother to build .Z dist; .z suffices.
+
+Fri May 21 16:35:22 1993 Paul Eggert (eggert@twinsun.com)
+
+ * diff.c: Include "system.h" to get memchr declaration.
+ * system.h (memchr): Declare if !HAVE_MEMCHR, not if
+ !HAVE_MEMCHR && !STDC_HEADERS.
+
+Wed May 19 17:43:55 1993 Paul Eggert (eggert@twinsun.com)
+
+ * Version 2.3 released.
+
+Fri Apr 23 17:18:44 1993 Paul Eggert (eggert@twinsun.com)
+
+ * io.c (find_identical_ends): Do not discard the last HORIZON_LINES
+ lines of the prefix, or the first HORIZON_LINES lines of the suffix.
+ * diff.c (main, longopts, usage): Add --horizon-lines option.
+ * diff3.c (main, process_diff, read_diff): Invoke second diff
+ with --horizon-lines determined by the first diff.
+ * diff.h, diff3.c (horizon_lines): New variable.
+
+Mon Mar 22 16:16:00 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu)
+
+ * system.h [HAVE_STRING_H || STDC_HEADERS] (bcopy, bcmp, bzero):
+ Don't define if already defined.
+
+Fri Mar 5 00:20:16 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu)
+
+ * diff.c (main): Use NULL in arg to compare_files.
+
+Thu Feb 25 15:26:01 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu)
+
+ * system.h: Declare memchr #if !HAVE_MEMCHR && !STDC_HEADERS,
+ not #if !HAVE_MEMCHR || !STDC_HEADERS.
+
+Mon Feb 22 15:04:46 1993 Richard Stallman (rms@geech.gnu.ai.mit.edu)
+
+ * io.c (find_identical_ends): Move complicated arg outside GUESS_LINES.
+
+Mon Feb 22 12:56:12 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu)
+
+ * Makefile.in (.c.o): Add -I$(srcdir); put $(CFLAGS) last before $<.
+
+Sat Feb 20 19:18:56 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu)
+
+ * io.c (binary_file_p): Return zero if file size is zero.
+
+Fri Feb 19 17:31:32 1993 Roland McGrath (roland@geech.gnu.ai.mit.edu)
+
+ * Version 2.2 released.
+
+ * system.h [HAVE_STRING_H || STDC_HEADERS] (index, rindex): Don't
+ define if already defined.
+
+Wed Feb 17 17:08:00 1993 Roland McGrath (roland@churchy.gnu.ai.mit.edu)
+
+ * Makefile.in (srcs): Remove limits.h.
+
+Thu Feb 11 03:36:00 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu)
+
+ * diff3.c (xmalloc): No longer static.
+
+ * sdiff.c (edit): Allocate buf dynamically.
+
+ * dir.c (dir_sort): Handle VOID_CLOSEDIR.
+
+Wed Feb 10 00:15:54 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu)
+
+ * limits.h: File deleted (should never have been there).
+
+Tue Feb 9 03:53:22 1993 Richard Stallman (rms@mole.gnu.ai.mit.edu)
+
+ * Makefile.in (.c.o, diff3.o, sdiff.o): Put $(CFLAGS) last.
+
+Wed Feb 3 15:42:10 1993 David J. MacKenzie (djm@goldman.gnu.ai.mit.edu)
+
+ * system.h: Don't #define const; let configure do it.
+
+Mon Feb 1 02:13:23 1993 Paul Eggert (eggert@hal.gnu.ai.mit.edu)
+
+ * Version 2.1 released.
+
+ * Makefile.in (dist): Survive ln failures. Create .tar.z
+ (gzipped tar) file as well as .tar.Z (compressed tar) file.
+
+Fri Jan 8 22:31:41 1993 Paul Eggert (eggert@twinsun.com)
+
+ * side.c (print_half_line): When the input position falls
+ outside the column, do not output a tab even if the output
+ position still falls within the column.
+
+Mon Dec 21 13:54:36 1992 David J. MacKenzie (djm@kropotkin.gnu.ai.mit.edu)
+
+ * Makefile.in (.c.o): Add -I.
+
+Fri Dec 18 14:08:20 1992 Paul Eggert (eggert@twinsun.com)
+
+ * configure.in: Add HAVE_FCNTL_H, since system.h uses it.
+
+Tue Nov 24 10:06:48 1992 David J. MacKenzie (djm@goldman.gnu.ai.mit.edu)
+
+ * Makefile.in: Note change from USG to HAVE_STRING_H.
+
+Mon Nov 23 18:44:00 1992 Paul Eggert (eggert@twinsun.com)
+
+ * io.c (find_and_hash_each_line): When running out of lines,
+ double the number of allocated lines, instead of just doubling
+ that number minus the prefix lines. This is more likely to
+ avoid the need for further memory allocation.
+
+Wed Nov 18 20:40:28 1992 Paul Eggert (eggert@twinsun.com)
+
+ * dir.c (dir_sort): Plug memory leak: space holding directory
+ contents was not being reclaimed. Get directory size from
+ struct file_data for initial guess at memory needed.
+ Detect errors when reading and closing directory.
+ (diff_dirs): Pass struct file_data to dir_sort. Finish plugging leak.
+ * diff.c (compare_files): Pass struct file_data to diff_dirs.
+
+ * io.c (find_and_hash_each_line): Don't assume alloc_lines is
+ nonzero when allocating more lines.
+
+Thu Nov 12 16:02:18 1992 Paul Eggert (eggert@twinsun.com)
+
+ * diff.c (main): Add `-U lines' as an alias for `--unified=lines'.
+
+ * diff3.c (usage): Add third --label option in example.
+
+ * util.c (analyze_hunk): Fix test for ignoring blank lines.
+
+ * configure.in, system.h: Avoid USG; use HAVE_TIME_H etc. instead.
+
+Mon Nov 9 05:13:25 1992 Paul Eggert (eggert@twinsun.com)
+
+ * diff3.c (main, usage): Add -A or --show-all.
+ -m now defaults to -A, not -E. Allow up to three -L options.
+ (output_diff3_edscript, output_diff3_merge):
+ Remove spurious differences between these two functions.
+ Output ||||||| for -A. Distinguish between conflicts and overlaps.
+ (dotlines, undotlines): New functions that output `Ns', not `N,Ns'.
+ (output_diff3_edscript, output_diff3_merge): Use them.
+
+ * io.c (find_identical_ends): shift_boundaries needs an extra
+ identical line at the end, not at the beginning.
+
+ * sdiff.c (edit): execvp wants char **, not const char **.
+
+Mon Oct 19 04:39:32 1992 Paul Eggert (eggert@twinsun.com)
+
+ * context.c (print_context_script, find_function): Context
+ line numbers start with - file->prefix_lines, not 0.
+
+ * io.c (binary_file_p): Undo last change; it was a library bug.
+
+Sun Oct 18 00:17:29 1992 Richard Stallman (rms@mole.gnu.ai.mit.edu)
+
+ * io.c (binary_file_p): Consider empty file as non-binary.
+
+Mon Oct 5 05:18:46 1992 Paul Eggert (eggert@twinsun.com)
+
+ * diff3.c (main, make_3way_diff, using_to_diff3_block): Don't
+ report bogus differences (for one of -mexEX3) just because the
+ file0-file1 diffs don't line up with the file0-file2 diffs.
+ (This is entirely possible since we don't use diff's -n
+ option.) Always compare file1 to file2, so that diff3 sees
+ those changes directly. Typically, file2 is now the common
+ file, not file0.
+ (output_diff3_merge): The input file is file 0, not the common file.
+
+ (FC, FO): New macros; they replace FILE1, FILE0 for two-way diffs,
+ to distinguish them from three-way diffs.
+
+ * diff3.c (using_to_diff3_block): Fold repeated code into loops.
+
+ * diff3.c (make_3way_diff, process_diff): Have the *_end
+ variable point to the next field to be changed, not to the last
+ object allocated; this saves an if-then-else.
+
+ * diff3.c (process_diff): Use D_NUMLINES instead of its definiens.
+
+ * diff3.c: Make fns and vars static unless they must be external.
+
+Wed Sep 30 09:21:59 1992 Paul Eggert (eggert@twinsun.com)
+
+ * analyze.c (diff_2_files): OUTPUT_IFDEF is now robust.
+ * diff.h (ROBUST_OUTPUT_STYLE): Likewise.
+ (default_line_format): Remove. All refs removed.
+
+ * ifdef.c (print_ifdef_lines): Add %L. Optimize %l\n even if user
+ specified it, as opposed to its being the default.
+
+Tue Sep 29 19:01:28 1992 Paul Eggert (eggert@twinsun.com)
+
+ * diff.c (longopts, main): --{old,new,unchanged,changed}--group-format
+ are new options, so that -D is no longer overloaded. Set
+ no_diff_means_no_output if --unchanged-{line,group}-format allows it.
+ * diff.h (enum line_class): New type.
+ (group_format, line_format): Use it to regularize option flags.
+ All refs changed.
+
+ * ifdef.c (format_ifdef, print_ifdef_lines): %n is no longer a format.
+
+Mon Sep 28 04:51:42 1992 Paul Eggert (eggert@twinsun.com)
+
+ * diff.c (main, usage): Replace --line-prefix with the more general
+ --{old,new,unchanged}-line-format options.
+ * ifdef.c (format_ifdef, print_ifdef_lines): Likewise.
+ * diff.h (line_format): Renamed from line_prefix. All refs changed.
+ * diff.h, ifdef.c (default_line_format): New variable.
+ * util.c (output_1_line): New function.
+ (print_1_line): Use it.
+
+ * ifdef.c: (format_ifdef, print_ifdef_lines): Add %0 format.
+
+Sun Sep 27 05:38:13 1992 Paul Eggert (eggert@twinsun.com)
+
+ * diff.c (main): Add -E or --line-prefix option. Add -D'=xxx'
+ for common lines. Change default -D< format from copy of -D>
+ format to to -D<%<; similarly for default -D> format.
+ * diff.h (common_format, line_prefix): New variables.
+ * ifdef.c (format_ifdef): New function.
+ (print_ifdef_script, print_ifdef_hunk, print_ifdef_lines):
+ Use it for -D'=xxx', -E.
+
+ * context.c (find_hunk): Glue together two non-ignorable changes that
+ are exactly CONTEXT * 2 lines apart. This shortens output, removes
+ a behavioral discontinuity at CONTEXT = 0, and is more compatible
+ with traditional diff.
+
+ * io.c (find_identical_ends): Slurp stdin at most once.
+
+ * util.c (print_line_line): line_flag is const char *.
+
+Thu Sep 24 15:18:07 1992 Paul Eggert (eggert@twinsun.com)
+
+ * ifdef.c (print_ifdef_lines): New function, which fwrites a sequence
+ of lines all at once for speed.
+ (print_ifdef_script, print_ifdef_hunk): Use it.
+
+Thu Sep 24 05:54:14 1992 Paul Eggert (eggert@twinsun.com)
+
+ * diff.c (main): Support new -D options for if-then-else formats.
+ (specify_format): New function.
+ * diff.h (ifndef_format, ifdef_format, ifnelse_format): New variables.
+ * ifdef.c (print_ifdef_hunk): Use the new variables instead of
+ a hardwired format.
+
+ * side.c (print_1sdiff_line): Represent incomplete lines on output.
+ (print_sdiff_script): Likewise. Don't print 'q' at end,
+ since that doesn't work with incomplete lines.
+ * sdiff.c (interact): Don't assume diff output ends with 'q' line.
+ * diff.h (ROBUST_OUTPUT_STYLE): OUTPUT_SDIFF is now robust.
+
+ * sdiff.c (lf_copy, lf_snarf): Use memchr instead of index,
+ to avoid dumping core when files contain null characters.
+ (memchr): New function (if memchr is missing).
+
+ * io.c (sip): New arg SKIP_TEST to skip test for binary file.
+ (read_files): Don't bother testing second file if first is binary.
+
+Thu Sep 17 21:17:49 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * system.h [!USG && !_POSIX_VERSION]: Protect from conflicting
+ prototype for wait in sys/wait.h.
+
+Wed Sep 16 12:32:18 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * Makefile.in: Include binprefix in -DDIFF_PROGRAM.
+
+Tue Sep 15 14:27:25 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * Version 2.0.
+
+Sat Sep 12 01:31:19 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * util.c, diff.h, system.h [!HAVE_MEMCHR]: Don't use void *
+ and const when declaring memchr replacement. Declare memchr
+ if !STDC_HEADERS && !USG.
+
+Thu Sep 10 15:17:32 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * Makefile.in (uninstall): New target.
+
+ * diff.c (excluded_filename): Use fnmatch, not wildmat.
+ (usage): Document -x, -X, --exclude, --exclude-from.
+ Makefile.in: Use fnmatch.c, not wildmat.c.
+
+Sun Sep 6 23:46:25 1992 Paul Eggert (eggert@twinsun.com)
+
+ * configure.in: Add HAVE_MEMCHR.
+ * diff.h, util.c: Use it instead of MEMCHR_MISSING.
+
+Sun Sep 6 07:25:49 1992 Paul Eggert (eggert@twinsun.com)
+
+ * diff.h: (struct line_def): Replace this 3-word struct with char *.
+ This uses less memory, particularly for large files with short lines.
+ (struct file_data): New member linbuf_base counts number of lines
+ in common prefix that are not recorded in linbuf;
+ this uses less memory if files are identical or differ only at end.
+ New member buffered_lines counts possibly differing lines.
+ New member valid_lines counts valid data.
+ New member alloc_lines - linbuf_base replaces old linbufsize.
+ linbuf[0] now always points at first differing line.
+ Remove unused members ltran, suffix_lines.
+ Add const where appropriate.
+ (Is_space): New macro, for consistent definition of `white space'.
+ (excluded_filename, memchr, sip, slurp): New declarations.
+ * ed.c (print_ed_hunk): Adjust to diff.h's struct changes.
+ * context.c (pr_context_hunk): Likewise.
+ * ifdef.c (print_ifdef_script): Likewise.
+ * side.c (print_sdiff_script, print_half_line): Likewise.
+ * util.c (analyze_hunk, line_cmp, print_1_line): Likewise.
+
+ * analyze.c (shift_boundaries): Remove unneeded variable `end' and
+ unnecessary comparisons of `preceding' and `other_preceding' against 0.
+ (diff_2_files): When comparing files byte-by-byte for equality,
+ don't slurp them all in at once; just compare them a buffer at a time.
+ This can win big if they differ early on.
+ Move some code to compare_files to enable this change.
+ Use only one buffer for stdin with `diff - -'.
+ (discard_confusing_lines, diff_2_files): Coalesce malloc/free calls.
+ (build_script): Remove obsolete OUTPUT_RCS code.
+
+ * diff.c (add_exclude, add_exclude_file, excluded_filename): New fns.
+ (main): Use them for the new --exclude and --exclude-from options.
+ (compare_files): Don't open a file unless it must be read.
+ Treat `diff file file' and `diff file dir' similarly.
+ Move some code here from diff_2_files to enable this.
+ Simplify file vs dir warning.
+
+ * dir.c (dir_sort): Support new --exclude* options.
+
+ * io.c (struct equivclass): Put hash code and line length here instead
+ of struct line_def, so that they can be shared.
+ (find_and_hash_each_line): Compute equivalence class as we go,
+ instead of doing it in a separate pass; this thrashes memory less.
+ Make buckets realloc-able, since we can't preallocate them.
+ Record one more line start than there are lines, so that we can compute
+ any line's length by subtracting its start from the next line's,
+ instead of storing the length explicitly. This saves memory.
+ Move prefix-handling code to find_identical_ends;
+ this wins with large prefixes.
+ Use Is_space, not is_space, for consistent treatment of white space.
+ (prepare_text_end): New function.
+ (find_identical_ends): Move slurping here, so it's only done when
+ needed. Work even if the buffers are the same (because of `diff - -').
+ Compare prefixes a word at a time for speed.
+ (find_equiv_class): Delete; now done by find_and_hash_each_line.
+ (read_files): Don't slurp unless needed.
+ find_equiv_class's work is now folded into find_and_hash_each_line.
+ Don't copy stdin buffer if `diff - -'.
+ Check for running out of primes.
+ (sip, slurp): Split first part of `slurp' into another function `sip'.
+ `sip' sets things up and perhaps reads the first ST_BLKSIZE buffer to
+ see whether the file is binary; `slurp' now just finishes the job.
+ This lets diff_2_files compare binary files lazily.
+ Allocate a one-word sentinel to allow word-at-a-time prefix comparison.
+ Count prefix lines only if needed, only count the first file's prefix.
+ Don't bother to count suffix lines; it's never needed.
+ Set up linbuf[0] to point at first differing line.
+ (binary_file_p): Change test for binary files:
+ if it has a null byte in its first buffer, it's binary.
+ (primes): Add more primes.
+
+ * util.c (line_cmp): Use bcmp for speed.
+ Use Is_space, not is_space, for consistent treatment of white space.
+ (translate_line_number): Internal line numbers now count from 0
+ starting after the prefix.
+ (memchr): New function (if memchr is missing).
+
+ * Makefile.in: Document HAVE_ST_BLKSIZE. Link with wildmat.o.
+ * system.h (STAT_BLOCKSIZE): New macro based on HAVE_ST_BLKSIZE.
+ * configure.in: Add AC_ST_BLKSIZE.
+ * wildmat.c: New file.
+
+Fri Sep 4 01:28:51 1992 Richard Stallman (rms@mole.gnu.ai.mit.edu)
+
+ * sdiff.c (xmalloc): Renamed from ck_malloc. Callers changed.
+
+Thu Sep 3 15:28:59 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * diff.h: Don't declare free, index, rindex.
+
+Tue Aug 11 22:18:06 1992 John Gilmore (gnu at cygnus.com)
+
+ * io.c (binary_file_p): Use heuristic to avoid declaring info
+ files as binary files. Allow about 1.5% non-printing
+ characters (in info's case, ^_).
+
+Tue Jul 7 01:09:26 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * diff.h: Replace function_regexp and ignore_regexp with lists
+ of compiled regexps.
+ * analyze.c, context.c, util.c: Test whether the lists, not
+ the old variables, are empty.
+ * util.c (analyze_hunk), context.c (find_function): Compare
+ lines with the lists of regexps.
+ * diff.c (add_regexp): New function.
+ (main): Use it.
+
+ * diff3: Add -v --version option.
+ * Makefile.in: Link with version.o.
+
+ * system.h: New file.
+ * diff.h, cmp.c, diff3.c, sdiff.c: Use it.
+
+ * diff.h, diff3.c: Include string.h or strings.h, as appropriate.
+ Declare malloc and realloc.
+
+ * diff3.c (perror_with_exit): Include program name in message.
+
+ * diff3.c: Lowercase error messages for GNU standards.
+
+ * sdiff.c [USG || STDC_HEADERS]: Define bcopy in terms of memcpy.
+
+ * sdiff.c: Use the version number from version.c.
+ * Makefile.in: Link with version.o.
+
+ * cmp.c error.c xmalloc.c: New files from textutils.
+ * Makefile.in: Add rules for them.
+
+ * diff.c (longopts): --unidirectional-new-file is like -P, not -N.
+ Rename --file-label to --label (leave old name, but undocumented).
+
+ * sdiff.c, diff.c (usage): Condense messages and fix some errors.
+
+ * diff3.c (main, usage): Add long-named options.
+
+Fri Jul 3 14:31:18 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu)
+
+ * diff.h, diff3.c, sdiff.c: Change FOO_MISSING macros to HAVE_FOO.
+
+Thu Jun 25 16:59:47 1992 David J. MacKenzie (djm@apple-gunkies.gnu.ai.mit.edu)
+
+ * diff.c: --reversed-ed -> --forward-ed.
+
+Wed Feb 26 12:17:32 1992 Paul Eggert (eggert@yata.uucp)
+
+ * analyze.c, diff.c, diff.h, io.c: For -y, compare even if same file.
+
+Fri Feb 14 22:46:38 1992 Richard Stallman (rms@mole.gnu.ai.mit.edu)
+
+ * io.c, diff3.c, analyze.c: Add extra parentheses.
+
+Sun Feb 9 00:22:42 1992 Richard Stallman (rms@mole.gnu.ai.mit.edu)
+
+ * diff.h (unidirectional_new_file_flag): New variable.
+ * diff.c (main): Set that for -P.
+ (compare_files): Support -P, somewhat like -N.
+ (longopts): Support long name for -P.
+
+Sat Jan 4 20:10:34 1992 Paul Eggert (eggert at yata.uucp)
+
+ * Makefile.in: Distribute diff.info-* too.
+
+ * README, sdiff.c: version number now matches version.c.
+
+ * configure: Fix and document vfork test.
+
+ * ifdef.c: Don't dump core if `diff -Dx f f'.
+
+Mon Dec 23 23:36:08 1991 David J. MacKenzie (djm at wookumz.gnu.ai.mit.edu)
+
+ * diff.h, diff3.c, sdiff.c: Change POSIX ifdefs to
+ HAVE_UNISTD_H and _POSIX_VERSION.
+
+Wed Dec 18 17:00:31 1991 David J. MacKenzie (djm at wookumz.gnu.ai.mit.edu)
+
+ * Makefile.in (srcs): Add sdiff.c.
+ (tapefiles): Add diff.texi and diff.info.
+
+ * diff.h, diff3.c, sdiff.c: Use HAVE_VFORK_H instead of
+ VFORK_HEADER and VFORK_WORKS.
+
+Tue Dec 17 00:02:59 1991 Paul Eggert (eggert at yata.uucp)
+
+ * Makefile.in (all): Add diff.info, sdiff.
+
+ * configure, diff.c, sdiff.c:
+ Prefix long options with `--', not `+'.
+ * diff.c: Regularize option names.
+
+ * configure: Fix check for vfork.
+ * configure, diff.c, diff.h, diff3.c, sdiff.c:
+ Use Posix definitions when possible.
+
+ * context.c: Align context with tab if -T is given. Tune.
+ * diff.c, diff.h, side.c: Calculate column widths so that tabs line up.
+ * io.c: Add distinction between white space and printing chars.
+ * side.c: Don't expand tabs unless -t is given.
+ * side.c, util.c: Tab expansion now knows about '\b', '\f', '\r', '\v'.
+ * util.c: -w skips all white space. Remove lint. Tune.
+
+ * sdiff.c: Support many more diff options, e.g. `-', `sdiff file dir'.
+ Ignore interrupts while the subsidiary editor is in control.
+ Clean up temporary file and kill subsidiary diff if interrupted.
+ Ensure subsidiary diff doesn't ignore SIGPIPE.
+ Don't get confused while waiting for two subprocesses.
+ Don't let buffers overflow. Check for I/O errors.
+ Convert to GNU style. Tune.
+
+ * sdiff.c, util.c: Don't lose errno.
+ Don't confuse sdiff with messages like `Binary files differ'.
+ * sdiff.c, side.c: Don't assume that common lines are identical.
+ Simplify --sdiff-merge-assist format.
+
+Mon Sep 16 16:42:01 1991 Tom Lord (lord at churchy.gnu.ai.mit.edu)
+
+ * Makefile.in, sdiff.c: introduced sdiff front end to diff.
+
+ * Makefile.in, analyze.c, diff.c, diff.h, io.c, side.c: Added
+ sdiff-style output format to diff.
+
+Mon Aug 26 16:44:55 1991 David J. MacKenzie (djm at pogo.gnu.ai.mit.edu)
+
+ * Makefile.in, configure: Only put $< in Makefile if using VPATH,
+ because older makes don't understand it.
+
+Fri Aug 2 12:22:30 1991 David J. MacKenzie (djm at apple-gunkies)
+
+ * configure: Create config.status. Remove it and Makefile if
+ interrupted while creating them.
+
+Thu Aug 1 22:24:31 1991 David J. MacKenzie (djm at apple-gunkies)
+
+ * configure: Check for +srcdir etc. arg and look for
+ Makefile.in in that directory. Set VPATH if srcdir is not `.'.
+ * Makefile.in: Get rid of $(archpfx).
+
+Tue Jul 30 21:28:44 1991 Richard Stallman (rms at mole.gnu.ai.mit.edu)
+
+ * Makefile.in (prefix): Renamed from DESTDIR.
+
+Wed Jul 24 23:08:56 1991 David J. MacKenzie (djm at wookumz.gnu.ai.mit.edu)
+
+ * diff.h, diff3.c: Rearrange ifdefs to use POSIX,
+ STDC_HEADERS, VFORK_MISSING, DIRENT. This way it works on
+ more systems that aren't pure USG or BSD.
+ Don't not define const if __GNUC__ is defined -- that would
+ break with -traditional.
+ * configure: Check for those features.
+
+Wed Jul 10 01:39:23 1991 David J. MacKenzie (djm at wookumz.gnu.ai.mit.edu)
+
+ * configure, Makefile.in: $(INSTALLPROG) -> $(INSTALL).
+
+Sat Jul 6 16:39:04 1991 David J. MacKenzie (djm at geech.gnu.ai.mit.edu)
+
+ * Replace Makefile with configure and Makefile.in.
+ Update README with current compilation instructions.
+
+Sat Jul 6 14:03:29 1991 Richard Stallman (rms at mole.gnu.ai.mit.edu)
+
+ * util.c (setup_output): Just save the args for later use.
+ (begin_output): Do the real work, with the values that were saved.
+ It's safe to call begin_output more than once.
+ Print the special headers for context format here.
+ * analyze.c (diff_2_files): Don't print special headers here.
+ * context.c (pr_context_hunk, pr_unidiff_hunk): Call begin_output.
+ * ed.c (print_ed_hunk, print_forward_ed_hunk, print_rcs_hunk):
+ * normal.c (print_normal_hunk): Likewise.
+ * ifdef.c (print_ifdef_hunk): Likewise.
+ * util.c (finish_output): Don't die if begin_output was not called.
+
+Thu Jun 20 23:10:01 1991 David J. MacKenzie (djm at geech.gnu.ai.mit.edu)
+
+ * Makefile: Add TAGS, distclean, and realclean targets.
+ Set SHELL.
+
+Tue Apr 30 13:54:36 1991 Richard Stallman (rms at mole.gnu.ai.mit.edu)
+
+ * diff.h (TRUE, FALSE): Undefine these before defining.
+
+Thu Mar 14 18:27:27 1991 Richard Stallman (rms@mole.ai.mit.edu)
+
+ * Makefile (objs): Include $(ALLOCA).
+
+Sat Mar 9 22:34:03 1991 Richard Stallman (rms at mole.ai.mit.edu)
+
+ * diff.h: Include regex.h.
+
+Thu Feb 28 18:59:53 1991 Richard Stallman (rms at mole.ai.mit.edu)
+
+ * Makefile (diff3): Link with GNU getopt.
+
+Sat Feb 23 12:49:43 1991 Richard Stallman (rms at mole.ai.mit.edu)
+
+ * io.c (find_equiv_class): Make hash code unsigned before mod.
+
+ * diff.h (files): Add EXTERN.
+
+Sun Jan 13 21:33:01 1991 Richard Stallman (rms at mole.ai.mit.edu)
+
+ * diff.c: +print option renamed +paginate. Remove +all-text.
+
+Mon Jan 7 06:18:01 1991 David J. MacKenzie (djm at geech.ai.mit.edu)
+
+ * Makefile (dist): New target, replacing diff.tar and
+ diff.tar.Z, to encode version number in distribution directory
+ and tar file names.
+
+Sun Jan 6 18:42:23 1991 Michael I Bushnell (mib at geech.ai.mit.edu)
+
+ * Version 1.15 released.
+
+ * version.c: Updated from 1.15 alpha to 1.15
+
+ * context.c (print_context_number_range,
+ print_unidiff_number_range): Don't print N,M when N=M, print
+ just N instead.
+
+ * README: Updated for version 1.15.
+ Makefile: Updated for version 1.15.
+
+ * diff3.c (main): Don't get confused if one of the arguments
+ is a directory.
+
+ * diff.c (compare_files): Don't get confused if comparing
+ standard input to a directory; print error instead.
+
+ * analyze.c (diff_2_files), context.c (print_context_header,
+ print_context_script), diff.c (main), diff.h (enum
+ output_style): Tread unidiff as an output style in its own
+ right. This also generates an error when both -u and -c are
+ given.
+
+ * diff.c (main): Better error messages when regexps are bad.
+
+ * diff.c (compare_files): Don't assume stdin is opened.
+
+ * diff3.c (read_diff): Don't assume things about the order of
+ descriptor assignment and closes.
+
+ * util.c (setup_output): Don't assume things about the order
+ of descriptor assignment and closes.
+
+ * diff.c (compare_files): Set a flag so that closes don't
+ happen more than once.
+
+ * diff.c (main): Don't just flush stdout, do a close. That
+ way on broken systems we can still get errors.
+
+Mon Dec 24 16:24:17 1990 Richard Stallman (rms at mole.ai.mit.edu)
+
+ * diff.c (usage): Use = for args of long options.
+
+Mon Dec 17 18:19:20 1990 Michael I Bushnell (mib at geech.ai.mit.edu)
+
+ * context.c (print_context_label): Labels were interchanged badly.
+
+ * context.c (pr_unidiff_hunk): Changes to deal with files
+ ending in incomplete lines.
+ * util.c (print_1_line): Other half of the changes.
+
+Mon Dec 3 14:23:55 1990 Richard Stallman (rms at mole.ai.mit.edu)
+
+ * diff.c (longopts, usage): unidiff => unified.
+
+Wed Nov 7 17:13:08 1990 Richard Stallman (rms at mole.ai.mit.edu)
+
+ * analyze.c (diff_2_files): No warnings about newlines for -D.
+
+ * diff.c (pr_unidiff_hunk): Remove ref to output_patch_flag.
+
+Tue Oct 23 23:19:18 1990 Richard Stallman (rms at mole.ai.mit.edu)
+
+ * diff.c (compare_files): For -D, compare even args are same file.
+ * analyze.c (diff_2_files): Likewise.
+ Also, output even if files have no differences.
+
+ * analyze.c (diff_2_files): Print missing newline messages last.
+ Return 2 if a newline is missing.
+ Print them even if files end with identical text.
+
+Mon Oct 22 19:40:09 1990 Richard Stallman (rms at mole.ai.mit.edu)
+
+ * diff.c (usage): Return 2.
+
+Wed Oct 10 20:54:04 1990 Richard Stallman (rms at mole.ai.mit.edu)
+
+ * diff.c (longopts): Add +new-files.
+
+Sun Sep 23 22:49:29 1990 Richard Stallman (rms at mole.ai.mit.edu)
+
+ * context.c (print_context_script): Handle unidiff_flag.
+ (print_context_header): Likewise.
+ (print_unidiff_number_range, pr_unidiff_hunk): New functions.
+ * diff.c (longopts): Add element for +unidiff.
+ (main): Handle +unidiff and -u.
+ (usage): Mention them.
+
+Wed Sep 5 16:33:22 1990 Richard Stallman (rms at mole.ai.mit.edu)
+
+ * io.c (find_and_hash_each_line): Deal with missing final newline
+ after buffering necessary context lines.
+
+Sat Sep 1 16:32:32 1990 Richard Stallman (rms at mole.ai.mit.edu)
+
+ * io.c (find_identical_ends): ROBUST_OUTPUT_FORMAT test was backward.
+
+Thu Aug 23 17:17:20 1990 Richard Stallman (rms at mole.ai.mit.edu)
+
+ * diff3.c (WIFEXITED): Undef it if WEXITSTATUS is not defined.
+ * context.c (find_function): Don't try to return values.
+
+Wed Aug 22 11:54:39 1990 Richard Stallman (rms at mole.ai.mit.edu)
+
+ * diff.h (O_RDONLY): Define if not defined.
+
+Tue Aug 21 13:49:26 1990 Richard Stallman (rms at mole.ai.mit.edu)
+
+ * Handle -L option.
+ * context.c (print_context_label): New function.
+ (print_context_header): Use that.
+ * diff.c (main): Recognize the option.
+ (usage): Updated.
+ * diff.h (file_label): New variable.
+ * diff3.c (main): Recognize -L instead of -t.
+
+ * diff3.c (main): Support -m without other option.
+
+ * diff3.c (WEXITSTATUS, WIFEXITED): Define whenever not defined.
+
+ * diff3.c (bcopy, index, rindex): Delete definitions; not used.
+ (D_LINENUM, D_LINELEN): Likewise.
+ (struct diff_block): lengths includes newlines.
+ (struct diff3_block): Likewise.
+ (always_text, merge): New variables.
+ (read_diff): Return address of end, not size read. Calls changed.
+ Pass -a to diff if given to diff3.
+ current_chunk_size now an int. Detect error in `pipe'.
+ Check for incomplete line of output here.
+ (scan_diff_line): Don't make scan_ptr + 2 before knowing it is valid.
+ No need to check validity of diff output here.
+ Include newline in length of line.
+ (main): Compute rev_mapping here. Handle -a and -m.
+ Error message if excess -t operands. Error for incompatible options.
+ Error if `-' given more than once.
+ Fix error storing in tag_strings.
+ (output_diff3): REV_MAPPING is now an arg. Call changed.
+ Change syntax of "missing newline" message.
+ Expect length of line to include newline.
+ (output_diff3_edscript): Return just 0 or 1.
+ REV_MAPPING is now an arg. Call changed.
+ (output_diff3_merge): New function.
+ (process_diff): Better error message for bad diff format.
+ (fatal, perror_with_exit): Return status 2.
+
+ * analyze.c (diff_2_files): Report missing newline in either
+ or both files, if not robust output style.
+
+ * util.c (setup_output): Detect error from pipe.
+ No need to close stdin.
+
+ * util.c (print_1_line): Change format of missing-newline msg.
+ Change if statements to switch.
+
+ * io.c (slurp): Don't mention differences in final newline if -B.
+
+ * io.c (binary_file_p): Use ISO char set as criterion, not ASCII.
+
+ * io.c (find_identical_ends): Increase value of BEG0 by 1.
+ Other changes in backwards scan to avoid decrementing pointers
+ before start of array, and set LINES properly.
+
+ * diff.h (ROBUST_OUTPUT_STYLE): New macro.
+ * io.c (find_identical_ends, find_and_hash_each_line): Use that macro.
+
+ * diff.h (dup2): Don't define if XENIX.
+
+ * diff.c (main): Check for write error at end.
+
+ * context.c (find_function): Don't return a value.
+ Use argument FILE rather than global files.
+
+ * analyze.c: Add external function declarations.
+ * analyze.c (build_script): Turn off explicit check for final newline.
+
+ * analyze.c (discard_confusing_lines): Make integers unsigned.
+
+Tue Jul 31 21:37:16 1990 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * io.c (find_and_hash_each_line): Correct the criterion
+ for leaving out the newline from the end of the line.
+
+Tue May 29 21:28:16 1990 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * dir.c (diff_dirs): Free things only if nonzero.
+
+Mon Apr 16 18:31:05 1990 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * diff.h (NDIR_IN_SYS): New macro controls location of ndir.h.
+
+ * diff3.c (xmalloc, xrealloc): Don't die if size == 0 returns 0.
+
+Sun Mar 25 15:58:42 1990 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * analyze.c (discard_confusing_lines):
+ `many' wasn't being used; use it.
+ Cancelling provisionals near start of run must handle already
+ cancelled provisionals.
+ Cancelling subruns of provisionals was cancelling last nonprovisional.
+
+Sat Mar 24 14:02:51 1990 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * analyze.c (discard_confusing_lines):
+ Threshold for line occurring many times scales by square root
+ of total lines.
+ Within each run, cancel any long subrun of provisionals.
+ Don't update `provisional' while cancelling provisionals.
+ In big outer loop, handle provisional and nonprovisional separately.
+
+Thu Mar 22 16:35:33 1990 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * analyze.c (discard_confusing_lines):
+ The first loops to discard provisionals from ends failed to step.
+ In second such loops, keep discarding all consecutive provisionals.
+ Increase threshold for stopping discarding, and also check for
+ consecutive nondiscardables as separate threshold.
+
+Fri Mar 16 00:33:08 1990 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * diff3.c (read_diff): Pass -- as first arg to diff.
+
+ * diff3.c: Include wait.h or define equivalent macros.
+ (read_diff): Don't use stdio printing error in the inferior.
+ Remember the pid and wait for it. Report failing status.
+ Report failure of vfork.
+
+Sun Mar 11 17:10:32 1990 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * diff3.c (main): Accept -t options and pass to output_diff3_edscript.
+ (usage): Mention -t.
+ (read_diff): Use vfork.
+ (vfork): Don't use it on Sparc.
+
+ * diff.h (vfork): Don't use it on Sparc.
+
+Tue Mar 6 22:37:20 1990 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * diff3.c (dup2): Don't define on Xenix.
+
+ * Makefile: Comments for Xenix.
+
+Thu Mar 1 17:19:23 1990 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * analyze.c (diff_2_files): `message' requires three args.
+
+Fri Feb 23 10:56:50 1990 David J. MacKenzie (djm at albert.ai.mit.edu)
+
+ * diff.h, util.c, diff3.c: Change 'void *' to 'VOID *', with
+ VOID defined as void if __STDC__, char if not.
+
+Sun Feb 18 20:31:58 1990 David J. MacKenzie (djm at albert.ai.mit.edu)
+
+ * Makefile: Add rules for getopt.c, getopt1.c, getopt.h.
+
+ * getopt.c, getopt.h, getopt1.c: New files.
+
+ * main.c (main, usage): Add long options.
+
+ * analyze.c (shift_boundaries): Remove unused var 'j_end'.
+
+Thu Feb 8 02:43:16 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
+
+ * GNUmakefile: include ../Makerules before Makefile.
+
+Fri Feb 2 23:21:38 1990 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * analyze.c (diif_2_files): If -B or -I, don't return 1
+ if all changes were ignored.
+
+Wed Jan 24 20:43:57 1990 Richard Stallman (rms at albert.ai.mit.edu)
+
+ * diff3.c (fatal): Output to stderr.
+
+Thu Jan 11 00:25:56 1990 David J. MacKenzie (djm at hobbes.ai.mit.edu)
+
+ * diff.c (usage): Mention -v.
+
+Wed Jan 10 16:06:38 1990 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * diff3.c (output_diff3_edscript): Return number of overlaps.
+ (main): If have overlaps, exit with status 1.
+
+Sun Dec 24 10:29:20 1989 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * io.c (find_equiv_class): Fix typo that came from changing init of B
+ to an assigment.
+
+ * version.c: New file.
+ * diff.c (main): -v prints version number.
+
+ * io.c (binary_file_p): Null char implies binary file.
+
+Fri Nov 17 23:44:55 1989 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * util.c (print_1_line): Fix off by 1 error.
+
+Thu Nov 16 13:51:10 1989 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * util.c (xcalloc): Function deleted.
+
+ * io.c (slurp): Null-terminate the buffer.
+
+ * io.c (read_files): Delete unused vars.
+
+ * io.c (find_equiv_class): Don't index by N if too low.
+
+ * dir.c (dir_sort): Delete the extra declaration of compare_names.
+
+ * diff.h: Don't declare xcalloc. Declare some other functions.
+
+ * analyze.c (shift_boundaries):
+ Test for END at end of range before indexing by it.
+ Fix typo `preceeding' in var names.
+
+Sat Nov 11 14:04:16 1989 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * diff3.c (using_to_diff3_block): Delete unused vars.
+ (make_3way_diff, process_diff_control, read_diff, output_diff3): Likewise.
+
+Mon Nov 6 18:15:50 EST 1989 Jay Fenlason (hack@ai.mit.edu)
+
+ * README Fix typo.
+
+Fri Nov 3 15:27:47 1989 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * diff.c (usage): Mention -D.
+
+ * ifdef.c (print_ifdef_hunk): Write comments on #else and #endif.
+
+Sun Oct 29 16:41:07 1989 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * diff.c (compare_files): Don't fflush for identical files.
+
+Wed Oct 25 17:57:12 1989 Randy Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * diff3.c (using_to_diff3_block): When defaulting lines from
+ FILE0, only copy up to just under the *lowest* line mentioned
+ in the next diff.
+
+ * diff3.c (fatal): Add \n to error messages.
+
+Wed Oct 25 15:05:49 1989 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * Makefile (tapefiles): Add ChangeLog.
+
+Tue Oct 3 00:51:17 1989 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * diff3.c (process_diff, create_diff3_block): Init ->next field.
+
+Fri Sep 29 08:16:45 1989 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * util.c (line_cmp): Alter end char of line 2, not line 1.
+
+Wed Sep 20 00:12:37 1989 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * Makefile (diff.tar): Expect ln to fail on some files;
+ copy them with cp.
+
+Mon Sep 18 02:54:29 1989 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * Handle -D option:
+ * io.c (find_and_hash_each_line): Keep all lines of 1st file.
+ * diff.c (main): Handle -D option.
+ (compare_files): Reject -D if files spec'd are directories.
+ * analyze.c (diff_2_files): Handle OUTPUT_IFDEF case.
+
+Fri Sep 1 20:15:50 1989 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * diff.c (option_list): Rename arg VECTOR as OPTIONVEC.
+
+Mon Aug 28 17:58:27 1989 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * diff.c (compare_files): Clear entire inf[i].stat.
+
+Wed Aug 23 17:48:47 1989 Richard Stallman (rms at apple-gunkies.ai.mit.edu)
+
+ * io.c (find_identical_ends): Sign was backward
+ determining where to bound the scan for the suffix.
+
+Wed Aug 16 12:49:16 1989 Richard Stallman (rms at hobbes.ai.mit.edu)
+
+ * analyze.c (diff_2_files): If -q, treat all files as binary.
+ * diff.c (main): Detect -q, record in no_details_flag.
+
+Sun Jul 30 23:12:00 1989 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * diff.c (usage): New function.
+ (main): Call it.
+
+Wed Jul 26 02:02:19 1989 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * diff.c (main): Make -C imply -c.
+
+Thu Jul 20 17:57:51 1989 Chris Hanson (cph at kleph)
+
+ * io.c (find_and_hash_each_line): Bug fix in context handling,
+ introduced by last change.
+
+Fri Jul 14 17:39:20 1989 Chris Hanson (cph at kleph)
+
+ * analyze.c: To make RCS work correctly on files that don't
+ necessarily end in newline, introduce some changes that cause
+ diffs to be sensitive to missing final newline. Because
+ non-RCS modes don't want to be affected by these changes, they
+ are conditional on `output_style == OUTPUT_RCS'.
+ (diff_2_files) [OUTPUT_RCS]: Suppress the "File X missing
+ newline" message.
+ (build_script) [OUTPUT_RCS]: Cause the last line to compare as
+ different if exactly one of the files is missing its final
+ newline.
+
+ * io.c (find_and_hash_each_line): Bug fix in
+ ignore_space_change mode. Change line's length to include the
+ newline. For OUTPUT_RCS, decrement last line's length if
+ there is no final newline.
+ (find_identical_ends) [OUTPUT_RCS]: If one of the files is
+ missing a final newline, make sure it's not included in either
+ the prefix or suffix.
+
+ * util.c (print_1_line): Change line output routine to account
+ for line length including the newline.
+
+Tue Jun 27 02:35:28 1989 Roland McGrath (roland at hobbes.ai.mit.edu)
+
+ * Makefile: Inserted $(archpfx) where appropriate.
+
+Wed May 17 20:18:43 1989 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * diff3.c [USG]: Include fcntl.h.
+
+ * diff.h [USG]: New compilation flags HAVE_NDIR, HAVE_DIRECT.
+
+Wed Apr 26 15:35:57 1989 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * dir.c (diff_dirs): Two new args, NONEX1 and NONEX2, say to pretend
+ nonex dirs are empty.
+ (dir_sort): New arg NONEX, likewise.
+ * diff.c (compare_files): Pass those args.
+ Sometimes call diff_dirs if subdir exists in just one place.
+
+Wed Apr 12 01:10:27 1989 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * io.c (find_identical_ends): Set END0 *after* last char
+ during backward scan for suffix.
+
+Sat Apr 8 15:49:49 1989 Randall Smith (randy at apple-gunkies.ai.mit.edu)
+
+ * diff3.c (using_to_diff3_block): Now find high marks in files 1
+ and 2 through mapping off of the last difference instead of the
+ first.
+
+ * diff3.c: Many trivial changes to spelling inside comments.
+
+Fri Feb 24 12:38:03 1989 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * util.c, normal.c, io.c, ed.c, dir.c, diff.h, diff.c, context.c,
+ analyze.c, Makefile: Changed copyright header to conform with new
+ GNU General Public license.
+ * diff3.c: Changed copyright header to conform with new GNU
+ General Public license.
+ * COPYING: Made a hard link to /gp/rms/COPYING.
+
+Fri Feb 24 10:01:58 1989 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * io.c (slurp): Leave 2 chars space at end of buffer, not one.
+ (find_identical_ends): Special case if either file is empty;
+ don't try to make a sentinel since could crash.
+
+Wed Feb 15 14:24:48 1989 Jay Fenlason (hack at apple-gunkies.ai.mit.edu)
+
+ * diff3.c (message) Re-wrote routine to avoid using alloca()
+
+Wed Feb 15 06:19:14 1989 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * io.c (find_identical_ends): Delete the variable `bytes'.
+
+Sun Feb 12 11:50:36 1989 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * io.c (slurp): ->bufsize is nominal amount we have room for;
+ add room for sentinel when calling xmalloc or xrealloc.
+
+ * io.c (find_identical_ends): Do need overrun check in finding suffix.
+
+Fri Feb 10 01:28:15 1989 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * diff.c (main): -C now takes arg to specify context length.
+ Now -p to show C function name--Damned IEEE!
+ Fatal error if context length spec'd twice.
+
+ * ed.c (print_ed_hunk): Now special treatment only for lines containing
+ precisely a dot and nothing else. Output `..', end the insert,
+ substitute that one line, then resume the insert if nec.
+
+ * io.c (find_and_hash_lines): When backing up over starting context,
+ don't move past buffer-beg.
+
+ * io.c (find_identical_ends): Use sentinels to make the loops faster.
+ If files are identical, skip the 2nd loop and return quickly.
+ (slurp): Leave 1 char extra space after each buffer.
+
+ * analyze.c (diff_2_files): Mention difference in final newlines.
+
+Wed Jan 25 22:44:44 1989 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * dir.c (diff_dirs): Use * when calling fcn ptr variable.
+
+Sat Dec 17 14:12:06 1988 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * Makefile: New vars INSTALL and LIBS used in some rules;
+ provide default defns plus commented-put defns for sysV.
+
+Thu Nov 17 16:42:53 1988 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * dir.c (dir_sort): Open-trouble not fatal; just say # files is -1.
+ (diff_dirs): If dir_sort does that, give up and return 2.
+
+ * diff.c (compare_files): Don't open directories.
+ Don't close them specially either.
+ Cross-propagate inf[i].dir_p sooner.
+
+Sun Nov 13 11:19:36 1988 Richard Stallman (rms at sugar-bombs.ai.mit.edu)
+
+ * diff.h: Declare index, rindex.
+
+ * diff.c (compare_files): If comparing foodir with b/f,
+ use foodir/f, not foodir/b/f.
+
+ * diff.c (compare_files): Don't print "are identical" msg for 2 dirs.
+ Status now 1 if one file is a dir and the other isn't, etc.
+
+Thu Nov 3 16:30:24 1988 Randall Smith (randy at gluteus.ai.mit.edu)
+
+ * Makefile: Added a define for diff3 to define DIFF_PROGRAM.
+
+ * util.c: Added hack to make sure that perror was not called with
+ a null pointer.
+
+ * diff.c: Changed S_IFDIR to S_IFMT in masking type of file bits
+ out.
+
+ * diff3.c: Included USG compatibility defines.
+
+ * diff.h: Moved sys/file.h into #else USG section (not needed or
+ wanted on System V).
+
+ * ed.c, analyze.c, context.c: Shortened names to 12 characters for
+ the sake of System V (too simple not to do).
+
+Local Variables:
+mode: indented-text
+left-margin: 8
+version-control: never
+End:
diff --git a/gnu/dist/diffutils/INSTALL b/gnu/dist/diffutils/INSTALL
new file mode 100644
index 00000000000..5c9d013aca4
--- /dev/null
+++ b/gnu/dist/diffutils/INSTALL
@@ -0,0 +1,179 @@
+Basic Installation
+==================
+
+ These are generic installation instructions.
+
+ The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation. It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions. Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+ If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release. If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+ The file `configure.in' is used to create `configure' by a program
+called `autoconf'. You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+ 1. `cd' to the directory containing the package's source code and type
+ `./configure' to configure the package for your system. If you're
+ using `csh' on an old version of System V, you might need to type
+ `sh ./configure' instead to prevent `csh' from trying to execute
+ `configure' itself.
+
+ Running `configure' takes awhile. While running, it prints some
+ messages telling which features it is checking for.
+
+ 2. Type `make' to compile the package.
+
+ 3. Optionally, type `make check' to run any self-tests that come with
+ the package.
+
+ 4. Type `make install' to install the programs and any data files and
+ documentation.
+
+ 5. You can remove the program binaries and object files from the
+ source directory by typing `make clean'. To also remove the files
+ that `configure' created (so you can compile the package for a
+ different kind of computer), type `make distclean'.
+
+Compilers and Options
+=====================
+
+ Some systems require unusual options for compilation or linking that
+the `configure' script does not know about. You can give `configure'
+initial values for variables by setting them in the environment. Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+ CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+ env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Using a Different Build Directory
+=================================
+
+ You can compile the package in a different directory from the one
+containing the source code. Doing so allows you to compile it on more
+than one kind of computer at the same time. To do this, you must use a
+version of `make' that supports the `VPATH' variable, such as GNU
+`make'. `cd' to the directory where you want the object files and
+executables to go and run the `configure' script. `configure'
+automatically checks for the source code in the directory that
+`configure' is in and in `..'.
+
+Installation Names
+==================
+
+ By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc. You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'. Alternately, you can do so by consistently
+giving a value for the `prefix' variable when you run `make', e.g.,
+ make prefix=/usr/gnu
+ make prefix=/usr/gnu install
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+give `configure' the option `--exec-prefix=PATH' or set the `make'
+variable `exec_prefix' to PATH, the package will use PATH as the prefix
+for installing programs and libraries. Documentation and other data
+files will still use the regular prefix.
+
+ If you use an unusual directory layout in which some of the
+installation directory names are not based on a single prefix, you can
+set the individual variables `bindir', `libdir', etc. on the `make'
+command line:
+ make bindir=/bin libdir=/usr/lib
+
+Check the `Makefile.in' files to see which variables each package uses.
+
+ If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+ Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System). The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+ For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+ There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on. Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option. TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+ CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field. If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+ If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+ If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/lib/config.site' if it exists, then
+`EXEC_PREFIX/lib/config.site' if it exists. Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+ `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+ Save the results of the tests in FILE instead of `config.cache'.
+ Set FILE to `/dev/null' to disable caching, for debugging
+ `configure'.
+
+`--help'
+ Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+ Do not print messages saying which checks are being made.
+
+`--srcdir=DIR'
+ Look for the package's source code in directory DIR. Usually
+ `configure' can determine that directory automatically.
+
+`--version'
+ Print the version of Autoconf used to generate the `configure'
+ script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
+
diff --git a/gnu/dist/diffutils/Makefile.in b/gnu/dist/diffutils/Makefile.in
new file mode 100644
index 00000000000..e8543ad6e4f
--- /dev/null
+++ b/gnu/dist/diffutils/Makefile.in
@@ -0,0 +1,198 @@
+# Makefile for GNU DIFF
+# Copyright (C) 1988,1989,1991,1992,1993,1994 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.
+
+#### Start of system configuration section. ####
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+CC = @CC@
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA = @INSTALL_DATA@
+MAKEINFO = makeinfo
+TEXI2DVI = texi2dvi
+
+CPPFLAGS = @CPPFLAGS@
+DEFS = @DEFS@
+CFLAGS = @CFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+LIBOBJS = @LIBOBJS@
+
+# Some System V machines do not come with libPW.
+# If this is true for you, use the GNU alloca.o here.
+ALLOCA = @ALLOCA@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+edit_program_name = sed '@program_transform_name@'
+
+bindir = $(exec_prefix)/bin
+
+infodir = $(prefix)/info
+
+DEFAULT_EDITOR_PROGRAM = ed
+DIFF_PROGRAM = $(bindir)/`echo diff | $(edit_program_name)`
+NULL_DEVICE = /dev/null
+PR_PROGRAM = /bin/pr
+
+#### End of system configuration section. ####
+
+SHELL = /bin/sh
+
+# The source files for all of the programs.
+srcs=diff.c analyze.c cmpbuf.c cmpbuf.h io.c context.c ed.c normal.c ifdef.c \
+ util.c dir.c memchr.c waitpid.c \
+ version.c diff.h regex.c regex.h side.c system.h \
+ diff3.c sdiff.c cmp.c error.c xmalloc.c getopt.c getopt1.c getopt.h \
+ fnmatch.c fnmatch.h alloca.c
+distfiles = $(srcs) README INSTALL NEWS diagmeet.note Makefile.in \
+ stamp-h.in config.hin configure configure.in COPYING ChangeLog \
+ diff.texi diff.info* texinfo.tex \
+ install-sh mkinstalldirs
+
+PROGRAMS = cmp diff diff3 sdiff
+
+all: $(PROGRAMS) info
+
+COMPILE = $(CC) -c $(CPPFLAGS) $(DEFS) -I. -I$(srcdir) $(CFLAGS)
+
+.c.o:
+ $(COMPILE) $<
+
+diff_o = diff.o analyze.o cmpbuf.o dir.o io.o util.o \
+ context.o ed.o ifdef.o normal.o side.o \
+ fnmatch.o getopt.o getopt1.o regex.o version.o $(ALLOCA) $(LIBOBJS)
+diff: $(diff_o)
+ $(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(diff_o) $(LIBS)
+
+diff3_o = diff3.o getopt.o getopt1.o version.o $(LIBOBJS)
+diff3: $(diff3_o)
+ $(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(diff3_o) $(LIBS)
+
+sdiff_o = sdiff.o getopt.o getopt1.o version.o $(LIBOBJS)
+sdiff: $(sdiff_o)
+ $(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(sdiff_o) $(LIBS)
+
+cmp_o = cmp.o cmpbuf.o error.o getopt.o getopt1.o xmalloc.o version.o $(LIBOBJS)
+cmp: $(cmp_o)
+ $(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(cmp_o) $(LIBS)
+
+info: diff.info
+diff.info: diff.texi
+ $(MAKEINFO) $(srcdir)/diff.texi --output=$@
+
+dvi: diff.dvi
+diff.dvi: diff.texi
+ $(TEXI2DVI) $(srcdir)/diff.texi
+
+$(diff_o): diff.h system.h
+cmp.o diff3.o sdiff.o: system.h
+context.o diff.o regex.o: regex.h
+cmp.o diff.o diff3.o sdiff.o getopt.o getopt1.o: getopt.h
+diff.o fnmatch.o: fnmatch.h
+analyze.o cmpbuf.o cmp.o: cmpbuf.h
+
+cmp.o: cmp.c
+ $(COMPILE) -DNULL_DEVICE=\"$(NULL_DEVICE)\" $(srcdir)/cmp.c
+
+diff3.o: diff3.c
+ $(COMPILE) -DDIFF_PROGRAM=\"$(DIFF_PROGRAM)\" $(srcdir)/diff3.c
+
+sdiff.o: sdiff.c
+ $(COMPILE) -DDEFAULT_EDITOR_PROGRAM=\"$(DEFAULT_EDITOR_PROGRAM)\" \
+ -DDIFF_PROGRAM=\"$(DIFF_PROGRAM)\" $(srcdir)/sdiff.c
+
+util.o: util.c
+ $(COMPILE) -DPR_PROGRAM=\"$(PR_PROGRAM)\" $(srcdir)/util.c
+
+TAGS: $(srcs)
+ etags $(srcs)
+
+clean:
+ rm -f *.o $(PROGRAMS) core
+ rm -f *.aux *.cp *.cps *.dvi *.fn *.fns *.ky *.kys *.log
+ rm -f *.pg *.pgs *.toc *.tp *.tps *.vr *.vrs
+
+mostlyclean: clean
+
+distclean: clean
+ rm -f Makefile config.cache config.h config.log config.status stamp-h
+
+realclean: distclean
+ rm -f TAGS *.info*
+
+install: all installdirs
+ for p in $(PROGRAMS); do \
+ $(INSTALL_PROGRAM) $$p $(bindir)/`echo $$p | $(edit_program_name)`; \
+ done
+ { test -f diff.info || cd $(srcdir); } && \
+ for f in diff.info*; do \
+ $(INSTALL_DATA) $$f $(infodir)/$$f; \
+ done
+
+installdirs:
+ $(SHELL) ${srcdir}/mkinstalldirs $(bindir) $(infodir)
+
+# We need more tests.
+check:
+ ./cmp cmp cmp
+ ./diff diff diff
+ ./diff3 diff3 diff3 diff3
+ ./sdiff sdiff sdiff
+
+uninstall:
+ for p in $(PROGRAMS); do \
+ rm -f $(bindir)/`echo $$p | $(edit_program_name)`; \
+ done
+ rm -f $(infodir)/diff.info*
+
+configure: configure.in
+ cd $(srcdir) && autoconf
+
+# autoheader might not change config.hin.
+config.hin: stamp-h.in
+stamp-h.in: configure.in
+ cd $(srcdir) && autoheader
+ date > $(srcdir)/stamp-h.in
+
+config.status: configure
+ ./config.status --recheck
+
+# config.status might not change config.h, but it changes stamp-h.
+config.h: stamp-h
+stamp-h: config.hin config.status
+ ./config.status
+Makefile: Makefile.in config.status
+ ./config.status
+
+dist: $(distfiles)
+ echo diffutils-`sed -e '/version_string/!d' -e 's/[^0-9]*\([0-9a-z.]*\).*/\1/' -e q version.c` > .fname
+ rm -rf `cat .fname`
+ mkdir `cat .fname`
+ -ln $(distfiles) `cat .fname`
+ for file in $(distfiles); do \
+ [ -r `cat .fname`/$$file ] || cp -p $$file `cat .fname` || exit; \
+ done
+ tar -chf - `cat .fname` | gzip >`cat .fname`.tar.gz
+ rm -rf `cat .fname` .fname
+
+# Prevent GNU make v3 from overflowing arg limit on SysV.
+.NOEXPORT:
diff --git a/gnu/dist/diffutils/NEWS b/gnu/dist/diffutils/NEWS
new file mode 100644
index 00000000000..dcde1227d30
--- /dev/null
+++ b/gnu/dist/diffutils/NEWS
@@ -0,0 +1,126 @@
+User-visible changes in version 2.7:
+
+* New diff option: --binary (useful only on non-Posix hosts)
+* diff -b and -w now ignore line incompleteness; -B no longer does this.
+* cmp -c now uses locale to decide which output characters to quote.
+* Help and version messages are reorganized.
+
+
+User-visible changes in version 2.6:
+
+* New cmp, diff, diff3, sdiff option: --help
+* A new heuristic for diff greatly reduces the time needed to compare
+ large input files that contain many differences.
+* Partly as a result, GNU diff's output is not exactly the same as before.
+ Usually it is a bit smaller, but sometimes it is a bit larger.
+
+
+User-visible changes in version 2.5:
+
+* New cmp option: -v --version
+
+
+User-visible changes in version 2.4:
+
+* New cmp option: --ignore-initial=BYTES
+* New diff3 option: -T --initial-tab
+* New diff option: --line-format=FORMAT
+* New diff group format specifications:
+ <PRINTF_SPEC>[eflmnEFLMN]
+ A printf spec followed by one of the following letters
+ causes the integer corresponding to that letter to be
+ printed according to the printf specification.
+ E.g. `%5df' prints the number of the first line in the
+ group in the old file using the "%5d" format.
+ e: line number just before the group in old file; equals f - 1
+ f: first line number in group in the old file
+ l: last line number in group in the old file
+ m: line number just after the group in old file; equals l + 1
+ n: number of lines in group in the old file; equals l - f + 1
+ E, F, L, M, N: likewise, for lines in the new file
+ %(A=B?T:E)
+ If A equals B then T else E. A and B are each either a decimal
+ constant or a single letter interpreted as above. T and E are
+ arbitrary format strings. This format spec is equivalent to T if
+ A's value equals B's; otherwise it is equivalent to E. For
+ example, `%(N=0?no:%dN) line%(N=1?:s)' is equivalent to `no lines'
+ if N (the number of lines in the group in the the new file) is 0,
+ to `1 line' if N is 1, and to `%dN lines' otherwise.
+ %c'C'
+ where C is a single character, stands for the character C. C may not
+ be a backslash or an apostrophe. E.g. %c':' stands for a colon.
+ %c'\O'
+ where O is a string of 1, 2, or 3 octal digits, stands for the
+ character with octal code O. E.g. %c'\0' stands for a null character.
+* New diff line format specifications:
+ <PRINTF_SPEC>n
+ The line number, printed with <PRINTF_SPEC>.
+ E.g. `%5dn' prints the line number with a "%5d" format.
+ %c'C'
+ %c'\O'
+ The character C, or with octal code O, as above.
+* Supported <PRINTF_SPEC>s have the same meaning as with printf, but must
+ match the extended regular expression %-*[0-9]*(\.[0-9]*)?[doxX].
+* The format spec %0 introduced in version 2.1 has been removed, since it
+ is incompatible with printf specs like %02d. To represent a null char,
+ use %c'\0' instead.
+* cmp and diff now conform to Posix.2 (ISO/IEC 9945-2:1993)
+ if the underlying system conforms to Posix:
+ - Some messages' wordings are changed in minor ways.
+ - ``White space'' is now whatever C's `isspace' says it is.
+ - When comparing directories, if `diff' finds a file that is not a regular
+ file or a directory, it reports the file's type instead of diffing it.
+ (As usual, it follows symbolic links first.)
+ - When signaled, sdiff exits with the signal's status, not with status 2.
+* Now portable to hosts where int, long, pointer, etc. are not all the same
+ size.
+* `cmp - -' now works like `diff - -'.
+
+
+User-visible changes in version 2.3:
+
+* New diff option: --horizon-lines=lines
+
+
+User-visible changes in version 2.1:
+
+* New diff options:
+ --{old,new,unchanged}-line-format='format'
+ --{old,new,unchanged,changed}-group-format='format'
+ -U
+* New diff3 option:
+ -A --show-all
+* diff3 -m now defaults to -A, not -E.
+* diff3 now takes up to three -L or --label options, not just two.
+ If just two options are given, they refer to the first two input files,
+ not the first and third input files.
+* sdiff and diff -y handle incomplete lines.
+
+
+User-visible changes in version 2.0:
+
+* Add sdiff and cmp programs.
+* Add Texinfo documentation.
+* Add configure script.
+* Improve diff performance.
+* New diff options:
+-x --exclude
+-X --exclude-from
+-P --unidirectional-new-file
+-W --width
+-y --side-by-side
+--left-column
+--sdiff-merge-assist
+--suppress-common-lines
+* diff options renamed:
+--label renamed from --file-label
+--forward-ed renamed from --reversed-ed
+--paginate renamed from --print
+--entire-new-file renamed from --entire-new-files
+--new-file renamed from --new-files
+--all-text removed
+* New diff3 options:
+-v --version
+* Add long-named equivalents for other diff3 options.
+* diff options -F (--show-function-line) and -I (--ignore-matching-lines)
+ can now be given more than once.
diff --git a/gnu/dist/diffutils/README b/gnu/dist/diffutils/README
new file mode 100644
index 00000000000..bfb99656a1b
--- /dev/null
+++ b/gnu/dist/diffutils/README
@@ -0,0 +1,9 @@
+This directory contains the GNU diff, diff3, sdiff, and cmp utilities.
+Their features are a superset of the Unix features and they are
+significantly faster. cmp has been moved here from the GNU textutils.
+
+See the file COPYING for copying conditions.
+See the file diff.texi (or diff.info*) for documentation.
+See the file INSTALL for compilation and installation instructions.
+
+Report bugs to bug-gnu-utils@prep.ai.mit.edu
diff --git a/gnu/dist/diffutils/alloca.c b/gnu/dist/diffutils/alloca.c
new file mode 100644
index 00000000000..7020f32c882
--- /dev/null
+++ b/gnu/dist/diffutils/alloca.c
@@ -0,0 +1,492 @@
+/* alloca.c -- allocate automatically reclaimed memory
+ (Mostly) portable public-domain implementation -- D A Gwyn
+
+ This implementation of the PWB library alloca function,
+ which is used to allocate space off the run-time stack so
+ that it is automatically reclaimed upon procedure exit,
+ was inspired by discussions with J. Q. Johnson of Cornell.
+ J.Otto Tennant <jot@cray.com> contributed the Cray support.
+
+ There are some preprocessor constants that can
+ be defined when compiling for your specific system, for
+ improved efficiency; however, the defaults should be okay.
+
+ The general concept of this implementation is to keep
+ track of all alloca-allocated blocks, and reclaim any
+ that are found to be deeper in the stack than the current
+ invocation. This heuristic does not reclaim storage as
+ soon as it becomes invalid, but it will do so eventually.
+
+ As a special case, alloca(0) reclaims storage without
+ allocating any. It is a good idea to use alloca(0) in
+ your main control loop, etc. to force garbage collection. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef emacs
+#include "blockinput.h"
+#endif
+
+/* If compiling with GCC 2, this file's not needed. */
+#if !defined (__GNUC__) || __GNUC__ < 2
+
+/* If someone has defined alloca as a macro,
+ there must be some other way alloca is supposed to work. */
+#ifndef alloca
+
+#ifdef emacs
+#ifdef static
+/* actually, only want this if static is defined as ""
+ -- this is for usg, in which emacs must undefine static
+ in order to make unexec workable
+ */
+#ifndef STACK_DIRECTION
+you
+lose
+-- must know STACK_DIRECTION at compile-time
+#endif /* STACK_DIRECTION undefined */
+#endif /* static */
+#endif /* emacs */
+
+/* If your stack is a linked list of frames, you have to
+ provide an "address metric" ADDRESS_FUNCTION macro. */
+
+#if defined (CRAY) && defined (CRAY_STACKSEG_END)
+long i00afunc ();
+#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg))
+#else
+#define ADDRESS_FUNCTION(arg) &(arg)
+#endif
+
+#if __STDC__
+typedef void *pointer;
+#else
+typedef char *pointer;
+#endif
+
+#define NULL 0
+
+/* Different portions of Emacs need to call different versions of
+ malloc. The Emacs executable needs alloca to call xmalloc, because
+ ordinary malloc isn't protected from input signals. On the other
+ hand, the utilities in lib-src need alloca to call malloc; some of
+ them are very simple, and don't have an xmalloc routine.
+
+ Non-Emacs programs expect this to call use xmalloc.
+
+ Callers below should use malloc. */
+
+#ifndef emacs
+#define malloc xmalloc
+#endif
+extern pointer malloc ();
+
+/* Define STACK_DIRECTION if you know the direction of stack
+ growth for your system; otherwise it will be automatically
+ deduced at run-time.
+
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown */
+
+#ifndef STACK_DIRECTION
+#define STACK_DIRECTION 0 /* Direction unknown. */
+#endif
+
+#if STACK_DIRECTION != 0
+
+#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */
+
+#else /* STACK_DIRECTION == 0; need run-time code. */
+
+static int stack_dir; /* 1 or -1 once known. */
+#define STACK_DIR stack_dir
+
+static void
+find_stack_direction ()
+{
+ static char *addr = NULL; /* Address of first `dummy', once known. */
+ auto char dummy; /* To get stack address. */
+
+ if (addr == NULL)
+ { /* Initial entry. */
+ addr = ADDRESS_FUNCTION (dummy);
+
+ find_stack_direction (); /* Recurse once. */
+ }
+ else
+ {
+ /* Second entry. */
+ if (ADDRESS_FUNCTION (dummy) > addr)
+ stack_dir = 1; /* Stack grew upward. */
+ else
+ stack_dir = -1; /* Stack grew downward. */
+ }
+}
+
+#endif /* STACK_DIRECTION == 0 */
+
+/* An "alloca header" is used to:
+ (a) chain together all alloca'ed blocks;
+ (b) keep track of stack depth.
+
+ It is very important that sizeof(header) agree with malloc
+ alignment chunk size. The following default should work okay. */
+
+#ifndef ALIGN_SIZE
+#define ALIGN_SIZE sizeof(double)
+#endif
+
+typedef union hdr
+{
+ char align[ALIGN_SIZE]; /* To force sizeof(header). */
+ struct
+ {
+ union hdr *next; /* For chaining headers. */
+ char *deep; /* For stack depth measure. */
+ } h;
+} header;
+
+static header *last_alloca_header = NULL; /* -> last alloca header. */
+
+/* Return a pointer to at least SIZE bytes of storage,
+ which will be automatically reclaimed upon exit from
+ the procedure that called alloca. Originally, this space
+ was supposed to be taken from the current stack frame of the
+ caller, but that method cannot be made to work for some
+ implementations of C, for example under Gould's UTX/32. */
+
+pointer
+alloca (size)
+ unsigned size;
+{
+ auto char probe; /* Probes stack depth: */
+ register char *depth = ADDRESS_FUNCTION (probe);
+
+#if STACK_DIRECTION == 0
+ if (STACK_DIR == 0) /* Unknown growth direction. */
+ find_stack_direction ();
+#endif
+
+ /* Reclaim garbage, defined as all alloca'd storage that
+ was allocated from deeper in the stack than currently. */
+
+ {
+ register header *hp; /* Traverses linked list. */
+
+#ifdef emacs
+ BLOCK_INPUT;
+#endif
+
+ for (hp = last_alloca_header; hp != NULL;)
+ if ((STACK_DIR > 0 && hp->h.deep > depth)
+ || (STACK_DIR < 0 && hp->h.deep < depth))
+ {
+ register header *np = hp->h.next;
+
+ free ((pointer) hp); /* Collect garbage. */
+
+ hp = np; /* -> next header. */
+ }
+ else
+ break; /* Rest are not deeper. */
+
+ last_alloca_header = hp; /* -> last valid storage. */
+
+#ifdef emacs
+ UNBLOCK_INPUT;
+#endif
+ }
+
+ if (size == 0)
+ return NULL; /* No allocation required. */
+
+ /* Allocate combined header + user data storage. */
+
+ {
+ register pointer new = malloc (sizeof (header) + size);
+ /* Address of header. */
+
+ ((header *) new)->h.next = last_alloca_header;
+ ((header *) new)->h.deep = depth;
+
+ last_alloca_header = (header *) new;
+
+ /* User storage begins just after header. */
+
+ return (pointer) ((char *) new + sizeof (header));
+ }
+}
+
+#if defined (CRAY) && defined (CRAY_STACKSEG_END)
+
+#ifdef DEBUG_I00AFUNC
+#include <stdio.h>
+#endif
+
+#ifndef CRAY_STACK
+#define CRAY_STACK
+#ifndef CRAY2
+/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */
+struct stack_control_header
+ {
+ long shgrow:32; /* Number of times stack has grown. */
+ long shaseg:32; /* Size of increments to stack. */
+ long shhwm:32; /* High water mark of stack. */
+ long shsize:32; /* Current size of stack (all segments). */
+ };
+
+/* The stack segment linkage control information occurs at
+ the high-address end of a stack segment. (The stack
+ grows from low addresses to high addresses.) The initial
+ part of the stack segment linkage control information is
+ 0200 (octal) words. This provides for register storage
+ for the routine which overflows the stack. */
+
+struct stack_segment_linkage
+ {
+ long ss[0200]; /* 0200 overflow words. */
+ long sssize:32; /* Number of words in this segment. */
+ long ssbase:32; /* Offset to stack base. */
+ long:32;
+ long sspseg:32; /* Offset to linkage control of previous
+ segment of stack. */
+ long:32;
+ long sstcpt:32; /* Pointer to task common address block. */
+ long sscsnm; /* Private control structure number for
+ microtasking. */
+ long ssusr1; /* Reserved for user. */
+ long ssusr2; /* Reserved for user. */
+ long sstpid; /* Process ID for pid based multi-tasking. */
+ long ssgvup; /* Pointer to multitasking thread giveup. */
+ long sscray[7]; /* Reserved for Cray Research. */
+ long ssa0;
+ long ssa1;
+ long ssa2;
+ long ssa3;
+ long ssa4;
+ long ssa5;
+ long ssa6;
+ long ssa7;
+ long sss0;
+ long sss1;
+ long sss2;
+ long sss3;
+ long sss4;
+ long sss5;
+ long sss6;
+ long sss7;
+ };
+
+#else /* CRAY2 */
+/* The following structure defines the vector of words
+ returned by the STKSTAT library routine. */
+struct stk_stat
+ {
+ long now; /* Current total stack size. */
+ long maxc; /* Amount of contiguous space which would
+ be required to satisfy the maximum
+ stack demand to date. */
+ long high_water; /* Stack high-water mark. */
+ long overflows; /* Number of stack overflow ($STKOFEN) calls. */
+ long hits; /* Number of internal buffer hits. */
+ long extends; /* Number of block extensions. */
+ long stko_mallocs; /* Block allocations by $STKOFEN. */
+ long underflows; /* Number of stack underflow calls ($STKRETN). */
+ long stko_free; /* Number of deallocations by $STKRETN. */
+ long stkm_free; /* Number of deallocations by $STKMRET. */
+ long segments; /* Current number of stack segments. */
+ long maxs; /* Maximum number of stack segments so far. */
+ long pad_size; /* Stack pad size. */
+ long current_address; /* Current stack segment address. */
+ long current_size; /* Current stack segment size. This
+ number is actually corrupted by STKSTAT to
+ include the fifteen word trailer area. */
+ long initial_address; /* Address of initial segment. */
+ long initial_size; /* Size of initial segment. */
+ };
+
+/* The following structure describes the data structure which trails
+ any stack segment. I think that the description in 'asdef' is
+ out of date. I only describe the parts that I am sure about. */
+
+struct stk_trailer
+ {
+ long this_address; /* Address of this block. */
+ long this_size; /* Size of this block (does not include
+ this trailer). */
+ long unknown2;
+ long unknown3;
+ long link; /* Address of trailer block of previous
+ segment. */
+ long unknown5;
+ long unknown6;
+ long unknown7;
+ long unknown8;
+ long unknown9;
+ long unknown10;
+ long unknown11;
+ long unknown12;
+ long unknown13;
+ long unknown14;
+ };
+
+#endif /* CRAY2 */
+#endif /* not CRAY_STACK */
+
+#ifdef CRAY2
+/* Determine a "stack measure" for an arbitrary ADDRESS.
+ I doubt that "lint" will like this much. */
+
+static long
+i00afunc (long *address)
+{
+ struct stk_stat status;
+ struct stk_trailer *trailer;
+ long *block, size;
+ long result = 0;
+
+ /* We want to iterate through all of the segments. The first
+ step is to get the stack status structure. We could do this
+ more quickly and more directly, perhaps, by referencing the
+ $LM00 common block, but I know that this works. */
+
+ STKSTAT (&status);
+
+ /* Set up the iteration. */
+
+ trailer = (struct stk_trailer *) (status.current_address
+ + status.current_size
+ - 15);
+
+ /* There must be at least one stack segment. Therefore it is
+ a fatal error if "trailer" is null. */
+
+ if (trailer == 0)
+ abort ();
+
+ /* Discard segments that do not contain our argument address. */
+
+ while (trailer != 0)
+ {
+ block = (long *) trailer->this_address;
+ size = trailer->this_size;
+ if (block == 0 || size == 0)
+ abort ();
+ trailer = (struct stk_trailer *) trailer->link;
+ if ((block <= address) && (address < (block + size)))
+ break;
+ }
+
+ /* Set the result to the offset in this segment and add the sizes
+ of all predecessor segments. */
+
+ result = address - block;
+
+ if (trailer == 0)
+ {
+ return result;
+ }
+
+ do
+ {
+ if (trailer->this_size <= 0)
+ abort ();
+ result += trailer->this_size;
+ trailer = (struct stk_trailer *) trailer->link;
+ }
+ while (trailer != 0);
+
+ /* We are done. Note that if you present a bogus address (one
+ not in any segment), you will get a different number back, formed
+ from subtracting the address of the first block. This is probably
+ not what you want. */
+
+ return (result);
+}
+
+#else /* not CRAY2 */
+/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP.
+ Determine the number of the cell within the stack,
+ given the address of the cell. The purpose of this
+ routine is to linearize, in some sense, stack addresses
+ for alloca. */
+
+static long
+i00afunc (long address)
+{
+ long stkl = 0;
+
+ long size, pseg, this_segment, stack;
+ long result = 0;
+
+ struct stack_segment_linkage *ssptr;
+
+ /* Register B67 contains the address of the end of the
+ current stack segment. If you (as a subprogram) store
+ your registers on the stack and find that you are past
+ the contents of B67, you have overflowed the segment.
+
+ B67 also points to the stack segment linkage control
+ area, which is what we are really interested in. */
+
+ stkl = CRAY_STACKSEG_END ();
+ ssptr = (struct stack_segment_linkage *) stkl;
+
+ /* If one subtracts 'size' from the end of the segment,
+ one has the address of the first word of the segment.
+
+ If this is not the first segment, 'pseg' will be
+ nonzero. */
+
+ pseg = ssptr->sspseg;
+ size = ssptr->sssize;
+
+ this_segment = stkl - size;
+
+ /* It is possible that calling this routine itself caused
+ a stack overflow. Discard stack segments which do not
+ contain the target address. */
+
+ while (!(this_segment <= address && address <= stkl))
+ {
+#ifdef DEBUG_I00AFUNC
+ fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl);
+#endif
+ if (pseg == 0)
+ break;
+ stkl = stkl - pseg;
+ ssptr = (struct stack_segment_linkage *) stkl;
+ size = ssptr->sssize;
+ pseg = ssptr->sspseg;
+ this_segment = stkl - size;
+ }
+
+ result = address - this_segment;
+
+ /* If you subtract pseg from the current end of the stack,
+ you get the address of the previous stack segment's end.
+ This seems a little convoluted to me, but I'll bet you save
+ a cycle somewhere. */
+
+ while (pseg != 0)
+ {
+#ifdef DEBUG_I00AFUNC
+ fprintf (stderr, "%011o %011o\n", pseg, size);
+#endif
+ stkl = stkl - pseg;
+ ssptr = (struct stack_segment_linkage *) stkl;
+ size = ssptr->sssize;
+ pseg = ssptr->sspseg;
+ result += size;
+ }
+ return (result);
+}
+
+#endif /* not CRAY2 */
+#endif /* CRAY */
+
+#endif /* no alloca */
+#endif /* not GCC version 2 */
diff --git a/gnu/dist/diffutils/analyze.c b/gnu/dist/diffutils/analyze.c
new file mode 100644
index 00000000000..556d388c46a
--- /dev/null
+++ b/gnu/dist/diffutils/analyze.c
@@ -0,0 +1,1084 @@
+/* Analyze file differences for GNU DIFF.
+ 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. */
+
+/* The basic algorithm is described in:
+ "An O(ND) Difference Algorithm and its Variations", Eugene Myers,
+ Algorithmica Vol. 1 No. 2, 1986, pp. 251-266;
+ see especially section 4.2, which describes the variation used below.
+ Unless the --minimal option is specified, this code uses the TOO_EXPENSIVE
+ heuristic, by Paul Eggert, to limit the cost to O(N**1.5 log N)
+ at the price of producing suboptimal output for large inputs with
+ many differences.
+
+ The basic algorithm was independently discovered as described in:
+ "Algorithms for Approximate String Matching", E. Ukkonen,
+ Information and Control Vol. 64, 1985, pp. 100-118. */
+
+#include "diff.h"
+#include "cmpbuf.h"
+
+extern int no_discards;
+
+static int *xvec, *yvec; /* Vectors being compared. */
+static int *fdiag; /* Vector, indexed by diagonal, containing
+ 1 + the X coordinate of the point furthest
+ along the given diagonal in the forward
+ search of the edit matrix. */
+static int *bdiag; /* Vector, indexed by diagonal, containing
+ the X coordinate of the point furthest
+ along the given diagonal in the backward
+ search of the edit matrix. */
+static int too_expensive; /* Edit scripts longer than this are too
+ expensive to compute. */
+
+#define SNAKE_LIMIT 20 /* Snakes bigger than this are considered `big'. */
+
+struct partition
+{
+ int xmid, ymid; /* Midpoints of this partition. */
+ int lo_minimal; /* Nonzero if low half will be analyzed minimally. */
+ int hi_minimal; /* Likewise for high half. */
+};
+
+static int diag PARAMS((int, int, int, int, int, struct partition *));
+static struct change *add_change PARAMS((int, int, int, int, struct change *));
+static struct change *build_reverse_script PARAMS((struct file_data const[]));
+static struct change *build_script PARAMS((struct file_data const[]));
+static void briefly_report PARAMS((int, struct file_data const[]));
+static void compareseq PARAMS((int, int, int, int, int));
+static void discard_confusing_lines PARAMS((struct file_data[]));
+static void shift_boundaries PARAMS((struct file_data[]));
+
+/* Find the midpoint of the shortest edit script for a specified
+ portion of the two files.
+
+ Scan from the beginnings of the files, and simultaneously from the ends,
+ doing a breadth-first search through the space of edit-sequence.
+ When the two searches meet, we have found the midpoint of the shortest
+ edit sequence.
+
+ If MINIMAL is nonzero, find the minimal edit script regardless
+ of expense. Otherwise, if the search is too expensive, use
+ heuristics to stop the search and report a suboptimal answer.
+
+ Set PART->(XMID,YMID) to the midpoint (XMID,YMID). The diagonal number
+ XMID - YMID equals the number of inserted lines minus the number
+ of deleted lines (counting only lines before the midpoint).
+ Return the approximate edit cost; this is the total number of
+ lines inserted or deleted (counting only lines before the midpoint),
+ unless a heuristic is used to terminate the search prematurely.
+
+ Set PART->LEFT_MINIMAL to nonzero iff the minimal edit script for the
+ left half of the partition is known; similarly for PART->RIGHT_MINIMAL.
+
+ This function assumes that the first lines of the specified portions
+ of the two files do not match, and likewise that the last lines do not
+ match. The caller must trim matching lines from the beginning and end
+ of the portions it is going to specify.
+
+ If we return the "wrong" partitions,
+ the worst this can do is cause suboptimal diff output.
+ It cannot cause incorrect diff output. */
+
+static int
+diag (xoff, xlim, yoff, ylim, minimal, part)
+ int xoff, xlim, yoff, ylim, minimal;
+ struct partition *part;
+{
+ int *const fd = fdiag; /* Give the compiler a chance. */
+ int *const bd = bdiag; /* Additional help for the compiler. */
+ int const *const xv = xvec; /* Still more help for the compiler. */
+ int const *const yv = yvec; /* And more and more . . . */
+ int const dmin = xoff - ylim; /* Minimum valid diagonal. */
+ int const dmax = xlim - yoff; /* Maximum valid diagonal. */
+ int const fmid = xoff - yoff; /* Center diagonal of top-down search. */
+ int const bmid = xlim - ylim; /* Center diagonal of bottom-up search. */
+ int fmin = fmid, fmax = fmid; /* Limits of top-down search. */
+ int bmin = bmid, bmax = bmid; /* Limits of bottom-up search. */
+ int c; /* Cost. */
+ int odd = (fmid - bmid) & 1; /* True if southeast corner is on an odd
+ diagonal with respect to the northwest. */
+
+ fd[fmid] = xoff;
+ bd[bmid] = xlim;
+
+ for (c = 1;; ++c)
+ {
+ int d; /* Active diagonal. */
+ int big_snake = 0;
+
+ /* Extend the top-down search by an edit step in each diagonal. */
+ fmin > dmin ? fd[--fmin - 1] = -1 : ++fmin;
+ fmax < dmax ? fd[++fmax + 1] = -1 : --fmax;
+ for (d = fmax; d >= fmin; d -= 2)
+ {
+ int x, y, oldx, tlo = fd[d - 1], thi = fd[d + 1];
+
+ if (tlo >= thi)
+ x = tlo + 1;
+ else
+ x = thi;
+ oldx = x;
+ y = x - d;
+ while (x < xlim && y < ylim && xv[x] == yv[y])
+ ++x, ++y;
+ if (x - oldx > SNAKE_LIMIT)
+ big_snake = 1;
+ fd[d] = x;
+ if (odd && bmin <= d && d <= bmax && bd[d] <= x)
+ {
+ part->xmid = x;
+ part->ymid = y;
+ part->lo_minimal = part->hi_minimal = 1;
+ return 2 * c - 1;
+ }
+ }
+
+ /* Similarly extend the bottom-up search. */
+ bmin > dmin ? bd[--bmin - 1] = INT_MAX : ++bmin;
+ bmax < dmax ? bd[++bmax + 1] = INT_MAX : --bmax;
+ for (d = bmax; d >= bmin; d -= 2)
+ {
+ int x, y, oldx, tlo = bd[d - 1], thi = bd[d + 1];
+
+ if (tlo < thi)
+ x = tlo;
+ else
+ x = thi - 1;
+ oldx = x;
+ y = x - d;
+ while (x > xoff && y > yoff && xv[x - 1] == yv[y - 1])
+ --x, --y;
+ if (oldx - x > SNAKE_LIMIT)
+ big_snake = 1;
+ bd[d] = x;
+ if (!odd && fmin <= d && d <= fmax && x <= fd[d])
+ {
+ part->xmid = x;
+ part->ymid = y;
+ part->lo_minimal = part->hi_minimal = 1;
+ return 2 * c;
+ }
+ }
+
+ if (minimal)
+ continue;
+
+ /* Heuristic: check occasionally for a diagonal that has made
+ lots of progress compared with the edit distance.
+ If we have any such, find the one that has made the most
+ progress and return it as if it had succeeded.
+
+ With this heuristic, for files with a constant small density
+ of changes, the algorithm is linear in the file size. */
+
+ if (c > 200 && big_snake && heuristic)
+ {
+ int best;
+
+ best = 0;
+ for (d = fmax; d >= fmin; d -= 2)
+ {
+ int dd = d - fmid;
+ int x = fd[d];
+ int y = x - d;
+ int v = (x - xoff) * 2 - dd;
+ if (v > 12 * (c + (dd < 0 ? -dd : dd)))
+ {
+ if (v > best
+ && xoff + SNAKE_LIMIT <= x && x < xlim
+ && yoff + SNAKE_LIMIT <= y && y < ylim)
+ {
+ /* We have a good enough best diagonal;
+ now insist that it end with a significant snake. */
+ int k;
+
+ for (k = 1; xv[x - k] == yv[y - k]; k++)
+ if (k == SNAKE_LIMIT)
+ {
+ best = v;
+ part->xmid = x;
+ part->ymid = y;
+ break;
+ }
+ }
+ }
+ }
+ if (best > 0)
+ {
+ part->lo_minimal = 1;
+ part->hi_minimal = 0;
+ return 2 * c - 1;
+ }
+
+ best = 0;
+ for (d = bmax; d >= bmin; d -= 2)
+ {
+ int dd = d - bmid;
+ int x = bd[d];
+ int y = x - d;
+ int v = (xlim - x) * 2 + dd;
+ if (v > 12 * (c + (dd < 0 ? -dd : dd)))
+ {
+ if (v > best
+ && xoff < x && x <= xlim - SNAKE_LIMIT
+ && yoff < y && y <= ylim - SNAKE_LIMIT)
+ {
+ /* We have a good enough best diagonal;
+ now insist that it end with a significant snake. */
+ int k;
+
+ for (k = 0; xv[x + k] == yv[y + k]; k++)
+ if (k == SNAKE_LIMIT - 1)
+ {
+ best = v;
+ part->xmid = x;
+ part->ymid = y;
+ break;
+ }
+ }
+ }
+ }
+ if (best > 0)
+ {
+ part->lo_minimal = 0;
+ part->hi_minimal = 1;
+ return 2 * c - 1;
+ }
+ }
+
+ /* Heuristic: if we've gone well beyond the call of duty,
+ give up and report halfway between our best results so far. */
+ if (c >= too_expensive)
+ {
+ int fxybest, fxbest;
+ int bxybest, bxbest;
+
+ fxbest = bxbest = 0; /* Pacify `gcc -Wall'. */
+
+ /* Find forward diagonal that maximizes X + Y. */
+ fxybest = -1;
+ for (d = fmax; d >= fmin; d -= 2)
+ {
+ int x = min (fd[d], xlim);
+ int y = x - d;
+ if (ylim < y)
+ x = ylim + d, y = ylim;
+ if (fxybest < x + y)
+ {
+ fxybest = x + y;
+ fxbest = x;
+ }
+ }
+
+ /* Find backward diagonal that minimizes X + Y. */
+ bxybest = INT_MAX;
+ for (d = bmax; d >= bmin; d -= 2)
+ {
+ int x = max (xoff, bd[d]);
+ int y = x - d;
+ if (y < yoff)
+ x = yoff + d, y = yoff;
+ if (x + y < bxybest)
+ {
+ bxybest = x + y;
+ bxbest = x;
+ }
+ }
+
+ /* Use the better of the two diagonals. */
+ if ((xlim + ylim) - bxybest < fxybest - (xoff + yoff))
+ {
+ part->xmid = fxbest;
+ part->ymid = fxybest - fxbest;
+ part->lo_minimal = 1;
+ part->hi_minimal = 0;
+ }
+ else
+ {
+ part->xmid = bxbest;
+ part->ymid = bxybest - bxbest;
+ part->lo_minimal = 0;
+ part->hi_minimal = 1;
+ }
+ return 2 * c - 1;
+ }
+ }
+}
+
+/* Compare in detail contiguous subsequences of the two files
+ which are known, as a whole, to match each other.
+
+ The results are recorded in the vectors files[N].changed_flag, by
+ storing a 1 in the element for each line that is an insertion or deletion.
+
+ The subsequence of file 0 is [XOFF, XLIM) and likewise for file 1.
+
+ Note that XLIM, YLIM are exclusive bounds.
+ All line numbers are origin-0 and discarded lines are not counted.
+
+ If MINIMAL is nonzero, find a minimal difference no matter how
+ expensive it is. */
+
+static void
+compareseq (xoff, xlim, yoff, ylim, minimal)
+ int xoff, xlim, yoff, ylim, minimal;
+{
+ int * const xv = xvec; /* Help the compiler. */
+ int * const yv = yvec;
+
+ /* Slide down the bottom initial diagonal. */
+ while (xoff < xlim && yoff < ylim && xv[xoff] == yv[yoff])
+ ++xoff, ++yoff;
+ /* Slide up the top initial diagonal. */
+ while (xlim > xoff && ylim > yoff && xv[xlim - 1] == yv[ylim - 1])
+ --xlim, --ylim;
+
+ /* Handle simple cases. */
+ if (xoff == xlim)
+ while (yoff < ylim)
+ files[1].changed_flag[files[1].realindexes[yoff++]] = 1;
+ else if (yoff == ylim)
+ while (xoff < xlim)
+ files[0].changed_flag[files[0].realindexes[xoff++]] = 1;
+ else
+ {
+ int c;
+ struct partition part;
+
+ /* Find a point of correspondence in the middle of the files. */
+
+ c = diag (xoff, xlim, yoff, ylim, minimal, &part);
+
+ if (c == 1)
+ {
+ /* This should be impossible, because it implies that
+ one of the two subsequences is empty,
+ and that case was handled above without calling `diag'.
+ Let's verify that this is true. */
+ abort ();
+#if 0
+ /* The two subsequences differ by a single insert or delete;
+ record it and we are done. */
+ if (part.xmid - part.ymid < xoff - yoff)
+ files[1].changed_flag[files[1].realindexes[part.ymid - 1]] = 1;
+ else
+ files[0].changed_flag[files[0].realindexes[part.xmid]] = 1;
+#endif
+ }
+ else
+ {
+ /* Use the partitions to split this problem into subproblems. */
+ compareseq (xoff, part.xmid, yoff, part.ymid, part.lo_minimal);
+ compareseq (part.xmid, xlim, part.ymid, ylim, part.hi_minimal);
+ }
+ }
+}
+
+/* Discard lines from one file that have no matches in the other file.
+
+ A line which is discarded will not be considered by the actual
+ comparison algorithm; it will be as if that line were not in the file.
+ The file's `realindexes' table maps virtual line numbers
+ (which don't count the discarded lines) into real line numbers;
+ this is how the actual comparison algorithm produces results
+ that are comprehensible when the discarded lines are counted.
+
+ When we discard a line, we also mark it as a deletion or insertion
+ so that it will be printed in the output. */
+
+static void
+discard_confusing_lines (filevec)
+ struct file_data filevec[];
+{
+ unsigned int f, i;
+ char *discarded[2];
+ int *equiv_count[2];
+ int *p;
+
+ /* Allocate our results. */
+ p = (int *) xmalloc ((filevec[0].buffered_lines + filevec[1].buffered_lines)
+ * (2 * sizeof (int)));
+ for (f = 0; f < 2; f++)
+ {
+ filevec[f].undiscarded = p; p += filevec[f].buffered_lines;
+ filevec[f].realindexes = p; p += filevec[f].buffered_lines;
+ }
+
+ /* Set up equiv_count[F][I] as the number of lines in file F
+ that fall in equivalence class I. */
+
+ p = (int *) xmalloc (filevec[0].equiv_max * (2 * sizeof (int)));
+ equiv_count[0] = p;
+ equiv_count[1] = p + filevec[0].equiv_max;
+ bzero (p, filevec[0].equiv_max * (2 * sizeof (int)));
+
+ for (i = 0; i < filevec[0].buffered_lines; ++i)
+ ++equiv_count[0][filevec[0].equivs[i]];
+ for (i = 0; i < filevec[1].buffered_lines; ++i)
+ ++equiv_count[1][filevec[1].equivs[i]];
+
+ /* Set up tables of which lines are going to be discarded. */
+
+ discarded[0] = xmalloc (sizeof (char)
+ * (filevec[0].buffered_lines
+ + filevec[1].buffered_lines));
+ discarded[1] = discarded[0] + filevec[0].buffered_lines;
+ bzero (discarded[0], sizeof (char) * (filevec[0].buffered_lines
+ + filevec[1].buffered_lines));
+
+ /* Mark to be discarded each line that matches no line of the other file.
+ If a line matches many lines, mark it as provisionally discardable. */
+
+ for (f = 0; f < 2; f++)
+ {
+ unsigned int end = filevec[f].buffered_lines;
+ char *discards = discarded[f];
+ int *counts = equiv_count[1 - f];
+ int *equivs = filevec[f].equivs;
+ unsigned int many = 5;
+ unsigned int tem = end / 64;
+
+ /* Multiply MANY by approximate square root of number of lines.
+ That is the threshold for provisionally discardable lines. */
+ while ((tem = tem >> 2) > 0)
+ many *= 2;
+
+ for (i = 0; i < end; i++)
+ {
+ int nmatch;
+ if (equivs[i] == 0)
+ continue;
+ nmatch = counts[equivs[i]];
+ if (nmatch == 0)
+ discards[i] = 1;
+ else if (nmatch > many)
+ discards[i] = 2;
+ }
+ }
+
+ /* Don't really discard the provisional lines except when they occur
+ in a run of discardables, with nonprovisionals at the beginning
+ and end. */
+
+ for (f = 0; f < 2; f++)
+ {
+ unsigned int end = filevec[f].buffered_lines;
+ register char *discards = discarded[f];
+
+ for (i = 0; i < end; i++)
+ {
+ /* Cancel provisional discards not in middle of run of discards. */
+ if (discards[i] == 2)
+ discards[i] = 0;
+ else if (discards[i] != 0)
+ {
+ /* We have found a nonprovisional discard. */
+ register int j;
+ unsigned int length;
+ unsigned int provisional = 0;
+
+ /* Find end of this run of discardable lines.
+ Count how many are provisionally discardable. */
+ for (j = i; j < end; j++)
+ {
+ if (discards[j] == 0)
+ break;
+ if (discards[j] == 2)
+ ++provisional;
+ }
+
+ /* Cancel provisional discards at end, and shrink the run. */
+ while (j > i && discards[j - 1] == 2)
+ discards[--j] = 0, --provisional;
+
+ /* Now we have the length of a run of discardable lines
+ whose first and last are not provisional. */
+ length = j - i;
+
+ /* If 1/4 of the lines in the run are provisional,
+ cancel discarding of all provisional lines in the run. */
+ if (provisional * 4 > length)
+ {
+ while (j > i)
+ if (discards[--j] == 2)
+ discards[j] = 0;
+ }
+ else
+ {
+ register unsigned int consec;
+ unsigned int minimum = 1;
+ unsigned int tem = length / 4;
+
+ /* MINIMUM is approximate square root of LENGTH/4.
+ A subrun of two or more provisionals can stand
+ when LENGTH is at least 16.
+ A subrun of 4 or more can stand when LENGTH >= 64. */
+ while ((tem = tem >> 2) > 0)
+ minimum *= 2;
+ minimum++;
+
+ /* Cancel any subrun of MINIMUM or more provisionals
+ within the larger run. */
+ for (j = 0, consec = 0; j < length; j++)
+ if (discards[i + j] != 2)
+ consec = 0;
+ else if (minimum == ++consec)
+ /* Back up to start of subrun, to cancel it all. */
+ j -= consec;
+ else if (minimum < consec)
+ discards[i + j] = 0;
+
+ /* Scan from beginning of run
+ until we find 3 or more nonprovisionals in a row
+ or until the first nonprovisional at least 8 lines in.
+ Until that point, cancel any provisionals. */
+ for (j = 0, consec = 0; j < length; j++)
+ {
+ if (j >= 8 && discards[i + j] == 1)
+ break;
+ if (discards[i + j] == 2)
+ consec = 0, discards[i + j] = 0;
+ else if (discards[i + j] == 0)
+ consec = 0;
+ else
+ consec++;
+ if (consec == 3)
+ break;
+ }
+
+ /* I advances to the last line of the run. */
+ i += length - 1;
+
+ /* Same thing, from end. */
+ for (j = 0, consec = 0; j < length; j++)
+ {
+ if (j >= 8 && discards[i - j] == 1)
+ break;
+ if (discards[i - j] == 2)
+ consec = 0, discards[i - j] = 0;
+ else if (discards[i - j] == 0)
+ consec = 0;
+ else
+ consec++;
+ if (consec == 3)
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /* Actually discard the lines. */
+ for (f = 0; f < 2; f++)
+ {
+ char *discards = discarded[f];
+ unsigned int end = filevec[f].buffered_lines;
+ unsigned int j = 0;
+ for (i = 0; i < end; ++i)
+ if (no_discards || discards[i] == 0)
+ {
+ filevec[f].undiscarded[j] = filevec[f].equivs[i];
+ filevec[f].realindexes[j++] = i;
+ }
+ else
+ filevec[f].changed_flag[i] = 1;
+ filevec[f].nondiscarded_lines = j;
+ }
+
+ free (discarded[0]);
+ free (equiv_count[0]);
+}
+
+/* Adjust inserts/deletes of identical lines to join changes
+ as much as possible.
+
+ We do something when a run of changed lines include a
+ line at one end and have an excluded, identical line at the other.
+ We are free to choose which identical line is included.
+ `compareseq' usually chooses the one at the beginning,
+ but usually it is cleaner to consider the following identical line
+ to be the "change". */
+
+int inhibit;
+
+static void
+shift_boundaries (filevec)
+ struct file_data filevec[];
+{
+ int f;
+
+ if (inhibit)
+ return;
+
+ for (f = 0; f < 2; f++)
+ {
+ char *changed = filevec[f].changed_flag;
+ char const *other_changed = filevec[1-f].changed_flag;
+ int const *equivs = filevec[f].equivs;
+ int i = 0;
+ int j = 0;
+ int i_end = filevec[f].buffered_lines;
+
+ while (1)
+ {
+ int runlength, start, corresponding;
+
+ /* Scan forwards to find beginning of another run of changes.
+ Also keep track of the corresponding point in the other file. */
+
+ while (i < i_end && changed[i] == 0)
+ {
+ while (other_changed[j++])
+ continue;
+ i++;
+ }
+
+ if (i == i_end)
+ break;
+
+ start = i;
+
+ /* Find the end of this run of changes. */
+
+ while (changed[++i])
+ continue;
+ while (other_changed[j])
+ j++;
+
+ do
+ {
+ /* Record the length of this run of changes, so that
+ we can later determine whether the run has grown. */
+ runlength = i - start;
+
+ /* Move the changed region back, so long as the
+ previous unchanged line matches the last changed one.
+ This merges with previous changed regions. */
+
+ while (start && equivs[start - 1] == equivs[i - 1])
+ {
+ changed[--start] = 1;
+ changed[--i] = 0;
+ while (changed[start - 1])
+ start--;
+ while (other_changed[--j])
+ continue;
+ }
+
+ /* Set CORRESPONDING to the end of the changed run, at the last
+ point where it corresponds to a changed run in the other file.
+ CORRESPONDING == I_END means no such point has been found. */
+ corresponding = other_changed[j - 1] ? i : i_end;
+
+ /* Move the changed region forward, so long as the
+ first changed line matches the following unchanged one.
+ This merges with following changed regions.
+ Do this second, so that if there are no merges,
+ the changed region is moved forward as far as possible. */
+
+ while (i != i_end && equivs[start] == equivs[i])
+ {
+ changed[start++] = 0;
+ changed[i++] = 1;
+ while (changed[i])
+ i++;
+ while (other_changed[++j])
+ corresponding = i;
+ }
+ }
+ while (runlength != i - start);
+
+ /* If possible, move the fully-merged run of changes
+ back to a corresponding run in the other file. */
+
+ while (corresponding < i)
+ {
+ changed[--start] = 1;
+ changed[--i] = 0;
+ while (other_changed[--j])
+ continue;
+ }
+ }
+ }
+}
+
+/* Cons an additional entry onto the front of an edit script OLD.
+ LINE0 and LINE1 are the first affected lines in the two files (origin 0).
+ DELETED is the number of lines deleted here from file 0.
+ INSERTED is the number of lines inserted here in file 1.
+
+ If DELETED is 0 then LINE0 is the number of the line before
+ which the insertion was done; vice versa for INSERTED and LINE1. */
+
+static struct change *
+add_change (line0, line1, deleted, inserted, old)
+ int line0, line1, deleted, inserted;
+ struct change *old;
+{
+ struct change *new = (struct change *) xmalloc (sizeof (struct change));
+
+ new->line0 = line0;
+ new->line1 = line1;
+ new->inserted = inserted;
+ new->deleted = deleted;
+ new->link = old;
+ return new;
+}
+
+/* Scan the tables of which lines are inserted and deleted,
+ producing an edit script in reverse order. */
+
+static struct change *
+build_reverse_script (filevec)
+ struct file_data const filevec[];
+{
+ struct change *script = 0;
+ char *changed0 = filevec[0].changed_flag;
+ char *changed1 = filevec[1].changed_flag;
+ int len0 = filevec[0].buffered_lines;
+ int len1 = filevec[1].buffered_lines;
+
+ /* Note that changedN[len0] does exist, and contains 0. */
+
+ int i0 = 0, i1 = 0;
+
+ while (i0 < len0 || i1 < len1)
+ {
+ if (changed0[i0] || changed1[i1])
+ {
+ int line0 = i0, line1 = i1;
+
+ /* Find # lines changed here in each file. */
+ while (changed0[i0]) ++i0;
+ while (changed1[i1]) ++i1;
+
+ /* Record this change. */
+ script = add_change (line0, line1, i0 - line0, i1 - line1, script);
+ }
+
+ /* We have reached lines in the two files that match each other. */
+ i0++, i1++;
+ }
+
+ return script;
+}
+
+/* Scan the tables of which lines are inserted and deleted,
+ producing an edit script in forward order. */
+
+static struct change *
+build_script (filevec)
+ struct file_data const filevec[];
+{
+ struct change *script = 0;
+ char *changed0 = filevec[0].changed_flag;
+ char *changed1 = filevec[1].changed_flag;
+ int i0 = filevec[0].buffered_lines, i1 = filevec[1].buffered_lines;
+
+ /* Note that changedN[-1] does exist, and contains 0. */
+
+ while (i0 >= 0 || i1 >= 0)
+ {
+ if (changed0[i0 - 1] || changed1[i1 - 1])
+ {
+ int line0 = i0, line1 = i1;
+
+ /* Find # lines changed here in each file. */
+ while (changed0[i0 - 1]) --i0;
+ while (changed1[i1 - 1]) --i1;
+
+ /* Record this change. */
+ script = add_change (i0, i1, line0 - i0, line1 - i1, script);
+ }
+
+ /* We have reached lines in the two files that match each other. */
+ i0--, i1--;
+ }
+
+ return script;
+}
+
+/* If CHANGES, briefly report that two files differed. */
+static void
+briefly_report (changes, filevec)
+ int changes;
+ struct file_data const filevec[];
+{
+ if (changes)
+ message (no_details_flag ? "Files %s and %s differ\n"
+ : "Binary files %s and %s differ\n",
+ filevec[0].name, filevec[1].name);
+}
+
+/* Report the differences of two files. DEPTH is the current directory
+ depth. */
+int
+diff_2_files (filevec, depth)
+ struct file_data filevec[];
+ int depth;
+{
+ int diags;
+ int i;
+ struct change *e, *p;
+ struct change *script;
+ int changes;
+
+
+ /* If we have detected that either file is binary,
+ compare the two files as binary. This can happen
+ only when the first chunk is read.
+ Also, --brief without any --ignore-* options means
+ we can speed things up by treating the files as binary. */
+
+ if (read_files (filevec, no_details_flag & ~ignore_some_changes))
+ {
+ /* Files with different lengths must be different. */
+ if (filevec[0].stat.st_size != filevec[1].stat.st_size
+ && (filevec[0].desc < 0 || S_ISREG (filevec[0].stat.st_mode))
+ && (filevec[1].desc < 0 || S_ISREG (filevec[1].stat.st_mode)))
+ changes = 1;
+
+ /* Standard input equals itself. */
+ else if (filevec[0].desc == filevec[1].desc)
+ changes = 0;
+
+ else
+ /* Scan both files, a buffer at a time, looking for a difference. */
+ {
+ /* Allocate same-sized buffers for both files. */
+ size_t buffer_size = buffer_lcm (STAT_BLOCKSIZE (filevec[0].stat),
+ STAT_BLOCKSIZE (filevec[1].stat));
+ for (i = 0; i < 2; i++)
+ filevec[i].buffer = xrealloc (filevec[i].buffer, buffer_size);
+
+ for (;; filevec[0].buffered_chars = filevec[1].buffered_chars = 0)
+ {
+ /* Read a buffer's worth from both files. */
+ for (i = 0; i < 2; i++)
+ if (0 <= filevec[i].desc)
+ while (filevec[i].buffered_chars != buffer_size)
+ {
+ int r = read (filevec[i].desc,
+ filevec[i].buffer
+ + filevec[i].buffered_chars,
+ buffer_size - filevec[i].buffered_chars);
+ if (r == 0)
+ break;
+ if (r < 0)
+ pfatal_with_name (filevec[i].name);
+ filevec[i].buffered_chars += r;
+ }
+
+ /* If the buffers differ, the files differ. */
+ if (filevec[0].buffered_chars != filevec[1].buffered_chars
+ || (filevec[0].buffered_chars != 0
+ && memcmp (filevec[0].buffer,
+ filevec[1].buffer,
+ filevec[0].buffered_chars) != 0))
+ {
+ changes = 1;
+ break;
+ }
+
+ /* If we reach end of file, the files are the same. */
+ if (filevec[0].buffered_chars != buffer_size)
+ {
+ changes = 0;
+ break;
+ }
+ }
+ }
+
+ briefly_report (changes, filevec);
+ }
+ else
+ {
+ /* Allocate vectors for the results of comparison:
+ a flag for each line of each file, saying whether that line
+ is an insertion or deletion.
+ Allocate an extra element, always zero, at each end of each vector. */
+
+ size_t s = filevec[0].buffered_lines + filevec[1].buffered_lines + 4;
+ filevec[0].changed_flag = xmalloc (s);
+ bzero (filevec[0].changed_flag, s);
+ filevec[0].changed_flag++;
+ filevec[1].changed_flag = filevec[0].changed_flag
+ + filevec[0].buffered_lines + 2;
+
+ /* Some lines are obviously insertions or deletions
+ because they don't match anything. Detect them now, and
+ avoid even thinking about them in the main comparison algorithm. */
+
+ discard_confusing_lines (filevec);
+
+ /* Now do the main comparison algorithm, considering just the
+ undiscarded lines. */
+
+ xvec = filevec[0].undiscarded;
+ yvec = filevec[1].undiscarded;
+ diags = filevec[0].nondiscarded_lines + filevec[1].nondiscarded_lines + 3;
+ fdiag = (int *) xmalloc (diags * (2 * sizeof (int)));
+ bdiag = fdiag + diags;
+ fdiag += filevec[1].nondiscarded_lines + 1;
+ bdiag += filevec[1].nondiscarded_lines + 1;
+
+ /* Set TOO_EXPENSIVE to be approximate square root of input size,
+ bounded below by 256. */
+ too_expensive = 1;
+ for (i = filevec[0].nondiscarded_lines + filevec[1].nondiscarded_lines;
+ i != 0; i >>= 2)
+ too_expensive <<= 1;
+ too_expensive = max (256, too_expensive);
+
+ files[0] = filevec[0];
+ files[1] = filevec[1];
+
+ compareseq (0, filevec[0].nondiscarded_lines,
+ 0, filevec[1].nondiscarded_lines, no_discards);
+
+ free (fdiag - (filevec[1].nondiscarded_lines + 1));
+
+ /* Modify the results slightly to make them prettier
+ in cases where that can validly be done. */
+
+ shift_boundaries (filevec);
+
+ /* Get the results of comparison in the form of a chain
+ of `struct change's -- an edit script. */
+
+ if (output_style == OUTPUT_ED)
+ script = build_reverse_script (filevec);
+ else
+ script = build_script (filevec);
+
+ /* Set CHANGES if we had any diffs.
+ If some changes are ignored, we must scan the script to decide. */
+ if (ignore_blank_lines_flag || ignore_regexp_list)
+ {
+ struct change *next = script;
+ changes = 0;
+
+ while (next && changes == 0)
+ {
+ struct change *this, *end;
+ int first0, last0, first1, last1, deletes, inserts;
+
+ /* Find a set of changes that belong together. */
+ this = next;
+ end = find_change (next);
+
+ /* Disconnect them from the rest of the changes, making them
+ a hunk, and remember the rest for next iteration. */
+ next = end->link;
+ end->link = 0;
+
+ /* Determine whether this hunk is really a difference. */
+ analyze_hunk (this, &first0, &last0, &first1, &last1,
+ &deletes, &inserts);
+
+ /* Reconnect the script so it will all be freed properly. */
+ end->link = next;
+
+ if (deletes || inserts)
+ changes = 1;
+ }
+ }
+ else
+ changes = (script != 0);
+
+ if (no_details_flag)
+ briefly_report (changes, filevec);
+ else
+ {
+ if (changes || ! no_diff_means_no_output)
+ {
+ /* Record info for starting up output,
+ to be used if and when we have some output to print. */
+ setup_output (files[0].name, files[1].name, depth);
+
+ switch (output_style)
+ {
+ case OUTPUT_CONTEXT:
+ print_context_script (script, 0);
+ break;
+
+ case OUTPUT_UNIFIED:
+ print_context_script (script, 1);
+ break;
+
+ case OUTPUT_ED:
+ print_ed_script (script);
+ break;
+
+ case OUTPUT_FORWARD_ED:
+ pr_forward_ed_script (script);
+ break;
+
+ case OUTPUT_RCS:
+ print_rcs_script (script);
+ break;
+
+ case OUTPUT_NORMAL:
+ print_normal_script (script);
+ break;
+
+ case OUTPUT_IFDEF:
+ print_ifdef_script (script);
+ break;
+
+ case OUTPUT_SDIFF:
+ print_sdiff_script (script);
+ }
+
+ finish_output ();
+ }
+ }
+
+ free (filevec[0].undiscarded);
+
+ free (filevec[0].changed_flag - 1);
+
+ for (i = 1; i >= 0; --i)
+ free (filevec[i].equivs);
+
+ for (i = 0; i < 2; ++i)
+ free (filevec[i].linbuf + filevec[i].linbuf_base);
+
+ for (e = script; e; e = p)
+ {
+ p = e->link;
+ free (e);
+ }
+
+ if (! ROBUST_OUTPUT_STYLE (output_style))
+ for (i = 0; i < 2; ++i)
+ if (filevec[i].missing_newline)
+ {
+ error ("No newline at end of file %s", filevec[i].name, "");
+ changes = 2;
+ }
+ }
+
+ if (filevec[0].buffer != filevec[1].buffer)
+ free (filevec[0].buffer);
+ free (filevec[1].buffer);
+
+ return changes;
+}
diff --git a/gnu/dist/diffutils/cmp.c b/gnu/dist/diffutils/cmp.c
new file mode 100644
index 00000000000..9840570e94a
--- /dev/null
+++ b/gnu/dist/diffutils/cmp.c
@@ -0,0 +1,568 @@
+/* cmp -- compare two files.
+ Copyright (C) 1990, 1991, 1992, 1993, 1994 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 Torbjorn Granlund and David MacKenzie. */
+
+#include "system.h"
+#include <stdio.h>
+#include "getopt.h"
+#include "cmpbuf.h"
+
+extern char const version_string[];
+
+#if __STDC__ && defined (HAVE_VPRINTF)
+void error (int, int, char const *, ...);
+#else
+void error ();
+#endif
+VOID *xmalloc PARAMS((size_t));
+
+static int cmp PARAMS((void));
+static off_t file_position PARAMS((int));
+static size_t block_compare PARAMS((char const *, char const *));
+static size_t block_compare_and_count PARAMS((char const *, char const *, long *));
+static size_t block_read PARAMS((int, char *, size_t));
+static void printc PARAMS((int, unsigned));
+static void try_help PARAMS((char const *));
+static void check_stdout PARAMS((void));
+static void usage PARAMS((void));
+
+/* Name under which this program was invoked. */
+char const *program_name;
+
+/* Filenames of the compared files. */
+static char const *file[2];
+
+/* File descriptors of the files. */
+static int file_desc[2];
+
+/* Read buffers for the files. */
+static char *buffer[2];
+
+/* Optimal block size for the files. */
+static size_t buf_size;
+
+/* Initial prefix to ignore for each file. */
+static off_t ignore_initial;
+
+/* Output format:
+ type_first_diff
+ to print the offset and line number of the first differing bytes
+ type_all_diffs
+ to print the (decimal) offsets and (octal) values of all differing bytes
+ type_status
+ to only return an exit status indicating whether the files differ */
+static enum
+ {
+ type_first_diff, type_all_diffs, type_status
+ } comparison_type;
+
+/* Type used for fast comparison of several bytes at a time. */
+#ifndef word
+#define word int
+#endif
+
+/* If nonzero, print values of bytes quoted like cat -t does. */
+static int opt_print_chars;
+
+static struct option const long_options[] =
+{
+ {"print-chars", 0, 0, 'c'},
+ {"ignore-initial", 1, 0, 'i'},
+ {"verbose", 0, 0, 'l'},
+ {"silent", 0, 0, 's'},
+ {"quiet", 0, 0, 's'},
+ {"version", 0, 0, 'v'},
+ {"help", 0, 0, 129},
+ {0, 0, 0, 0}
+};
+
+static void
+try_help (reason)
+ char const *reason;
+{
+ if (reason)
+ error (0, 0, "%s", reason);
+ error (2, 0, "Try `%s --help' for more information.", program_name);
+}
+
+static void
+check_stdout ()
+{
+ if (ferror (stdout))
+ error (2, 0, "write error");
+ else if (fclose (stdout) != 0)
+ error (2, errno, "write error");
+}
+
+static void
+usage ()
+{
+ printf ("Usage: %s [OPTION]... FILE1 [FILE2]\n", program_name);
+ printf ("%s", "\
+ -c --print-chars Output differing bytes as characters.\n\
+ -i N --ignore-initial=N Ignore differences in the first N bytes of input.\n\
+ -l --verbose Output offsets and codes of all differing bytes.\n\
+ -s --quiet --silent Output nothing; yield exit status only.\n\
+ -v --version Output version info.\n\
+ --help Output this help.\n");
+ printf ("If a FILE is `-' or missing, read standard input.\n");
+}
+
+int
+main (argc, argv)
+ int argc;
+ char *argv[];
+{
+ int c, i, exit_status;
+ struct stat stat_buf[2];
+
+ initialize_main (&argc, &argv);
+ program_name = argv[0];
+
+ /* Parse command line options. */
+
+ while ((c = getopt_long (argc, argv, "ci:lsv", long_options, 0))
+ != EOF)
+ switch (c)
+ {
+ case 'c':
+ opt_print_chars = 1;
+ break;
+
+ case 'i':
+ ignore_initial = 0;
+ while (*optarg)
+ {
+ /* Don't use `atol', because `off_t' may be longer than `long'. */
+ unsigned digit = *optarg++ - '0';
+ if (9 < digit)
+ try_help ("non-digit in --ignore-initial value");
+ ignore_initial = 10 * ignore_initial + digit;
+ }
+ break;
+
+ case 'l':
+ comparison_type = type_all_diffs;
+ break;
+
+ case 's':
+ comparison_type = type_status;
+ break;
+
+ case 'v':
+ printf ("cmp - GNU diffutils version %s\n", version_string);
+ exit (0);
+
+ case 129:
+ usage ();
+ check_stdout ();
+ exit (0);
+
+ default:
+ try_help (0);
+ }
+
+ if (optind == argc)
+ try_help ("missing operand");
+
+ file[0] = argv[optind++];
+ file[1] = optind < argc ? argv[optind++] : "-";
+
+ if (optind < argc)
+ try_help ("extra operands");
+
+ for (i = 0; i < 2; i++)
+ {
+ /* If file[1] is "-", treat it first; this avoids a misdiagnostic if
+ stdin is closed and opening file[0] yields file descriptor 0. */
+ int i1 = i ^ (strcmp (file[1], "-") == 0);
+
+ /* Two files with the same name are identical.
+ But wait until we open the file once, for proper diagnostics. */
+ if (i && filename_cmp (file[0], file[1]) == 0)
+ exit (0);
+
+ file_desc[i1] = (strcmp (file[i1], "-") == 0
+ ? STDIN_FILENO
+ : open (file[i1], O_RDONLY, 0));
+ if (file_desc[i1] < 0 || fstat (file_desc[i1], &stat_buf[i1]) != 0)
+ {
+ if (file_desc[i1] < 0 && comparison_type == type_status)
+ exit (2);
+ else
+ error (2, errno, "%s", file[i1]);
+ }
+#if HAVE_SETMODE
+ setmode (file_desc[i1], O_BINARY);
+#endif
+ }
+
+ /* If the files are links to the same inode and have the same file position,
+ they are identical. */
+
+ if (0 < same_file (&stat_buf[0], &stat_buf[1])
+ && file_position (0) == file_position (1))
+ exit (0);
+
+ /* If output is redirected to the null device, we may assume `-s'. */
+
+ if (comparison_type != type_status)
+ {
+ struct stat outstat, nullstat;
+
+ if (fstat (STDOUT_FILENO, &outstat) == 0
+ && stat (NULL_DEVICE, &nullstat) == 0
+ && 0 < same_file (&outstat, &nullstat))
+ comparison_type = type_status;
+ }
+
+ /* If only a return code is needed,
+ and if both input descriptors are associated with plain files,
+ conclude that the files differ if they have different sizes. */
+
+ if (comparison_type == type_status
+ && S_ISREG (stat_buf[0].st_mode)
+ && S_ISREG (stat_buf[1].st_mode))
+ {
+ off_t s0 = stat_buf[0].st_size - file_position (0);
+ off_t s1 = stat_buf[1].st_size - file_position (1);
+
+ if (max (0, s0) != max (0, s1))
+ exit (1);
+ }
+
+ /* Get the optimal block size of the files. */
+
+ buf_size = buffer_lcm (STAT_BLOCKSIZE (stat_buf[0]),
+ STAT_BLOCKSIZE (stat_buf[1]));
+
+ /* Allocate buffers, with space for sentinels at the end. */
+
+ for (i = 0; i < 2; i++)
+ buffer[i] = xmalloc (buf_size + sizeof (word));
+
+ exit_status = cmp ();
+
+ for (i = 0; i < 2; i++)
+ if (close (file_desc[i]) != 0)
+ error (2, errno, "%s", file[i]);
+ if (exit_status != 0 && comparison_type != type_status)
+ check_stdout ();
+ exit (exit_status);
+ return exit_status;
+}
+
+/* Compare the two files already open on `file_desc[0]' and `file_desc[1]',
+ using `buffer[0]' and `buffer[1]'.
+ Return 0 if identical, 1 if different, >1 if error. */
+
+static int
+cmp ()
+{
+ long line_number = 1; /* Line number (1...) of first difference. */
+ long char_number = ignore_initial + 1;
+ /* Offset (1...) in files of 1st difference. */
+ size_t read0, read1; /* Number of chars read from each file. */
+ size_t first_diff; /* Offset (0...) in buffers of 1st diff. */
+ size_t smaller; /* The lesser of `read0' and `read1'. */
+ char *buf0 = buffer[0];
+ char *buf1 = buffer[1];
+ int ret = 0;
+ int i;
+
+ if (ignore_initial)
+ for (i = 0; i < 2; i++)
+ if (file_position (i) == -1)
+ {
+ /* lseek failed; read and discard the ignored initial prefix. */
+ off_t ig = ignore_initial;
+ do
+ {
+ size_t r = read (file_desc[i], buf0, (size_t) min (ig, buf_size));
+ if (!r)
+ break;
+ if (r == -1)
+ error (2, errno, "%s", file[i]);
+ ig -= r;
+ }
+ while (ig);
+ }
+
+ do
+ {
+ read0 = block_read (file_desc[0], buf0, buf_size);
+ if (read0 == -1)
+ error (2, errno, "%s", file[0]);
+ read1 = block_read (file_desc[1], buf1, buf_size);
+ if (read1 == -1)
+ error (2, errno, "%s", file[1]);
+
+ /* Insert sentinels for the block compare. */
+
+ buf0[read0] = ~buf1[read0];
+ buf1[read1] = ~buf0[read1];
+
+ /* If the line number should be written for differing files,
+ compare the blocks and count the number of newlines
+ simultaneously. */
+ first_diff = (comparison_type == type_first_diff
+ ? block_compare_and_count (buf0, buf1, &line_number)
+ : block_compare (buf0, buf1));
+
+ char_number += first_diff;
+ smaller = min (read0, read1);
+
+ if (first_diff < smaller)
+ {
+ switch (comparison_type)
+ {
+ case type_first_diff:
+ /* See Posix.2 section 4.10.6.1 for this format. */
+ printf ("%s %s differ: char %lu, line %lu",
+ file[0], file[1], char_number, line_number);
+ if (opt_print_chars)
+ {
+ unsigned char c0 = buf0[first_diff];
+ unsigned char c1 = buf1[first_diff];
+ printf (" is %3o ", c0);
+ printc (0, c0);
+ printf (" %3o ", c1);
+ printc (0, c1);
+ }
+ putchar ('\n');
+ /* Fall through. */
+ case type_status:
+ return 1;
+
+ case type_all_diffs:
+ do
+ {
+ unsigned char c0 = buf0[first_diff];
+ unsigned char c1 = buf1[first_diff];
+ if (c0 != c1)
+ {
+ if (opt_print_chars)
+ {
+ printf ("%6lu %3o ", char_number, c0);
+ printc (4, c0);
+ printf (" %3o ", c1);
+ printc (0, c1);
+ putchar ('\n');
+ }
+ else
+ /* See Posix.2 section 4.10.6.1 for this format. */
+ printf ("%6lu %3o %3o\n", char_number, c0, c1);
+ }
+ char_number++;
+ first_diff++;
+ }
+ while (first_diff < smaller);
+ ret = 1;
+ break;
+ }
+ }
+
+ if (read0 != read1)
+ {
+ if (comparison_type != type_status)
+ /* See Posix.2 section 4.10.6.2 for this format. */
+ fprintf (stderr, "cmp: EOF on %s\n", file[read1 < read0]);
+
+ return 1;
+ }
+ }
+ while (read0 == buf_size);
+ return ret;
+}
+
+/* Compare two blocks of memory P0 and P1 until they differ,
+ and count the number of '\n' occurrences in the common
+ part of P0 and P1.
+ Assumes that P0 and P1 are aligned at word addresses!
+ If the blocks are not guaranteed to be different, put sentinels at the ends
+ of the blocks before calling this function.
+
+ Return the offset of the first byte that differs.
+ Increment *COUNT by the count of '\n' occurrences. */
+
+static size_t
+block_compare_and_count (p0, p1, count)
+ char const *p0, *p1;
+ long *count;
+{
+ word l; /* One word from first buffer. */
+ word const *l0, *l1; /* Pointers into each buffer. */
+ char const *c0, *c1; /* Pointers for finding exact address. */
+ long cnt = 0; /* Number of '\n' occurrences. */
+ word nnnn; /* Newline, sizeof (word) times. */
+ int i;
+
+ l0 = (word const *) p0;
+ l1 = (word const *) p1;
+
+ nnnn = 0;
+ for (i = 0; i < sizeof (word); i++)
+ nnnn = (nnnn << CHAR_BIT) | '\n';
+
+ /* Find the rough position of the first difference by reading words,
+ not bytes. */
+
+ while ((l = *l0++) == *l1++)
+ {
+ l ^= nnnn;
+ for (i = 0; i < sizeof (word); i++)
+ {
+ cnt += ! (unsigned char) l;
+ l >>= CHAR_BIT;
+ }
+ }
+
+ /* Find the exact differing position (endianness independent). */
+
+ c0 = (char const *) (l0 - 1);
+ c1 = (char const *) (l1 - 1);
+ while (*c0 == *c1)
+ {
+ cnt += *c0 == '\n';
+ c0++;
+ c1++;
+ }
+
+ *count += cnt;
+ return c0 - p0;
+}
+
+/* Compare two blocks of memory P0 and P1 until they differ.
+ Assumes that P0 and P1 are aligned at word addresses!
+ If the blocks are not guaranteed to be different, put sentinels at the ends
+ of the blocks before calling this function.
+
+ Return the offset of the first byte that differs. */
+
+static size_t
+block_compare (p0, p1)
+ char const *p0, *p1;
+{
+ word const *l0, *l1;
+ char const *c0, *c1;
+
+ l0 = (word const *) p0;
+ l1 = (word const *) p1;
+
+ /* Find the rough position of the first difference by reading words,
+ not bytes. */
+
+ while (*l0++ == *l1++)
+ ;
+
+ /* Find the exact differing position (endianness independent). */
+
+ c0 = (char const *) (l0 - 1);
+ c1 = (char const *) (l1 - 1);
+ while (*c0 == *c1)
+ {
+ c0++;
+ c1++;
+ }
+
+ return c0 - p0;
+}
+
+/* Read NCHARS bytes from descriptor FD into BUF.
+ Return the number of characters successfully read.
+ The number returned is always NCHARS unless end-of-file or error. */
+
+static size_t
+block_read (fd, buf, nchars)
+ int fd;
+ char *buf;
+ size_t nchars;
+{
+ char *bp = buf;
+
+ do
+ {
+ size_t nread = read (fd, bp, nchars);
+ if (nread == -1)
+ return -1;
+ if (nread == 0)
+ break;
+ bp += nread;
+ nchars -= nread;
+ }
+ while (nchars != 0);
+
+ return bp - buf;
+}
+
+/* Print character C, making unprintable characters
+ visible by quoting like cat -t does.
+ Pad with spaces on the right to WIDTH characters. */
+
+static void
+printc (width, c)
+ int width;
+ unsigned c;
+{
+ register FILE *fs = stdout;
+
+ if (! ISPRINT (c))
+ {
+ if (c >= 128)
+ {
+ putc ('M', fs);
+ putc ('-', fs);
+ c -= 128;
+ width -= 2;
+ }
+ if (c < 32)
+ {
+ putc ('^', fs);
+ c += 64;
+ --width;
+ }
+ else if (c == 127)
+ {
+ putc ('^', fs);
+ c = '?';
+ --width;
+ }
+ }
+
+ putc (c, fs);
+ while (--width > 0)
+ putc (' ', fs);
+}
+
+/* Position file I to `ignore_initial' bytes from its initial position,
+ and yield its new position. Don't try more than once. */
+
+static off_t
+file_position (i)
+ int i;
+{
+ static int positioned[2];
+ static off_t position[2];
+
+ if (! positioned[i])
+ {
+ positioned[i] = 1;
+ position[i] = lseek (file_desc[i], ignore_initial, SEEK_CUR);
+ }
+ return position[i];
+}
diff --git a/gnu/dist/diffutils/cmpbuf.c b/gnu/dist/diffutils/cmpbuf.c
new file mode 100644
index 00000000000..e95a8f98ed9
--- /dev/null
+++ b/gnu/dist/diffutils/cmpbuf.c
@@ -0,0 +1,40 @@
+/* Buffer primitives for comparison operations.
+ Copyright (C) 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include "system.h"
+#include "cmpbuf.h"
+
+/* Least common multiple of two buffer sizes A and B. */
+
+size_t
+buffer_lcm (a, b)
+ size_t a, b;
+{
+ size_t m, n, r;
+
+ /* Yield reasonable values if buffer sizes are zero. */
+ if (!a)
+ return b ? b : 8 * 1024;
+ if (!b)
+ return a;
+
+ /* n = gcd (a, b) */
+ for (m = a, n = b; (r = m % n) != 0; m = n, n = r)
+ continue;
+
+ return a/n * b;
+}
diff --git a/gnu/dist/diffutils/cmpbuf.h b/gnu/dist/diffutils/cmpbuf.h
new file mode 100644
index 00000000000..e3852b7bd4f
--- /dev/null
+++ b/gnu/dist/diffutils/cmpbuf.h
@@ -0,0 +1,20 @@
+/* Buffer primitives for comparison operations.
+ Copyright (C) 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. */
+
+size_t buffer_lcm PARAMS((size_t, size_t));
diff --git a/gnu/dist/diffutils/config.hin b/gnu/dist/diffutils/config.hin
new file mode 100644
index 00000000000..d1a5f93e6e9
--- /dev/null
+++ b/gnu/dist/diffutils/config.hin
@@ -0,0 +1,117 @@
+/* config.hin. Generated automatically from configure.in by autoheader. */
+
+/* Define if using alloca.c. */
+#undef C_ALLOCA
+
+/* Define if the closedir function returns void instead of int. */
+#undef CLOSEDIR_VOID
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
+ This function is required for alloca.c support on those systems. */
+#undef CRAY_STACKSEG_END
+
+/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
+#undef HAVE_ALLOCA_H
+
+/* Define if you don't have vprintf but do have _doprnt. */
+#undef HAVE_DOPRNT
+
+/* Define if your struct stat has st_blksize. */
+#undef HAVE_ST_BLKSIZE
+
+/* Define if you have <vfork.h>. */
+#undef HAVE_VFORK_H
+
+/* Define if you have the vprintf function. */
+#undef HAVE_VPRINTF
+
+/* Define if on MINIX. */
+#undef _MINIX
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef pid_t
+
+/* Define if the system does not provide POSIX.1 features except
+ with this defined. */
+#undef _POSIX_1_SOURCE
+
+/* Define if you need to in order for stat and other things to work. */
+#undef _POSIX_SOURCE
+
+/* Define as the return type of signal handlers (int or void). */
+#undef RETSIGTYPE
+
+/* If using the C implementation of alloca, define if you know the
+ direction of stack growth for your system; otherwise it will be
+ automatically deduced at run-time.
+ STACK_DIRECTION > 0 => grows toward higher addresses
+ STACK_DIRECTION < 0 => grows toward lower addresses
+ STACK_DIRECTION = 0 => direction of growth unknown
+ */
+#undef STACK_DIRECTION
+
+/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */
+#undef STAT_MACROS_BROKEN
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if <sys/wait.h> is compatible with Posix applications. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define vfork as fork if vfork does not work. */
+#undef vfork
+
+/* Define if you have the dup2 function. */
+#undef HAVE_DUP2
+
+/* Define if you have the memchr function. */
+#undef HAVE_MEMCHR
+
+/* Define if you have the sigaction function. */
+#undef HAVE_SIGACTION
+
+/* Define if you have the strchr function. */
+#undef HAVE_STRCHR
+
+/* Define if you have the strerror function. */
+#undef HAVE_STRERROR
+
+/* Define if you have the tmpnam function. */
+#undef HAVE_TMPNAM
+
+/* Define if you have the <dirent.h> header file. */
+#undef HAVE_DIRENT_H
+
+/* Define if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
+/* Define if you have the <ndir.h> header file. */
+#undef HAVE_NDIR_H
+
+/* Define if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define if you have the <sys/dir.h> header file. */
+#undef HAVE_SYS_DIR_H
+
+/* Define if you have the <sys/file.h> header file. */
+#undef HAVE_SYS_FILE_H
+
+/* Define if you have the <sys/ndir.h> header file. */
+#undef HAVE_SYS_NDIR_H
+
+/* Define if you have the <time.h> header file. */
+#undef HAVE_TIME_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
diff --git a/gnu/dist/diffutils/configure b/gnu/dist/diffutils/configure
new file mode 100755
index 00000000000..b24ef2a9479
--- /dev/null
+++ b/gnu/dist/diffutils/configure
@@ -0,0 +1,2149 @@
+#!/bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 1.120
+# Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+#
+# This configure script 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 script 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 script; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+# The redistribution and modification terms for this script do not affect
+# the terms for software that it configures.
+
+ac_help=
+
+# Omit some internal or obsolete options to make the list less imposing.
+ac_usage="Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --exec-prefix=PREFIX install host dependent files in PREFIX [/usr/local]
+ --prefix=PREFIX install host independent files in PREFIX [/usr/local]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+--enable and --with options recognized:$ac_help"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Initialize some other variables.
+subdirs=
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -build | --build | --buil | --bui | --bu | --b)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=* | --b=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ cat << EOF
+$ac_usage
+EOF
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 1.120"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 unused; standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 unused; some systems may open it to /dev/tty
+# 4 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 4>/dev/null
+else
+ exec 4>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=diff.h
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE=$prefix/lib/config.site
+ else
+ CONFIG_SITE=/usr/local/lib/config.site
+ fi
+ # System dependent files override system independent ones.
+ if test "x$exec_prefix" != xNONE && test "x$exec_prefix" != "x$prefix"; then
+ CONFIG_SITE="$CONFIG_SITE $exec_prefix/lib/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_link='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext -o conftest $LIBS 1>&5 2>&5'
+
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $.
+ echo 's,\\,\\\\,g; s,\$,$$,g' > conftestsed
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_CC" && ac_cv_prog_CC="cc"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&4
+else
+ echo "$ac_t""no" 1>&4
+fi
+
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes
+#endif
+EOF
+if ${CC-cc} -E conftest.c 2>&5 | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+echo "$ac_t""$ac_cv_prog_gcc" 1>&4
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+ if test "${CFLAGS+set}" != set; then
+ echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_prog_gcc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_gcc_g=yes
+else
+ ac_cv_prog_gcc_g=no
+fi
+rm -f conftest*
+
+fi
+ echo "$ac_t""$ac_cv_prog_gcc_g" 1>&4
+ if test $ac_cv_prog_gcc_g = yes; then
+ CFLAGS="-g -O"
+ else
+ CFLAGS="-O"
+ fi
+ fi
+else
+ GCC=
+ test "${CFLAGS+set}" = set || CFLAGS="-g"
+fi
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&4
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '${'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 513 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+Syntax Error
+EOF
+eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 527 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+Syntax Error
+EOF
+eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+fi
+CPP="$ac_cv_prog_CPP"
+echo "$ac_t""$CPP" 1>&4
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&4
+if test -z "$INSTALL"; then
+if eval "test \"`echo '${'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+ for ac_dir in $PATH; do
+ case "$ac_dir" in
+ ''|.|/etc|/usr/sbin|/usr/etc|/sbin|/usr/afsws/bin|/usr/ucb) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ for ac_prog in ginstall installbsd scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ # OSF/1 installbsd also uses dspmsg, but is usable.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_ifs"
+ # As a last resort, use the slow shell script.
+ test -z "$ac_cv_path_install" && ac_cv_path_install="$ac_install_sh"
+fi
+ INSTALL="$ac_cv_path_install"
+fi
+echo "$ac_t""$INSTALL" 1>&4
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&4
+if test -d /etc/conf/kconfig.d &&
+ grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
+then
+ echo "$ac_t""yes" 1>&4
+ ISC=yes # If later tests want to check for ISC.
+ cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+ if test "$GCC" = yes; then
+ CC="$CC -posix"
+ else
+ CC="$CC -Xp"
+ fi
+else
+ echo "$ac_t""no" 1>&4
+ ISC=
+fi
+
+ac_safe=`echo "minix/config.h" | tr './' '__'`
+echo $ac_n "checking for minix/config.h""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 646 "configure"
+#include "confdefs.h"
+#include <minix/config.h>
+EOF
+eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&4
+ MINIX=yes
+else
+ echo "$ac_t""no" 1>&4
+MINIX=
+fi
+
+if test "$MINIX" = yes; then
+ cat >> confdefs.h <<\EOF
+#define _POSIX_SOURCE 1
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define _POSIX_1_SOURCE 2
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define _MINIX 1
+EOF
+
+fi
+
+echo $ac_n "checking for working const""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 690 "configure"
+#include "confdefs.h"
+
+int main() { return 0; }
+int t() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero;
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_c_const" 1>&4
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+# If we cannot run a trivial program, we must be cross compiling.
+echo $ac_n "checking whether cross-compiling""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_c_cross'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_cross=yes
+else
+cat > conftest.$ac_ext <<EOF
+#line 767 "configure"
+#include "confdefs.h"
+main(){return(0);}
+EOF
+eval $ac_link
+if test -s conftest && (./conftest; exit) 2>/dev/null; then
+ ac_cv_c_cross=no
+else
+ ac_cv_c_cross=yes
+fi
+fi
+rm -fr conftest*
+fi
+cross_compiling=$ac_cv_c_cross
+echo "$ac_t""$ac_cv_c_cross" 1>&4
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 788 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 810 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 828 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ ac_cv_header_stdc=no
+else
+cat > conftest.$ac_ext <<EOF
+#line 849 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+eval $ac_link
+if test -s conftest && (./conftest; exit) 2>/dev/null; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+fi
+rm -fr conftest*
+fi
+fi
+echo "$ac_t""$ac_cv_header_stdc" 1>&4
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+for ac_hdr in unistd.h fcntl.h limits.h stdlib.h string.h sys/file.h time.h
+do
+ac_safe=`echo "$ac_hdr" | tr './' '__'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 886 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&4
+ ac_tr_hdr=HAVE_`echo $ac_hdr | tr '[a-z]./' '[A-Z]__'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&4
+fi
+done
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
+do
+ac_safe=`echo "$ac_hdr" | tr './' '__'`
+echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 923 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <$ac_hdr>
+int main() { return 0; }
+int t() {
+DIR *dirp = 0;
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ eval "ac_cv_header_dirent_$ac_safe=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_header_dirent_$ac_safe=no"
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&4
+ ac_tr_hdr=HAVE_`echo $ac_hdr | tr '[a-z]./' '[A-Z]__'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ ac_header_dirent=$ac_hdr; break
+else
+ echo "$ac_t""no" 1>&4
+fi
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix,
+# and -lx contains other useful things as well. (FIXME what are they?)
+if test $ac_header_dirent = dirent.h; then
+echo $ac_n "checking for -ldir""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_lib_dir'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ ac_save_LIBS="$LIBS"
+LIBS="$LIBS -ldir "
+cat > conftest.$ac_ext <<EOF
+#line 963 "configure"
+#include "confdefs.h"
+
+int main() { return 0; }
+int t() {
+opendir()
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ eval "ac_cv_lib_dir=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_lib_dir=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'dir`\" = yes"; then
+ echo "$ac_t""yes" 1>&4
+ LIBS="$LIBS -ldir"
+else
+ echo "$ac_t""no" 1>&4
+fi
+
+fi
+echo $ac_n "checking for -lx""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_lib_x'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ ac_save_LIBS="$LIBS"
+LIBS="$LIBS -lx "
+cat > conftest.$ac_ext <<EOF
+#line 997 "configure"
+#include "confdefs.h"
+
+int main() { return 0; }
+int t() {
+main()
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ eval "ac_cv_lib_x=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_lib_x=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'x`\" = yes"; then
+ echo "$ac_t""yes" 1>&4
+ LIBS="$LIBS -lx"
+else
+ echo "$ac_t""no" 1>&4
+fi
+
+
+echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_header_stat_broken'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1029 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef S_ISBLK
+# if S_ISBLK (S_IFDIR)
+You lose.
+# endif
+# ifdef S_IFCHR
+# if S_ISBLK (S_IFCHR)
+You lose.
+# endif
+# endif
+#endif
+
+#ifdef S_ISLNK
+# if S_ISLNK (S_IFREG)
+You lose.
+# endif
+#endif
+
+#ifdef S_ISSOCK
+# if S_ISSOCK (S_IFREG)
+You lose.
+# endif
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "You lose" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_header_stat_broken=yes
+else
+ rm -rf conftest*
+ ac_cv_header_stat_broken=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_header_stat_broken" 1>&4
+if test $ac_cv_header_stat_broken = yes; then
+ cat >> confdefs.h <<\EOF
+#define STAT_MACROS_BROKEN 1
+EOF
+
+fi
+
+echo $ac_n "checking for sys/wait.h that is compatible with Posix.1""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1081 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+int main() { return 0; }
+int t() {
+int s;
+wait (&s);
+waitpid (0, &s, 0);
+s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ ac_cv_header_sys_wait_h=yes
+else
+ rm -rf conftest*
+ ac_cv_header_sys_wait_h=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&4
+if test $ac_cv_header_sys_wait_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYS_WAIT_H 1
+EOF
+
+fi
+
+echo $ac_n "checking for pid_t""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_type_pid_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1122 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "pid_t" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_pid_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_pid_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_pid_t" 1>&4
+if test $ac_cv_type_pid_t = no; then
+ cat >> confdefs.h <<\EOF
+#define pid_t int
+EOF
+
+fi
+
+echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_type_signal'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1153 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <signal.h>
+#ifdef signal
+#undef signal
+#endif
+extern void (*signal ()) ();
+int main() { return 0; }
+int t() {
+int i;
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ ac_cv_type_signal=void
+else
+ rm -rf conftest*
+ ac_cv_type_signal=int
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_signal" 1>&4
+cat >> confdefs.h <<EOF
+#define RETSIGTYPE $ac_cv_type_signal
+EOF
+
+
+for ac_func in dup2 memchr sigaction strchr strerror tmpnam
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1189 "configure"
+#include "confdefs.h"
+#include <ctype.h> /* Arbitrary system header to define __stub macros. */
+int main() { return 0; }
+int t() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+/* Override any gcc2 internal prototype to avoid an error. */
+char $ac_func(); $ac_func();
+#endif
+
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&4
+ ac_tr_func=HAVE_`echo $ac_func | tr '[a-z]' '[A-Z]'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&4
+fi
+done
+
+for ac_func in memchr waitpid
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1236 "configure"
+#include "confdefs.h"
+#include <ctype.h> /* Arbitrary system header to define __stub macros. */
+int main() { return 0; }
+int t() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+/* Override any gcc2 internal prototype to avoid an error. */
+char $ac_func(); $ac_func();
+#endif
+
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&4
+ :
+else
+ echo "$ac_t""no" 1>&4
+LIBOBJS="$LIBOBJS ${ac_func}.o"
+fi
+
+done
+
+# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
+# for constant arguments. Useless!
+echo $ac_n "checking for working alloca.h""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_header_alloca_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1281 "configure"
+#include "confdefs.h"
+#include <alloca.h>
+int main() { return 0; }
+int t() {
+char *p = alloca(2 * sizeof(int));
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ ac_cv_header_alloca_h=yes
+else
+ rm -rf conftest*
+ ac_cv_header_alloca_h=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_header_alloca_h" 1>&4
+if test $ac_cv_header_alloca_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA_H 1
+EOF
+
+fi
+
+echo $ac_n "checking for alloca""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_func_alloca'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1312 "configure"
+#include "confdefs.h"
+
+#ifdef __GNUC__
+# define alloca __builtin_alloca
+#else
+# if HAVE_ALLOCA_H
+# include <alloca.h>
+# else
+# ifdef _AIX
+ #pragma alloca
+# else
+# ifndef alloca /* predefined by HP cc +Olibcalls */
+char *alloca ();
+# endif
+# endif
+# endif
+#endif
+
+int main() { return 0; }
+int t() {
+char *p = (char *) alloca(1);
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ ac_cv_func_alloca=yes
+else
+ rm -rf conftest*
+ ac_cv_func_alloca=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_func_alloca" 1>&4
+if test $ac_cv_func_alloca = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ALLOCA 1
+EOF
+
+fi
+
+if test $ac_cv_func_alloca = no; then
+ # The SVR3 libPW and SVR4 libucb both contain incompatible functions
+ # that cause trouble. Some versions do not even contain alloca or
+ # contain a buggy version. If you still want to use their alloca,
+ # use ar to extract alloca.o from them instead of compiling alloca.c.
+ ALLOCA=alloca.o
+ cat >> confdefs.h <<\EOF
+#define C_ALLOCA 1
+EOF
+
+
+echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_os_cray'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1370 "configure"
+#include "confdefs.h"
+#if defined(CRAY) && ! defined(CRAY2)
+webecray
+#else
+wenotbecray
+#endif
+
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "webecray" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_os_cray=yes
+else
+ rm -rf conftest*
+ ac_cv_os_cray=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_os_cray" 1>&4
+if test $ac_cv_os_cray = yes; then
+echo $ac_n "checking for _getb67""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_func__getb67'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1397 "configure"
+#include "confdefs.h"
+#include <ctype.h> /* Arbitrary system header to define __stub macros. */
+int main() { return 0; }
+int t() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub__getb67) || defined (__stub____getb67)
+choke me
+#else
+/* Override any gcc2 internal prototype to avoid an error. */
+char _getb67(); _getb67();
+#endif
+
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ eval "ac_cv_func__getb67=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_func__getb67=no"
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_func_'_getb67`\" = yes"; then
+ echo "$ac_t""yes" 1>&4
+ cat >> confdefs.h <<\EOF
+#define CRAY_STACKSEG_END _getb67
+EOF
+
+else
+ echo "$ac_t""no" 1>&4
+echo $ac_n "checking for GETB67""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_func_GETB67'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1438 "configure"
+#include "confdefs.h"
+#include <ctype.h> /* Arbitrary system header to define __stub macros. */
+int main() { return 0; }
+int t() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_GETB67) || defined (__stub___GETB67)
+choke me
+#else
+/* Override any gcc2 internal prototype to avoid an error. */
+char GETB67(); GETB67();
+#endif
+
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ eval "ac_cv_func_GETB67=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_func_GETB67=no"
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_func_'GETB67`\" = yes"; then
+ echo "$ac_t""yes" 1>&4
+ cat >> confdefs.h <<\EOF
+#define CRAY_STACKSEG_END GETB67
+EOF
+
+else
+ echo "$ac_t""no" 1>&4
+echo $ac_n "checking for getb67""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_func_getb67'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1479 "configure"
+#include "confdefs.h"
+#include <ctype.h> /* Arbitrary system header to define __stub macros. */
+int main() { return 0; }
+int t() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_getb67) || defined (__stub___getb67)
+choke me
+#else
+/* Override any gcc2 internal prototype to avoid an error. */
+char getb67(); getb67();
+#endif
+
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ eval "ac_cv_func_getb67=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_func_getb67=no"
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_func_'getb67`\" = yes"; then
+ echo "$ac_t""yes" 1>&4
+ cat >> confdefs.h <<\EOF
+#define CRAY_STACKSEG_END getb67
+EOF
+
+else
+ echo "$ac_t""no" 1>&4
+fi
+
+fi
+
+fi
+
+fi
+
+echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_c_stack_direction'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_c_stack_direction=0
+else
+cat > conftest.$ac_ext <<EOF
+#line 1531 "configure"
+#include "confdefs.h"
+find_stack_direction ()
+{
+ static char *addr = 0;
+ auto char dummy;
+ if (addr == 0)
+ {
+ addr = &dummy;
+ return find_stack_direction ();
+ }
+ else
+ return (&dummy > addr) ? 1 : -1;
+}
+main ()
+{
+ exit (find_stack_direction() < 0);
+}
+EOF
+eval $ac_link
+if test -s conftest && (./conftest; exit) 2>/dev/null; then
+ ac_cv_c_stack_direction=1
+else
+ ac_cv_c_stack_direction=-1
+fi
+fi
+rm -fr conftest*
+fi
+echo "$ac_t""$ac_cv_c_stack_direction" 1>&4
+cat >> confdefs.h <<EOF
+#define STACK_DIRECTION $ac_cv_c_stack_direction
+EOF
+
+fi
+
+echo $ac_n "checking whether closedir returns void""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_func_closedir_void'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+cat > conftest.$ac_ext <<EOF
+#line 1574 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <$ac_header_dirent>
+int closedir(); main() { exit(closedir(opendir(".")) != 0); }
+EOF
+eval $ac_link
+if test -s conftest && (./conftest; exit) 2>/dev/null; then
+ ac_cv_func_closedir_void=no
+else
+ ac_cv_func_closedir_void=yes
+fi
+fi
+rm -fr conftest*
+fi
+echo "$ac_t""$ac_cv_func_closedir_void" 1>&4
+if test $ac_cv_func_closedir_void = yes; then
+ cat >> confdefs.h <<\EOF
+#define CLOSEDIR_VOID 1
+EOF
+
+fi
+
+ac_safe=`echo "vfork.h" | tr './' '__'`
+echo $ac_n "checking for vfork.h""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1603 "configure"
+#include "confdefs.h"
+#include <vfork.h>
+EOF
+eval "$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+ac_err=`grep -v '^ *+' conftest.out`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&4
+ cat >> confdefs.h <<\EOF
+#define HAVE_VFORK_H 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&4
+fi
+
+echo $ac_n "checking for working vfork""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_func_vfork'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+
+if test "$cross_compiling" = yes; then
+ ac_cv_func_vfork=no
+else
+cat > conftest.$ac_ext <<EOF
+#line 1638 "configure"
+#include "confdefs.h"
+/* Thanks to Paul Eggert for this test. */
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <signal.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_VFORK_H
+#include <vfork.h>
+#endif
+/* On sparc systems, changes by the child to local and incoming
+ argument registers are propagated back to the parent.
+ The compiler is told about this with #include <vfork.h>,
+ but some compilers (e.g. gcc -O) don't grok <vfork.h>.
+ Test for this by using a static variable whose address
+ is put into a register that is clobbered by the vfork. */
+static
+#ifdef __cplusplus
+sparc_address_test (int arg)
+#else
+sparc_address_test (arg) int arg;
+#endif
+{
+ static pid_t child;
+ if (!child) {
+ child = vfork ();
+ if (child < 0)
+ perror ("vfork");
+ if (!child) {
+ arg = getpid();
+ write(-1, "", 0);
+ _exit (arg);
+ }
+ }
+}
+static int signalled;
+static RETSIGTYPE catch (s) int s; { signalled = 1; }
+main() {
+ pid_t parent = getpid ();
+ pid_t child;
+
+ sparc_address_test ();
+
+ signal (SIGINT, catch);
+
+ child = vfork ();
+
+ if (child == 0) {
+ /* Here is another test for sparc vfork register problems.
+ This test uses lots of local variables, at least
+ as many local variables as main has allocated so far
+ including compiler temporaries. 4 locals are enough for
+ gcc 1.40.3 on a sparc, but we use 8 to be safe.
+ A buggy compiler should reuse the register of parent
+ for one of the local variables, since it will think that
+ parent can't possibly be used any more in this routine.
+ Assigning to the local variable will thus munge parent
+ in the parent process. */
+ pid_t
+ p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
+ p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
+ /* Convince the compiler that p..p7 are live; otherwise, it might
+ use the same hardware register for all 8 local variables. */
+ if (p != p1 || p != p2 || p != p3 || p != p4
+ || p != p5 || p != p6 || p != p7)
+ _exit(1);
+
+ /* On some systems (e.g. SunOS 5.2), if the parent is catching
+ a signal, the child ignores the signal before execing,
+ and the parent later receives that signal, the parent dumps core.
+ Test for this by ignoring SIGINT in the child. */
+ signal (SIGINT, SIG_IGN);
+
+ /* On some systems (e.g. IRIX 3.3),
+ vfork doesn't separate parent from child file descriptors.
+ If the child closes a descriptor before it execs or exits,
+ this munges the parent's descriptor as well.
+ Test for this by closing stdout in the child. */
+ _exit(close(fileno(stdout)) != 0);
+ } else {
+ int status;
+ struct stat st;
+
+ while (wait(&status) != child)
+ ;
+ exit(
+ /* Was there some problem with vforking? */
+ child < 0
+
+ /* Did the child fail? (This shouldn't happen.) */
+ || status
+
+ /* Did the vfork/compiler bug occur? */
+ || parent != getpid()
+
+ /* Did the signal handling bug occur? */
+ || kill(parent, SIGINT) != 0
+ || signalled != 1
+
+ /* Did the file descriptor bug occur? */
+ || fstat(fileno(stdout), &st) != 0
+ );
+ }
+}
+EOF
+eval $ac_link
+if test -s conftest && (./conftest; exit) 2>/dev/null; then
+ ac_cv_func_vfork=yes
+else
+ ac_cv_func_vfork=no
+fi
+fi
+rm -fr conftest*
+fi
+echo "$ac_t""$ac_cv_func_vfork" 1>&4
+if test $ac_cv_func_vfork = no; then
+ cat >> confdefs.h <<\EOF
+#define vfork fork
+EOF
+
+fi
+
+echo $ac_n "checking for vprintf""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_func_vprintf'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1768 "configure"
+#include "confdefs.h"
+#include <ctype.h> /* Arbitrary system header to define __stub macros. */
+int main() { return 0; }
+int t() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_vprintf) || defined (__stub___vprintf)
+choke me
+#else
+/* Override any gcc2 internal prototype to avoid an error. */
+char vprintf(); vprintf();
+#endif
+
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ eval "ac_cv_func_vprintf=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_func_vprintf=no"
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_func_'vprintf`\" = yes"; then
+ echo "$ac_t""yes" 1>&4
+ cat >> confdefs.h <<\EOF
+#define HAVE_VPRINTF 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&4
+fi
+
+if test "$ac_cv_func_vprintf" != yes; then
+echo $ac_n "checking for _doprnt""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_func__doprnt'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1812 "configure"
+#include "confdefs.h"
+#include <ctype.h> /* Arbitrary system header to define __stub macros. */
+int main() { return 0; }
+int t() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub__doprnt) || defined (__stub____doprnt)
+choke me
+#else
+/* Override any gcc2 internal prototype to avoid an error. */
+char _doprnt(); _doprnt();
+#endif
+
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ eval "ac_cv_func__doprnt=yes"
+else
+ rm -rf conftest*
+ eval "ac_cv_func__doprnt=no"
+fi
+rm -f conftest*
+
+fi
+if eval "test \"`echo '$ac_cv_func_'_doprnt`\" = yes"; then
+ echo "$ac_t""yes" 1>&4
+ cat >> confdefs.h <<\EOF
+#define HAVE_DOPRNT 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&4
+fi
+
+fi
+
+echo $ac_n "checking for st_blksize in struct stat""... $ac_c" 1>&4
+if eval "test \"`echo '${'ac_cv_struct_st_blksize'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&4
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1857 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+int main() { return 0; }
+int t() {
+struct stat s; s.st_blksize;
+; return 0; }
+EOF
+if eval $ac_link; then
+ rm -rf conftest*
+ ac_cv_struct_st_blksize=yes
+else
+ rm -rf conftest*
+ ac_cv_struct_st_blksize=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_struct_st_blksize" 1>&4
+if test $ac_cv_struct_st_blksize = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_ST_BLKSIZE 1
+EOF
+
+fi
+
+trap '' 1 2 15
+if test -w $cache_file; then
+echo "updating cache $cache_file"
+cat > $cache_file <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# Ultrix sh set writes to stderr and can't be redirected directly.
+(set) 2>&1 |
+ sed -n "s/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/: \${\1='\2'}/p" \
+ >> $cache_file
+else
+echo "not updating unwritable cache $cache_file"
+fi
+
+trap 'rm -fr conftest* confdefs* core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=/usr/local
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#!/bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 1.120"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr Makefile config.h:config.hin conftest*; exit 1' 1 2 15
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g$/@g/; /@g$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g$/%g/' > conftest.subs <<\CEOF
+$ac_vpsub
+$extrasub
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@CC@%$CC%g
+s%@CPP@%$CPP%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@LIBOBJS@%$LIBOBJS%g
+s%@ALLOCA@%$ALLOCA%g
+
+CEOF
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust relative srcdir, etc. for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/$ac_dir"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" -f conftest.subs $ac_given_srcdir/$ac_file_in > $ac_file
+fi; done
+rm -f conftest.subs
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+CONFIG_HEADERS=${CONFIG_HEADERS-"config.h:config.hin"}
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%.*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ cp $ac_given_srcdir/$ac_file_in conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) \(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+# Maximum number of lines to put in a single here document.
+ac_max_here_lines=12
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+
+date > stamp-h
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS
+
diff --git a/gnu/dist/diffutils/configure.in b/gnu/dist/diffutils/configure.in
new file mode 100644
index 00000000000..1aa66d1700b
--- /dev/null
+++ b/gnu/dist/diffutils/configure.in
@@ -0,0 +1,26 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(diff.h)
+AC_CONFIG_HEADER(config.h:config.hin)
+AC_ARG_PROGRAM
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_INSTALL
+AC_ISC_POSIX
+AC_MINIX
+AC_C_CONST
+AC_HEADER_STDC
+AC_CHECK_HEADERS(unistd.h fcntl.h limits.h stdlib.h string.h sys/file.h time.h)
+AC_HEADER_DIRENT
+AC_HEADER_STAT
+AC_HEADER_SYS_WAIT
+AC_TYPE_PID_T
+AC_TYPE_SIGNAL
+AC_CHECK_FUNCS(dup2 memchr sigaction strchr strerror tmpnam)
+AC_REPLACE_FUNCS(memchr waitpid)
+AC_FUNC_ALLOCA
+AC_FUNC_CLOSEDIR_VOID
+dnl No need for AC_FUNC_MEMCMP, since memcmp is used only to test for equality.
+AC_FUNC_VFORK
+AC_FUNC_VPRINTF
+AC_STRUCT_ST_BLKSIZE
+AC_OUTPUT(Makefile, [date > stamp-h])
diff --git a/gnu/dist/diffutils/context.c b/gnu/dist/diffutils/context.c
new file mode 100644
index 00000000000..14f950c5269
--- /dev/null
+++ b/gnu/dist/diffutils/context.c
@@ -0,0 +1,468 @@
+/* Context-format output routines for GNU DIFF.
+ Copyright (C) 1988,1989,1991,1992,1993,1994 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 "diff.h"
+
+static struct change *find_hunk PARAMS((struct change *));
+static void find_function PARAMS((struct file_data const *, int, char const **, size_t *));
+static void mark_ignorable PARAMS((struct change *));
+static void pr_context_hunk PARAMS((struct change *));
+static void pr_unidiff_hunk PARAMS((struct change *));
+static void print_context_label PARAMS ((char const *, struct file_data *, char const *));
+static void print_context_number_range PARAMS((struct file_data const *, int, int));
+static void print_unidiff_number_range PARAMS((struct file_data const *, int, int));
+
+/* Last place find_function started searching from. */
+static int find_function_last_search;
+
+/* The value find_function returned when it started searching there. */
+static int find_function_last_match;
+
+/* Print a label for a context diff, with a file name and date or a label. */
+
+static void
+print_context_label (mark, inf, label)
+ char const *mark;
+ struct file_data *inf;
+ char const *label;
+{
+ if (label)
+ fprintf (outfile, "%s %s\n", mark, label);
+ else
+ {
+ char const *ct = ctime (&inf->stat.st_mtime);
+ if (!ct)
+ ct = "?\n";
+ /* See Posix.2 section 4.17.6.1.4 for this format. */
+ fprintf (outfile, "%s %s\t%s", mark, inf->name, ct);
+ }
+}
+
+/* Print a header for a context diff, with the file names and dates. */
+
+void
+print_context_header (inf, unidiff_flag)
+ struct file_data inf[];
+ int unidiff_flag;
+{
+ if (unidiff_flag)
+ {
+ print_context_label ("---", &inf[0], file_label[0]);
+ print_context_label ("+++", &inf[1], file_label[1]);
+ }
+ else
+ {
+ print_context_label ("***", &inf[0], file_label[0]);
+ print_context_label ("---", &inf[1], file_label[1]);
+ }
+}
+
+/* Print an edit script in context format. */
+
+void
+print_context_script (script, unidiff_flag)
+ struct change *script;
+ int unidiff_flag;
+{
+ if (ignore_blank_lines_flag || ignore_regexp_list)
+ mark_ignorable (script);
+ else
+ {
+ struct change *e;
+ for (e = script; e; e = e->link)
+ e->ignore = 0;
+ }
+
+ find_function_last_search = - files[0].prefix_lines;
+ find_function_last_match = find_function_last_search - 1;
+
+ if (unidiff_flag)
+ print_script (script, find_hunk, pr_unidiff_hunk);
+ else
+ print_script (script, find_hunk, pr_context_hunk);
+}
+
+/* Print a pair of line numbers with a comma, translated for file FILE.
+ If the second number is not greater, use the first in place of it.
+
+ Args A and B are internal line numbers.
+ We print the translated (real) line numbers. */
+
+static void
+print_context_number_range (file, a, b)
+ struct file_data const *file;
+ int a, b;
+{
+ int trans_a, trans_b;
+ translate_range (file, a, b, &trans_a, &trans_b);
+
+ /* Note: we can have B < A in the case of a range of no lines.
+ In this case, we should print the line number before the range,
+ which is B. */
+ if (trans_b > trans_a)
+ fprintf (outfile, "%d,%d", trans_a, trans_b);
+ else
+ fprintf (outfile, "%d", trans_b);
+}
+
+/* Print a portion of an edit script in context format.
+ HUNK is the beginning of the portion to be printed.
+ The end is marked by a `link' that has been nulled out.
+
+ Prints out lines from both files, and precedes each
+ line with the appropriate flag-character. */
+
+static void
+pr_context_hunk (hunk)
+ struct change *hunk;
+{
+ int first0, last0, first1, last1, show_from, show_to, i;
+ struct change *next;
+ char const *prefix;
+ char const *function;
+ size_t function_length;
+ FILE *out;
+
+ /* Determine range of line numbers involved in each file. */
+
+ analyze_hunk (hunk, &first0, &last0, &first1, &last1, &show_from, &show_to);
+
+ if (!show_from && !show_to)
+ return;
+
+ /* Include a context's width before and after. */
+
+ i = - files[0].prefix_lines;
+ first0 = max (first0 - context, i);
+ first1 = max (first1 - context, i);
+ last0 = min (last0 + context, files[0].valid_lines - 1);
+ last1 = min (last1 + context, files[1].valid_lines - 1);
+
+ /* If desired, find the preceding function definition line in file 0. */
+ function = 0;
+ if (function_regexp_list)
+ find_function (&files[0], first0, &function, &function_length);
+
+ begin_output ();
+ out = outfile;
+
+ /* If we looked for and found a function this is part of,
+ include its name in the header of the diff section. */
+ fprintf (out, "***************");
+
+ if (function)
+ {
+ fprintf (out, " ");
+ fwrite (function, 1, min (function_length - 1, 40), out);
+ }
+
+ fprintf (out, "\n*** ");
+ print_context_number_range (&files[0], first0, last0);
+ fprintf (out, " ****\n");
+
+ if (show_from)
+ {
+ next = hunk;
+
+ for (i = first0; i <= last0; i++)
+ {
+ /* Skip past changes that apply (in file 0)
+ only to lines before line I. */
+
+ while (next && next->line0 + next->deleted <= i)
+ next = next->link;
+
+ /* Compute the marking for line I. */
+
+ prefix = " ";
+ if (next && next->line0 <= i)
+ /* The change NEXT covers this line.
+ If lines were inserted here in file 1, this is "changed".
+ Otherwise it is "deleted". */
+ prefix = (next->inserted > 0 ? "!" : "-");
+
+ print_1_line (prefix, &files[0].linbuf[i]);
+ }
+ }
+
+ fprintf (out, "--- ");
+ print_context_number_range (&files[1], first1, last1);
+ fprintf (out, " ----\n");
+
+ if (show_to)
+ {
+ next = hunk;
+
+ for (i = first1; i <= last1; i++)
+ {
+ /* Skip past changes that apply (in file 1)
+ only to lines before line I. */
+
+ while (next && next->line1 + next->inserted <= i)
+ next = next->link;
+
+ /* Compute the marking for line I. */
+
+ prefix = " ";
+ if (next && next->line1 <= i)
+ /* The change NEXT covers this line.
+ If lines were deleted here in file 0, this is "changed".
+ Otherwise it is "inserted". */
+ prefix = (next->deleted > 0 ? "!" : "+");
+
+ print_1_line (prefix, &files[1].linbuf[i]);
+ }
+ }
+}
+
+/* Print a pair of line numbers with a comma, translated for file FILE.
+ If the second number is smaller, use the first in place of it.
+ If the numbers are equal, print just one number.
+
+ Args A and B are internal line numbers.
+ We print the translated (real) line numbers. */
+
+static void
+print_unidiff_number_range (file, a, b)
+ struct file_data const *file;
+ int a, b;
+{
+ int trans_a, trans_b;
+ translate_range (file, a, b, &trans_a, &trans_b);
+
+ /* Note: we can have B < A in the case of a range of no lines.
+ In this case, we should print the line number before the range,
+ which is B. */
+ if (trans_b <= trans_a)
+ fprintf (outfile, trans_b == trans_a ? "%d" : "%d,0", trans_b);
+ else
+ fprintf (outfile, "%d,%d", trans_a, trans_b - trans_a + 1);
+}
+
+/* Print a portion of an edit script in unidiff format.
+ HUNK is the beginning of the portion to be printed.
+ The end is marked by a `link' that has been nulled out.
+
+ Prints out lines from both files, and precedes each
+ line with the appropriate flag-character. */
+
+static void
+pr_unidiff_hunk (hunk)
+ struct change *hunk;
+{
+ int first0, last0, first1, last1, show_from, show_to, i, j, k;
+ struct change *next;
+ char const *function;
+ size_t function_length;
+ FILE *out;
+
+ /* Determine range of line numbers involved in each file. */
+
+ analyze_hunk (hunk, &first0, &last0, &first1, &last1, &show_from, &show_to);
+
+ if (!show_from && !show_to)
+ return;
+
+ /* Include a context's width before and after. */
+
+ i = - files[0].prefix_lines;
+ first0 = max (first0 - context, i);
+ first1 = max (first1 - context, i);
+ last0 = min (last0 + context, files[0].valid_lines - 1);
+ last1 = min (last1 + context, files[1].valid_lines - 1);
+
+ /* If desired, find the preceding function definition line in file 0. */
+ function = 0;
+ if (function_regexp_list)
+ find_function (&files[0], first0, &function, &function_length);
+
+ begin_output ();
+ out = outfile;
+
+ fprintf (out, "@@ -");
+ print_unidiff_number_range (&files[0], first0, last0);
+ fprintf (out, " +");
+ print_unidiff_number_range (&files[1], first1, last1);
+ fprintf (out, " @@");
+
+ /* If we looked for and found a function this is part of,
+ include its name in the header of the diff section. */
+
+ if (function)
+ {
+ putc (' ', out);
+ fwrite (function, 1, min (function_length - 1, 40), out);
+ }
+ putc ('\n', out);
+
+ next = hunk;
+ i = first0;
+ j = first1;
+
+ while (i <= last0 || j <= last1)
+ {
+
+ /* If the line isn't a difference, output the context from file 0. */
+
+ if (!next || i < next->line0)
+ {
+ putc (tab_align_flag ? '\t' : ' ', out);
+ print_1_line (0, &files[0].linbuf[i++]);
+ j++;
+ }
+ else
+ {
+ /* For each difference, first output the deleted part. */
+
+ k = next->deleted;
+ while (k--)
+ {
+ putc ('-', out);
+ if (tab_align_flag)
+ putc ('\t', out);
+ print_1_line (0, &files[0].linbuf[i++]);
+ }
+
+ /* Then output the inserted part. */
+
+ k = next->inserted;
+ while (k--)
+ {
+ putc ('+', out);
+ if (tab_align_flag)
+ putc ('\t', out);
+ print_1_line (0, &files[1].linbuf[j++]);
+ }
+
+ /* We're done with this hunk, so on to the next! */
+
+ next = next->link;
+ }
+ }
+}
+
+/* Scan a (forward-ordered) edit script for the first place that more than
+ 2*CONTEXT unchanged lines appear, and return a pointer
+ to the `struct change' for the last change before those lines. */
+
+static struct change *
+find_hunk (start)
+ struct change *start;
+{
+ struct change *prev;
+ int top0, top1;
+ int thresh;
+
+ do
+ {
+ /* Compute number of first line in each file beyond this changed. */
+ top0 = start->line0 + start->deleted;
+ top1 = start->line1 + start->inserted;
+ prev = start;
+ start = start->link;
+ /* Threshold distance is 2*CONTEXT between two non-ignorable changes,
+ but only CONTEXT if one is ignorable. */
+ thresh = ((prev->ignore || (start && start->ignore))
+ ? context
+ : 2 * context + 1);
+ /* It is not supposed to matter which file we check in the end-test.
+ If it would matter, crash. */
+ if (start && start->line0 - top0 != start->line1 - top1)
+ abort ();
+ } while (start
+ /* Keep going if less than THRESH lines
+ elapse before the affected line. */
+ && start->line0 < top0 + thresh);
+
+ return prev;
+}
+
+/* Set the `ignore' flag properly in each change in SCRIPT.
+ It should be 1 if all the lines inserted or deleted in that change
+ are ignorable lines. */
+
+static void
+mark_ignorable (script)
+ struct change *script;
+{
+ while (script)
+ {
+ struct change *next = script->link;
+ int first0, last0, first1, last1, deletes, inserts;
+
+ /* Turn this change into a hunk: detach it from the others. */
+ script->link = 0;
+
+ /* Determine whether this change is ignorable. */
+ analyze_hunk (script, &first0, &last0, &first1, &last1, &deletes, &inserts);
+ /* Reconnect the chain as before. */
+ script->link = next;
+
+ /* If the change is ignorable, mark it. */
+ script->ignore = (!deletes && !inserts);
+
+ /* Advance to the following change. */
+ script = next;
+ }
+}
+
+/* Find the last function-header line in FILE prior to line number LINENUM.
+ This is a line containing a match for the regexp in `function_regexp'.
+ Store the address of the line text into LINEP and the length of the
+ line into LENP.
+ Do not store anything if no function-header is found. */
+
+static void
+find_function (file, linenum, linep, lenp)
+ struct file_data const *file;
+ int linenum;
+ char const **linep;
+ size_t *lenp;
+{
+ int i = linenum;
+ int last = find_function_last_search;
+ find_function_last_search = i;
+
+ while (--i >= last)
+ {
+ /* See if this line is what we want. */
+ struct regexp_list *r;
+ char const *line = file->linbuf[i];
+ size_t len = file->linbuf[i + 1] - line;
+
+ for (r = function_regexp_list; r; r = r->next)
+ if (0 <= re_search (&r->buf, line, len, 0, len, 0))
+ {
+ *linep = line;
+ *lenp = len;
+ find_function_last_match = i;
+ return;
+ }
+ }
+ /* If we search back to where we started searching the previous time,
+ find the line we found last time. */
+ if (find_function_last_match >= - file->prefix_lines)
+ {
+ i = find_function_last_match;
+ *linep = file->linbuf[i];
+ *lenp = file->linbuf[i + 1] - *linep;
+ return;
+ }
+ return;
+}
diff --git a/gnu/dist/diffutils/diagmeet.note b/gnu/dist/diffutils/diagmeet.note
new file mode 100644
index 00000000000..8f7242c7356
--- /dev/null
+++ b/gnu/dist/diffutils/diagmeet.note
@@ -0,0 +1,71 @@
+Here is a comparison matrix which shows a case in which
+it is possible for the forward and backward scan in `diag'
+to meet along a nonzero length of diagonal simultaneous
+(so that bdiag[d] and fdiag[d] are not equal)
+even though there is no snake on that diagonal at the meeting point.
+
+
+ 85 1 1 1 159 1 1 17
+ 1 2 3 4
+60
+ 1 2
+1
+ 2 2 3 4
+71
+ 3 3 4 5
+85
+ 4 3 4 5
+17
+ 5 4 5
+1
+ 6 4 5 6
+183
+ 7 5 6 7
+10
+ 8 6 7
+1
+ 9 6 7 8
+12
+ 7 8 9 10
+13
+ 10 8 9 10
+14
+ 10 9 10
+17
+ 10 10
+1
+ 10 9 10
+1
+ 8 10 10 10
+183
+ 8 7 9 9 9
+10
+ 7 6 8 9 8 8
+1
+ 6 5 7 7
+1
+ 5 6 6
+1
+ 5 5 5
+50
+ 5 4 4 4
+1
+ 4 3 3
+85
+ 5 4 3 2 2
+1
+ 2 1
+17
+ 5 4 3 2 1 1
+1
+ 1 0
+ 85 1 1 1 159 1 1 17
+
+
+
+
+
+
+
+
+
diff --git a/gnu/dist/diffutils/diff.c b/gnu/dist/diffutils/diff.c
new file mode 100644
index 00000000000..ab1549be864
--- /dev/null
+++ b/gnu/dist/diffutils/diff.c
@@ -0,0 +1,1106 @@
+/* GNU DIFF main routine.
+ Copyright (C) 1988, 1989, 1992, 1993, 1994 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. */
+
+/* GNU DIFF was written by Mike Haertel, David Hayes,
+ Richard Stallman, Len Tower, and Paul Eggert. */
+
+#define GDIFF_MAIN
+#include "diff.h"
+#include <signal.h>
+#include "getopt.h"
+#include "fnmatch.h"
+
+#ifndef DEFAULT_WIDTH
+#define DEFAULT_WIDTH 130
+#endif
+
+#ifndef GUTTER_WIDTH_MINIMUM
+#define GUTTER_WIDTH_MINIMUM 3
+#endif
+
+static char const *filetype PARAMS((struct stat const *));
+static char *option_list PARAMS((char **, int));
+static int add_exclude_file PARAMS((char const *));
+static int ck_atoi PARAMS((char const *, int *));
+static int compare_files PARAMS((char const *, char const *, char const *, char const *, int));
+static int specify_format PARAMS((char **, char *));
+static void add_exclude PARAMS((char const *));
+static void add_regexp PARAMS((struct regexp_list **, char const *));
+static void specify_style PARAMS((enum output_style));
+static void try_help PARAMS((char const *));
+static void check_stdout PARAMS((void));
+static void usage PARAMS((void));
+
+/* Nonzero for -r: if comparing two directories,
+ compare their common subdirectories recursively. */
+
+static int recursive;
+
+/* For debugging: don't do discard_confusing_lines. */
+
+int no_discards;
+
+#if HAVE_SETMODE
+/* I/O mode: nonzero only if using binary input/output. */
+static int binary_I_O;
+#endif
+
+/* Return a string containing the command options with which diff was invoked.
+ Spaces appear between what were separate ARGV-elements.
+ There is a space at the beginning but none at the end.
+ If there were no options, the result is an empty string.
+
+ Arguments: OPTIONVEC, a vector containing separate ARGV-elements, and COUNT,
+ the length of that vector. */
+
+static char *
+option_list (optionvec, count)
+ char **optionvec; /* Was `vector', but that collides on Alliant. */
+ int count;
+{
+ int i;
+ size_t length = 0;
+ char *result;
+
+ for (i = 0; i < count; i++)
+ length += strlen (optionvec[i]) + 1;
+
+ result = xmalloc (length + 1);
+ result[0] = 0;
+
+ for (i = 0; i < count; i++)
+ {
+ strcat (result, " ");
+ strcat (result, optionvec[i]);
+ }
+
+ return result;
+}
+
+/* Convert STR to a positive integer, storing the result in *OUT.
+ If STR is not a valid integer, return -1 (otherwise 0). */
+static int
+ck_atoi (str, out)
+ char const *str;
+ int *out;
+{
+ char const *p;
+ for (p = str; *p; p++)
+ if (*p < '0' || *p > '9')
+ return -1;
+
+ *out = atoi (optarg);
+ return 0;
+}
+
+/* Keep track of excluded file name patterns. */
+
+static char const **exclude;
+static int exclude_alloc, exclude_count;
+
+int
+excluded_filename (f)
+ char const *f;
+{
+ int i;
+ for (i = 0; i < exclude_count; i++)
+ if (fnmatch (exclude[i], f, 0) == 0)
+ return 1;
+ return 0;
+}
+
+static void
+add_exclude (pattern)
+ char const *pattern;
+{
+ if (exclude_alloc <= exclude_count)
+ exclude = (char const **)
+ (exclude_alloc == 0
+ ? xmalloc ((exclude_alloc = 64) * sizeof (*exclude))
+ : xrealloc (exclude, (exclude_alloc *= 2) * sizeof (*exclude)));
+
+ exclude[exclude_count++] = pattern;
+}
+
+static int
+add_exclude_file (name)
+ char const *name;
+{
+ struct file_data f;
+ char *p, *q, *lim;
+
+ f.name = optarg;
+ f.desc = (strcmp (optarg, "-") == 0
+ ? STDIN_FILENO
+ : open (optarg, O_RDONLY, 0));
+ if (f.desc < 0 || fstat (f.desc, &f.stat) != 0)
+ return -1;
+
+ sip (&f, 1);
+ slurp (&f);
+
+ for (p = f.buffer, lim = p + f.buffered_chars; p < lim; p = q)
+ {
+ q = (char *) memchr (p, '\n', lim - p);
+ if (!q)
+ q = lim;
+ *q++ = 0;
+ add_exclude (p);
+ }
+
+ return close (f.desc);
+}
+
+/* The numbers 129- that appear in the fourth element of some entries
+ tell the big switch in `main' how to process those options. */
+
+static struct option const longopts[] =
+{
+ {"ignore-blank-lines", 0, 0, 'B'},
+ {"context", 2, 0, 'C'},
+ {"ifdef", 1, 0, 'D'},
+ {"show-function-line", 1, 0, 'F'},
+ {"speed-large-files", 0, 0, 'H'},
+ {"ignore-matching-lines", 1, 0, 'I'},
+ {"label", 1, 0, 'L'},
+ {"file-label", 1, 0, 'L'}, /* An alias, no longer recommended */
+ {"new-file", 0, 0, 'N'},
+ {"entire-new-file", 0, 0, 'N'}, /* An alias, no longer recommended */
+ {"unidirectional-new-file", 0, 0, 'P'},
+ {"starting-file", 1, 0, 'S'},
+ {"initial-tab", 0, 0, 'T'},
+ {"width", 1, 0, 'W'},
+ {"text", 0, 0, 'a'},
+ {"ascii", 0, 0, 'a'}, /* An alias, no longer recommended */
+ {"ignore-space-change", 0, 0, 'b'},
+ {"minimal", 0, 0, 'd'},
+ {"ed", 0, 0, 'e'},
+ {"forward-ed", 0, 0, 'f'},
+ {"ignore-case", 0, 0, 'i'},
+ {"paginate", 0, 0, 'l'},
+ {"print", 0, 0, 'l'}, /* An alias, no longer recommended */
+ {"rcs", 0, 0, 'n'},
+ {"show-c-function", 0, 0, 'p'},
+ {"brief", 0, 0, 'q'},
+ {"recursive", 0, 0, 'r'},
+ {"report-identical-files", 0, 0, 's'},
+ {"expand-tabs", 0, 0, 't'},
+ {"version", 0, 0, 'v'},
+ {"ignore-all-space", 0, 0, 'w'},
+ {"exclude", 1, 0, 'x'},
+ {"exclude-from", 1, 0, 'X'},
+ {"side-by-side", 0, 0, 'y'},
+ {"unified", 2, 0, 'U'},
+ {"left-column", 0, 0, 129},
+ {"suppress-common-lines", 0, 0, 130},
+ {"sdiff-merge-assist", 0, 0, 131},
+ {"old-line-format", 1, 0, 132},
+ {"new-line-format", 1, 0, 133},
+ {"unchanged-line-format", 1, 0, 134},
+ {"line-format", 1, 0, 135},
+ {"old-group-format", 1, 0, 136},
+ {"new-group-format", 1, 0, 137},
+ {"unchanged-group-format", 1, 0, 138},
+ {"changed-group-format", 1, 0, 139},
+ {"horizon-lines", 1, 0, 140},
+ {"help", 0, 0, 141},
+ {"binary", 0, 0, 142},
+ {0, 0, 0, 0}
+};
+
+int
+main (argc, argv)
+ int argc;
+ char *argv[];
+{
+ int val;
+ int c;
+ int prev = -1;
+ int width = DEFAULT_WIDTH;
+ int show_c_function = 0;
+
+ /* Do our initializations. */
+ initialize_main (&argc, &argv);
+ program_name = argv[0];
+ output_style = OUTPUT_NORMAL;
+ context = -1;
+
+ /* Decode the options. */
+
+ while ((c = getopt_long (argc, argv,
+ "0123456789abBcC:dD:efF:hHiI:lL:nNpPqrsS:tTuU:vwW:x:X:y",
+ longopts, 0)) != EOF)
+ {
+ switch (c)
+ {
+ /* All digits combine in decimal to specify the context-size. */
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case '0':
+ if (context == -1)
+ context = 0;
+ /* If a context length has already been specified,
+ more digits allowed only if they follow right after the others.
+ Reject two separate runs of digits, or digits after -C. */
+ else if (prev < '0' || prev > '9')
+ fatal ("context length specified twice");
+
+ context = context * 10 + c - '0';
+ break;
+
+ case 'a':
+ /* Treat all files as text files; never treat as binary. */
+ always_text_flag = 1;
+ break;
+
+ case 'b':
+ /* Ignore changes in amount of white space. */
+ ignore_space_change_flag = 1;
+ ignore_some_changes = 1;
+ ignore_some_line_changes = 1;
+ break;
+
+ case 'B':
+ /* Ignore changes affecting only blank lines. */
+ ignore_blank_lines_flag = 1;
+ ignore_some_changes = 1;
+ break;
+
+ case 'C': /* +context[=lines] */
+ case 'U': /* +unified[=lines] */
+ if (optarg)
+ {
+ if (context >= 0)
+ fatal ("context length specified twice");
+
+ if (ck_atoi (optarg, &context))
+ fatal ("invalid context length argument");
+ }
+
+ /* Falls through. */
+ case 'c':
+ /* Make context-style output. */
+ specify_style (c == 'U' ? OUTPUT_UNIFIED : OUTPUT_CONTEXT);
+ break;
+
+ case 'd':
+ /* Don't discard lines. This makes things slower (sometimes much
+ slower) but will find a guaranteed minimal set of changes. */
+ no_discards = 1;
+ break;
+
+ case 'D':
+ /* Make merged #ifdef output. */
+ specify_style (OUTPUT_IFDEF);
+ {
+ int i, err = 0;
+ static char const C_ifdef_group_formats[] =
+ "#ifndef %s\n%%<#endif /* not %s */\n%c#ifdef %s\n%%>#endif /* %s */\n%c%%=%c#ifndef %s\n%%<#else /* %s */\n%%>#endif /* %s */\n";
+ char *b = xmalloc (sizeof (C_ifdef_group_formats)
+ + 7 * strlen(optarg) - 14 /* 7*"%s" */
+ - 8 /* 5*"%%" + 3*"%c" */);
+ sprintf (b, C_ifdef_group_formats,
+ optarg, optarg, 0,
+ optarg, optarg, 0, 0,
+ optarg, optarg, optarg);
+ for (i = 0; i < 4; i++)
+ {
+ err |= specify_format (&group_format[i], b);
+ b += strlen (b) + 1;
+ }
+ if (err)
+ error ("conflicting #ifdef formats", 0, 0);
+ }
+ break;
+
+ case 'e':
+ /* Make output that is a valid `ed' script. */
+ specify_style (OUTPUT_ED);
+ break;
+
+ case 'f':
+ /* Make output that looks vaguely like an `ed' script
+ but has changes in the order they appear in the file. */
+ specify_style (OUTPUT_FORWARD_ED);
+ break;
+
+ case 'F':
+ /* Show, for each set of changes, the previous line that
+ matches the specified regexp. Currently affects only
+ context-style output. */
+ add_regexp (&function_regexp_list, optarg);
+ break;
+
+ case 'h':
+ /* Split the files into chunks of around 1500 lines
+ for faster processing. Usually does not change the result.
+
+ This currently has no effect. */
+ break;
+
+ case 'H':
+ /* Turn on heuristics that speed processing of large files
+ with a small density of changes. */
+ heuristic = 1;
+ break;
+
+ case 'i':
+ /* Ignore changes in case. */
+ ignore_case_flag = 1;
+ ignore_some_changes = 1;
+ ignore_some_line_changes = 1;
+ break;
+
+ case 'I':
+ /* Ignore changes affecting only lines that match the
+ specified regexp. */
+ add_regexp (&ignore_regexp_list, optarg);
+ ignore_some_changes = 1;
+ break;
+
+ case 'l':
+ /* Pass the output through `pr' to paginate it. */
+ paginate_flag = 1;
+#if !defined(SIGCHLD) && defined(SIGCLD)
+#define SIGCHLD SIGCLD
+#endif
+#ifdef SIGCHLD
+ /* Pagination requires forking and waiting, and
+ System V fork+wait does not work if SIGCHLD is ignored. */
+ signal (SIGCHLD, SIG_DFL);
+#endif
+ break;
+
+ case 'L':
+ /* Specify file labels for `-c' output headers. */
+ if (!file_label[0])
+ file_label[0] = optarg;
+ else if (!file_label[1])
+ file_label[1] = optarg;
+ else
+ fatal ("too many file label options");
+ break;
+
+ case 'n':
+ /* Output RCS-style diffs, like `-f' except that each command
+ specifies the number of lines affected. */
+ specify_style (OUTPUT_RCS);
+ break;
+
+ case 'N':
+ /* When comparing directories, if a file appears only in one
+ directory, treat it as present but empty in the other. */
+ entire_new_file_flag = 1;
+ break;
+
+ case 'p':
+ /* Make context-style output and show name of last C function. */
+ show_c_function = 1;
+ add_regexp (&function_regexp_list, "^[_a-zA-Z$]");
+ break;
+
+ case 'P':
+ /* When comparing directories, if a file appears only in
+ the second directory of the two,
+ treat it as present but empty in the other. */
+ unidirectional_new_file_flag = 1;
+ break;
+
+ case 'q':
+ no_details_flag = 1;
+ break;
+
+ case 'r':
+ /* When comparing directories,
+ recursively compare any subdirectories found. */
+ recursive = 1;
+ break;
+
+ case 's':
+ /* Print a message if the files are the same. */
+ print_file_same_flag = 1;
+ break;
+
+ case 'S':
+ /* When comparing directories, start with the specified
+ file name. This is used for resuming an aborted comparison. */
+ dir_start_file = optarg;
+ break;
+
+ case 't':
+ /* Expand tabs to spaces in the output so that it preserves
+ the alignment of the input files. */
+ tab_expand_flag = 1;
+ break;
+
+ case 'T':
+ /* Use a tab in the output, rather than a space, before the
+ text of an input line, so as to keep the proper alignment
+ in the input line without changing the characters in it. */
+ tab_align_flag = 1;
+ break;
+
+ case 'u':
+ /* Output the context diff in unidiff format. */
+ specify_style (OUTPUT_UNIFIED);
+ break;
+
+ case 'v':
+ printf ("diff - GNU diffutils version %s\n", version_string);
+ exit (0);
+
+ case 'w':
+ /* Ignore horizontal white space when comparing lines. */
+ ignore_all_space_flag = 1;
+ ignore_some_changes = 1;
+ ignore_some_line_changes = 1;
+ break;
+
+ case 'x':
+ add_exclude (optarg);
+ break;
+
+ case 'X':
+ if (add_exclude_file (optarg) != 0)
+ pfatal_with_name (optarg);
+ break;
+
+ case 'y':
+ /* Use side-by-side (sdiff-style) columnar output. */
+ specify_style (OUTPUT_SDIFF);
+ break;
+
+ case 'W':
+ /* Set the line width for OUTPUT_SDIFF. */
+ if (ck_atoi (optarg, &width) || width <= 0)
+ fatal ("column width must be a positive integer");
+ break;
+
+ case 129:
+ sdiff_left_only = 1;
+ break;
+
+ case 130:
+ sdiff_skip_common_lines = 1;
+ break;
+
+ case 131:
+ /* sdiff-style columns output. */
+ specify_style (OUTPUT_SDIFF);
+ sdiff_help_sdiff = 1;
+ break;
+
+ case 132:
+ case 133:
+ case 134:
+ specify_style (OUTPUT_IFDEF);
+ if (specify_format (&line_format[c - 132], optarg) != 0)
+ error ("conflicting line format", 0, 0);
+ break;
+
+ case 135:
+ specify_style (OUTPUT_IFDEF);
+ {
+ int i, err = 0;
+ for (i = 0; i < sizeof (line_format) / sizeof (*line_format); i++)
+ err |= specify_format (&line_format[i], optarg);
+ if (err)
+ error ("conflicting line format", 0, 0);
+ }
+ break;
+
+ case 136:
+ case 137:
+ case 138:
+ case 139:
+ specify_style (OUTPUT_IFDEF);
+ if (specify_format (&group_format[c - 136], optarg) != 0)
+ error ("conflicting group format", 0, 0);
+ break;
+
+ case 140:
+ if (ck_atoi (optarg, &horizon_lines) || horizon_lines < 0)
+ fatal ("horizon must be a nonnegative integer");
+ break;
+
+ case 141:
+ usage ();
+ check_stdout ();
+ exit (0);
+
+ case 142:
+ /* Use binary I/O when reading and writing data.
+ On Posix hosts, this has no effect. */
+#if HAVE_SETMODE
+ binary_I_O = 1;
+ setmode (STDOUT_FILENO, O_BINARY);
+#endif
+ break;
+
+ default:
+ try_help (0);
+ }
+ prev = c;
+ }
+
+ if (argc - optind != 2)
+ try_help (argc - optind < 2 ? "missing operand" : "extra operand");
+
+
+ {
+ /*
+ * We maximize first the half line width, and then the gutter width,
+ * according to the following constraints:
+ * 1. Two half lines plus a gutter must fit in a line.
+ * 2. If the half line width is nonzero:
+ * a. The gutter width is at least GUTTER_WIDTH_MINIMUM.
+ * b. If tabs are not expanded to spaces,
+ * a half line plus a gutter is an integral number of tabs,
+ * so that tabs in the right column line up.
+ */
+ int t = tab_expand_flag ? 1 : TAB_WIDTH;
+ int off = (width + t + GUTTER_WIDTH_MINIMUM) / (2*t) * t;
+ sdiff_half_width = max (0, min (off - GUTTER_WIDTH_MINIMUM, width - off)),
+ sdiff_column2_offset = sdiff_half_width ? off : width;
+ }
+
+ if (show_c_function && output_style != OUTPUT_UNIFIED)
+ specify_style (OUTPUT_CONTEXT);
+
+ if (output_style != OUTPUT_CONTEXT && output_style != OUTPUT_UNIFIED)
+ context = 0;
+ else if (context == -1)
+ /* Default amount of context for -c. */
+ context = 3;
+
+ if (output_style == OUTPUT_IFDEF)
+ {
+ /* Format arrays are char *, not char const *,
+ because integer formats are temporarily modified.
+ But it is safe to assign a constant like "%=" to a format array,
+ since "%=" does not format any integers. */
+ int i;
+ for (i = 0; i < sizeof (line_format) / sizeof (*line_format); i++)
+ if (!line_format[i])
+ line_format[i] = "%l\n";
+ if (!group_format[OLD])
+ group_format[OLD]
+ = group_format[UNCHANGED] ? group_format[UNCHANGED] : "%<";
+ if (!group_format[NEW])
+ group_format[NEW]
+ = group_format[UNCHANGED] ? group_format[UNCHANGED] : "%>";
+ if (!group_format[UNCHANGED])
+ group_format[UNCHANGED] = "%=";
+ if (!group_format[CHANGED])
+ group_format[CHANGED] = concat (group_format[OLD],
+ group_format[NEW], "");
+ }
+
+ no_diff_means_no_output =
+ (output_style == OUTPUT_IFDEF ?
+ (!*group_format[UNCHANGED]
+ || (strcmp (group_format[UNCHANGED], "%=") == 0
+ && !*line_format[UNCHANGED]))
+ : output_style == OUTPUT_SDIFF ? sdiff_skip_common_lines : 1);
+
+ switch_string = option_list (argv + 1, optind - 1);
+
+ val = compare_files (0, argv[optind], 0, argv[optind + 1], 0);
+
+ /* Print any messages that were saved up for last. */
+ print_message_queue ();
+
+ check_stdout ();
+ exit (val);
+ return val;
+}
+
+/* Add the compiled form of regexp PATTERN to REGLIST. */
+
+static void
+add_regexp (reglist, pattern)
+ struct regexp_list **reglist;
+ char const *pattern;
+{
+ struct regexp_list *r;
+ char const *m;
+
+ r = (struct regexp_list *) xmalloc (sizeof (*r));
+ bzero (r, sizeof (*r));
+ r->buf.fastmap = xmalloc (256);
+ m = re_compile_pattern (pattern, strlen (pattern), &r->buf);
+ if (m != 0)
+ error ("%s: %s", pattern, m);
+
+ /* Add to the start of the list, since it's easier than the end. */
+ r->next = *reglist;
+ *reglist = r;
+}
+
+static void
+try_help (reason)
+ char const *reason;
+{
+ if (reason)
+ error ("%s", reason, 0);
+ error ("Try `%s --help' for more information.", program_name, 0);
+ exit (2);
+}
+
+static void
+check_stdout ()
+{
+ if (ferror (stdout) || fclose (stdout) != 0)
+ fatal ("write error");
+}
+
+static char const * const option_help[] = {
+"-i --ignore-case Consider upper- and lower-case to be the same.",
+"-w --ignore-all-space Ignore all white space.",
+"-b --ignore-space-change Ignore changes in the amount of white space.",
+"-B --ignore-blank-lines Ignore changes whose lines are all blank.",
+"-I RE --ignore-matching-lines=RE Ignore changes whose lines all match RE.",
+#if HAVE_SETMODE
+"--binary Read and write data in binary mode.",
+#endif
+"-a --text Treat all files as text.\n",
+"-c -C NUM --context[=NUM] Output NUM (default 2) lines of copied context.",
+"-u -U NUM --unified[=NUM] Output NUM (default 2) lines of unified context.",
+" -NUM Use NUM context lines.",
+" -L LABEL --label LABEL Use LABEL instead of file name.",
+" -p --show-c-function Show which C function each change is in.",
+" -F RE --show-function-line=RE Show the most recent line matching RE.",
+"-q --brief Output only whether files differ.",
+"-e --ed Output an ed script.",
+"-n --rcs Output an RCS format diff.",
+"-y --side-by-side Output in two columns.",
+" -w NUM --width=NUM Output at most NUM (default 130) characters per line.",
+" --left-column Output only the left column of common lines.",
+" --suppress-common-lines Do not output common lines.",
+"-DNAME --ifdef=NAME Output merged file to show `#ifdef NAME' diffs.",
+"--GTYPE-group-format=GFMT Similar, but format GTYPE input groups with GFMT.",
+"--line-format=LFMT Similar, but format all input lines with LFMT.",
+"--LTYPE-line-format=LFMT Similar, but format LTYPE input lines with LFMT.",
+" LTYPE is `old', `new', or `unchanged'. GTYPE is LTYPE or `changed'.",
+" GFMT may contain:",
+" %< lines from FILE1",
+" %> lines from FILE2",
+" %= lines common to FILE1 and FILE2",
+" %[-][WIDTH][.[PREC]]{doxX}LETTER printf-style spec for LETTER",
+" LETTERs are as follows for new group, lower case for old group:",
+" F first line number",
+" L last line number",
+" N number of lines = L-F+1",
+" E F-1",
+" M L+1",
+" LFMT may contain:",
+" %L contents of line",
+" %l contents of line, excluding any trailing newline",
+" %[-][WIDTH][.[PREC]]{doxX}n printf-style spec for input line number",
+" Either GFMT or LFMT may contain:",
+" %% %",
+" %c'C' the single character C",
+" %c'\\OOO' the character with octal code OOO\n",
+"-l --paginate Pass the output through `pr' to paginate it.",
+"-t --expand-tabs Expand tabs to spaces in output.",
+"-T --initial-tab Make tabs line up by prepending a tab.\n",
+"-r --recursive Recursively compare any subdirectories found.",
+"-N --new-file Treat absent files as empty.",
+"-P --unidirectional-new-file Treat absent first files as empty.",
+"-s --report-identical-files Report when two files are the same.",
+"-x PAT --exclude=PAT Exclude files that match PAT.",
+"-X FILE --exclude-from=FILE Exclude files that match any pattern in FILE.",
+"-S FILE --starting-file=FILE Start with FILE when comparing directories.\n",
+"--horizon-lines=NUM Keep NUM lines of the common prefix and suffix.",
+"-d --minimal Try hard to find a smaller set of changes.",
+"-H --speed-large-files Assume large files and many scattered small changes.\n",
+"-v --version Output version info.",
+"--help Output this help.",
+0
+};
+
+static void
+usage ()
+{
+ char const * const *p;
+
+ printf ("Usage: %s [OPTION]... FILE1 FILE2\n\n", program_name);
+ for (p = option_help; *p; p++)
+ printf (" %s\n", *p);
+ printf ("\nIf FILE1 or FILE2 is `-', read standard input.\n");
+}
+
+static int
+specify_format (var, value)
+ char **var;
+ char *value;
+{
+ int err = *var ? strcmp (*var, value) : 0;
+ *var = value;
+ return err;
+}
+
+static void
+specify_style (style)
+ enum output_style style;
+{
+ if (output_style != OUTPUT_NORMAL
+ && output_style != style)
+ error ("conflicting specifications of output style", 0, 0);
+ output_style = style;
+}
+
+static char const *
+filetype (st)
+ struct stat const *st;
+{
+ /* See Posix.2 section 4.17.6.1.1 and Table 5-1 for these formats.
+ To keep diagnostics grammatical, the returned string must start
+ with a consonant. */
+
+ if (S_ISREG (st->st_mode))
+ {
+ if (st->st_size == 0)
+ return "regular empty file";
+ /* Posix.2 section 5.14.2 seems to suggest that we must read the file
+ and guess whether it's C, Fortran, etc., but this is somewhat useless
+ and doesn't reflect historical practice. We're allowed to guess
+ wrong, so we don't bother to read the file. */
+ return "regular file";
+ }
+ if (S_ISDIR (st->st_mode)) return "directory";
+
+ /* other Posix.1 file types */
+#ifdef S_ISBLK
+ if (S_ISBLK (st->st_mode)) return "block special file";
+#endif
+#ifdef S_ISCHR
+ if (S_ISCHR (st->st_mode)) return "character special file";
+#endif
+#ifdef S_ISFIFO
+ if (S_ISFIFO (st->st_mode)) return "fifo";
+#endif
+
+ /* other Posix.1b file types */
+#ifdef S_TYPEISMQ
+ if (S_TYPEISMQ (st)) return "message queue";
+#endif
+#ifdef S_TYPEISSEM
+ if (S_TYPEISSEM (st)) return "semaphore";
+#endif
+#ifdef S_TYPEISSHM
+ if (S_TYPEISSHM (st)) return "shared memory object";
+#endif
+
+ /* other popular file types */
+ /* S_ISLNK is impossible with `fstat' and `stat'. */
+#ifdef S_ISSOCK
+ if (S_ISSOCK (st->st_mode)) return "socket";
+#endif
+
+ return "weird file";
+}
+
+/* Compare two files (or dirs) with specified names
+ DIR0/NAME0 and DIR1/NAME1, at level DEPTH in directory recursion.
+ (if DIR0 is 0, then the name is just NAME0, etc.)
+ This is self-contained; it opens the files and closes them.
+
+ Value is 0 if files are the same, 1 if different,
+ 2 if there is a problem opening them. */
+
+static int
+compare_files (dir0, name0, dir1, name1, depth)
+ char const *dir0, *dir1;
+ char const *name0, *name1;
+ int depth;
+{
+ struct file_data inf[2];
+ register int i;
+ int val;
+ int same_files;
+ int failed = 0;
+ char *free0 = 0, *free1 = 0;
+
+ /* If this is directory comparison, perhaps we have a file
+ that exists only in one of the directories.
+ If so, just print a message to that effect. */
+
+ if (! ((name0 != 0 && name1 != 0)
+ || (unidirectional_new_file_flag && name1 != 0)
+ || entire_new_file_flag))
+ {
+ char const *name = name0 == 0 ? name1 : name0;
+ char const *dir = name0 == 0 ? dir1 : dir0;
+ message ("Only in %s: %s\n", dir, name);
+ /* Return 1 so that diff_dirs will return 1 ("some files differ"). */
+ return 1;
+ }
+
+ bzero (inf, sizeof (inf));
+
+ /* Mark any nonexistent file with -1 in the desc field. */
+ /* Mark unopened files (e.g. directories) with -2. */
+
+ inf[0].desc = name0 == 0 ? -1 : -2;
+ inf[1].desc = name1 == 0 ? -1 : -2;
+
+ /* Now record the full name of each file, including nonexistent ones. */
+
+ if (name0 == 0)
+ name0 = name1;
+ if (name1 == 0)
+ name1 = name0;
+
+ inf[0].name = dir0 == 0 ? name0 : (free0 = dir_file_pathname (dir0, name0));
+ inf[1].name = dir1 == 0 ? name1 : (free1 = dir_file_pathname (dir1, name1));
+
+ /* Stat the files. Record whether they are directories. */
+
+ for (i = 0; i <= 1; i++)
+ {
+ if (inf[i].desc != -1)
+ {
+ int stat_result;
+
+ if (i && filename_cmp (inf[i].name, inf[0].name) == 0)
+ {
+ inf[i].stat = inf[0].stat;
+ stat_result = 0;
+ }
+ else if (strcmp (inf[i].name, "-") == 0)
+ {
+ inf[i].desc = STDIN_FILENO;
+ stat_result = fstat (STDIN_FILENO, &inf[i].stat);
+ if (stat_result == 0 && S_ISREG (inf[i].stat.st_mode))
+ {
+ off_t pos = lseek (STDIN_FILENO, (off_t) 0, SEEK_CUR);
+ if (pos == -1)
+ stat_result = -1;
+ else
+ {
+ if (pos <= inf[i].stat.st_size)
+ inf[i].stat.st_size -= pos;
+ else
+ inf[i].stat.st_size = 0;
+ /* Posix.2 4.17.6.1.4 requires current time for stdin. */
+ time (&inf[i].stat.st_mtime);
+ }
+ }
+ }
+ else
+ stat_result = stat (inf[i].name, &inf[i].stat);
+
+ if (stat_result != 0)
+ {
+ perror_with_name (inf[i].name);
+ failed = 1;
+ }
+ else
+ {
+ inf[i].dir_p = S_ISDIR (inf[i].stat.st_mode) && inf[i].desc != 0;
+ if (inf[1 - i].desc == -1)
+ {
+ inf[1 - i].dir_p = inf[i].dir_p;
+ inf[1 - i].stat.st_mode = inf[i].stat.st_mode;
+ }
+ }
+ }
+ }
+
+ if (! failed && depth == 0 && inf[0].dir_p != inf[1].dir_p)
+ {
+ /* If one is a directory, and it was specified in the command line,
+ use the file in that dir with the other file's basename. */
+
+ int fnm_arg = inf[0].dir_p;
+ int dir_arg = 1 - fnm_arg;
+ char const *fnm = inf[fnm_arg].name;
+ char const *dir = inf[dir_arg].name;
+ char const *p = filename_lastdirchar (fnm);
+ char const *filename = inf[dir_arg].name
+ = dir_file_pathname (dir, p ? p + 1 : fnm);
+
+ if (strcmp (fnm, "-") == 0)
+ fatal ("can't compare - to a directory");
+
+ if (stat (filename, &inf[dir_arg].stat) != 0)
+ {
+ perror_with_name (filename);
+ failed = 1;
+ }
+ else
+ inf[dir_arg].dir_p = S_ISDIR (inf[dir_arg].stat.st_mode);
+ }
+
+ if (failed)
+ {
+
+ /* If either file should exist but does not, return 2. */
+
+ val = 2;
+
+ }
+ else if ((same_files = inf[0].desc != -1 && inf[1].desc != -1
+ && 0 < same_file (&inf[0].stat, &inf[1].stat))
+ && no_diff_means_no_output)
+ {
+ /* The two named files are actually the same physical file.
+ We know they are identical without actually reading them. */
+
+ val = 0;
+ }
+ else if (inf[0].dir_p & inf[1].dir_p)
+ {
+ if (output_style == OUTPUT_IFDEF)
+ fatal ("-D option not supported with directories");
+
+ /* If both are directories, compare the files in them. */
+
+ if (depth > 0 && !recursive)
+ {
+ /* But don't compare dir contents one level down
+ unless -r was specified. */
+ message ("Common subdirectories: %s and %s\n",
+ inf[0].name, inf[1].name);
+ val = 0;
+ }
+ else
+ {
+ val = diff_dirs (inf, compare_files, depth);
+ }
+
+ }
+ else if ((inf[0].dir_p | inf[1].dir_p)
+ || (depth > 0
+ && (! S_ISREG (inf[0].stat.st_mode)
+ || ! S_ISREG (inf[1].stat.st_mode))))
+ {
+ /* Perhaps we have a subdirectory that exists only in one directory.
+ If so, just print a message to that effect. */
+
+ if (inf[0].desc == -1 || inf[1].desc == -1)
+ {
+ if ((inf[0].dir_p | inf[1].dir_p)
+ && recursive
+ && (entire_new_file_flag
+ || (unidirectional_new_file_flag && inf[0].desc == -1)))
+ val = diff_dirs (inf, compare_files, depth);
+ else
+ {
+ char const *dir = (inf[0].desc == -1) ? dir1 : dir0;
+ /* See Posix.2 section 4.17.6.1.1 for this format. */
+ message ("Only in %s: %s\n", dir, name0);
+ val = 1;
+ }
+ }
+ else
+ {
+ /* We have two files that are not to be compared. */
+
+ /* See Posix.2 section 4.17.6.1.1 for this format. */
+ message5 ("File %s is a %s while file %s is a %s\n",
+ inf[0].name, filetype (&inf[0].stat),
+ inf[1].name, filetype (&inf[1].stat));
+
+ /* This is a difference. */
+ val = 1;
+ }
+ }
+ else if ((no_details_flag & ~ignore_some_changes)
+ && inf[0].stat.st_size != inf[1].stat.st_size
+ && (inf[0].desc == -1 || S_ISREG (inf[0].stat.st_mode))
+ && (inf[1].desc == -1 || S_ISREG (inf[1].stat.st_mode)))
+ {
+ message ("Files %s and %s differ\n", inf[0].name, inf[1].name);
+ val = 1;
+ }
+ else
+ {
+ /* Both exist and neither is a directory. */
+
+ /* Open the files and record their descriptors. */
+
+ if (inf[0].desc == -2)
+ if ((inf[0].desc = open (inf[0].name, O_RDONLY, 0)) < 0)
+ {
+ perror_with_name (inf[0].name);
+ failed = 1;
+ }
+ if (inf[1].desc == -2)
+ if (same_files)
+ inf[1].desc = inf[0].desc;
+ else if ((inf[1].desc = open (inf[1].name, O_RDONLY, 0)) < 0)
+ {
+ perror_with_name (inf[1].name);
+ failed = 1;
+ }
+
+#if HAVE_SETMODE
+ if (binary_I_O)
+ for (i = 0; i <= 1; i++)
+ if (0 <= inf[i].desc)
+ setmode (inf[i].desc, O_BINARY);
+#endif
+
+ /* Compare the files, if no error was found. */
+
+ val = failed ? 2 : diff_2_files (inf, depth);
+
+ /* Close the file descriptors. */
+
+ if (inf[0].desc >= 0 && close (inf[0].desc) != 0)
+ {
+ perror_with_name (inf[0].name);
+ val = 2;
+ }
+ if (inf[1].desc >= 0 && inf[0].desc != inf[1].desc
+ && close (inf[1].desc) != 0)
+ {
+ perror_with_name (inf[1].name);
+ val = 2;
+ }
+ }
+
+ /* Now the comparison has been done, if no error prevented it,
+ and VAL is the value this function will return. */
+
+ if (val == 0 && !inf[0].dir_p)
+ {
+ if (print_file_same_flag)
+ message ("Files %s and %s are identical\n",
+ inf[0].name, inf[1].name);
+ }
+ else
+ fflush (stdout);
+
+ if (free0)
+ free (free0);
+ if (free1)
+ free (free1);
+
+ return val;
+}
diff --git a/gnu/dist/diffutils/diff.h b/gnu/dist/diffutils/diff.h
new file mode 100644
index 00000000000..66c6940c72b
--- /dev/null
+++ b/gnu/dist/diffutils/diff.h
@@ -0,0 +1,340 @@
+/* Shared definitions for GNU DIFF
+ Copyright (C) 1988, 89, 91, 92, 93 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 "system.h"
+#include <stdio.h>
+#include "regex.h"
+
+#define TAB_WIDTH 8
+
+/* Variables for command line options */
+
+#ifndef GDIFF_MAIN
+#define EXTERN extern
+#else
+#define EXTERN
+#endif
+
+enum output_style {
+ /* Default output style. */
+ OUTPUT_NORMAL,
+ /* Output the differences with lines of context before and after (-c). */
+ OUTPUT_CONTEXT,
+ /* Output the differences in a unified context diff format (-u). */
+ OUTPUT_UNIFIED,
+ /* Output the differences as commands suitable for `ed' (-e). */
+ OUTPUT_ED,
+ /* Output the diff as a forward ed script (-f). */
+ OUTPUT_FORWARD_ED,
+ /* Like -f, but output a count of changed lines in each "command" (-n). */
+ OUTPUT_RCS,
+ /* Output merged #ifdef'd file (-D). */
+ OUTPUT_IFDEF,
+ /* Output sdiff style (-y). */
+ OUTPUT_SDIFF
+};
+
+/* True for output styles that are robust,
+ i.e. can handle a file that ends in a non-newline. */
+#define ROBUST_OUTPUT_STYLE(S) ((S) != OUTPUT_ED && (S) != OUTPUT_FORWARD_ED)
+
+EXTERN enum output_style output_style;
+
+/* Nonzero if output cannot be generated for identical files. */
+EXTERN int no_diff_means_no_output;
+
+/* Number of lines of context to show in each set of diffs.
+ This is zero when context is not to be shown. */
+EXTERN int context;
+
+/* Consider all files as text files (-a).
+ Don't interpret codes over 0177 as implying a "binary file". */
+EXTERN int always_text_flag;
+
+/* Number of lines to keep in identical prefix and suffix. */
+EXTERN int horizon_lines;
+
+/* Ignore changes in horizontal white space (-b). */
+EXTERN int ignore_space_change_flag;
+
+/* Ignore all horizontal white space (-w). */
+EXTERN int ignore_all_space_flag;
+
+/* Ignore changes that affect only blank lines (-B). */
+EXTERN int ignore_blank_lines_flag;
+
+/* 1 if lines may match even if their contents do not match exactly.
+ This depends on various options. */
+EXTERN int ignore_some_line_changes;
+
+/* 1 if files may match even if their contents are not byte-for-byte identical.
+ This depends on various options. */
+EXTERN int ignore_some_changes;
+
+/* Ignore differences in case of letters (-i). */
+EXTERN int ignore_case_flag;
+
+/* File labels for `-c' output headers (-L). */
+EXTERN char *file_label[2];
+
+struct regexp_list
+{
+ struct re_pattern_buffer buf;
+ struct regexp_list *next;
+};
+
+/* Regexp to identify function-header lines (-F). */
+EXTERN struct regexp_list *function_regexp_list;
+
+/* Ignore changes that affect only lines matching this regexp (-I). */
+EXTERN struct regexp_list *ignore_regexp_list;
+
+/* Say only whether files differ, not how (-q). */
+EXTERN int no_details_flag;
+
+/* Report files compared that match (-s).
+ Normally nothing is output when that happens. */
+EXTERN int print_file_same_flag;
+
+/* Output the differences with exactly 8 columns added to each line
+ so that any tabs in the text line up properly (-T). */
+EXTERN int tab_align_flag;
+
+/* Expand tabs in the output so the text lines up properly
+ despite the characters added to the front of each line (-t). */
+EXTERN int tab_expand_flag;
+
+/* In directory comparison, specify file to start with (-S).
+ All file names less than this name are ignored. */
+EXTERN char *dir_start_file;
+
+/* If a file is new (appears in only one dir)
+ include its entire contents (-N).
+ Then `patch' would create the file with appropriate contents. */
+EXTERN int entire_new_file_flag;
+
+/* If a file is new (appears in only the second dir)
+ include its entire contents (-P).
+ Then `patch' would create the file with appropriate contents. */
+EXTERN int unidirectional_new_file_flag;
+
+/* Pipe each file's output through pr (-l). */
+EXTERN int paginate_flag;
+
+enum line_class {
+ /* Lines taken from just the first file. */
+ OLD,
+ /* Lines taken from just the second file. */
+ NEW,
+ /* Lines common to both files. */
+ UNCHANGED,
+ /* A hunk containing both old and new lines (line groups only). */
+ CHANGED
+};
+
+/* Line group formats for old, new, unchanged, and changed groups. */
+EXTERN char *group_format[CHANGED + 1];
+
+/* Line formats for old, new, and unchanged lines. */
+EXTERN char *line_format[UNCHANGED + 1];
+
+/* If using OUTPUT_SDIFF print extra information to help the sdiff filter. */
+EXTERN int sdiff_help_sdiff;
+
+/* Tell OUTPUT_SDIFF to show only the left version of common lines. */
+EXTERN int sdiff_left_only;
+
+/* Tell OUTPUT_SDIFF to not show common lines. */
+EXTERN int sdiff_skip_common_lines;
+
+/* The half line width and column 2 offset for OUTPUT_SDIFF. */
+EXTERN unsigned sdiff_half_width;
+EXTERN unsigned sdiff_column2_offset;
+
+/* String containing all the command options diff received,
+ with spaces between and at the beginning but none at the end.
+ If there were no options given, this string is empty. */
+EXTERN char * switch_string;
+
+/* Nonzero means use heuristics for better speed. */
+EXTERN int heuristic;
+
+/* Name of program the user invoked (for error messages). */
+EXTERN char *program_name;
+
+/* The result of comparison is an "edit script": a chain of `struct change'.
+ Each `struct change' represents one place where some lines are deleted
+ and some are inserted.
+
+ LINE0 and LINE1 are the first affected lines in the two files (origin 0).
+ DELETED is the number of lines deleted here from file 0.
+ INSERTED is the number of lines inserted here in file 1.
+
+ If DELETED is 0 then LINE0 is the number of the line before
+ which the insertion was done; vice versa for INSERTED and LINE1. */
+
+struct change
+{
+ struct change *link; /* Previous or next edit command */
+ int inserted; /* # lines of file 1 changed here. */
+ int deleted; /* # lines of file 0 changed here. */
+ int line0; /* Line number of 1st deleted line. */
+ int line1; /* Line number of 1st inserted line. */
+ char ignore; /* Flag used in context.c */
+};
+
+/* Structures that describe the input files. */
+
+/* Data on one input file being compared. */
+
+struct file_data {
+ int desc; /* File descriptor */
+ char const *name; /* File name */
+ struct stat stat; /* File status from fstat() */
+ int dir_p; /* nonzero if file is a directory */
+
+ /* Buffer in which text of file is read. */
+ char * buffer;
+ /* Allocated size of buffer. */
+ size_t bufsize;
+ /* Number of valid characters now in the buffer. */
+ size_t buffered_chars;
+
+ /* Array of pointers to lines in the file. */
+ char const **linbuf;
+
+ /* linbuf_base <= buffered_lines <= valid_lines <= alloc_lines.
+ linebuf[linbuf_base ... buffered_lines - 1] are possibly differing.
+ linebuf[linbuf_base ... valid_lines - 1] contain valid data.
+ linebuf[linbuf_base ... alloc_lines - 1] are allocated. */
+ int linbuf_base, buffered_lines, valid_lines, alloc_lines;
+
+ /* Pointer to end of prefix of this file to ignore when hashing. */
+ char const *prefix_end;
+
+ /* Count of lines in the prefix.
+ There are this many lines in the file before linbuf[0]. */
+ int prefix_lines;
+
+ /* Pointer to start of suffix of this file to ignore when hashing. */
+ char const *suffix_begin;
+
+ /* Vector, indexed by line number, containing an equivalence code for
+ each line. It is this vector that is actually compared with that
+ of another file to generate differences. */
+ int *equivs;
+
+ /* Vector, like the previous one except that
+ the elements for discarded lines have been squeezed out. */
+ int *undiscarded;
+
+ /* Vector mapping virtual line numbers (not counting discarded lines)
+ to real ones (counting those lines). Both are origin-0. */
+ int *realindexes;
+
+ /* Total number of nondiscarded lines. */
+ int nondiscarded_lines;
+
+ /* Vector, indexed by real origin-0 line number,
+ containing 1 for a line that is an insertion or a deletion.
+ The results of comparison are stored here. */
+ char *changed_flag;
+
+ /* 1 if file ends in a line with no final newline. */
+ int missing_newline;
+
+ /* 1 more than the maximum equivalence value used for this or its
+ sibling file. */
+ int equiv_max;
+};
+
+/* Describe the two files currently being compared. */
+
+EXTERN struct file_data files[2];
+
+/* Stdio stream to output diffs to. */
+
+EXTERN FILE *outfile;
+
+/* Declare various functions. */
+
+/* analyze.c */
+int diff_2_files PARAMS((struct file_data[], int));
+
+/* context.c */
+void print_context_header PARAMS((struct file_data[], int));
+void print_context_script PARAMS((struct change *, int));
+
+/* diff.c */
+int excluded_filename PARAMS((char const *));
+
+/* dir.c */
+int diff_dirs PARAMS((struct file_data const[], int (*) PARAMS((char const *, char const *, char const *, char const *, int)), int));
+
+/* ed.c */
+void print_ed_script PARAMS((struct change *));
+void pr_forward_ed_script PARAMS((struct change *));
+
+/* ifdef.c */
+void print_ifdef_script PARAMS((struct change *));
+
+/* io.c */
+int read_files PARAMS((struct file_data[], int));
+int sip PARAMS((struct file_data *, int));
+void slurp PARAMS((struct file_data *));
+
+/* normal.c */
+void print_normal_script PARAMS((struct change *));
+
+/* rcs.c */
+void print_rcs_script PARAMS((struct change *));
+
+/* side.c */
+void print_sdiff_script PARAMS((struct change *));
+
+/* util.c */
+VOID *xmalloc PARAMS((size_t));
+VOID *xrealloc PARAMS((VOID *, size_t));
+char *concat PARAMS((char const *, char const *, char const *));
+char *dir_file_pathname PARAMS((char const *, char const *));
+int change_letter PARAMS((int, int));
+int line_cmp PARAMS((char const *, char const *));
+int translate_line_number PARAMS((struct file_data const *, int));
+struct change *find_change PARAMS((struct change *));
+struct change *find_reverse_change PARAMS((struct change *));
+void analyze_hunk PARAMS((struct change *, int *, int *, int *, int *, int *, int *));
+void begin_output PARAMS((void));
+void debug_script PARAMS((struct change *));
+void error PARAMS((char const *, char const *, char const *));
+void fatal PARAMS((char const *));
+void finish_output PARAMS((void));
+void message PARAMS((char const *, char const *, char const *));
+void message5 PARAMS((char const *, char const *, char const *, char const *, char const *));
+void output_1_line PARAMS((char const *, char const *, char const *, char const *));
+void perror_with_name PARAMS((char const *));
+void pfatal_with_name PARAMS((char const *));
+void print_1_line PARAMS((char const *, char const * const *));
+void print_message_queue PARAMS((void));
+void print_number_range PARAMS((int, struct file_data *, int, int));
+void print_script PARAMS((struct change *, struct change * (*) PARAMS((struct change *)), void (*) PARAMS((struct change *))));
+void setup_output PARAMS((char const *, char const *, int));
+void translate_range PARAMS((struct file_data const *, int, int, int *, int *));
+
+/* version.c */
+extern char const version_string[];
diff --git a/gnu/dist/diffutils/diff.info b/gnu/dist/diffutils/diff.info
new file mode 100644
index 00000000000..b606a5ea5cf
--- /dev/null
+++ b/gnu/dist/diffutils/diff.info
@@ -0,0 +1,128 @@
+This is Info file diff.info, produced by Makeinfo-1.55 from the input
+file ./diff.texi.
+
+ This file documents the the GNU `diff', `diff3', `sdiff', and `cmp'
+commands for showing the differences between text files and the `patch'
+command for using their output to update files.
+
+ Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+
+ Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+ Permission is granted to copy and distribute modified versions of
+this manual under the conditions for verbatim copying, provided that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+ Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be stated in a
+translation approved by the Foundation.
+
+
+Indirect:
+diff.info-1: 1007
+diff.info-2: 48281
+diff.info-3: 98082
+diff.info-4: 144163
+
+Tag Table:
+(Indirect)
+Node: Top1007
+Node: Overview2412
+Node: Comparison5556
+Node: Hunks8174
+Node: White Space9600
+Node: Blank Lines10825
+Node: Case Folding11589
+Node: Specified Folding12002
+Node: Brief13092
+Node: Binary14343
+Node: Output Formats17683
+Node: Sample diff Input18375
+Node: Normal19868
+Node: Detailed Normal20797
+Node: Example Normal22522
+Node: Context23245
+Node: Context Format24793
+Node: Detailed Context25566
+Node: Example Context27122
+Node: Less Context28615
+Node: Unified Format29747
+Node: Detailed Unified30526
+Node: Example Unified31510
+Node: Sections32509
+Node: Specified Headings33253
+Node: C Function Headings34800
+Node: Alternate Names35619
+Node: Side by Side36516
+Node: Side by Side Format38656
+Node: Example Side by Side39553
+Node: Scripts40880
+Node: ed Scripts41278
+Node: Detailed ed42473
+Node: Example ed44214
+Node: Forward ed44652
+Node: RCS45414
+Node: If-then-else46624
+Node: Line Group Formats48281
+Node: Line Formats53963
+Node: Detailed If-then-else57225
+Node: Example If-then-else59126
+Node: Comparing Directories60178
+Node: Adjusting Output63293
+Node: Tabs63712
+Node: Pagination65234
+Node: diff Performance65653
+Node: Comparing Three Files67599
+Node: Sample diff3 Input68460
+Node: Detailed diff3 Normal69409
+Node: diff3 Hunks71189
+Node: Example diff3 Normal72475
+Node: diff3 Merging73499
+Node: Which Changes75709
+Node: Marking Conflicts77115
+Node: Bypassing ed79572
+Node: Merging Incomplete Lines80927
+Node: Saving the Changed File81644
+Node: Interactive Merging82254
+Node: sdiff Option Summary82952
+Node: Merge Commands84052
+Node: Merging with patch85188
+Node: patch Input87295
+Node: Imperfect87958
+Node: Changed White Space88695
+Node: Reversed Patches89446
+Node: Inexact91031
+Node: Empty Files94385
+Node: Multiple Patches94949
+Node: patch Messages96261
+Node: Making Patches98082
+Node: Invoking cmp101380
+Node: cmp Options101984
+Node: Invoking diff103414
+Node: diff Options104880
+Node: Invoking diff3115476
+Node: diff3 Options116107
+Node: Invoking patch119709
+Node: patch Directories121649
+Node: Backups123464
+Node: Rejects126011
+Node: patch Options126561
+Node: Invoking sdiff131418
+Node: sdiff Options132528
+Node: Incomplete Lines135845
+Node: Projects137468
+Node: Shortcomings138162
+Node: Changing Structure139157
+Node: Special Files140105
+Node: Unusual File Names141051
+Node: Arbitrary Limits141673
+Node: Large Files142102
+Node: Ignoring Changes142974
+Node: Bugs143518
+Node: Concept Index144163
+
+End Tag Table
diff --git a/gnu/dist/diffutils/diff.info-1 b/gnu/dist/diffutils/diff.info-1
new file mode 100644
index 00000000000..477ac98399d
--- /dev/null
+++ b/gnu/dist/diffutils/diff.info-1
@@ -0,0 +1,1211 @@
+This is Info file diff.info, produced by Makeinfo-1.55 from the input
+file ./diff.texi.
+
+ This file documents the the GNU `diff', `diff3', `sdiff', and `cmp'
+commands for showing the differences between text files and the `patch'
+command for using their output to update files.
+
+ Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+
+ Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+ Permission is granted to copy and distribute modified versions of
+this manual under the conditions for verbatim copying, provided that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+ Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be stated in a
+translation approved by the Foundation.
+
+
+File: diff.info, Node: Top, Up: (dir)
+
+ This file documents the the GNU `diff', `diff3', `sdiff', and `cmp'
+commands for showing the differences between text files and the `patch'
+command for using their output to update files.
+
+ This is Edition 1.2, for `diff' 2.4 and `patch' 2.1.
+
+* Menu:
+
+* Overview:: Preliminary information.
+
+* Comparison:: What file comparison means.
+* Output Formats:: Formats for difference reports.
+* Comparing Directories:: Comparing files and directories.
+* Adjusting Output:: Making `diff' output prettier.
+* diff Performance:: Making `diff' smarter or faster.
+* Comparing Three Files:: Formats for three-way difference reports.
+
+* diff3 Merging:: Merging from a common ancestor.
+* Interactive Merging:: Interactive merging with `sdiff'.
+* Merging with patch:: Using `patch' to change old files into new ones.
+* Making Patches:: Tips for making patch distributions.
+
+* Invoking cmp:: How to run `cmp' and a summary of its options.
+* Invoking diff:: How to run `diff' and a summary of its options.
+* Invoking diff3:: How to run `diff3' and a summary of its options.
+* Invoking patch:: How to run `patch' and a summary of its options.
+* Invoking sdiff:: How to run `sdiff' and a summary of its options.
+
+* Incomplete Lines:: Lines that lack trailing newlines.
+* Projects:: If you think you've found a bug or other shortcoming.
+
+* Concept Index:: Index of concepts.
+
+
+File: diff.info, Node: Overview, Next: Comparison, Up: Top
+
+Overview
+********
+
+ Computer users often find occasion to ask how two files differ.
+Perhaps one file is a newer version of the other file. Or maybe the
+two files started out as identical copies but were changed by different
+people.
+
+ You can use the `diff' command to show differences between two
+files, or each corresponding file in two directories. `diff' outputs
+differences between files line by line in any of several formats,
+selectable by command line options. This set of differences is often
+called a "diff" or "patch". For files that are identical, `diff'
+normally produces no output; for binary (non-text) files, `diff'
+normally reports only that they are different.
+
+ You can use the `cmp' command to show the offsets and line numbers
+where two files differ. `cmp' can also show all the characters that
+differ between the two files, side by side. Another way to compare two
+files character by character is the Emacs command `M-x
+compare-windows'. *Note Other Window: (emacs)Other Window, for more
+information on that command.
+
+ You can use the `diff3' command to show differences among three
+files. When two people have made independent changes to a common
+original, `diff3' can report the differences between the original and
+the two changed versions, and can produce a merged file that contains
+both persons' changes together with warnings about conflicts.
+
+ You can use the `sdiff' command to merge two files interactively.
+
+ You can use the set of differences produced by `diff' to distribute
+updates to text files (such as program source code) to other people.
+This method is especially useful when the differences are small compared
+to the complete files. Given `diff' output, you can use the `patch'
+program to update, or "patch", a copy of the file. If you think of
+`diff' as subtracting one file from another to produce their
+difference, you can think of `patch' as adding the difference to one
+file to reproduce the other.
+
+ This manual first concentrates on making diffs, and later shows how
+to use diffs to update files.
+
+ GNU `diff' was written by Mike Haertel, David Hayes, Richard
+Stallman, Len Tower, and Paul Eggert. Wayne Davison designed and
+implemented the unified output format. The basic algorithm is described
+in "An O(ND) Difference Algorithm and its Variations", Eugene W. Myers,
+`Algorithmica' Vol. 1 No. 2, 1986, pp. 251-266; and in "A File
+Comparison Program", Webb Miller and Eugene W. Myers,
+`Software--Practice and Experience' Vol. 15 No. 11, 1985, pp. 1025-1040.
+The algorithm was independently discovered as described in "Algorithms
+for Approximate String Matching", E. Ukkonen, `Information and Control'
+Vol. 64, 1985, pp. 100-118.
+
+ GNU `diff3' was written by Randy Smith. GNU `sdiff' was written by
+Thomas Lord. GNU `cmp' was written by Torbjorn Granlund and David
+MacKenzie.
+
+ `patch' was written mainly by Larry Wall; the GNU enhancements were
+written mainly by Wayne Davison and David MacKenzie. Parts of this
+manual are adapted from a manual page written by Larry Wall, with his
+permission.
+
+
+File: diff.info, Node: Comparison, Next: Output Formats, Prev: Overview, Up: Top
+
+What Comparison Means
+*********************
+
+ There are several ways to think about the differences between two
+files. One way to think of the differences is as a series of lines
+that were deleted from, inserted in, or changed in one file to produce
+the other file. `diff' compares two files line by line, finds groups of
+lines that differ, and reports each group of differing lines. It can
+report the differing lines in several formats, which have different
+purposes.
+
+ GNU `diff' can show whether files are different without detailing
+the differences. It also provides ways to suppress certain kinds of
+differences that are not important to you. Most commonly, such
+differences are changes in the amount of white space between words or
+lines. `diff' also provides ways to suppress differences in alphabetic
+case or in lines that match a regular expression that you provide.
+These options can accumulate; for example, you can ignore changes in
+both white space and alphabetic case.
+
+ Another way to think of the differences between two files is as a
+sequence of pairs of characters that can be either identical or
+different. `cmp' reports the differences between two files character
+by character, instead of line by line. As a result, it is more useful
+than `diff' for comparing binary files. For text files, `cmp' is
+useful mainly when you want to know only whether two files are
+identical.
+
+ To illustrate the effect that considering changes character by
+character can have compared with considering them line by line, think
+of what happens if a single newline character is added to the beginning
+of a file. If that file is then compared with an otherwise identical
+file that lacks the newline at the beginning, `diff' will report that a
+blank line has been added to the file, while `cmp' will report that
+almost every character of the two files differs.
+
+ `diff3' normally compares three input files line by line, finds
+groups of lines that differ, and reports each group of differing lines.
+Its output is designed to make it easy to inspect two different sets of
+changes to the same file.
+
+* Menu:
+
+* Hunks:: Groups of differing lines.
+* White Space:: Suppressing differences in white space.
+* Blank Lines:: Suppressing differences in blank lines.
+* Case Folding:: Suppressing differences in alphabetic case.
+* Specified Folding:: Suppressing differences that match regular expressions.
+* Brief:: Summarizing which files are different.
+* Binary:: Comparing binary files or forcing text comparisons.
+
+
+File: diff.info, Node: Hunks, Next: White Space, Up: Comparison
+
+Hunks
+=====
+
+ When comparing two files, `diff' finds sequences of lines common to
+both files, interspersed with groups of differing lines called "hunks".
+Comparing two identical files yields one sequence of common lines and
+no hunks, because no lines differ. Comparing two entirely different
+files yields no common lines and one large hunk that contains all lines
+of both files. In general, there are many ways to match up lines
+between two given files. `diff' tries to minimize the total hunk size
+by finding large sequences of common lines interspersed with small
+hunks of differing lines.
+
+ For example, suppose the file `F' contains the three lines `a', `b',
+`c', and the file `G' contains the same three lines in reverse order
+`c', `b', `a'. If `diff' finds the line `c' as common, then the command
+`diff F G' produces this output:
+
+ 1,2d0
+ < a
+ < b
+ 3a2,3
+ > b
+ > a
+
+But if `diff' notices the common line `b' instead, it produces this
+output:
+
+ 1c1
+ < a
+ ---
+ > c
+ 3c3
+ < c
+ ---
+ > a
+
+It is also possible to find `a' as the common line. `diff' does not
+always find an optimal matching between the files; it takes shortcuts
+to run faster. But its output is usually close to the shortest
+possible. You can adjust this tradeoff with the `--minimal' option
+(*note diff Performance::.).
+
+
+File: diff.info, Node: White Space, Next: Blank Lines, Prev: Hunks, Up: Comparison
+
+Suppressing Differences in Blank and Tab Spacing
+================================================
+
+ The `-b' and `--ignore-space-change' options ignore white space at
+line end, and considers all other sequences of one or more white space
+characters to be equivalent. With these options, `diff' considers the
+following two lines to be equivalent, where `$' denotes the line end:
+
+ Here lyeth muche rychnesse in lytell space. -- John Heywood$
+ Here lyeth muche rychnesse in lytell space. -- John Heywood $
+
+ The `-w' and `--ignore-all-space' options are stronger than `-b'.
+They ignore difference even if one file has white space where the other
+file has none. "White space" characters include tab, newline, vertical
+tab, form feed, carriage return, and space; some locales may define
+additional characters to be white space. With these options, `diff'
+considers the following two lines to be equivalent, where `$' denotes
+the line end and `^M' denotes a carriage return:
+
+ Here lyeth muche rychnesse in lytell space.-- John Heywood$
+ He relyeth much erychnes seinly tells pace. --John Heywood ^M$
+
+
+File: diff.info, Node: Blank Lines, Next: Case Folding, Prev: White Space, Up: Comparison
+
+Suppressing Differences in Blank Lines
+======================================
+
+ The `-B' and `--ignore-blank-lines' options ignore insertions or
+deletions of blank lines. These options normally affect only lines
+that are completely empty; they do not affect lines that look empty but
+contain space or tab characters. With these options, for example, a
+file containing
+ 1. A point is that which has no part.
+
+ 2. A line is breadthless length.
+ -- Euclid, The Elements, I
+
+is considered identical to a file containing
+ 1. A point is that which has no part.
+ 2. A line is breadthless length.
+
+
+ -- Euclid, The Elements, I
+
+
+File: diff.info, Node: Case Folding, Next: Specified Folding, Prev: Blank Lines, Up: Comparison
+
+Suppressing Case Differences
+============================
+
+ GNU `diff' can treat lowercase letters as equivalent to their
+uppercase counterparts, so that, for example, it considers `Funky
+Stuff', `funky STUFF', and `fUNKy stuFf' to all be the same. To
+request this, use the `-i' or `--ignore-case' option.
+
+
+File: diff.info, Node: Specified Folding, Next: Brief, Prev: Case Folding, Up: Comparison
+
+Suppressing Lines Matching a Regular Expression
+===============================================
+
+ To ignore insertions and deletions of lines that match a regular
+expression, use the `-I REGEXP' or `--ignore-matching-lines=REGEXP'
+option. You should escape regular expressions that contain shell
+metacharacters to prevent the shell from expanding them. For example,
+`diff -I '^[0-9]'' ignores all changes to lines beginning with a digit.
+
+ However, `-I' only ignores the insertion or deletion of lines that
+contain the regular expression if every changed line in the hunk--every
+insertion and every deletion--matches the regular expression. In other
+words, for each nonignorable change, `diff' prints the complete set of
+changes in its vicinity, including the ignorable ones.
+
+ You can specify more than one regular expression for lines to ignore
+by using more than one `-I' option. `diff' tries to match each line
+against each regular expression, starting with the last one given.
+
+
+File: diff.info, Node: Brief, Next: Binary, Prev: Specified Folding, Up: Comparison
+
+Summarizing Which Files Differ
+==============================
+
+ When you only want to find out whether files are different, and you
+don't care what the differences are, you can use the summary output
+format. In this format, instead of showing the differences between the
+files, `diff' simply reports whether files differ. The `-q' and
+`--brief' options select this output format.
+
+ This format is especially useful when comparing the contents of two
+directories. It is also much faster than doing the normal line by line
+comparisons, because `diff' can stop analyzing the files as soon as it
+knows that there are any differences.
+
+ You can also get a brief indication of whether two files differ by
+using `cmp'. For files that are identical, `cmp' produces no output.
+When the files differ, by default, `cmp' outputs the byte offset and
+line number where the first difference occurs. You can use the `-s'
+option to suppress that information, so that `cmp' produces no output
+and reports whether the files differ using only its exit status (*note
+Invoking cmp::.).
+
+ Unlike `diff', `cmp' cannot compare directories; it can only compare
+two files.
+
+
+File: diff.info, Node: Binary, Prev: Brief, Up: Comparison
+
+Binary Files and Forcing Text Comparisons
+=========================================
+
+ If `diff' thinks that either of the two files it is comparing is
+binary (a non-text file), it normally treats that pair of files much as
+if the summary output format had been selected (*note Brief::.), and
+reports only that the binary files are different. This is because line
+by line comparisons are usually not meaningful for binary files.
+
+ `diff' determines whether a file is text or binary by checking the
+first few bytes in the file; the exact number of bytes is system
+dependent, but it is typically several thousand. If every character in
+that part of the file is non-null, `diff' considers the file to be
+text; otherwise it considers the file to be binary.
+
+ Sometimes you might want to force `diff' to consider files to be
+text. For example, you might be comparing text files that contain null
+characters; `diff' would erroneously decide that those are non-text
+files. Or you might be comparing documents that are in a format used
+by a word processing system that uses null characters to indicate
+special formatting. You can force `diff' to consider all files to be
+text files, and compare them line by line, by using the `-a' or
+`--text' option. If the files you compare using this option do not in
+fact contain text, they will probably contain few newline characters,
+and the `diff' output will consist of hunks showing differences between
+long lines of whatever characters the files contain.
+
+ You can also force `diff' to consider all files to be binary files,
+and report only whether they differ (but not how). Use the `--brief'
+option for this.
+
+ In operating systems that distinguish between text and binary files,
+`diff' normally reads and writes all data as text. Use the `--binary'
+option to force `diff' to read and write binary data instead. This
+option has no effect on a Posix-compliant system like GNU or
+traditional Unix. However, many personal computer operating systems
+represent the end of a line with a carriage return followed by a
+newline. On such systems, `diff' normally ignores these carriage
+returns on input and generates them at the end of each output line, but
+with the `--binary' option `diff' treats each carriage return as just
+another input character, and does not generate a carriage return at the
+end of each output line. This can be useful when dealing with non-text
+files that are meant to be interchanged with Posix-compliant systems.
+
+ If you want to compare two files byte by byte, you can use the `cmp'
+program with the `-l' option to show the values of each differing byte
+in the two files. With GNU `cmp', you can also use the `-c' option to
+show the ASCII representation of those bytes. *Note Invoking cmp::,
+for more information.
+
+ If `diff3' thinks that any of the files it is comparing is binary (a
+non-text file), it normally reports an error, because such comparisons
+are usually not useful. `diff3' uses the same test as `diff' to decide
+whether a file is binary. As with `diff', if the input files contain a
+few non-text characters but otherwise are like text files, you can
+force `diff3' to consider all files to be text files and compare them
+line by line by using the `-a' or `--text' options.
+
+
+File: diff.info, Node: Output Formats, Next: Comparing Directories, Prev: Comparison, Up: Top
+
+`diff' Output Formats
+*********************
+
+ `diff' has several mutually exclusive options for output format.
+The following sections describe each format, illustrating how `diff'
+reports the differences between two sample input files.
+
+* Menu:
+
+* Sample diff Input:: Sample `diff' input files for examples.
+* Normal:: Showing differences without surrounding text.
+* Context:: Showing differences with the surrounding text.
+* Side by Side:: Showing differences in two columns.
+* Scripts:: Generating scripts for other programs.
+* If-then-else:: Merging files with if-then-else.
+
+
+File: diff.info, Node: Sample diff Input, Next: Normal, Up: Output Formats
+
+Two Sample Input Files
+======================
+
+ Here are two sample files that we will use in numerous examples to
+illustrate the output of `diff' and how various options can change it.
+
+ This is the file `lao':
+
+ The Way that can be told of is not the eternal Way;
+ The name that can be named is not the eternal name.
+ The Nameless is the origin of Heaven and Earth;
+ The Named is the mother of all things.
+ Therefore let there always be non-being,
+ so we may see their subtlety,
+ And let there always be being,
+ so we may see their outcome.
+ The two are the same,
+ But after they are produced,
+ they have different names.
+
+ This is the file `tzu':
+
+ The Nameless is the origin of Heaven and Earth;
+ The named is the mother of all things.
+
+ Therefore let there always be non-being,
+ so we may see their subtlety,
+ And let there always be being,
+ so we may see their outcome.
+ The two are the same,
+ But after they are produced,
+ they have different names.
+ They both may be called deep and profound.
+ Deeper and more profound,
+ The door of all subtleties!
+
+ In this example, the first hunk contains just the first two lines of
+`lao', the second hunk contains the fourth line of `lao' opposing the
+second and third lines of `tzu', and the last hunk contains just the
+last three lines of `tzu'.
+
+
+File: diff.info, Node: Normal, Next: Context, Prev: Sample diff Input, Up: Output Formats
+
+Showing Differences Without Context
+===================================
+
+ The "normal" `diff' output format shows each hunk of differences
+without any surrounding context. Sometimes such output is the clearest
+way to see how lines have changed, without the clutter of nearby
+unchanged lines (although you can get similar results with the context
+or unified formats by using 0 lines of context). However, this format
+is no longer widely used for sending out patches; for that purpose, the
+context format (*note Context Format::.) and the unified format (*note
+Unified Format::.) are superior. Normal format is the default for
+compatibility with older versions of `diff' and the Posix standard.
+
+* Menu:
+
+* Detailed Normal:: A detailed description of normal output format.
+* Example Normal:: Sample output in the normal format.
+
+
+File: diff.info, Node: Detailed Normal, Next: Example Normal, Up: Normal
+
+Detailed Description of Normal Format
+-------------------------------------
+
+ The normal output format consists of one or more hunks of
+differences; each hunk shows one area where the files differ. Normal
+format hunks look like this:
+
+ CHANGE-COMMAND
+ < FROM-FILE-LINE
+ < FROM-FILE-LINE...
+ ---
+ > TO-FILE-LINE
+ > TO-FILE-LINE...
+
+ There are three types of change commands. Each consists of a line
+number or comma-separated range of lines in the first file, a single
+character indicating the kind of change to make, and a line number or
+comma-separated range of lines in the second file. All line numbers are
+the original line numbers in each file. The types of change commands
+are:
+
+`LaR'
+ Add the lines in range R of the second file after line L of the
+ first file. For example, `8a12,15' means append lines 12-15 of
+ file 2 after line 8 of file 1; or, if changing file 2 into file 1,
+ delete lines 12-15 of file 2.
+
+`FcT'
+ Replace the lines in range F of the first file with lines in range
+ T of the second file. This is like a combined add and delete, but
+ more compact. For example, `5,7c8,10' means change lines 5-7 of
+ file 1 to read as lines 8-10 of file 2; or, if changing file 2 into
+ file 1, change lines 8-10 of file 2 to read as lines 5-7 of file 1.
+
+`RdL'
+ Delete the lines in range R from the first file; line L is where
+ they would have appeared in the second file had they not been
+ deleted. For example, `5,7d3' means delete lines 5-7 of file 1;
+ or, if changing file 2 into file 1, append lines 5-7 of file 1
+ after line 3 of file 2.
+
+
+File: diff.info, Node: Example Normal, Prev: Detailed Normal, Up: Normal
+
+An Example of Normal Format
+---------------------------
+
+ Here is the output of the command `diff lao tzu' (*note Sample diff
+Input::., for the complete contents of the two files). Notice that it
+shows only the lines that are different between the two files.
+
+ 1,2d0
+ < The Way that can be told of is not the eternal Way;
+ < The name that can be named is not the eternal name.
+ 4c2,3
+ < The Named is the mother of all things.
+ ---
+ > The named is the mother of all things.
+ >
+ 11a11,13
+ > They both may be called deep and profound.
+ > Deeper and more profound,
+ > The door of all subtleties!
+
+
+File: diff.info, Node: Context, Next: Side by Side, Prev: Normal, Up: Output Formats
+
+Showing Differences in Their Context
+====================================
+
+ Usually, when you are looking at the differences between files, you
+will also want to see the parts of the files near the lines that
+differ, to help you understand exactly what has changed. These nearby
+parts of the files are called the "context".
+
+ GNU `diff' provides two output formats that show context around the
+differing lines: "context format" and "unified format". It can
+optionally show in which function or section of the file the differing
+lines are found.
+
+ If you are distributing new versions of files to other people in the
+form of `diff' output, you should use one of the output formats that
+show context so that they can apply the diffs even if they have made
+small changes of their own to the files. `patch' can apply the diffs
+in this case by searching in the files for the lines of context around
+the differing lines; if those lines are actually a few lines away from
+where the diff says they are, `patch' can adjust the line numbers
+accordingly and still apply the diff correctly. *Note Imperfect::, for
+more information on using `patch' to apply imperfect diffs.
+
+* Menu:
+
+* Context Format:: An output format that shows surrounding lines.
+* Unified Format:: A more compact output format that shows context.
+* Sections:: Showing which sections of the files differences are in.
+* Alternate Names:: Showing alternate file names in context headers.
+
+
+File: diff.info, Node: Context Format, Next: Unified Format, Up: Context
+
+Context Format
+--------------
+
+ The context output format shows several lines of context around the
+lines that differ. It is the standard format for distributing updates
+to source code.
+
+ To select this output format, use the `-C LINES',
+`--context[=LINES]', or `-c' option. The argument LINES that some of
+these options take is the number of lines of context to show. If you
+do not specify LINES, it defaults to three. For proper operation,
+`patch' typically needs at least two lines of context.
+
+* Menu:
+
+* Detailed Context:: A detailed description of the context output format.
+* Example Context:: Sample output in context format.
+* Less Context:: Another sample with less context.
+
+
+File: diff.info, Node: Detailed Context, Next: Example Context, Up: Context Format
+
+Detailed Description of Context Format
+......................................
+
+ The context output format starts with a two-line header, which looks
+like this:
+
+ *** FROM-FILE FROM-FILE-MODIFICATION-TIME
+ --- TO-FILE TO-FILE-MODIFICATION TIME
+
+You can change the header's content with the `-L LABEL' or
+`--label=LABEL' option; see *Note Alternate Names::.
+
+ Next come one or more hunks of differences; each hunk shows one area
+where the files differ. Context format hunks look like this:
+
+ ***************
+ *** FROM-FILE-LINE-RANGE ****
+ FROM-FILE-LINE
+ FROM-FILE-LINE...
+ --- TO-FILE-LINE-RANGE ----
+ TO-FILE-LINE
+ TO-FILE-LINE...
+
+ The lines of context around the lines that differ start with two
+space characters. The lines that differ between the two files start
+with one of the following indicator characters, followed by a space
+character:
+
+`!'
+ A line that is part of a group of one or more lines that changed
+ between the two files. There is a corresponding group of lines
+ marked with `!' in the part of this hunk for the other file.
+
+`+'
+ An "inserted" line in the second file that corresponds to nothing
+ in the first file.
+
+`-'
+ A "deleted" line in the first file that corresponds to nothing in
+ the second file.
+
+ If all of the changes in a hunk are insertions, the lines of
+FROM-FILE are omitted. If all of the changes are deletions, the lines
+of TO-FILE are omitted.
+
+
+File: diff.info, Node: Example Context, Next: Less Context, Prev: Detailed Context, Up: Context Format
+
+An Example of Context Format
+............................
+
+ Here is the output of `diff -c lao tzu' (*note Sample diff Input::.,
+for the complete contents of the two files). Notice that up to three
+lines that are not different are shown around each line that is
+different; they are the context lines. Also notice that the first two
+hunks have run together, because their contents overlap.
+
+ *** lao Sat Jan 26 23:30:39 1991
+ --- tzu Sat Jan 26 23:30:50 1991
+ ***************
+ *** 1,7 ****
+ - The Way that can be told of is not the eternal Way;
+ - The name that can be named is not the eternal name.
+ The Nameless is the origin of Heaven and Earth;
+ ! The Named is the mother of all things.
+ Therefore let there always be non-being,
+ so we may see their subtlety,
+ And let there always be being,
+ --- 1,6 ----
+ The Nameless is the origin of Heaven and Earth;
+ ! The named is the mother of all things.
+ !
+ Therefore let there always be non-being,
+ so we may see their subtlety,
+ And let there always be being,
+ ***************
+ *** 9,11 ****
+ --- 8,13 ----
+ The two are the same,
+ But after they are produced,
+ they have different names.
+ + They both may be called deep and profound.
+ + Deeper and more profound,
+ + The door of all subtleties!
+
+
+File: diff.info, Node: Less Context, Prev: Example Context, Up: Context Format
+
+An Example of Context Format with Less Context
+..............................................
+
+ Here is the output of `diff --context=1 lao tzu' (*note Sample diff
+Input::., for the complete contents of the two files). Notice that at
+most one context line is reported here.
+
+ *** lao Sat Jan 26 23:30:39 1991
+ --- tzu Sat Jan 26 23:30:50 1991
+ ***************
+ *** 1,5 ****
+ - The Way that can be told of is not the eternal Way;
+ - The name that can be named is not the eternal name.
+ The Nameless is the origin of Heaven and Earth;
+ ! The Named is the mother of all things.
+ Therefore let there always be non-being,
+ --- 1,4 ----
+ The Nameless is the origin of Heaven and Earth;
+ ! The named is the mother of all things.
+ !
+ Therefore let there always be non-being,
+ ***************
+ *** 11 ****
+ --- 10,13 ----
+ they have different names.
+ + They both may be called deep and profound.
+ + Deeper and more profound,
+ + The door of all subtleties!
+
+
+File: diff.info, Node: Unified Format, Next: Sections, Prev: Context Format, Up: Context
+
+Unified Format
+--------------
+
+ The unified output format is a variation on the context format that
+is more compact because it omits redundant context lines. To select
+this output format, use the `-U LINES', `--unified[=LINES]', or `-u'
+option. The argument LINES is the number of lines of context to show.
+When it is not given, it defaults to three.
+
+ At present, only GNU `diff' can produce this format and only GNU
+`patch' can automatically apply diffs in this format. For proper
+operation, `patch' typically needs at least two lines of context.
+
+* Menu:
+
+* Detailed Unified:: A detailed description of unified format.
+* Example Unified:: Sample output in unified format.
+
+
+File: diff.info, Node: Detailed Unified, Next: Example Unified, Up: Unified Format
+
+Detailed Description of Unified Format
+......................................
+
+ The unified output format starts with a two-line header, which looks
+like this:
+
+ --- FROM-FILE FROM-FILE-MODIFICATION-TIME
+ +++ TO-FILE TO-FILE-MODIFICATION-TIME
+
+You can change the header's content with the `-L LABEL' or
+`--label=LABEL' option; see *Note Alternate Names::.
+
+ Next come one or more hunks of differences; each hunk shows one area
+where the files differ. Unified format hunks look like this:
+
+ @@ FROM-FILE-RANGE TO-FILE-RANGE @@
+ LINE-FROM-EITHER-FILE
+ LINE-FROM-EITHER-FILE...
+
+ The lines common to both files begin with a space character. The
+lines that actually differ between the two files have one of the
+following indicator characters in the left column:
+
+`+'
+ A line was added here to the first file.
+
+`-'
+ A line was removed here from the first file.
+
+
+File: diff.info, Node: Example Unified, Prev: Detailed Unified, Up: Unified Format
+
+An Example of Unified Format
+............................
+
+ Here is the output of the command `diff -u lao tzu' (*note Sample
+diff Input::., for the complete contents of the two files):
+
+ --- lao Sat Jan 26 23:30:39 1991
+ +++ tzu Sat Jan 26 23:30:50 1991
+ @@ -1,7 +1,6 @@
+ -The Way that can be told of is not the eternal Way;
+ -The name that can be named is not the eternal name.
+ The Nameless is the origin of Heaven and Earth;
+ -The Named is the mother of all things.
+ +The named is the mother of all things.
+ +
+ Therefore let there always be non-being,
+ so we may see their subtlety,
+ And let there always be being,
+ @@ -9,3 +8,6 @@
+ The two are the same,
+ But after they are produced,
+ they have different names.
+ +They both may be called deep and profound.
+ +Deeper and more profound,
+ +The door of all subtleties!
+
+
+File: diff.info, Node: Sections, Next: Alternate Names, Prev: Unified Format, Up: Context
+
+Showing Which Sections Differences Are in
+-----------------------------------------
+
+ Sometimes you might want to know which part of the files each change
+falls in. If the files are source code, this could mean which function
+was changed. If the files are documents, it could mean which chapter or
+appendix was changed. GNU `diff' can show this by displaying the
+nearest section heading line that precedes the differing lines. Which
+lines are "section headings" is determined by a regular expression.
+
+* Menu:
+
+* Specified Headings:: Showing headings that match regular expressions.
+* C Function Headings:: Showing headings of C functions.
+
+
+File: diff.info, Node: Specified Headings, Next: C Function Headings, Up: Sections
+
+Showing Lines That Match Regular Expressions
+............................................
+
+ To show in which sections differences occur for files that are not
+source code for C or similar languages, use the `-F REGEXP' or
+`--show-function-line=REGEXP' option. `diff' considers lines that
+match the argument REGEXP to be the beginning of a section of the file.
+Here are suggested regular expressions for some common languages:
+
+`^[A-Za-z_]'
+ C, C++, Prolog
+
+`^('
+ Lisp
+
+`^@\(chapter\|appendix\|unnumbered\|chapheading\)'
+ Texinfo
+
+ This option does not automatically select an output format; in order
+to use it, you must select the context format (*note Context Format::.)
+or unified format (*note Unified Format::.). In other output formats it
+has no effect.
+
+ The `-F' and `--show-function-line' options find the nearest
+unchanged line that precedes each hunk of differences and matches the
+given regular expression. Then they add that line to the end of the
+line of asterisks in the context format, or to the `@@' line in unified
+format. If no matching line exists, they leave the output for that
+hunk unchanged. If that line is more than 40 characters long, they
+output only the first 40 characters. You can specify more than one
+regular expression for such lines; `diff' tries to match each line
+against each regular expression, starting with the last one given. This
+means that you can use `-p' and `-F' together, if you wish.
+
+
+File: diff.info, Node: C Function Headings, Prev: Specified Headings, Up: Sections
+
+Showing C Function Headings
+...........................
+
+ To show in which functions differences occur for C and similar
+languages, you can use the `-p' or `--show-c-function' option. This
+option automatically defaults to the context output format (*note
+Context Format::.), with the default number of lines of context. You
+can override that number with `-C LINES' elsewhere in the command line.
+You can override both the format and the number with `-U LINES'
+elsewhere in the command line.
+
+ The `-p' and `--show-c-function' options are equivalent to
+`-F'^[_a-zA-Z$]'' if the unified format is specified, otherwise `-c
+-F'^[_a-zA-Z$]'' (*note Specified Headings::.). GNU `diff' provides
+them for the sake of convenience.
+
+
+File: diff.info, Node: Alternate Names, Prev: Sections, Up: Context
+
+Showing Alternate File Names
+----------------------------
+
+ If you are comparing two files that have meaningless or uninformative
+names, you might want `diff' to show alternate names in the header of
+the context and unified output formats. To do this, use the `-L LABEL'
+or `--label=LABEL' option. The first time you give this option, its
+argument replaces the name and date of the first file in the header;
+the second time, its argument replaces the name and date of the second
+file. If you give this option more than twice, `diff' reports an
+error. The `-L' option does not affect the file names in the `pr'
+header when the `-l' or `--paginate' option is used (*note
+Pagination::.).
+
+ Here are the first two lines of the output from `diff -C2 -Loriginal
+-Lmodified lao tzu':
+
+ *** original
+ --- modified
+
+
+File: diff.info, Node: Side by Side, Next: Scripts, Prev: Context, Up: Output Formats
+
+Showing Differences Side by Side
+================================
+
+ `diff' can produce a side by side difference listing of two files.
+The files are listed in two columns with a gutter between them. The
+gutter contains one of the following markers:
+
+white space
+ The corresponding lines are in common. That is, either the lines
+ are identical, or the difference is ignored because of one of the
+ `--ignore' options (*note White Space::.).
+
+`|'
+ The corresponding lines differ, and they are either both complete
+ or both incomplete.
+
+`<'
+ The files differ and only the first file contains the line.
+
+`>'
+ The files differ and only the second file contains the line.
+
+`('
+ Only the first file contains the line, but the difference is
+ ignored.
+
+`)'
+ Only the second file contains the line, but the difference is
+ ignored.
+
+`\'
+ The corresponding lines differ, and only the first line is
+ incomplete.
+
+`/'
+ The corresponding lines differ, and only the second line is
+ incomplete.
+
+ Normally, an output line is incomplete if and only if the lines that
+it contains are incomplete; *Note Incomplete Lines::. However, when an
+output line represents two differing lines, one might be incomplete
+while the other is not. In this case, the output line is complete, but
+its the gutter is marked `\' if the first line is incomplete, `/' if
+the second line is.
+
+ Side by side format is sometimes easiest to read, but it has
+limitations. It generates much wider output than usual, and truncates
+lines that are too long to fit. Also, it relies on lining up output
+more heavily than usual, so its output looks particularly bad if you
+use varying width fonts, nonstandard tab stops, or nonprinting
+characters.
+
+ You can use the `sdiff' command to interactively merge side by side
+differences. *Note Interactive Merging::, for more information on
+merging files.
+
+* Menu:
+
+* Side by Side Format:: Controlling side by side output format.
+* Example Side by Side:: Sample side by side output.
+
+
+File: diff.info, Node: Side by Side Format, Next: Example Side by Side, Up: Side by Side
+
+Controlling Side by Side Format
+===============================
+
+ The `-y' or `--side-by-side' option selects side by side format.
+Because side by side output lines contain two input lines, they are
+wider than usual. They are normally 130 columns, which can fit onto a
+traditional printer line. You can set the length of output lines with
+the `-W COLUMNS' or `--width=COLUMNS' option. The output line is split
+into two halves of equal length, separated by a small gutter to mark
+differences; the right half is aligned to a tab stop so that tabs line
+up. Input lines that are too long to fit in half of an output line are
+truncated for output.
+
+ The `--left-column' option prints only the left column of two common
+lines. The `--suppress-common-lines' option suppresses common lines
+entirely.
+
+
+File: diff.info, Node: Example Side by Side, Prev: Side by Side Format, Up: Side by Side
+
+An Example of Side by Side Format
+---------------------------------
+
+ Here is the output of the command `diff -y -W 72 lao tzu' (*note
+Sample diff Input::., for the complete contents of the two files).
+
+ The Way that can be told of is n <
+ The name that can be named is no <
+ The Nameless is the origin of He The Nameless is the origin of He
+ The Named is the mother of all t | The named is the mother of all t
+ >
+ Therefore let there always be no Therefore let there always be no
+ so we may see their subtlety, so we may see their subtlety,
+ And let there always be being, And let there always be being,
+ so we may see their outcome. so we may see their outcome.
+ The two are the same, The two are the same,
+ But after they are produced, But after they are produced,
+ they have different names. they have different names.
+ > They both may be called deep and
+ > Deeper and more profound,
+ > The door of all subtleties!
+
+
+File: diff.info, Node: Scripts, Next: If-then-else, Prev: Side by Side, Up: Output Formats
+
+Making Edit Scripts
+===================
+
+ Several output modes produce command scripts for editing FROM-FILE
+to produce TO-FILE.
+
+* Menu:
+
+* ed Scripts:: Using `diff' to produce commands for `ed'.
+* Forward ed:: Making forward `ed' scripts.
+* RCS:: A special `diff' output format used by RCS.
+
+
+File: diff.info, Node: ed Scripts, Next: Forward ed, Up: Scripts
+
+`ed' Scripts
+------------
+
+ `diff' can produce commands that direct the `ed' text editor to
+change the first file into the second file. Long ago, this was the
+only output mode that was suitable for editing one file into another
+automatically; today, with `patch', it is almost obsolete. Use the
+`-e' or `--ed' option to select this output format.
+
+ Like the normal format (*note Normal::.), this output format does not
+show any context; unlike the normal format, it does not include the
+information necessary to apply the diff in reverse (to produce the first
+file if all you have is the second file and the diff).
+
+ If the file `d' contains the output of `diff -e old new', then the
+command `(cat d && echo w) | ed - old' edits `old' to make it a copy of
+`new'. More generally, if `d1', `d2', ..., `dN' contain the outputs of
+`diff -e old new1', `diff -e new1 new2', ..., `diff -e newN-1 newN',
+respectively, then the command `(cat d1 d2 ... dN && echo w) | ed -
+old' edits `old' to make it a copy of `newN'.
+
+* Menu:
+
+* Detailed ed:: A detailed description of `ed' format.
+* Example ed:: A sample `ed' script.
+
+
+File: diff.info, Node: Detailed ed, Next: Example ed, Up: ed Scripts
+
+Detailed Description of `ed' Format
+...................................
+
+ The `ed' output format consists of one or more hunks of differences.
+The changes closest to the ends of the files come first so that
+commands that change the number of lines do not affect how `ed'
+interprets line numbers in succeeding commands. `ed' format hunks look
+like this:
+
+ CHANGE-COMMAND
+ TO-FILE-LINE
+ TO-FILE-LINE...
+ .
+
+ Because `ed' uses a single period on a line to indicate the end of
+input, GNU `diff' protects lines of changes that contain a single
+period on a line by writing two periods instead, then writing a
+subsequent `ed' command to change the two periods into one. The `ed'
+format cannot represent an incomplete line, so if the second file ends
+in a changed incomplete line, `diff' reports an error and then pretends
+that a newline was appended.
+
+ There are three types of change commands. Each consists of a line
+number or comma-separated range of lines in the first file and a single
+character indicating the kind of change to make. All line numbers are
+the original line numbers in the file. The types of change commands
+are:
+
+`La'
+ Add text from the second file after line L in the first file. For
+ example, `8a' means to add the following lines after line 8 of file
+ 1.
+
+`Rc'
+ Replace the lines in range R in the first file with the following
+ lines. Like a combined add and delete, but more compact. For
+ example, `5,7c' means change lines 5-7 of file 1 to read as the
+ text file 2.
+
+`Rd'
+ Delete the lines in range R from the first file. For example,
+ `5,7d' means delete lines 5-7 of file 1.
+
+
+File: diff.info, Node: Example ed, Prev: Detailed ed, Up: ed Scripts
+
+Example `ed' Script
+...................
+
+ Here is the output of `diff -e lao tzu' (*note Sample diff Input::.,
+for the complete contents of the two files):
+
+ 11a
+ They both may be called deep and profound.
+ Deeper and more profound,
+ The door of all subtleties!
+ .
+ 4c
+ The named is the mother of all things.
+
+ .
+ 1,2d
+
+
+File: diff.info, Node: Forward ed, Next: RCS, Prev: ed Scripts, Up: Scripts
+
+Forward `ed' Scripts
+--------------------
+
+ `diff' can produce output that is like an `ed' script, but with
+hunks in forward (front to back) order. The format of the commands is
+also changed slightly: command characters precede the lines they
+modify, spaces separate line numbers in ranges, and no attempt is made
+to disambiguate hunk lines consisting of a single period. Like `ed'
+format, forward `ed' format cannot represent incomplete lines.
+
+ Forward `ed' format is not very useful, because neither `ed' nor
+`patch' can apply diffs in this format. It exists mainly for
+compatibility with older versions of `diff'. Use the `-f' or
+`--forward-ed' option to select it.
+
+
+File: diff.info, Node: RCS, Prev: Forward ed, Up: Scripts
+
+RCS Scripts
+-----------
+
+ The RCS output format is designed specifically for use by the
+Revision Control System, which is a set of free programs used for
+organizing different versions and systems of files. Use the `-n' or
+`--rcs' option to select this output format. It is like the forward
+`ed' format (*note Forward ed::.), but it can represent arbitrary
+changes to the contents of a file because it avoids the forward `ed'
+format's problems with lines consisting of a single period and with
+incomplete lines. Instead of ending text sections with a line
+consisting of a single period, each command specifies the number of
+lines it affects; a combination of the `a' and `d' commands are used
+instead of `c'. Also, if the second file ends in a changed incomplete
+line, then the output also ends in an incomplete line.
+
+ Here is the output of `diff -n lao tzu' (*note Sample diff Input::.,
+for the complete contents of the two files):
+
+ d1 2
+ d4 1
+ a4 2
+ The named is the mother of all things.
+
+ a11 3
+ They both may be called deep and profound.
+ Deeper and more profound,
+ The door of all subtleties!
+
+
+File: diff.info, Node: If-then-else, Prev: Scripts, Up: Output Formats
+
+Merging Files with If-then-else
+===============================
+
+ You can use `diff' to merge two files of C source code. The output
+of `diff' in this format contains all the lines of both files. Lines
+common to both files are output just once; the differing parts are
+separated by the C preprocessor directives `#ifdef NAME' or `#ifndef
+NAME', `#else', and `#endif'. When compiling the output, you select
+which version to use by either defining or leaving undefined the macro
+NAME.
+
+ To merge two files, use `diff' with the `-D NAME' or `--ifdef=NAME'
+option. The argument NAME is the C preprocessor identifier to use in
+the `#ifdef' and `#ifndef' directives.
+
+ For example, if you change an instance of `wait (&s)' to `waitpid
+(-1, &s, 0)' and then merge the old and new files with the
+`--ifdef=HAVE_WAITPID' option, then the affected part of your code
+might look like this:
+
+ do {
+ #ifndef HAVE_WAITPID
+ if ((w = wait (&s)) < 0 && errno != EINTR)
+ #else /* HAVE_WAITPID */
+ if ((w = waitpid (-1, &s, 0)) < 0 && errno != EINTR)
+ #endif /* HAVE_WAITPID */
+ return w;
+ } while (w != child);
+
+ You can specify formats for languages other than C by using line
+group formats and line formats, as described in the next sections.
+
+* Menu:
+
+* Line Group Formats:: Formats for general if-then-else line groups.
+* Line Formats:: Formats for each line in a line group.
+* Detailed If-then-else:: A detailed description of if-then-else format.
+* Example If-then-else:: Sample if-then-else format output.
+
diff --git a/gnu/dist/diffutils/diff.info-2 b/gnu/dist/diffutils/diff.info-2
new file mode 100644
index 00000000000..43fae2835c7
--- /dev/null
+++ b/gnu/dist/diffutils/diff.info-2
@@ -0,0 +1,1312 @@
+This is Info file diff.info, produced by Makeinfo-1.55 from the input
+file ./diff.texi.
+
+ This file documents the the GNU `diff', `diff3', `sdiff', and `cmp'
+commands for showing the differences between text files and the `patch'
+command for using their output to update files.
+
+ Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+
+ Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+ Permission is granted to copy and distribute modified versions of
+this manual under the conditions for verbatim copying, provided that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+ Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be stated in a
+translation approved by the Foundation.
+
+
+File: diff.info, Node: Line Group Formats, Next: Line Formats, Up: If-then-else
+
+Line Group Formats
+------------------
+
+ Line group formats let you specify formats suitable for many
+applications that allow if-then-else input, including programming
+languages and text formatting languages. A line group format specifies
+the output format for a contiguous group of similar lines.
+
+ For example, the following command compares the TeX files `old' and
+`new', and outputs a merged file in which old regions are surrounded by
+`\begin{em}'-`\end{em}' lines, and new regions are surrounded by
+`\begin{bf}'-`\end{bf}' lines.
+
+ diff \
+ --old-group-format='\begin{em}
+ %<\end{em}
+ ' \
+ --new-group-format='\begin{bf}
+ %>\end{bf}
+ ' \
+ old new
+
+ The following command is equivalent to the above example, but it is a
+little more verbose, because it spells out the default line group
+formats.
+
+ diff \
+ --old-group-format='\begin{em}
+ %<\end{em}
+ ' \
+ --new-group-format='\begin{bf}
+ %>\end{bf}
+ ' \
+ --unchanged-group-format='%=' \
+ --changed-group-format='\begin{em}
+ %<\end{em}
+ \begin{bf}
+ %>\end{bf}
+ ' \
+ old new
+
+ Here is a more advanced example, which outputs a diff listing with
+headers containing line numbers in a "plain English" style.
+
+ diff \
+ --unchanged-group-format='' \
+ --old-group-format='-------- %dn line%(n=1?:s) deleted at %df:
+ %<' \
+ --new-group-format='-------- %dN line%(N=1?:s) added after %de:
+ %>' \
+ --changed-group-format='-------- %dn line%(n=1?:s) changed at %df:
+ %<-------- to:
+ %>' \
+ old new
+
+ To specify a line group format, use `diff' with one of the options
+listed below. You can specify up to four line group formats, one for
+each kind of line group. You should quote FORMAT, because it typically
+contains shell metacharacters.
+
+`--old-group-format=FORMAT'
+ These line groups are hunks containing only lines from the first
+ file. The default old group format is the same as the changed
+ group format if it is specified; otherwise it is a format that
+ outputs the line group as-is.
+
+`--new-group-format=FORMAT'
+ These line groups are hunks containing only lines from the second
+ file. The default new group format is same as the the changed
+ group format if it is specified; otherwise it is a format that
+ outputs the line group as-is.
+
+`--changed-group-format=FORMAT'
+ These line groups are hunks containing lines from both files. The
+ default changed group format is the concatenation of the old and
+ new group formats.
+
+`--unchanged-group-format=FORMAT'
+ These line groups contain lines common to both files. The default
+ unchanged group format is a format that outputs the line group
+ as-is.
+
+ In a line group format, ordinary characters represent themselves;
+conversion specifications start with `%' and have one of the following
+forms.
+
+`%<'
+ stands for the lines from the first file, including the trailing
+ newline. Each line is formatted according to the old line format
+ (*note Line Formats::.).
+
+`%>'
+ stands for the lines from the second file, including the trailing
+ newline. Each line is formatted according to the new line format.
+
+`%='
+ stands for the lines common to both files, including the trailing
+ newline. Each line is formatted according to the unchanged line
+ format.
+
+`%%'
+ stands for `%'.
+
+`%c'C''
+ where C is a single character, stands for C. C may not be a
+ backslash or an apostrophe. For example, `%c':'' stands for a
+ colon, even inside the then-part of an if-then-else format, which
+ a colon would normally terminate.
+
+`%c'\O''
+ where O is a string of 1, 2, or 3 octal digits, stands for the
+ character with octal code O. For example, `%c'\0'' stands for a
+ null character.
+
+`FN'
+ where F is a `printf' conversion specification and N is one of the
+ following letters, stands for N's value formatted with F.
+
+ `e'
+ The line number of the line just before the group in the old
+ file.
+
+ `f'
+ The line number of the first line in the group in the old
+ file; equals E + 1.
+
+ `l'
+ The line number of the last line in the group in the old file.
+
+ `m'
+ The line number of the line just after the group in the old
+ file; equals L + 1.
+
+ `n'
+ The number of lines in the group in the old file; equals L -
+ F + 1.
+
+ `E, F, L, M, N'
+ Likewise, for lines in the new file.
+
+ The `printf' conversion specification can be `%d', `%o', `%x', or
+ `%X', specifying decimal, octal, lower case hexadecimal, or upper
+ case hexadecimal output respectively. After the `%' the following
+ options can appear in sequence: a `-' specifying
+ left-justification; an integer specifying the minimum field width;
+ and a period followed by an optional integer specifying the
+ minimum number of digits. For example, `%5dN' prints the number
+ of new lines in the group in a field of width 5 characters, using
+ the `printf' format `"%5d"'.
+
+`(A=B?T:E)'
+ If A equals B then T else E. A and B are each either a decimal
+ constant or a single letter interpreted as above. This format
+ spec is equivalent to T if A's value equals B's; otherwise it is
+ equivalent to E.
+
+ For example, `%(N=0?no:%dN) line%(N=1?:s)' is equivalent to `no
+ lines' if N (the number of lines in the group in the the new file)
+ is 0, to `1 line' if N is 1, and to `%dN lines' otherwise.
+
+
+File: diff.info, Node: Line Formats, Next: Detailed If-then-else, Prev: Line Group Formats, Up: If-then-else
+
+Line Formats
+------------
+
+ Line formats control how each line taken from an input file is
+output as part of a line group in if-then-else format.
+
+ For example, the following command outputs text with a one-column
+change indicator to the left of the text. The first column of output
+is `-' for deleted lines, `|' for added lines, and a space for
+unchanged lines. The formats contain newline characters where newlines
+are desired on output.
+
+ diff \
+ --old-line-format='-%l
+ ' \
+ --new-line-format='|%l
+ ' \
+ --unchanged-line-format=' %l
+ ' \
+ old new
+
+ To specify a line format, use one of the following options. You
+should quote FORMAT, since it often contains shell metacharacters.
+
+`--old-line-format=FORMAT'
+ formats lines just from the first file.
+
+`--new-line-format=FORMAT'
+ formats lines just from the second file.
+
+`--unchanged-line-format=FORMAT'
+ formats lines common to both files.
+
+`--line-format=FORMAT'
+ formats all lines; in effect, it sets all three above options
+ simultaneously.
+
+ In a line format, ordinary characters represent themselves;
+conversion specifications start with `%' and have one of the following
+forms.
+
+`%l'
+ stands for the the contents of the line, not counting its trailing
+ newline (if any). This format ignores whether the line is
+ incomplete; *Note Incomplete Lines::.
+
+`%L'
+ stands for the the contents of the line, including its trailing
+ newline (if any). If a line is incomplete, this format preserves
+ its incompleteness.
+
+`%%'
+ stands for `%'.
+
+`%c'C''
+ where C is a single character, stands for C. C may not be a
+ backslash or an apostrophe. For example, `%c':'' stands for a
+ colon.
+
+`%c'\O''
+ where O is a string of 1, 2, or 3 octal digits, stands for the
+ character with octal code O. For example, `%c'\0'' stands for a
+ null character.
+
+`Fn'
+ where F is a `printf' conversion specification, stands for the
+ line number formatted with F. For example, `%.5dn' prints the
+ line number using the `printf' format `"%.5d"'. *Note Line Group
+ Formats::, for more about printf conversion specifications.
+
+ The default line format is `%l' followed by a newline character.
+
+ If the input contains tab characters and it is important that they
+line up on output, you should ensure that `%l' or `%L' in a line format
+is just after a tab stop (e.g. by preceding `%l' or `%L' with a tab
+character), or you should use the `-t' or `--expand-tabs' option.
+
+ Taken together, the line and line group formats let you specify many
+different formats. For example, the following command uses a format
+similar to `diff''s normal format. You can tailor this command to get
+fine control over `diff''s output.
+
+ diff \
+ --old-line-format='< %l
+ ' \
+ --new-line-format='> %l
+ ' \
+ --old-group-format='%df%(f=l?:,%dl)d%dE
+ %<' \
+ --new-group-format='%dea%dF%(F=L?:,%dL)
+ %>' \
+ --changed-group-format='%df%(f=l?:,%dl)c%dF%(F=L?:,%dL)
+ %<---
+ %>' \
+ --unchanged-group-format='' \
+ old new
+
+
+File: diff.info, Node: Detailed If-then-else, Next: Example If-then-else, Prev: Line Formats, Up: If-then-else
+
+Detailed Description of If-then-else Format
+-------------------------------------------
+
+ For lines common to both files, `diff' uses the unchanged line group
+format. For each hunk of differences in the merged output format, if
+the hunk contains only lines from the first file, `diff' uses the old
+line group format; if the hunk contains only lines from the second
+file, `diff' uses the new group format; otherwise, `diff' uses the
+changed group format.
+
+ The old, new, and unchanged line formats specify the output format of
+lines from the first file, lines from the second file, and lines common
+to both files, respectively.
+
+ The option `--ifdef=NAME' is equivalent to the following sequence of
+options using shell syntax:
+
+ --old-group-format='#ifndef NAME
+ %<#endif /* not NAME */
+ ' \
+ --new-group-format='#ifdef NAME
+ %>#endif /* NAME */
+ ' \
+ --unchanged-group-format='%=' \
+ --changed-group-format='#ifndef NAME
+ %<#else /* NAME */
+ %>#endif /* NAME */
+ '
+
+ You should carefully check the `diff' output for proper nesting.
+For example, when using the the `-D NAME' or `--ifdef=NAME' option, you
+should check that if the differing lines contain any of the C
+preprocessor directives `#ifdef', `#ifndef', `#else', `#elif', or
+`#endif', they are nested properly and match. If they don't, you must
+make corrections manually. It is a good idea to carefully check the
+resulting code anyway to make sure that it really does what you want it
+to; depending on how the input files were produced, the output might
+contain duplicate or otherwise incorrect code.
+
+ The `patch' `-D NAME' option behaves just like the `diff' `-D NAME'
+option, except it operates on a file and a diff to produce a merged
+file; *Note patch Options::.
+
+
+File: diff.info, Node: Example If-then-else, Prev: Detailed If-then-else, Up: If-then-else
+
+An Example of If-then-else Format
+---------------------------------
+
+ Here is the output of `diff -DTWO lao tzu' (*note Sample diff
+Input::., for the complete contents of the two files):
+
+ #ifndef TWO
+ The Way that can be told of is not the eternal Way;
+ The name that can be named is not the eternal name.
+ #endif /* not TWO */
+ The Nameless is the origin of Heaven and Earth;
+ #ifndef TWO
+ The Named is the mother of all things.
+ #else /* TWO */
+ The named is the mother of all things.
+
+ #endif /* TWO */
+ Therefore let there always be non-being,
+ so we may see their subtlety,
+ And let there always be being,
+ so we may see their outcome.
+ The two are the same,
+ But after they are produced,
+ they have different names.
+ #ifdef TWO
+ They both may be called deep and profound.
+ Deeper and more profound,
+ The door of all subtleties!
+ #endif /* TWO */
+
+
+File: diff.info, Node: Comparing Directories, Next: Adjusting Output, Prev: Output Formats, Up: Top
+
+Comparing Directories
+*********************
+
+ You can use `diff' to compare some or all of the files in two
+directory trees. When both file name arguments to `diff' are
+directories, it compares each file that is contained in both
+directories, examining file names in alphabetical order. Normally
+`diff' is silent about pairs of files that contain no differences, but
+if you use the `-s' or `--report-identical-files' option, it reports
+pairs of identical files. Normally `diff' reports subdirectories
+common to both directories without comparing subdirectories' files, but
+if you use the `-r' or `--recursive' option, it compares every
+corresponding pair of files in the directory trees, as many levels deep
+as they go.
+
+ For file names that are in only one of the directories, `diff'
+normally does not show the contents of the file that exists; it reports
+only that the file exists in that directory and not in the other. You
+can make `diff' act as though the file existed but was empty in the
+other directory, so that it outputs the entire contents of the file that
+actually exists. (It is output as either an insertion or a deletion,
+depending on whether it is in the first or the second directory given.)
+To do this, use the `-N' or `--new-file' option.
+
+ If the older directory contains one or more large files that are not
+in the newer directory, you can make the patch smaller by using the
+`-P' or `--unidirectional-new-file' option instead of `-N'. This
+option is like `-N' except that it only inserts the contents of files
+that appear in the second directory but not the first (that is, files
+that were added). At the top of the patch, write instructions for the
+user applying the patch to remove the files that were deleted before
+applying the patch. *Note Making Patches::, for more discussion of
+making patches for distribution.
+
+ To ignore some files while comparing directories, use the `-x
+PATTERN' or `--exclude=PATTERN' option. This option ignores any files
+or subdirectories whose base names match the shell pattern PATTERN.
+Unlike in the shell, a period at the start of the base of a file name
+matches a wildcard at the start of a pattern. You should enclose
+PATTERN in quotes so that the shell does not expand it. For example,
+the option `-x '*.[ao]'' ignores any file whose name ends with `.a' or
+`.o'.
+
+ This option accumulates if you specify it more than once. For
+example, using the options `-x 'RCS' -x '*,v'' ignores any file or
+subdirectory whose base name is `RCS' or ends with `,v'.
+
+ If you need to give this option many times, you can instead put the
+patterns in a file, one pattern per line, and use the `-X FILE' or
+`--exclude-from=FILE' option.
+
+ If you have been comparing two directories and stopped partway
+through, later you might want to continue where you left off. You can
+do this by using the `-S FILE' or `--starting-file=FILE' option. This
+compares only the file FILE and all alphabetically later files in the
+topmost directory level.
+
+
+File: diff.info, Node: Adjusting Output, Next: diff Performance, Prev: Comparing Directories, Up: Top
+
+Making `diff' Output Prettier
+*****************************
+
+ `diff' provides several ways to adjust the appearance of its output.
+These adjustments can be applied to any output format.
+
+* Menu:
+
+* Tabs:: Preserving the alignment of tabstops.
+* Pagination:: Page numbering and timestamping `diff' output.
+
+
+File: diff.info, Node: Tabs, Next: Pagination, Up: Adjusting Output
+
+Preserving Tabstop Alignment
+============================
+
+ The lines of text in some of the `diff' output formats are preceded
+by one or two characters that indicate whether the text is inserted,
+deleted, or changed. The addition of those characters can cause tabs to
+move to the next tabstop, throwing off the alignment of columns in the
+line. GNU `diff' provides two ways to make tab-aligned columns line up
+correctly.
+
+ The first way is to have `diff' convert all tabs into the correct
+number of spaces before outputting them; select this method with the
+`-t' or `--expand-tabs' option. `diff' assumes that tabstops are set
+every 8 columns. To use this form of output with `patch', you must
+give `patch' the `-l' or `--ignore-white-space' option (*note Changed
+White Space::., for more information).
+
+ The other method for making tabs line up correctly is to add a tab
+character instead of a space after the indicator character at the
+beginning of the line. This ensures that all following tab characters
+are in the same position relative to tabstops that they were in the
+original files, so that the output is aligned correctly. Its
+disadvantage is that it can make long lines too long to fit on one line
+of the screen or the paper. It also does not work with the unified
+output format, which does not have a space character after the change
+type indicator character. Select this method with the `-T' or
+`--initial-tab' option.
+
+
+File: diff.info, Node: Pagination, Prev: Tabs, Up: Adjusting Output
+
+Paginating `diff' Output
+========================
+
+ It can be convenient to have long output page-numbered and
+time-stamped. The `-l' and `--paginate' options do this by sending the
+`diff' output through the `pr' program. Here is what the page header
+might look like for `diff -lc lao tzu':
+
+ Mar 11 13:37 1991 diff -lc lao tzu Page 1
+
+
+File: diff.info, Node: diff Performance, Next: Comparing Three Files, Prev: Adjusting Output, Up: Top
+
+`diff' Performance Tradeoffs
+****************************
+
+ GNU `diff' runs quite efficiently; however, in some circumstances
+you can cause it to run faster or produce a more compact set of changes.
+There are two ways that you can affect the performance of GNU `diff' by
+changing the way it compares files.
+
+ Performance has more than one dimension. These options improve one
+aspect of performance at the cost of another, or they improve
+performance in some cases while hurting it in others.
+
+ The way that GNU `diff' determines which lines have changed always
+comes up with a near-minimal set of differences. Usually it is good
+enough for practical purposes. If the `diff' output is large, you
+might want `diff' to use a modified algorithm that sometimes produces a
+smaller set of differences. The `-d' or `--minimal' option does this;
+however, it can also cause `diff' to run more slowly than usual, so it
+is not the default behavior.
+
+ When the files you are comparing are large and have small groups of
+changes scattered throughout them, you can use the `-H' or
+`--speed-large-files' option to make a different modification to the
+algorithm that `diff' uses. If the input files have a constant small
+density of changes, this option speeds up the comparisons without
+changing the output. If not, `diff' might produce a larger set of
+differences; however, the output will still be correct.
+
+ Normally `diff' discards the prefix and suffix that is common to
+both files before it attempts to find a minimal set of differences.
+This makes `diff' run faster, but occasionally it may produce
+non-minimal output. The `--horizon-lines=LINES' option prevents `diff'
+from discarding the last LINES lines of the prefix and the first LINES
+lines of the suffix. This gives `diff' further opportunities to find a
+minimal output.
+
+
+File: diff.info, Node: Comparing Three Files, Next: diff3 Merging, Prev: diff Performance, Up: Top
+
+Comparing Three Files
+*********************
+
+ Use the program `diff3' to compare three files and show any
+differences among them. (`diff3' can also merge files; see *Note diff3
+Merging::).
+
+ The "normal" `diff3' output format shows each hunk of differences
+without surrounding context. Hunks are labeled depending on whether
+they are two-way or three-way, and lines are annotated by their
+location in the input files.
+
+ *Note Invoking diff3::, for more information on how to run `diff3'.
+
+* Menu:
+
+* Sample diff3 Input:: Sample `diff3' input for examples.
+* Detailed diff3 Normal:: A detailed description of normal output format.
+* diff3 Hunks:: The format of normal output format.
+* Example diff3 Normal:: Sample output in the normal format.
+
+
+File: diff.info, Node: Sample diff3 Input, Next: Detailed diff3 Normal, Up: Comparing Three Files
+
+A Third Sample Input File
+=========================
+
+ Here is a third sample file that will be used in examples to
+illustrate the output of `diff3' and how various options can change it.
+The first two files are the same that we used for `diff' (*note Sample
+diff Input::.). This is the third sample file, called `tao':
+
+ The Way that can be told of is not the eternal Way;
+ The name that can be named is not the eternal name.
+ The Nameless is the origin of Heaven and Earth;
+ The named is the mother of all things.
+
+ Therefore let there always be non-being,
+ so we may see their subtlety,
+ And let there always be being,
+ so we may see their result.
+ The two are the same,
+ But after they are produced,
+ they have different names.
+
+ -- The Way of Lao-Tzu, tr. Wing-tsit Chan
+
+
+File: diff.info, Node: Detailed diff3 Normal, Next: diff3 Hunks, Prev: Sample diff3 Input, Up: Comparing Three Files
+
+Detailed Description of `diff3' Normal Format
+=============================================
+
+ Each hunk begins with a line marked `===='. Three-way hunks have
+plain `====' lines, and two-way hunks have `1', `2', or `3' appended to
+specify which of the three input files differ in that hunk. The hunks
+contain copies of two or three sets of input lines each preceded by one
+or two commands identifying where the lines came from.
+
+ Normally, two spaces precede each copy of an input line to
+distinguish it from the commands. But with the `-T' or `--initial-tab'
+option, `diff3' uses a tab instead of two spaces; this lines up tabs
+correctly. *Note Tabs::, for more information.
+
+ Commands take the following forms:
+
+`FILE:La'
+ This hunk appears after line L of file FILE, and contains no lines
+ in that file. To edit this file to yield the other files, one
+ must append hunk lines taken from the other files. For example,
+ `1:11a' means that the hunk follows line 11 in the first file and
+ contains no lines from that file.
+
+`FILE:Rc'
+ This hunk contains the lines in the range R of file FILE. The
+ range R is a comma-separated pair of line numbers, or just one
+ number if the range is a singleton. To edit this file to yield the
+ other files, one must change the specified lines to be the lines
+ taken from the other files. For example, `2:11,13c' means that
+ the hunk contains lines 11 through 13 from the second file.
+
+ If the last line in a set of input lines is incomplete (*note
+Incomplete Lines::.), it is distinguished on output from a full line by
+a following line that starts with `\'.
+
+
+File: diff.info, Node: diff3 Hunks, Next: Example diff3 Normal, Prev: Detailed diff3 Normal, Up: Comparing Three Files
+
+`diff3' Hunks
+=============
+
+ Groups of lines that differ in two or three of the input files are
+called "diff3 hunks", by analogy with `diff' hunks (*note Hunks::.).
+If all three input files differ in a `diff3' hunk, the hunk is called a
+"three-way hunk"; if just two input files differ, it is a "two-way
+hunk".
+
+ As with `diff', several solutions are possible. When comparing the
+files `A', `B', and `C', `diff3' normally finds `diff3' hunks by
+merging the two-way hunks output by the two commands `diff A B' and
+`diff A C'. This does not necessarily minimize the size of the output,
+but exceptions should be rare.
+
+ For example, suppose `F' contains the three lines `a', `b', `f', `G'
+contains the lines `g', `b', `g', and `H' contains the lines `a', `b',
+`h'. `diff3 F G H' might output the following:
+
+ ====2
+ 1:1c
+ 3:1c
+ a
+ 2:1c
+ g
+ ====
+ 1:3c
+ f
+ 2:3c
+ g
+ 3:3c
+ h
+
+because it found a two-way hunk containing `a' in the first and third
+files and `g' in the second file, then the single line `b' common to
+all three files, then a three-way hunk containing the last line of each
+file.
+
+
+File: diff.info, Node: Example diff3 Normal, Prev: diff3 Hunks, Up: Comparing Three Files
+
+An Example of `diff3' Normal Format
+===================================
+
+ Here is the output of the command `diff3 lao tzu tao' (*note Sample
+diff3 Input::., for the complete contents of the files). Notice that
+it shows only the lines that are different among the three files.
+
+ ====2
+ 1:1,2c
+ 3:1,2c
+ The Way that can be told of is not the eternal Way;
+ The name that can be named is not the eternal name.
+ 2:0a
+ ====1
+ 1:4c
+ The Named is the mother of all things.
+ 2:2,3c
+ 3:4,5c
+ The named is the mother of all things.
+
+ ====3
+ 1:8c
+ 2:7c
+ so we may see their outcome.
+ 3:9c
+ so we may see their result.
+ ====
+ 1:11a
+ 2:11,13c
+ They both may be called deep and profound.
+ Deeper and more profound,
+ The door of all subtleties!
+ 3:13,14c
+
+ -- The Way of Lao-Tzu, tr. Wing-tsit Chan
+
+
+File: diff.info, Node: diff3 Merging, Next: Interactive Merging, Prev: Comparing Three Files, Up: Top
+
+Merging From a Common Ancestor
+******************************
+
+ When two people have made changes to copies of the same file,
+`diff3' can produce a merged output that contains both sets of changes
+together with warnings about conflicts.
+
+ One might imagine programs with names like `diff4' and `diff5' to
+compare more than three files simultaneously, but in practice the need
+rarely arises. You can use `diff3' to merge three or more sets of
+changes to a file by merging two change sets at a time.
+
+ `diff3' can incorporate changes from two modified versions into a
+common preceding version. This lets you merge the sets of changes
+represented by the two newer files. Specify the common ancestor version
+as the second argument and the two newer versions as the first and third
+arguments, like this:
+
+ diff3 MINE OLDER YOURS
+
+You can remember the order of the arguments by noting that they are in
+alphabetical order.
+
+ You can think of this as subtracting OLDER from YOURS and adding the
+result to MINE, or as merging into MINE the changes that would turn
+OLDER into YOURS. This merging is well-defined as long as MINE and
+OLDER match in the neighborhood of each such change. This fails to be
+true when all three input files differ or when only OLDER differs; we
+call this a "conflict". When all three input files differ, we call the
+conflict an "overlap".
+
+ `diff3' gives you several ways to handle overlaps and conflicts.
+You can omit overlaps or conflicts, or select only overlaps, or mark
+conflicts with special `<<<<<<<' and `>>>>>>>' lines.
+
+ `diff3' can output the merge results as an `ed' script that that can
+be applied to the first file to yield the merged output. However, it
+is usually better to have `diff3' generate the merged output directly;
+this bypasses some problems with `ed'.
+
+* Menu:
+
+* Which Changes:: Selecting changes to incorporate.
+* Marking Conflicts:: Marking conflicts.
+* Bypassing ed:: Generating merged output directly.
+* Merging Incomplete Lines:: How `diff3' merges incomplete lines.
+* Saving the Changed File:: Emulating System V behavior.
+
+
+File: diff.info, Node: Which Changes, Next: Marking Conflicts, Up: diff3 Merging
+
+Selecting Which Changes to Incorporate
+======================================
+
+ You can select all unmerged changes from OLDER to YOURS for merging
+into MINE with the `-e' or `--ed' option. You can select only the
+nonoverlapping unmerged changes with `-3' or `--easy-only', and you can
+select only the overlapping changes with `-x' or `--overlap-only'.
+
+ The `-e', `-3' and `-x' options select only "unmerged changes", i.e.
+changes where MINE and YOURS differ; they ignore changes from OLDER to
+YOURS where MINE and YOURS are identical, because they assume that such
+changes have already been merged. If this assumption is not a safe
+one, you can use the `-A' or `--show-all' option (*note Marking
+Conflicts::.).
+
+ Here is the output of the command `diff3' with each of these three
+options (*note Sample diff3 Input::., for the complete contents of the
+files). Notice that `-e' outputs the union of the disjoint sets of
+changes output by `-3' and `-x'.
+
+ Output of `diff3 -e lao tzu tao':
+ 11a
+
+ -- The Way of Lao-Tzu, tr. Wing-tsit Chan
+ .
+ 8c
+ so we may see their result.
+ .
+
+ Output of `diff3 -3 lao tzu tao':
+ 8c
+ so we may see their result.
+ .
+
+ Output of `diff3 -x lao tzu tao':
+ 11a
+
+ -- The Way of Lao-Tzu, tr. Wing-tsit Chan
+ .
+
+
+File: diff.info, Node: Marking Conflicts, Next: Bypassing ed, Prev: Which Changes, Up: diff3 Merging
+
+Marking Conflicts
+=================
+
+ `diff3' can mark conflicts in the merged output by bracketing them
+with special marker lines. A conflict that comes from two files A and
+B is marked as follows:
+
+ <<<<<<< A
+ lines from A
+ =======
+ lines from B
+ >>>>>>> B
+
+ A conflict that comes from three files A, B and C is marked as
+follows:
+
+ <<<<<<< A
+ lines from A
+ ||||||| B
+ lines from B
+ =======
+ lines from C
+ >>>>>>> C
+
+ The `-A' or `--show-all' option acts like the `-e' option, except
+that it brackets conflicts, and it outputs all changes from OLDER to
+YOURS, not just the unmerged changes. Thus, given the sample input
+files (*note Sample diff3 Input::.), `diff3 -A lao tzu tao' puts
+brackets around the conflict where only `tzu' differs:
+
+ <<<<<<< tzu
+ =======
+ The Way that can be told of is not the eternal Way;
+ The name that can be named is not the eternal name.
+ >>>>>>> tao
+
+ And it outputs the three-way conflict as follows:
+
+ <<<<<<< lao
+ ||||||| tzu
+ They both may be called deep and profound.
+ Deeper and more profound,
+ The door of all subtleties!
+ =======
+
+ -- The Way of Lao-Tzu, tr. Wing-tsit Chan
+ >>>>>>> tao
+
+ The `-E' or `--show-overlap' option outputs less information than
+the `-A' or `--show-all' option, because it outputs only unmerged
+changes, and it never outputs the contents of the second file. Thus
+the `-E' option acts like the `-e' option, except that it brackets the
+first and third files from three-way overlapping changes. Similarly,
+`-X' acts like `-x', except it brackets all its (necessarily
+overlapping) changes. For example, for the three-way overlapping
+change above, the `-E' and `-X' options output the following:
+
+ <<<<<<< lao
+ =======
+
+ -- The Way of Lao-Tzu, tr. Wing-tsit Chan
+ >>>>>>> tao
+
+ If you are comparing files that have meaningless or uninformative
+names, you can use the `-L LABEL' or `--label=LABEL' option to show
+alternate names in the `<<<<<<<', `|||||||' and `>>>>>>>' brackets.
+This option can be given up to three times, once for each input file.
+Thus `diff3 -A -L X -L Y -L Z A B C' acts like `diff3 -A A B C', except
+that the output looks like it came from files named `X', `Y' and `Z'
+rather than from files named `A', `B' and `C'.
+
+
+File: diff.info, Node: Bypassing ed, Next: Merging Incomplete Lines, Prev: Marking Conflicts, Up: diff3 Merging
+
+Generating the Merged Output Directly
+=====================================
+
+ With the `-m' or `--merge' option, `diff3' outputs the merged file
+directly. This is more efficient than using `ed' to generate it, and
+works even with non-text files that `ed' would reject. If you specify
+`-m' without an `ed' script option, `-A' (`--show-all') is assumed.
+
+ For example, the command `diff3 -m lao tzu tao' (*note Sample diff3
+Input::. for a copy of the input files) would output the following:
+
+ <<<<<<< tzu
+ =======
+ The Way that can be told of is not the eternal Way;
+ The name that can be named is not the eternal name.
+ >>>>>>> tao
+ The Nameless is the origin of Heaven and Earth;
+ The Named is the mother of all things.
+ Therefore let there always be non-being,
+ so we may see their subtlety,
+ And let there always be being,
+ so we may see their result.
+ The two are the same,
+ But after they are produced,
+ they have different names.
+ <<<<<<< lao
+ ||||||| tzu
+ They both may be called deep and profound.
+ Deeper and more profound,
+ The door of all subtleties!
+ =======
+
+ -- The Way of Lao-Tzu, tr. Wing-tsit Chan
+ >>>>>>> tao
+
+
+File: diff.info, Node: Merging Incomplete Lines, Next: Saving the Changed File, Prev: Bypassing ed, Up: diff3 Merging
+
+How `diff3' Merges Incomplete Lines
+===================================
+
+ With `-m', incomplete lines (*note Incomplete Lines::.) are simply
+copied to the output as they are found; if the merged output ends in an
+conflict and one of the input files ends in an incomplete line,
+succeeding `|||||||', `=======' or `>>>>>>>' brackets appear somewhere
+other than the start of a line because they are appended to the
+incomplete line.
+
+ Without `-m', if an `ed' script option is specified and an
+incomplete line is found, `diff3' generates a warning and acts as if a
+newline had been present.
+
+
+File: diff.info, Node: Saving the Changed File, Prev: Merging Incomplete Lines, Up: diff3 Merging
+
+Saving the Changed File
+=======================
+
+ Traditional Unix `diff3' generates an `ed' script without the
+trailing `w' and and `q' commands that save the changes. System V
+`diff3' generates these extra commands. GNU `diff3' normally behaves
+like traditional Unix `diff3', but with the `-i' option it behaves like
+System V `diff3' and appends the `w' and `q' commands.
+
+ The `-i' option requires one of the `ed' script options `-AeExX3',
+and is incompatible with the merged output option `-m'.
+
+
+File: diff.info, Node: Interactive Merging, Next: Merging with patch, Prev: diff3 Merging, Up: Top
+
+Interactive Merging with `sdiff'
+********************************
+
+ With `sdiff', you can merge two files interactively based on a
+side-by-side `-y' format comparison (*note Side by Side::.). Use `-o
+FILE' or `--output=FILE' to specify where to put the merged text.
+*Note Invoking sdiff::, for more details on the options to `sdiff'.
+
+ Another way to merge files interactively is to use the Emacs Lisp
+package `emerge'. *Note emerge: (emacs)emerge, for more information.
+
+* Menu:
+
+* sdiff Option Summary::Summary of `sdiff' options.
+* Merge Commands:: Merging two files interactively.
+
+
+File: diff.info, Node: sdiff Option Summary, Next: Merge Commands, Up: Interactive Merging
+
+Specifying `diff' Options to `sdiff'
+====================================
+
+ The following `sdiff' options have the same meaning as for `diff'.
+*Note diff Options::, for the use of these options.
+
+ -a -b -d -i -t -v
+ -B -H -I REGEXP
+
+ --ignore-blank-lines --ignore-case
+ --ignore-matching-lines=REGEXP --ignore-space-change
+ --left-column --minimal --speed-large-files
+ --suppress-common-lines --expand-tabs
+ --text --version --width=COLUMNS
+
+ For historical reasons, `sdiff' has alternate names for some
+options. The `-l' option is equivalent to the `--left-column' option,
+and similarly `-s' is equivalent to `--suppress-common-lines'. The
+meaning of the `sdiff' `-w' and `-W' options is interchanged from that
+of `diff': with `sdiff', `-w COLUMNS' is equivalent to
+`--width=COLUMNS', and `-W' is equivalent to `--ignore-all-space'.
+`sdiff' without the `-o' option is equivalent to `diff' with the `-y'
+or `--side-by-side' option (*note Side by Side::.).
+
+
+File: diff.info, Node: Merge Commands, Prev: sdiff Option Summary, Up: Interactive Merging
+
+Merge Commands
+==============
+
+ Groups of common lines, with a blank gutter, are copied from the
+first file to the output. After each group of differing lines, `sdiff'
+prompts with `%' and pauses, waiting for one of the following commands.
+Follow each command with RET.
+
+`e'
+ Discard both versions. Invoke a text editor on an empty temporary
+ file, then copy the resulting file to the output.
+
+`eb'
+ Concatenate the two versions, edit the result in a temporary file,
+ then copy the edited result to the output.
+
+`el'
+ Edit a copy of the left version, then copy the result to the
+ output.
+
+`er'
+ Edit a copy of the right version, then copy the result to the
+ output.
+
+`l'
+ Copy the left version to the output.
+
+`q'
+ Quit.
+
+`r'
+ Copy the right version to the output.
+
+`s'
+ Silently copy common lines.
+
+`v'
+ Verbosely copy common lines. This is the default.
+
+ The text editor invoked is specified by the `EDITOR' environment
+variable if it is set. The default is system-dependent.
+
+
+File: diff.info, Node: Merging with patch, Next: Making Patches, Prev: Interactive Merging, Up: Top
+
+Merging with `patch'
+********************
+
+ `patch' takes comparison output produced by `diff' and applies the
+differences to a copy of the original file, producing a patched
+version. With `patch', you can distribute just the changes to a set of
+files instead of distributing the entire file set; your correspondents
+can apply `patch' to update their copy of the files with your changes.
+`patch' automatically determines the diff format, skips any leading or
+trailing headers, and uses the headers to determine which file to
+patch. This lets your correspondents feed an article or message
+containing a difference listing directly to `patch'.
+
+ `patch' detects and warns about common problems like forward
+patches. It saves the original version of the files it patches, and
+saves any patches that it could not apply. It can also maintain a
+`patchlevel.h' file to ensures that your correspondents apply diffs in
+the proper order.
+
+ `patch' accepts a series of diffs in its standard input, usually
+separated by headers that specify which file to patch. It applies
+`diff' hunks (*note Hunks::.) one by one. If a hunk does not exactly
+match the original file, `patch' uses heuristics to try to patch the
+file as well as it can. If no approximate match can be found, `patch'
+rejects the hunk and skips to the next hunk. `patch' normally replaces
+each file F with its new version, saving the original file in `F.orig',
+and putting reject hunks (if any) into `F.rej'.
+
+ *Note Invoking patch::, for detailed information on the options to
+`patch'. *Note Backups::, for more information on how `patch' names
+backup files. *Note Rejects::, for more information on where `patch'
+puts reject hunks.
+
+* Menu:
+
+* patch Input:: Selecting the type of `patch' input.
+* Imperfect:: Dealing with imperfect patches.
+* Empty Files:: Removing empty files after patching.
+* Multiple Patches:: Handling multiple patches in a file specially.
+* patch Messages:: Messages and questions `patch' can produce.
+
+
+File: diff.info, Node: patch Input, Next: Imperfect, Up: Merging with patch
+
+Selecting the `patch' Input Format
+==================================
+
+ `patch' normally determines which `diff' format the patch file uses
+by examining its contents. For patch files that contain particularly
+confusing leading text, you might need to use one of the following
+options to force `patch' to interpret the patch file as a certain
+format of diff. The output formats listed here are the only ones that
+`patch' can understand.
+
+`-c'
+`--context'
+ context diff.
+
+`-e'
+`--ed'
+ `ed' script.
+
+`-n'
+`--normal'
+ normal diff.
+
+`-u'
+`--unified'
+ unified diff.
+
+
+File: diff.info, Node: Imperfect, Next: Empty Files, Prev: patch Input, Up: Merging with patch
+
+Applying Imperfect Patches
+==========================
+
+ `patch' tries to skip any leading text in the patch file, apply the
+diff, and then skip any trailing text. Thus you can feed a news article
+or mail message directly to `patch', and it should work. If the entire
+diff is indented by a constant amount of white space, `patch'
+automatically ignores the indentation.
+
+ However, certain other types of imperfect input require user
+intervention.
+
+* Menu:
+
+* Changed White Space:: When tabs and spaces don't match exactly.
+* Reversed Patches:: Applying reversed patches correctly.
+* Inexact:: Helping `patch' find close matches.
+
+
+File: diff.info, Node: Changed White Space, Next: Reversed Patches, Up: Imperfect
+
+Applying Patches with Changed White Space
+-----------------------------------------
+
+ Sometimes mailers, editors, or other programs change spaces into
+tabs, or vice versa. If this happens to a patch file or an input file,
+the files might look the same, but `patch' will not be able to match
+them properly. If this problem occurs, use the `-l' or
+`--ignore-white-space' option, which makes `patch' compare white space
+loosely so that any sequence of white space in the patch file matches
+any sequence of white space in the input files. Non-white-space
+characters must still match exactly. Each line of the context must
+still match a line in the input file.
+
+
+File: diff.info, Node: Reversed Patches, Next: Inexact, Prev: Changed White Space, Up: Imperfect
+
+Applying Reversed Patches
+-------------------------
+
+ Sometimes people run `diff' with the new file first instead of
+second. This creates a diff that is "reversed". To apply such
+patches, give `patch' the `-R' or `--reverse' option. `patch' then
+attempts to swap each hunk around before applying it. Rejects come out
+in the swapped format. The `-R' option does not work with `ed' scripts
+because there is too little information in them to reconstruct the
+reverse operation.
+
+ Often `patch' can guess that the patch is reversed. If the first
+hunk of a patch fails, `patch' reverses the hunk to see if it can apply
+it that way. If it can, `patch' asks you if you want to have the `-R'
+option set; if it can't, `patch' continues to apply the patch normally.
+This method cannot detect a reversed patch if it is a normal diff and
+the first command is an append (which should have been a delete) since
+appends always succeed, because a null context matches anywhere. But
+most patches add or change lines rather than delete them, so most
+reversed normal diffs begin with a delete, which fails, and `patch'
+notices.
+
+ If you apply a patch that you have already applied, `patch' thinks
+it is a reversed patch and offers to un-apply the patch. This could be
+construed as a feature. If you did this inadvertently and you don't
+want to un-apply the patch, just answer `n' to this offer and to the
+subsequent "apply anyway" question--or type `C-c' to kill the `patch'
+process.
+
+
+File: diff.info, Node: Inexact, Prev: Reversed Patches, Up: Imperfect
+
+Helping `patch' Find Inexact Matches
+------------------------------------
+
+ For context diffs, and to a lesser extent normal diffs, `patch' can
+detect when the line numbers mentioned in the patch are incorrect, and
+it attempts to find the correct place to apply each hunk of the patch.
+As a first guess, it takes the line number mentioned in the hunk, plus
+or minus any offset used in applying the previous hunk. If that is not
+the correct place, `patch' scans both forward and backward for a set of
+lines matching the context given in the hunk.
+
+ First `patch' looks for a place where all lines of the context
+match. If it cannot find such a place, and it is reading a context or
+unified diff, and the maximum fuzz factor is set to 1 or more, then
+`patch' makes another scan, ignoring the first and last line of
+context. If that fails, and the maximum fuzz factor is set to 2 or
+more, it makes another scan, ignoring the first two and last two lines
+of context are ignored. It continues similarly if the maximum fuzz
+factor is larger.
+
+ The `-F LINES' or `--fuzz=LINES' option sets the maximum fuzz factor
+to LINES. This option only applies to context and unified diffs; it
+ignores up to LINES lines while looking for the place to install a
+hunk. Note that a larger fuzz factor increases the odds of making a
+faulty patch. The default fuzz factor is 2; it may not be set to more
+than the number of lines of context in the diff, ordinarily 3.
+
+ If `patch' cannot find a place to install a hunk of the patch, it
+writes the hunk out to a reject file (*note Rejects::., for information
+on how reject files are named). It writes out rejected hunks in context
+format no matter what form the input patch is in. If the input is a
+normal or `ed' diff, many of the contexts are simply null. The line
+numbers on the hunks in the reject file may be different from those in
+the patch file: they show the approximate location where `patch' thinks
+the failed hunks belong in the new file rather than in the old one.
+
+ As it completes each hunk, `patch' tells you whether the hunk
+succeeded or failed, and if it failed, on which line (in the new file)
+`patch' thinks the hunk should go. If this is different from the line
+number specified in the diff, it tells you the offset. A single large
+offset *may* indicate that `patch' installed a hunk in the wrong place.
+`patch' also tells you if it used a fuzz factor to make the match, in
+which case you should also be slightly suspicious.
+
+ `patch' cannot tell if the line numbers are off in an `ed' script,
+and can only detect wrong line numbers in a normal diff when it finds a
+change or delete command. It may have the same problem with a context
+diff using a fuzz factor equal to or greater than the number of lines
+of context shown in the diff (typically 3). In these cases, you should
+probably look at a context diff between your original and patched input
+files to see if the changes make sense. Compiling without errors is a
+pretty good indication that the patch worked, but not a guarantee.
+
+ `patch' usually produces the correct results, even when it must make
+many guesses. However, the results are guaranteed only when the patch
+is applied to an exact copy of the file that the patch was generated
+from.
+
+
+File: diff.info, Node: Empty Files, Next: Multiple Patches, Prev: Imperfect, Up: Merging with patch
+
+Removing Empty Files
+====================
+
+ Sometimes when comparing two directories, the first directory
+contains a file that the second directory does not. If you give `diff'
+the `-N' or `--new-file' option, it outputs a diff that deletes the
+contents of this file. By default, `patch' leaves an empty file after
+applying such a diff. The `-E' or `--remove-empty-files' option to
+`patch' deletes output files that are empty after applying the diff.
+
+
+File: diff.info, Node: Multiple Patches, Next: patch Messages, Prev: Empty Files, Up: Merging with patch
+
+Multiple Patches in a File
+==========================
+
+ If the patch file contains more than one patch, `patch' tries to
+apply each of them as if they came from separate patch files. This
+means that it determines the name of the file to patch for each patch,
+and that it examines the leading text before each patch for file names
+and prerequisite revision level (*note Making Patches::., for more on
+that topic).
+
+ For the second and subsequent patches in the patch file, you can give
+options and another original file name by separating their argument
+lists with a `+'. However, the argument list for a second or
+subsequent patch may not specify a new patch file, since that does not
+make sense.
+
+ For example, to tell `patch' to strip the first three slashes from
+the name of the first patch in the patch file and none from subsequent
+patches, and to use `code.c' as the first input file, you can use:
+
+ patch -p3 code.c + -p0 < patchfile
+
+ The `-S' or `--skip' option ignores the current patch from the patch
+file, but continue looking for the next patch in the file. Thus, to
+ignore the first and third patches in the patch file, you can use:
+
+ patch -S + + -S + < patch file
+
+
+File: diff.info, Node: patch Messages, Prev: Multiple Patches, Up: Merging with patch
+
+Messages and Questions from `patch'
+===================================
+
+ `patch' can produce a variety of messages, especially if it has
+trouble decoding its input. In a few situations where it's not sure how
+to proceed, `patch' normally prompts you for more information from the
+keyboard. There are options to suppress printing non-fatal messages
+and stopping for keyboard input.
+
+ The message `Hmm...' indicates that `patch' is reading text in the
+patch file, attempting to determine whether there is a patch in that
+text, and if so, what kind of patch it is.
+
+ You can inhibit all terminal output from `patch', unless an error
+occurs, by using the `-s', `--quiet', or `--silent' option.
+
+ There are two ways you can prevent `patch' from asking you any
+questions. The `-f' or `--force' option assumes that you know what you
+are doing. It assumes the following:
+
+ * skip patches that do not contain file names in their headers;
+
+ * patch files even though they have the wrong version for the
+ `Prereq:' line in the patch;
+
+ * assume that patches are not reversed even if they look like they
+ are.
+
+ The `-t' or `--batch' option is similar to `-f', in that it
+suppresses questions, but it makes somewhat different assumptions:
+
+ * skip patches that do not contain file names in their headers (the
+ same as `-f');
+
+ * skip patches for which the file has the wrong version for the
+ `Prereq:' line in the patch;
+
+ * assume that patches are reversed if they look like they are.
+
+ `patch' exits with a non-zero status if it creates any reject files.
+When applying a set of patches in a loop, you should check the exit
+status, so you don't apply a later patch to a partially patched file.
+
diff --git a/gnu/dist/diffutils/diff.info-3 b/gnu/dist/diffutils/diff.info-3
new file mode 100644
index 00000000000..71bf86972d2
--- /dev/null
+++ b/gnu/dist/diffutils/diff.info-3
@@ -0,0 +1,1327 @@
+This is Info file diff.info, produced by Makeinfo-1.55 from the input
+file ./diff.texi.
+
+ This file documents the the GNU `diff', `diff3', `sdiff', and `cmp'
+commands for showing the differences between text files and the `patch'
+command for using their output to update files.
+
+ Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+
+ Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+ Permission is granted to copy and distribute modified versions of
+this manual under the conditions for verbatim copying, provided that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+ Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be stated in a
+translation approved by the Foundation.
+
+
+File: diff.info, Node: Making Patches, Next: Invoking cmp, Prev: Merging with patch, Up: Top
+
+Tips for Making Patch Distributions
+***********************************
+
+ Here are some things you should keep in mind if you are going to
+distribute patches for updating a software package.
+
+ Make sure you have specified the file names correctly, either in a
+context diff header or with an `Index:' line. If you are patching
+files in a subdirectory, be sure to tell the patch user to specify a
+`-p' or `--strip' option as needed. Take care to not send out reversed
+patches, since these make people wonder whether they have already
+applied the patch.
+
+ To save people from partially applying a patch before other patches
+that should have gone before it, you can make the first patch in the
+patch file update a file with a name like `patchlevel.h' or
+`version.c', which contains a patch level or version number. If the
+input file contains the wrong version number, `patch' will complain
+immediately.
+
+ An even clearer way to prevent this problem is to put a `Prereq:'
+line before the patch. If the leading text in the patch file contains a
+line that starts with `Prereq:', `patch' takes the next word from that
+line (normally a version number) and checks whether the next input file
+contains that word, preceded and followed by either white space or a
+newline. If not, `patch' prompts you for confirmation before
+proceeding. This makes it difficult to accidentally apply patches in
+the wrong order.
+
+ Since `patch' does not handle incomplete lines properly, make sure
+that all the source files in your program end with a newline whenever
+you release a version.
+
+ To create a patch that changes an older version of a package into a
+newer version, first make a copy of the older version in a scratch
+directory. Typically you do that by unpacking a `tar' or `shar'
+archive of the older version.
+
+ You might be able to reduce the size of the patch by renaming or
+removing some files before making the patch. If the older version of
+the package contains any files that the newer version does not, or if
+any files have been renamed between the two versions, make a list of
+`rm' and `mv' commands for the user to execute in the old version
+directory before applying the patch. Then run those commands yourself
+in the scratch directory.
+
+ If there are any files that you don't need to include in the patch
+because they can easily be rebuilt from other files (for example,
+`TAGS' and output from `yacc' and `makeinfo'), replace the versions in
+the scratch directory with the newer versions, using `rm' and `ln' or
+`cp'.
+
+ Now you can create the patch. The de-facto standard `diff' format
+for patch distributions is context format with two lines of context,
+produced by giving `diff' the `-C 2' option. Do not use less than two
+lines of context, because `patch' typically needs at least two lines
+for proper operation. Give `diff' the `-P' option in case the newer
+version of the package contains any files that the older one does not.
+Make sure to specify the scratch directory first and the newer
+directory second.
+
+ Add to the top of the patch a note telling the user any `rm' and
+`mv' commands to run before applying the patch. Then you can remove
+the scratch directory.
+
+
+File: diff.info, Node: Invoking cmp, Next: Invoking diff, Prev: Making Patches, Up: Top
+
+Invoking `cmp'
+**************
+
+ The `cmp' command compares two files, and if they differ, tells the
+first byte and line number where they differ. Its arguments are as
+follows:
+
+ cmp OPTIONS... FROM-FILE [TO-FILE]
+
+ The file name `-' is always the standard input. `cmp' also uses the
+standard input if one file name is omitted.
+
+ An exit status of 0 means no differences were found, 1 means some
+differences were found, and 2 means trouble.
+
+* Menu:
+
+* cmp Options:: Summary of options to `cmp'.
+
+
+File: diff.info, Node: cmp Options, Up: Invoking cmp
+
+Options to `cmp'
+================
+
+ Below is a summary of all of the options that GNU `cmp' accepts.
+Most options have two equivalent names, one of which is a single letter
+preceded by `-', and the other of which is a long name preceded by
+`--'. Multiple single letter options (unless they take an argument)
+can be combined into a single command line word: `-cl' is equivalent to
+`-c -l'.
+
+`-c'
+ Print the differing characters. Display control characters as a
+ `^' followed by a letter of the alphabet and precede characters
+ that have the high bit set with `M-' (which stands for "meta").
+
+`--ignore-initial=BYTES'
+ Ignore any differences in the the first BYTES bytes of the input
+ files. Treat files with fewer than BYTES bytes as if they are
+ empty.
+
+`-l'
+ Print the (decimal) offsets and (octal) values of all differing
+ bytes.
+
+`--print-chars'
+ Print the differing characters. Display control characters as a
+ `^' followed by a letter of the alphabet and precede characters
+ that have the high bit set with `M-' (which stands for "meta").
+
+`--quiet'
+`-s'
+`--silent'
+ Do not print anything; only return an exit status indicating
+ whether the files differ.
+
+`--verbose'
+ Print the (decimal) offsets and (octal) values of all differing
+ bytes.
+
+`-v'
+`--version'
+ Output the version number of `cmp'.
+
+
+File: diff.info, Node: Invoking diff, Next: Invoking diff3, Prev: Invoking cmp, Up: Top
+
+Invoking `diff'
+***************
+
+ The format for running the `diff' command is:
+
+ diff OPTIONS... FROM-FILE TO-FILE
+
+ In the simplest case, `diff' compares the contents of the two files
+FROM-FILE and TO-FILE. A file name of `-' stands for text read from
+the standard input. As a special case, `diff - -' compares a copy of
+standard input to itself.
+
+ If FROM-FILE is a directory and TO-FILE is not, `diff' compares the
+file in FROM-FILE whose file name is that of TO-FILE, and vice versa.
+The non-directory file must not be `-'.
+
+ If both FROM-FILE and TO-FILE are directories, `diff' compares
+corresponding files in both directories, in alphabetical order; this
+comparison is not recursive unless the `-r' or `--recursive' option is
+given. `diff' never compares the actual contents of a directory as if
+it were a file. The file that is fully specified may not be standard
+input, because standard input is nameless and the notion of "file with
+the same name" does not apply.
+
+ `diff' options begin with `-', so normally FROM-FILE and TO-FILE may
+not begin with `-'. However, `--' as an argument by itself treats the
+remaining arguments as file names even if they begin with `-'.
+
+ An exit status of 0 means no differences were found, 1 means some
+differences were found, and 2 means trouble.
+
+* Menu:
+
+* diff Options:: Summary of options to `diff'.
+
+
+File: diff.info, Node: diff Options, Up: Invoking diff
+
+Options to `diff'
+=================
+
+ Below is a summary of all of the options that GNU `diff' accepts.
+Most options have two equivalent names, one of which is a single letter
+preceded by `-', and the other of which is a long name preceded by
+`--'. Multiple single letter options (unless they take an argument)
+can be combined into a single command line word: `-ac' is equivalent to
+`-a -c'. Long named options can be abbreviated to any unique prefix of
+their name. Brackets ([ and ]) indicate that an option takes an
+optional argument.
+
+`-LINES'
+ Show LINES (an integer) lines of context. This option does not
+ specify an output format by itself; it has no effect unless it is
+ combined with `-c' (*note Context Format::.) or `-u' (*note
+ Unified Format::.). This option is obsolete. For proper
+ operation, `patch' typically needs at least two lines of context.
+
+`-a'
+ Treat all files as text and compare them line-by-line, even if they
+ do not seem to be text. *Note Binary::.
+
+`-b'
+ Ignore changes in amount of white space. *Note White Space::.
+
+`-B'
+ Ignore changes that just insert or delete blank lines. *Note
+ Blank Lines::.
+
+`--binary'
+ Read and write data in binary mode. *Note Binary::.
+
+`--brief'
+ Report only whether the files differ, not the details of the
+ differences. *Note Brief::.
+
+`-c'
+ Use the context output format. *Note Context Format::.
+
+`-C LINES'
+`--context[=LINES]'
+ Use the context output format, showing LINES (an integer) lines of
+ context, or three if LINES is not given. *Note Context Format::.
+ For proper operation, `patch' typically needs at least two lines of
+ context.
+
+`--changed-group-format=FORMAT'
+ Use FORMAT to output a line group containing differing lines from
+ both files in if-then-else format. *Note Line Group Formats::.
+
+`-d'
+ Change the algorithm perhaps find a smaller set of changes. This
+ makes `diff' slower (sometimes much slower). *Note diff
+ Performance::.
+
+`-D NAME'
+ Make merged `#ifdef' format output, conditional on the preprocessor
+ macro NAME. *Note If-then-else::.
+
+`-e'
+`--ed'
+ Make output that is a valid `ed' script. *Note ed Scripts::.
+
+`--exclude=PATTERN'
+ When comparing directories, ignore files and subdirectories whose
+ basenames match PATTERN. *Note Comparing Directories::.
+
+`--exclude-from=FILE'
+ When comparing directories, ignore files and subdirectories whose
+ basenames match any pattern contained in FILE. *Note Comparing
+ Directories::.
+
+`--expand-tabs'
+ Expand tabs to spaces in the output, to preserve the alignment of
+ tabs in the input files. *Note Tabs::.
+
+`-f'
+ Make output that looks vaguely like an `ed' script but has changes
+ in the order they appear in the file. *Note Forward ed::.
+
+`-F REGEXP'
+ In context and unified format, for each hunk of differences, show
+ some of the last preceding line that matches REGEXP. *Note
+ Specified Headings::.
+
+`--forward-ed'
+ Make output that looks vaguely like an `ed' script but has changes
+ in the order they appear in the file. *Note Forward ed::.
+
+`-h'
+ This option currently has no effect; it is present for Unix
+ compatibility.
+
+`-H'
+ Use heuristics to speed handling of large files that have numerous
+ scattered small changes. *Note diff Performance::.
+
+`--horizon-lines=LINES'
+ Do not discard the last LINES lines of the common prefix and the
+ first LINES lines of the common suffix. *Note diff Performance::.
+
+`-i'
+ Ignore changes in case; consider upper- and lower-case letters
+ equivalent. *Note Case Folding::.
+
+`-I REGEXP'
+ Ignore changes that just insert or delete lines that match REGEXP.
+ *Note Specified Folding::.
+
+`--ifdef=NAME'
+ Make merged if-then-else output using NAME. *Note If-then-else::.
+
+`--ignore-all-space'
+ Ignore white space when comparing lines. *Note White Space::.
+
+`--ignore-blank-lines'
+ Ignore changes that just insert or delete blank lines. *Note
+ Blank Lines::.
+
+`--ignore-case'
+ Ignore changes in case; consider upper- and lower-case to be the
+ same. *Note Case Folding::.
+
+`--ignore-matching-lines=REGEXP'
+ Ignore changes that just insert or delete lines that match REGEXP.
+ *Note Specified Folding::.
+
+`--ignore-space-change'
+ Ignore changes in amount of white space. *Note White Space::.
+
+`--initial-tab'
+ Output a tab rather than a space before the text of a line in
+ normal or context format. This causes the alignment of tabs in
+ the line to look normal. *Note Tabs::.
+
+`-l'
+ Pass the output through `pr' to paginate it. *Note Pagination::.
+
+`-L LABEL'
+ Use LABEL instead of the file name in the context format (*note
+ Context Format::.) and unified format (*note Unified Format::.)
+ headers. *Note RCS::.
+
+`--label=LABEL'
+ Use LABEL instead of the file name in the context format (*note
+ Context Format::.) and unified format (*note Unified Format::.)
+ headers.
+
+`--left-column'
+ Print only the left column of two common lines in side by side
+ format. *Note Side by Side Format::.
+
+`--line-format=FORMAT'
+ Use FORMAT to output all input lines in if-then-else format.
+ *Note Line Formats::.
+
+`--minimal'
+ Change the algorithm to perhaps find a smaller set of changes.
+ This makes `diff' slower (sometimes much slower). *Note diff
+ Performance::.
+
+`-n'
+ Output RCS-format diffs; like `-f' except that each command
+ specifies the number of lines affected. *Note RCS::.
+
+`-N'
+`--new-file'
+ In directory comparison, if a file is found in only one directory,
+ treat it as present but empty in the other directory. *Note
+ Comparing Directories::.
+
+`--new-group-format=FORMAT'
+ Use FORMAT to output a group of lines taken from just the second
+ file in if-then-else format. *Note Line Group Formats::.
+
+`--new-line-format=FORMAT'
+ Use FORMAT to output a line taken from just the second file in
+ if-then-else format. *Note Line Formats::.
+
+`--old-group-format=FORMAT'
+ Use FORMAT to output a group of lines taken from just the first
+ file in if-then-else format. *Note Line Group Formats::.
+
+`--old-line-format=FORMAT'
+ Use FORMAT to output a line taken from just the first file in
+ if-then-else format. *Note Line Formats::.
+
+`-p'
+ Show which C function each change is in. *Note C Function
+ Headings::.
+
+`-P'
+ When comparing directories, if a file appears only in the second
+ directory of the two, treat it as present but empty in the other.
+ *Note Comparing Directories::.
+
+`--paginate'
+ Pass the output through `pr' to paginate it. *Note Pagination::.
+
+`-q'
+ Report only whether the files differ, not the details of the
+ differences. *Note Brief::.
+
+`-r'
+ When comparing directories, recursively compare any subdirectories
+ found. *Note Comparing Directories::.
+
+`--rcs'
+ Output RCS-format diffs; like `-f' except that each command
+ specifies the number of lines affected. *Note RCS::.
+
+`--recursive'
+ When comparing directories, recursively compare any subdirectories
+ found. *Note Comparing Directories::.
+
+`--report-identical-files'
+ Report when two files are the same. *Note Comparing Directories::.
+
+`-s'
+ Report when two files are the same. *Note Comparing Directories::.
+
+`-S FILE'
+ When comparing directories, start with the file FILE. This is
+ used for resuming an aborted comparison. *Note Comparing
+ Directories::.
+
+`--sdiff-merge-assist'
+ Print extra information to help `sdiff'. `sdiff' uses this option
+ when it runs `diff'. This option is not intended for users to use
+ directly.
+
+`--show-c-function'
+ Show which C function each change is in. *Note C Function
+ Headings::.
+
+`--show-function-line=REGEXP'
+ In context and unified format, for each hunk of differences, show
+ some of the last preceding line that matches REGEXP. *Note
+ Specified Headings::.
+
+`--side-by-side'
+ Use the side by side output format. *Note Side by Side Format::.
+
+`--speed-large-files'
+ Use heuristics to speed handling of large files that have numerous
+ scattered small changes. *Note diff Performance::.
+
+`--starting-file=FILE'
+ When comparing directories, start with the file FILE. This is
+ used for resuming an aborted comparison. *Note Comparing
+ Directories::.
+
+`--suppress-common-lines'
+ Do not print common lines in side by side format. *Note Side by
+ Side Format::.
+
+`-t'
+ Expand tabs to spaces in the output, to preserve the alignment of
+ tabs in the input files. *Note Tabs::.
+
+`-T'
+ Output a tab rather than a space before the text of a line in
+ normal or context format. This causes the alignment of tabs in
+ the line to look normal. *Note Tabs::.
+
+`--text'
+ Treat all files as text and compare them line-by-line, even if they
+ do not appear to be text. *Note Binary::.
+
+`-u'
+ Use the unified output format. *Note Unified Format::.
+
+`--unchanged-group-format=FORMAT'
+ Use FORMAT to output a group of common lines taken from both files
+ in if-then-else format. *Note Line Group Formats::.
+
+`--unchanged-line-format=FORMAT'
+ Use FORMAT to output a line common to both files in if-then-else
+ format. *Note Line Formats::.
+
+`--unidirectional-new-file'
+ When comparing directories, if a file appears only in the second
+ directory of the two, treat it as present but empty in the other.
+ *Note Comparing Directories::.
+
+`-U LINES'
+`--unified[=LINES]'
+ Use the unified output format, showing LINES (an integer) lines of
+ context, or three if LINES is not given. *Note Unified Format::.
+ For proper operation, `patch' typically needs at least two lines of
+ context.
+
+`-v'
+`--version'
+ Output the version number of `diff'.
+
+`-w'
+ Ignore white space when comparing lines. *Note White Space::.
+
+`-W COLUMNS'
+`--width=COLUMNS'
+ Use an output width of COLUMNS in side by side format. *Note Side
+ by Side Format::.
+
+`-x PATTERN'
+ When comparing directories, ignore files and subdirectories whose
+ basenames match PATTERN. *Note Comparing Directories::.
+
+`-X FILE'
+ When comparing directories, ignore files and subdirectories whose
+ basenames match any pattern contained in FILE. *Note Comparing
+ Directories::.
+
+`-y'
+ Use the side by side output format. *Note Side by Side Format::.
+
+
+File: diff.info, Node: Invoking diff3, Next: Invoking patch, Prev: Invoking diff, Up: Top
+
+Invoking `diff3'
+****************
+
+ The `diff3' command compares three files and outputs descriptions of
+their differences. Its arguments are as follows:
+
+ diff3 OPTIONS... MINE OLDER YOURS
+
+ The files to compare are MINE, OLDER, and YOURS. At most one of
+these three file names may be `-', which tells `diff3' to read the
+standard input for that file.
+
+ An exit status of 0 means `diff3' was successful, 1 means some
+conflicts were found, and 2 means trouble.
+
+* Menu:
+
+* diff3 Options:: Summary of options to `diff3'.
+
+
+File: diff.info, Node: diff3 Options, Up: Invoking diff3
+
+Options to `diff3'
+==================
+
+ Below is a summary of all of the options that GNU `diff3' accepts.
+Multiple single letter options (unless they take an argument) can be
+combined into a single command line argument.
+
+`-a'
+ Treat all files as text and compare them line-by-line, even if they
+ do not appear to be text. *Note Binary::.
+
+`-A'
+ Incorporate all changes from OLDER to YOURS into MINE, surrounding
+ all conflicts with bracket lines. *Note Marking Conflicts::.
+
+`-e'
+ Generate an `ed' script that incorporates all the changes from
+ OLDER to YOURS into MINE. *Note Which Changes::.
+
+`-E'
+ Like `-e', except bracket lines from overlapping changes' first
+ and third files. *Note Marking Conflicts::. With `-e', an
+ overlapping change looks like this:
+
+ <<<<<<< MINE
+ lines from MINE
+ =======
+ lines from YOURS
+ >>>>>>> YOURS
+
+`--ed'
+ Generate an `ed' script that incorporates all the changes from
+ OLDER to YOURS into MINE. *Note Which Changes::.
+
+`--easy-only'
+ Like `-e', except output only the nonoverlapping changes. *Note
+ Which Changes::.
+
+`-i'
+ Generate `w' and `q' commands at the end of the `ed' script for
+ System V compatibility. This option must be combined with one of
+ the `-AeExX3' options, and may not be combined with `-m'. *Note
+ Saving the Changed File::.
+
+`--initial-tab'
+ Output a tab rather than two spaces before the text of a line in
+ normal format. This causes the alignment of tabs in the line to
+ look normal. *Note Tabs::.
+
+`-L LABEL'
+`--label=LABEL'
+ Use the label LABEL for the brackets output by the `-A', `-E' and
+ `-X' options. This option may be given up to three times, one for
+ each input file. The default labels are the names of the input
+ files. Thus `diff3 -L X -L Y -L Z -m A B C' acts like `diff3 -m A
+ B C', except that the output looks like it came from files named
+ `X', `Y' and `Z' rather than from files named `A', `B' and `C'.
+ *Note Marking Conflicts::.
+
+`-m'
+`--merge'
+ Apply the edit script to the first file and send the result to
+ standard output. Unlike piping the output from `diff3' to `ed',
+ this works even for binary files and incomplete lines. `-A' is
+ assumed if no edit script option is specified. *Note Bypassing
+ ed::.
+
+`--overlap-only'
+ Like `-e', except output only the overlapping changes. *Note
+ Which Changes::.
+
+`--show-all'
+ Incorporate all unmerged changes from OLDER to YOURS into MINE,
+ surrounding all overlapping changes with bracket lines. *Note
+ Marking Conflicts::.
+
+`--show-overlap'
+ Like `-e', except bracket lines from overlapping changes' first
+ and third files. *Note Marking Conflicts::.
+
+`-T'
+ Output a tab rather than two spaces before the text of a line in
+ normal format. This causes the alignment of tabs in the line to
+ look normal. *Note Tabs::.
+
+`--text'
+ Treat all files as text and compare them line-by-line, even if they
+ do not appear to be text. *Note Binary::.
+
+`-v'
+`--version'
+ Output the version number of `diff3'.
+
+`-x'
+ Like `-e', except output only the overlapping changes. *Note
+ Which Changes::.
+
+`-X'
+ Like `-E', except output only the overlapping changes. In other
+ words, like `-x', except bracket changes as in `-E'. *Note
+ Marking Conflicts::.
+
+`-3'
+ Like `-e', except output only the nonoverlapping changes. *Note
+ Which Changes::.
+
+
+File: diff.info, Node: Invoking patch, Next: Invoking sdiff, Prev: Invoking diff3, Up: Top
+
+Invoking `patch'
+****************
+
+ Normally `patch' is invoked like this:
+
+ patch <PATCHFILE
+
+ The full format for invoking `patch' is:
+
+ patch OPTIONS... [ORIGFILE [PATCHFILE]] [+ OPTIONS... [ORIGFILE]]...
+
+ If you do not specify PATCHFILE, or if PATCHFILE is `-', `patch'
+reads the patch (that is, the `diff' output) from the standard input.
+
+ You can specify one or more of the original files as ORIG arguments;
+each one and options for interpreting it is separated from the others
+with a `+'. *Note Multiple Patches::, for more information.
+
+ If you do not specify an input file on the command line, `patch'
+tries to figure out from the "leading text" (any text in the patch that
+comes before the `diff' output) which file to edit. In the header of a
+context or unified diff, `patch' looks in lines beginning with `***',
+`---', or `+++'; among those, it chooses the shortest name of an
+existing file. Otherwise, if there is an `Index:' line in the leading
+text, `patch' tries to use the file name from that line. If `patch'
+cannot figure out the name of an existing file from the leading text,
+it prompts you for the name of the file to patch.
+
+ If the input file does not exist or is read-only, and a suitable RCS
+or SCCS file exists, `patch' attempts to check out or get the file
+before proceeding.
+
+ By default, `patch' replaces the original input file with the
+patched version, after renaming the original file into a backup file
+(*note Backups::., for a description of how `patch' names backup
+files). You can also specify where to put the output with the `-o
+OUTPUT-FILE' or `--output=OUTPUT-FILE' option.
+
+* Menu:
+
+* patch Directories:: Changing directory and stripping directories.
+* Backups:: Backup file names.
+* Rejects:: Reject file names.
+* patch Options:: Summary table of options to `patch'.
+
+
+File: diff.info, Node: patch Directories, Next: Backups, Up: Invoking patch
+
+Applying Patches in Other Directories
+=====================================
+
+ The `-d DIRECTORY' or `--directory=DIRECTORY' option to `patch'
+makes directory DIRECTORY the current directory for interpreting both
+file names in the patch file, and file names given as arguments to
+other options (such as `-B' and `-o'). For example, while in a news
+reading program, you can patch a file in the `/usr/src/emacs' directory
+directly from the article containing the patch like this:
+
+ | patch -d /usr/src/emacs
+
+ Sometimes the file names given in a patch contain leading
+directories, but you keep your files in a directory different from the
+one given in the patch. In those cases, you can use the `-p[NUMBER]'
+or `--strip[=NUMBER]' option to set the file name strip count to
+NUMBER. The strip count tells `patch' how many slashes, along with the
+directory names between them, to strip from the front of file names.
+`-p' with no NUMBER given is equivalent to `-p0'. By default, `patch'
+strips off all leading directories, leaving just the base file names,
+except that when a file name given in the patch is a relative file name
+and all of its leading directories already exist, `patch' does not
+strip off the leading directory. (A "relative" file name is one that
+does not start with a slash.)
+
+ `patch' looks for each file (after any slashes have been stripped)
+in the current directory, or if you used the `-d DIRECTORY' option, in
+that directory.
+
+ For example, suppose the file name in the patch file is
+`/gnu/src/emacs/etc/NEWS'. Using `-p' or `-p0' gives the entire file
+name unmodified, `-p1' gives `gnu/src/emacs/etc/NEWS' (no leading
+slash), `-p4' gives `etc/NEWS', and not specifying `-p' at all gives
+`NEWS'.
+
+
+File: diff.info, Node: Backups, Next: Rejects, Prev: patch Directories, Up: Invoking patch
+
+Backup File Names
+=================
+
+ Normally, `patch' renames an original input file into a backup file
+by appending to its name the extension `.orig', or `~' on systems that
+do not support long file names. The `-b BACKUP-SUFFIX' or
+`--suffix=BACKUP-SUFFIX' option uses BACKUP-SUFFIX as the backup
+extension instead.
+
+ Alternately, you can specify the extension for backup files with the
+`SIMPLE_BACKUP_SUFFIX' environment variable, which the options override.
+
+ `patch' can also create numbered backup files the way GNU Emacs
+does. With this method, instead of having a single backup of each file,
+`patch' makes a new backup file name each time it patches a file. For
+example, the backups of a file named `sink' would be called,
+successively, `sink.~1~', `sink.~2~', `sink.~3~', etc.
+
+ The `-V BACKUP-STYLE' or `--version-control=BACKUP-STYLE' option
+takes as an argument a method for creating backup file names. You can
+alternately control the type of backups that `patch' makes with the
+`VERSION_CONTROL' environment variable, which the `-V' option
+overrides. The value of the `VERSION_CONTROL' environment variable and
+the argument to the `-V' option are like the GNU Emacs
+`version-control' variable (*note emacs: Backups., for more information
+on backup versions in Emacs). They also recognize synonyms that are
+more descriptive. The valid values are listed below; unique
+abbreviations are acceptable.
+
+`t'
+`numbered'
+ Always make numbered backups.
+
+`nil'
+`existing'
+ Make numbered backups of files that already have them, simple
+ backups of the others. This is the default.
+
+`never'
+`simple'
+ Always make simple backups.
+
+ Alternately, you can tell `patch' to prepend a prefix, such as a
+directory name, to produce backup file names. The `-B BACKUP-PREFIX'
+or `--prefix=BACKUP-PREFIX' option makes backup files by prepending
+BACKUP-PREFIX to them. If you use this option, `patch' ignores any
+`-b' option that you give.
+
+ If the backup file already exists, `patch' creates a new backup file
+name by changing the first lowercase letter in the last component of
+the file name into uppercase. If there are no more lowercase letters
+in the name, it removes the first character from the name. It repeats
+this process until it comes up with a backup file name that does not
+already exist.
+
+ If you specify the output file with the `-o' option, that file is
+the one that is backed up, not the input file.
+
+
+File: diff.info, Node: Rejects, Next: patch Options, Prev: Backups, Up: Invoking patch
+
+Reject File Names
+=================
+
+ The names for reject files (files containing patches that `patch'
+could not find a place to apply) are normally the name of the output
+file with `.rej' appended (or `#' on systems that do not support long
+file names).
+
+ Alternatively, you can tell `patch' to place all of the rejected
+patches in a single file. The `-r REJECT-FILE' or
+`--reject-file=REJECT-FILE' option uses REJECT-FILE as the reject file
+name.
+
+
+File: diff.info, Node: patch Options, Prev: Rejects, Up: Invoking patch
+
+Options to `patch'
+==================
+
+ Here is a summary of all of the options that `patch' accepts. Older
+versions of `patch' do not accept long-named options or the `-t', `-E',
+or `-V' options.
+
+ Multiple single-letter options that do not take an argument can be
+combined into a single command line argument (with only one dash).
+Brackets ([ and ]) indicate that an option takes an optional argument.
+
+`-b BACKUP-SUFFIX'
+ Use BACKUP-SUFFIX as the backup extension instead of `.orig' or
+ `~'. *Note Backups::.
+
+`-B BACKUP-PREFIX'
+ Use BACKUP-PREFIX as a prefix to the backup file name. If this
+ option is specified, any `-b' option is ignored. *Note Backups::.
+
+`--batch'
+ Do not ask any questions. *Note patch Messages::.
+
+`-c'
+`--context'
+ Interpret the patch file as a context diff. *Note patch Input::.
+
+`-d DIRECTORY'
+`--directory=DIRECTORY'
+ Makes directory DIRECTORY the current directory for interpreting
+ both file names in the patch file, and file names given as
+ arguments to other options. *Note patch Directories::.
+
+`-D NAME'
+ Make merged if-then-else output using FORMAT. *Note
+ If-then-else::.
+
+`--debug=NUMBER'
+ Set internal debugging flags. Of interest only to `patch'
+ patchers.
+
+`-e'
+`--ed'
+ Interpret the patch file as an `ed' script. *Note patch Input::.
+
+`-E'
+ Remove output files that are empty after the patches have been
+ applied. *Note Empty Files::.
+
+`-f'
+ Assume that the user knows exactly what he or she is doing, and do
+ not ask any questions. *Note patch Messages::.
+
+`-F LINES'
+ Set the maximum fuzz factor to LINES. *Note Inexact::.
+
+`--force'
+ Assume that the user knows exactly what he or she is doing, and do
+ not ask any questions. *Note patch Messages::.
+
+`--forward'
+ Ignore patches that `patch' thinks are reversed or already applied.
+ See also `-R'. *Note Reversed Patches::.
+
+`--fuzz=LINES'
+ Set the maximum fuzz factor to LINES. *Note Inexact::.
+
+`--help'
+ Print a summary of the options that `patch' recognizes, then exit.
+
+`--ifdef=NAME'
+ Make merged if-then-else output using FORMAT. *Note
+ If-then-else::.
+
+`--ignore-white-space'
+`-l'
+ Let any sequence of white space in the patch file match any
+ sequence of white space in the input file. *Note Changed White
+ Space::.
+
+`-n'
+`--normal'
+ Interpret the patch file as a normal diff. *Note patch Input::.
+
+`-N'
+ Ignore patches that `patch' thinks are reversed or already applied.
+ See also `-R'. *Note Reversed Patches::.
+
+`-o OUTPUT-FILE'
+`--output=OUTPUT-FILE'
+ Use OUTPUT-FILE as the output file name. *Note patch Options::.
+
+`-p[NUMBER]'
+ Set the file name strip count to NUMBER. *Note patch
+ Directories::.
+
+`--prefix=BACKUP-PREFIX'
+ Use BACKUP-PREFIX as a prefix to the backup file name. If this
+ option is specified, any `-b' option is ignored. *Note Backups::.
+
+`--quiet'
+ Work silently unless an error occurs. *Note patch Messages::.
+
+`-r REJECT-FILE'
+ Use REJECT-FILE as the reject file name. *Note Rejects::.
+
+`-R'
+ Assume that this patch was created with the old and new files
+ swapped. *Note Reversed Patches::.
+
+`--reject-file=REJECT-FILE'
+ Use REJECT-FILE as the reject file name. *Note Rejects::.
+
+`--remove-empty-files'
+ Remove output files that are empty after the patches have been
+ applied. *Note Empty Files::.
+
+`--reverse'
+ Assume that this patch was created with the old and new files
+ swapped. *Note Reversed Patches::.
+
+`-s'
+ Work silently unless an error occurs. *Note patch Messages::.
+
+`-S'
+ Ignore this patch from the patch file, but continue looking for
+ the next patch in the file. *Note Multiple Patches::.
+
+`--silent'
+ Work silently unless an error occurs. *Note patch Messages::.
+
+`--skip'
+ Ignore this patch from the patch file, but continue looking for
+ the next patch in the file. *Note Multiple Patches::.
+
+`--strip[=NUMBER]'
+ Set the file name strip count to NUMBER. *Note patch
+ Directories::.
+
+`--suffix=BACKUP-SUFFIX'
+ Use BACKUP-SUFFIX as the backup extension instead of `.orig' or
+ `~'. *Note Backups::.
+
+`-t'
+ Do not ask any questions. *Note patch Messages::.
+
+`-u'
+`--unified'
+ Interpret the patch file as a unified diff. *Note patch Input::.
+
+`-v'
+ Output the revision header and patch level of `patch'.
+
+`-V BACKUP-STYLE'
+ Select the kind of backups to make. *Note Backups::.
+
+`--version'
+ Output the revision header and patch level of `patch', then exit.
+
+`--version=control=BACKUP-STYLE'
+ Select the kind of backups to make. *Note Backups::.
+
+`-x NUMBER'
+ Set internal debugging flags. Of interest only to `patch'
+ patchers.
+
+
+File: diff.info, Node: Invoking sdiff, Next: Incomplete Lines, Prev: Invoking patch, Up: Top
+
+Invoking `sdiff'
+****************
+
+ The `sdiff' command merges two files and interactively outputs the
+results. Its arguments are as follows:
+
+ sdiff -o OUTFILE OPTIONS... FROM-FILE TO-FILE
+
+ This merges FROM-FILE with TO-FILE, with output to OUTFILE. If
+FROM-FILE is a directory and TO-FILE is not, `sdiff' compares the file
+in FROM-FILE whose file name is that of TO-FILE, and vice versa.
+fROM-FILE and TO-FILE may not both be directories.
+
+ `sdiff' options begin with `-', so normally FROM-FILE and TO-FILE
+may not begin with `-'. However, `--' as an argument by itself treats
+the remaining arguments as file names even if they begin with `-'. You
+may not use `-' as an input file.
+
+ An exit status of 0 means no differences were found, 1 means some
+differences were found, and 2 means trouble.
+
+ `sdiff' without `-o' (or `--output') produces a side-by-side
+difference. This usage is obsolete; use `diff --side-by-side' instead.
+
+* Menu:
+
+* sdiff Options:: Summary of options to `diff'.
+
+
+File: diff.info, Node: sdiff Options, Up: Invoking sdiff
+
+Options to `sdiff'
+==================
+
+ Below is a summary of all of the options that GNU `sdiff' accepts.
+Each option has two equivalent names, one of which is a single letter
+preceded by `-', and the other of which is a long name preceded by
+`--'. Multiple single letter options (unless they take an argument)
+can be combined into a single command line argument. Long named
+options can be abbreviated to any unique prefix of their name.
+
+`-a'
+ Treat all files as text and compare them line-by-line, even if they
+ do not appear to be text. *Note Binary::.
+
+`-b'
+ Ignore changes in amount of white space. *Note White Space::.
+
+`-B'
+ Ignore changes that just insert or delete blank lines. *Note
+ Blank Lines::.
+
+`-d'
+ Change the algorithm to perhaps find a smaller set of changes.
+ This makes `sdiff' slower (sometimes much slower). *Note diff
+ Performance::.
+
+`-H'
+ Use heuristics to speed handling of large files that have numerous
+ scattered small changes. *Note diff Performance::.
+
+`--expand-tabs'
+ Expand tabs to spaces in the output, to preserve the alignment of
+ tabs in the input files. *Note Tabs::.
+
+`-i'
+ Ignore changes in case; consider upper- and lower-case to be the
+ same. *Note Case Folding::.
+
+`-I REGEXP'
+ Ignore changes that just insert or delete lines that match REGEXP.
+ *Note Specified Folding::.
+
+`--ignore-all-space'
+ Ignore white space when comparing lines. *Note White Space::.
+
+`--ignore-blank-lines'
+ Ignore changes that just insert or delete blank lines. *Note
+ Blank Lines::.
+
+`--ignore-case'
+ Ignore changes in case; consider upper- and lower-case to be the
+ same. *Note Case Folding::.
+
+`--ignore-matching-lines=REGEXP'
+ Ignore changes that just insert or delete lines that match REGEXP.
+ *Note Specified Folding::.
+
+`--ignore-space-change'
+ Ignore changes in amount of white space. *Note White Space::.
+
+`-l'
+`--left-column'
+ Print only the left column of two common lines. *Note Side by
+ Side Format::.
+
+`--minimal'
+ Change the algorithm to perhaps find a smaller set of changes.
+ This makes `sdiff' slower (sometimes much slower). *Note diff
+ Performance::.
+
+`-o FILE'
+`--output=FILE'
+ Put merged output into FILE. This option is required for merging.
+
+`-s'
+`--suppress-common-lines'
+ Do not print common lines. *Note Side by Side Format::.
+
+`--speed-large-files'
+ Use heuristics to speed handling of large files that have numerous
+ scattered small changes. *Note diff Performance::.
+
+`-t'
+ Expand tabs to spaces in the output, to preserve the alignment of
+ tabs in the input files. *Note Tabs::.
+
+`--text'
+ Treat all files as text and compare them line-by-line, even if they
+ do not appear to be text. *Note Binary::.
+
+`-v'
+`--version'
+ Output the version number of `sdiff'.
+
+`-w COLUMNS'
+`--width=COLUMNS'
+ Use an output width of COLUMNS. *Note Side by Side Format::.
+ Note that for historical reasons, this option is `-W' in `diff',
+ `-w' in `sdiff'.
+
+`-W'
+ Ignore horizontal white space when comparing lines. *Note White
+ Space::. Note that for historical reasons, this option is `-w' in
+ `diff', `-W' in `sdiff'.
+
+
+File: diff.info, Node: Incomplete Lines, Next: Projects, Prev: Invoking sdiff, Up: Top
+
+Incomplete Lines
+****************
+
+ When an input file ends in a non-newline character, its last line is
+called an "incomplete line" because its last character is not a
+newline. All other lines are called "full lines" and end in a newline
+character. Incomplete lines do not match full lines unless differences
+in white space are ignored (*note White Space::.).
+
+ An incomplete line is normally distinguished on output from a full
+line by a following line that starts with `\'. However, the RCS format
+(*note RCS::.) outputs the incomplete line as-is, without any trailing
+newline or following line. The side by side format normally represents
+incomplete lines as-is, but in some cases uses a `\' or `/' gutter
+marker; *Note Side by Side::. The if-then-else line format preserves a
+line's incompleteness with `%L', and discards the newline with `%l';
+*Note Line Formats::. Finally, with the `ed' and forward `ed' output
+formats (*note Output Formats::.) `diff' cannot represent an incomplete
+line, so it pretends there was a newline and reports an error.
+
+ For example, suppose `F' and `G' are one-byte files that contain
+just `f' and `g', respectively. Then `diff F G' outputs
+
+ 1c1
+ < f
+ \ No newline at end of file
+ ---
+ > g
+ \ No newline at end of file
+
+(The exact message may differ in non-English locales.) `diff -n F G'
+outputs the following without a trailing newline:
+
+ d1 1
+ a1 1
+ g
+
+ `diff -e F G' reports two errors and outputs the following:
+
+ 1c
+ g
+ .
+
+
+File: diff.info, Node: Projects, Next: Concept Index, Prev: Incomplete Lines, Up: Top
+
+Future Projects
+***************
+
+ Here are some ideas for improving GNU `diff' and `patch'. The GNU
+project has identified some improvements as potential programming
+projects for volunteers. You can also help by reporting any bugs that
+you find.
+
+ If you are a programmer and would like to contribute something to the
+GNU project, please consider volunteering for one of these projects. If
+you are seriously contemplating work, please write to
+`gnu@prep.ai.mit.edu' to coordinate with other volunteers.
+
+* Menu:
+
+* Shortcomings:: Suggested projects for improvements.
+* Bugs:: Reporting bugs.
+
+
+File: diff.info, Node: Shortcomings, Next: Bugs, Up: Projects
+
+Suggested Projects for Improving GNU `diff' and `patch'
+=======================================================
+
+ One should be able to use GNU `diff' to generate a patch from any
+pair of directory trees, and given the patch and a copy of one such
+tree, use `patch' to generate a faithful copy of the other.
+Unfortunately, some changes to directory trees cannot be expressed using
+current patch formats; also, `patch' does not handle some of the
+existing formats. These shortcomings motivate the following suggested
+projects.
+
+* Menu:
+
+* Changing Structure:: Handling changes to the directory structure.
+* Special Files:: Handling symbolic links, device special files, etc.
+* Unusual File Names:: Handling file names that contain unusual characters.
+* Arbitrary Limits:: Patching non-text files.
+* Large Files:: Handling files that do not fit in memory.
+* Ignoring Changes:: Ignoring certain changes while showing others.
+
+
+File: diff.info, Node: Changing Structure, Next: Special Files, Up: Shortcomings
+
+Handling Changes to the Directory Structure
+-------------------------------------------
+
+ `diff' and `patch' do not handle some changes to directory
+structure. For example, suppose one directory tree contains a directory
+named `D' with some subsidiary files, and another contains a file with
+the same name `D'. `diff -r' does not output enough information for
+`patch' to transform the the directory subtree into the file.
+
+ There should be a way to specify that a file has been deleted without
+having to include its entire contents in the patch file. There should
+also be a way to tell `patch' that a file was renamed, even if there is
+no way for `diff' to generate such information.
+
+ These problems can be fixed by extending the `diff' output format to
+represent changes in directory structure, and extending `patch' to
+understand these extensions.
+
+
+File: diff.info, Node: Special Files, Next: Unusual File Names, Prev: Changing Structure, Up: Shortcomings
+
+Files that are Neither Directories Nor Regular Files
+----------------------------------------------------
+
+ Some files are neither directories nor regular files: they are
+unusual files like symbolic links, device special files, named pipes,
+and sockets. Currently, `diff' treats symbolic links like regular
+files; it treats other special files like regular files if they are
+specified at the top level, but simply reports their presence when
+comparing directories. This means that `patch' cannot represent changes
+to such files. For example, if you change which file a symbolic link
+points to, `diff' outputs the difference between the two files, instead
+of the change to the symbolic link.
+
+ `diff' should optionally report changes to special files specially,
+and `patch' should be extended to understand these extensions.
+
+
+File: diff.info, Node: Unusual File Names, Next: Arbitrary Limits, Prev: Special Files, Up: Shortcomings
+
+File Names that Contain Unusual Characters
+------------------------------------------
+
+ When a file name contains an unusual character like a newline or
+white space, `diff -r' generates a patch that `patch' cannot parse.
+The problem is with format of `diff' output, not just with `patch',
+because with odd enough file names one can cause `diff' to generate a
+patch that is syntactically correct but patches the wrong files. The
+format of `diff' output should be extended to handle all possible file
+names.
+
+
+File: diff.info, Node: Arbitrary Limits, Next: Large Files, Prev: Unusual File Names, Up: Shortcomings
+
+Arbitrary Limits
+----------------
+
+ GNU `diff' can analyze files with arbitrarily long lines and files
+that end in incomplete lines. However, `patch' cannot patch such
+files. The `patch' internal limits on line lengths should be removed,
+and `patch' should be extended to parse `diff' reports of incomplete
+lines.
+
+
+File: diff.info, Node: Large Files, Next: Ignoring Changes, Prev: Arbitrary Limits, Up: Shortcomings
+
+Handling Files that Do Not Fit in Memory
+----------------------------------------
+
+ `diff' operates by reading both files into memory. This method
+fails if the files are too large, and `diff' should have a fallback.
+
+ One way to do this is to scan the files sequentially to compute hash
+codes of the lines and put the lines in equivalence classes based only
+on hash code. Then compare the files normally. This does produce some
+false matches.
+
+ Then scan the two files sequentially again, checking each match to
+see whether it is real. When a match is not real, mark both the
+"matching" lines as changed. Then build an edit script as usual.
+
+ The output routines would have to be changed to scan the files
+sequentially looking for the text to print.
+
+
+File: diff.info, Node: Ignoring Changes, Prev: Large Files, Up: Shortcomings
+
+Ignoring Certain Changes
+------------------------
+
+ It would be nice to have a feature for specifying two strings, one in
+FROM-FILE and one in TO-FILE, which should be considered to match.
+Thus, if the two strings are `foo' and `bar', then if two lines differ
+only in that `foo' in file 1 corresponds to `bar' in file 2, the lines
+are treated as identical.
+
+ It is not clear how general this feature can or should be, or what
+syntax should be used for it.
+
+
+File: diff.info, Node: Bugs, Prev: Shortcomings, Up: Projects
+
+Reporting Bugs
+==============
+
+ If you think you have found a bug in GNU `cmp', `diff', `diff3',
+`sdiff', or `patch', please report it by electronic mail to
+`bug-gnu-utils@prep.ai.mit.edu'. Send as precise a description of the
+problem as you can, including sample input files that produce the bug,
+if applicable.
+
+ Because Larry Wall has not released a new version of `patch' since
+mid 1988 and the GNU version of `patch' has been changed since then,
+please send bug reports for `patch' by electronic mail to both
+`bug-gnu-utils@prep.ai.mit.edu' and `lwall@netlabs.com'.
+
diff --git a/gnu/dist/diffutils/diff.info-4 b/gnu/dist/diffutils/diff.info-4
new file mode 100644
index 00000000000..95cf8e561e6
--- /dev/null
+++ b/gnu/dist/diffutils/diff.info-4
@@ -0,0 +1,152 @@
+This is Info file diff.info, produced by Makeinfo-1.55 from the input
+file ./diff.texi.
+
+ This file documents the the GNU `diff', `diff3', `sdiff', and `cmp'
+commands for showing the differences between text files and the `patch'
+command for using their output to update files.
+
+ Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+
+ Permission is granted to make and distribute verbatim copies of this
+manual provided the copyright notice and this permission notice are
+preserved on all copies.
+
+ Permission is granted to copy and distribute modified versions of
+this manual under the conditions for verbatim copying, provided that
+the entire resulting derived work is distributed under the terms of a
+permission notice identical to this one.
+
+ Permission is granted to copy and distribute translations of this
+manual into another language, under the above conditions for modified
+versions, except that this permission notice may be stated in a
+translation approved by the Foundation.
+
+
+File: diff.info, Node: Concept Index, Prev: Projects, Up: Top
+
+Concept Index
+*************
+
+* Menu:
+
+* cmp invocation: Invoking cmp.
+* cmp options: cmp Options.
+* diff3 hunks: diff3 Hunks.
+* diff3 invocation: Invoking diff3.
+* diff3 options: diff3 Options.
+* diff3 sample input: Sample diff3 Input.
+* diff invocation: Invoking diff.
+* diff options: diff Options.
+* diff sample input: Sample diff Input.
+* ed script output format: ed Scripts.
+* ifdef output format: If-then-else.
+* patch input format: patch Input.
+* patch invocation: Invoking patch.
+* patch messages and questions: patch Messages.
+* patch options: patch Options.
+* sdiff invocation: Invoking sdiff.
+* sdiff options: sdiff Options.
+* sdiff output format: sdiff Option Summary.
+* ! output format: Context.
+* +- output format: Unified Format.
+* <<<<<<< for marking conflicts: Marking Conflicts.
+* < output format: Normal.
+* aligning tabstops: Tabs.
+* alternate file names: Alternate Names.
+* backup file names: Backups.
+* binary file diff: Binary.
+* binary file patching: Arbitrary Limits.
+* blank and tab difference suppression: White Space.
+* blank line difference suppression: Blank Lines.
+* brief difference reports: Brief.
+* bug reports: Bugs.
+* C function headings: C Function Headings.
+* C if-then-else output format: If-then-else.
+* case difference suppression: Case Folding.
+* columnar output: Side by Side.
+* comparing three files: Comparing Three Files.
+* conflict: diff3 Merging.
+* conflict marking: Marking Conflicts.
+* context output format: Context.
+* diagnostics from patch: patch Messages.
+* diff merging: Interactive Merging.
+* directories and patch: patch Directories.
+* directory structure changes: Changing Structure.
+* empty files, removing: Empty Files.
+* file name alternates: Alternate Names.
+* file names with unusual characters: Unusual File Names.
+* format of diff3 output: Comparing Three Files.
+* format of diff output: Output Formats.
+* formats for if-then-else line groups: Line Group Formats.
+* forward ed script output format: Forward ed.
+* full lines: Incomplete Lines.
+* function headings, C: C Function Headings.
+* fuzz factor when patching: Inexact.
+* headings: Sections.
+* hunks: Hunks.
+* hunks for diff3: diff3 Hunks.
+* if-then-else output format: If-then-else.
+* imperfect patch application: Imperfect.
+* incomplete line merging: Merging Incomplete Lines.
+* incomplete lines: Incomplete Lines.
+* inexact patches: Inexact.
+* interactive merging: Interactive Merging.
+* introduction: Comparison.
+* invoking cmp: Invoking cmp.
+* invoking diff3: Invoking diff3.
+* invoking diff: Invoking diff.
+* invoking patch: Invoking patch.
+* invoking sdiff: Invoking sdiff.
+* large files: Large Files.
+* line formats: Line Formats.
+* line group formats: Line Group Formats.
+* merge commands: Merge Commands.
+* merged diff3 format: Bypassing ed.
+* merged output format: If-then-else.
+* merging from a common ancestor: diff3 Merging.
+* merging interactively: Merge Commands.
+* messages from patch: patch Messages.
+* multiple patches: Multiple Patches.
+* newline treatment by diff: Incomplete Lines.
+* normal output format: Normal.
+* options for cmp: cmp Options.
+* options for diff3: diff3 Options.
+* options for diff: diff Options.
+* options for patch: patch Options.
+* options for sdiff: sdiff Options.
+* output formats: Output Formats.
+* overlap: diff3 Merging.
+* overlapping change, selection of: Which Changes.
+* overview of diff and patch: Overview.
+* paginating diff output: Pagination.
+* patch making tips: Making Patches.
+* patching directories: patch Directories.
+* performance of diff: diff Performance.
+* projects for directories: Shortcomings.
+* RCS script output format: RCS.
+* regular expression matching headings: Specified Headings.
+* regular expression suppression: Specified Folding.
+* reject file names: Rejects.
+* removing empty files: Empty Files.
+* reporting bugs: Bugs.
+* reversed patches: Reversed Patches.
+* sample input for diff3: Sample diff3 Input.
+* sample input for diff: Sample diff Input.
+* script output formats: Scripts.
+* section headings: Sections.
+* side by side: Side by Side.
+* side by side format: Side by Side Format.
+* special files: Special Files.
+* specified headings: Specified Headings.
+* summarizing which files differ: Brief.
+* System V diff3 compatibility: Saving the Changed File.
+* tab and blank difference suppression: White Space.
+* tabstop alignment: Tabs.
+* text versus binary diff: Binary.
+* tips for patch making: Making Patches.
+* two-column output: Side by Side.
+* unified output format: Unified Format.
+* unmerged change: Which Changes.
+* white space in patches: Changed White Space.
+
+
diff --git a/gnu/dist/diffutils/diff.texi b/gnu/dist/diffutils/diff.texi
new file mode 100644
index 00000000000..7551acba8b3
--- /dev/null
+++ b/gnu/dist/diffutils/diff.texi
@@ -0,0 +1,3916 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename diff.info
+@settitle Comparing and Merging Files
+@setchapternewpage odd
+@c %**end of header
+
+@ifinfo
+This file documents the the GNU @code{diff}, @code{diff3}, @code{sdiff},
+and @code{cmp} commands for showing the differences between text files
+and the @code{patch} command for using their output to update files.
+
+Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+@ignore
+Permission is granted to process this file through TeX and print the
+results, provided the printed document carries copying permission
+notice identical to this one except for the removal of this paragraph
+(this paragraph not being relevant to the printed manual).
+
+@end ignore
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation approved
+by the Foundation.
+@end ifinfo
+
+@titlepage
+@title Comparing and Merging Files
+@subtitle @code{diff}, @code{diff3}, @code{sdiff}, @code{cmp}, and @code{patch}
+@subtitle Edition 1.3, for @code{diff} 2.5 and @code{patch} 2.1
+@subtitle September 1993
+@author by David MacKenzie, Paul Eggert, and Richard Stallman
+
+@page
+@vskip 0pt plus 1filll
+Copyright @copyright{} 1992, 1993, 1994 Free Software Foundation, Inc.
+
+Permission is granted to make and distribute verbatim copies of
+this manual provided the copyright notice and this permission notice
+are preserved on all copies.
+
+Permission is granted to copy and distribute modified versions of this
+manual under the conditions for verbatim copying, provided that the entire
+resulting derived work is distributed under the terms of a permission
+notice identical to this one.
+
+Permission is granted to copy and distribute translations of this manual
+into another language, under the above conditions for modified versions,
+except that this permission notice may be stated in a translation approved
+by the Foundation.
+@end titlepage
+
+@node Top, , , (dir)
+
+@ifinfo
+This file documents the the GNU @code{diff}, @code{diff3}, @code{sdiff},
+and @code{cmp} commands for showing the differences between text files
+and the @code{patch} command for using their output to update files.
+
+This is Edition 1.2, for @code{diff} 2.4 and @code{patch} 2.1.
+@end ifinfo
+
+@menu
+* Overview:: Preliminary information.
+
+* Comparison:: What file comparison means.
+* Output Formats:: Formats for difference reports.
+* Comparing Directories:: Comparing files and directories.
+* Adjusting Output:: Making @code{diff} output prettier.
+* diff Performance:: Making @code{diff} smarter or faster.
+* Comparing Three Files:: Formats for three-way difference reports.
+
+* diff3 Merging:: Merging from a common ancestor.
+* Interactive Merging:: Interactive merging with @code{sdiff}.
+* Merging with patch:: Using @code{patch} to change old files into new ones.
+* Making Patches:: Tips for making patch distributions.
+
+* Invoking cmp:: How to run @code{cmp} and a summary of its options.
+* Invoking diff:: How to run @code{diff} and a summary of its options.
+* Invoking diff3:: How to run @code{diff3} and a summary of its options.
+* Invoking patch:: How to run @code{patch} and a summary of its options.
+* Invoking sdiff:: How to run @code{sdiff} and a summary of its options.
+
+* Incomplete Lines:: Lines that lack trailing newlines.
+* Projects:: If you think you've found a bug or other shortcoming.
+
+* Concept Index:: Index of concepts.
+@end menu
+
+@node Overview, Comparison, , Top
+@unnumbered Overview
+@cindex overview of @code{diff} and @code{patch}
+
+Computer users often find occasion to ask how two files differ. Perhaps
+one file is a newer version of the other file. Or maybe the two files
+started out as identical copies but were changed by different people.
+
+You can use the @code{diff} command to show differences between two
+files, or each corresponding file in two directories. @code{diff}
+outputs differences between files line by line in any of several
+formats, selectable by command line options. This set of differences is
+often called a @dfn{diff} or @dfn{patch}. For files that are identical,
+@code{diff} normally produces no output; for binary (non-text) files,
+@code{diff} normally reports only that they are different.
+
+You can use the @code{cmp} command to show the offsets and line numbers
+where two files differ. @code{cmp} can also show all the characters
+that differ between the two files, side by side. Another way to compare
+two files character by character is the Emacs command @kbd{M-x
+compare-windows}. @xref{Other Window, , Other Window, emacs, The GNU
+Emacs Manual}, for more information on that command.
+
+You can use the @code{diff3} command to show differences among three
+files. When two people have made independent changes to a common
+original, @code{diff3} can report the differences between the original
+and the two changed versions, and can produce a merged file that
+contains both persons' changes together with warnings about conflicts.
+
+You can use the @code{sdiff} command to merge two files interactively.
+
+You can use the set of differences produced by @code{diff} to distribute
+updates to text files (such as program source code) to other people.
+This method is especially useful when the differences are small compared
+to the complete files. Given @code{diff} output, you can use the
+@code{patch} program to update, or @dfn{patch}, a copy of the file. If you
+think of @code{diff} as subtracting one file from another to produce
+their difference, you can think of @code{patch} as adding the difference
+to one file to reproduce the other.
+
+This manual first concentrates on making diffs, and later shows how to
+use diffs to update files.
+
+GNU @code{diff} was written by Mike Haertel, David Hayes, Richard
+Stallman, Len Tower, and Paul Eggert. Wayne Davison designed and
+implemented the unified output format. The basic algorithm is described
+in ``An O(ND) Difference Algorithm and its Variations'', Eugene W. Myers,
+@cite{Algorithmica} Vol.@: 1 No.@: 2, 1986, pp.@: 251--266; and in ``A File
+Comparison Program'', Webb Miller and Eugene W. Myers,
+@cite{Software---Practice and Experience} Vol.@: 15 No.@: 11, 1985,
+pp.@: 1025--1040.
+@c From: "Gene Myers" <gene@cs.arizona.edu>
+@c They are about the same basic algorithm; the Algorithmica
+@c paper gives a rigorous treatment and the sub-algorithm for
+@c delivering scripts and should be the primary reference, but
+@c both should be mentioned.
+The algorithm was independently discovered as described in
+``Algorithms for Approximate String Matching'',
+E. Ukkonen, @cite{Information and Control} Vol.@: 64, 1985, pp.@: 100--118.
+@c From: "Gene Myers" <gene@cs.arizona.edu>
+@c Date: Wed, 29 Sep 1993 08:27:55 MST
+@c Ukkonen should be given credit for also discovering the algorithm used
+@c in GNU diff.
+
+GNU @code{diff3} was written by Randy Smith. GNU @code{sdiff} was
+written by Thomas Lord. GNU @code{cmp} was written by Torbjorn Granlund
+and David MacKenzie.
+
+@code{patch} was written mainly by Larry Wall; the GNU enhancements were
+written mainly by Wayne Davison and David MacKenzie. Parts of this
+manual are adapted from a manual page written by Larry Wall, with his
+permission.
+
+@node Comparison, Output Formats, Overview, Top
+@chapter What Comparison Means
+@cindex introduction
+
+There are several ways to think about the differences between two files.
+One way to think of the differences is as a series of lines that were
+deleted from, inserted in, or changed in one file to produce the other
+file. @code{diff} compares two files line by line, finds groups of
+lines that differ, and reports each group of differing lines. It can
+report the differing lines in several formats, which have different
+purposes.
+
+GNU @code{diff} can show whether files are different without detailing
+the differences. It also provides ways to suppress certain kinds of
+differences that are not important to you. Most commonly, such
+differences are changes in the amount of white space between words or
+lines. @code{diff} also provides ways to suppress differences in
+alphabetic case or in lines that match a regular expression that you
+provide. These options can accumulate; for example, you can ignore
+changes in both white space and alphabetic case.
+
+Another way to think of the differences between two files is as a
+sequence of pairs of characters that can be either identical or
+different. @code{cmp} reports the differences between two files
+character by character, instead of line by line. As a result, it is
+more useful than @code{diff} for comparing binary files. For text
+files, @code{cmp} is useful mainly when you want to know only whether
+two files are identical.
+
+To illustrate the effect that considering changes character by character
+can have compared with considering them line by line, think of what
+happens if a single newline character is added to the beginning of a
+file. If that file is then compared with an otherwise identical file
+that lacks the newline at the beginning, @code{diff} will report that a
+blank line has been added to the file, while @code{cmp} will report that
+almost every character of the two files differs.
+
+@code{diff3} normally compares three input files line by line, finds
+groups of lines that differ, and reports each group of differing lines.
+Its output is designed to make it easy to inspect two different sets of
+changes to the same file.
+
+@menu
+* Hunks:: Groups of differing lines.
+* White Space:: Suppressing differences in white space.
+* Blank Lines:: Suppressing differences in blank lines.
+* Case Folding:: Suppressing differences in alphabetic case.
+* Specified Folding:: Suppressing differences that match regular expressions.
+* Brief:: Summarizing which files are different.
+* Binary:: Comparing binary files or forcing text comparisons.
+@end menu
+
+@node Hunks, White Space, , Comparison
+@section Hunks
+@cindex hunks
+
+When comparing two files, @code{diff} finds sequences of lines common to
+both files, interspersed with groups of differing lines called
+@dfn{hunks}. Comparing two identical files yields one sequence of
+common lines and no hunks, because no lines differ. Comparing two
+entirely different files yields no common lines and one large hunk that
+contains all lines of both files. In general, there are many ways to
+match up lines between two given files. @code{diff} tries to minimize
+the total hunk size by finding large sequences of common lines
+interspersed with small hunks of differing lines.
+
+For example, suppose the file @file{F} contains the three lines
+@samp{a}, @samp{b}, @samp{c}, and the file @file{G} contains the same
+three lines in reverse order @samp{c}, @samp{b}, @samp{a}. If
+@code{diff} finds the line @samp{c} as common, then the command
+@samp{diff F G} produces this output:
+
+@example
+1,2d0
+< a
+< b
+3a2,3
+> b
+> a
+@end example
+
+@noindent
+But if @code{diff} notices the common line @samp{b} instead, it produces
+this output:
+
+@example
+1c1
+< a
+---
+> c
+3c3
+< c
+---
+> a
+@end example
+
+@noindent
+It is also possible to find @samp{a} as the common line. @code{diff}
+does not always find an optimal matching between the files; it takes
+shortcuts to run faster. But its output is usually close to the
+shortest possible. You can adjust this tradeoff with the
+@samp{--minimal} option (@pxref{diff Performance}).
+
+@node White Space, Blank Lines, Hunks, Comparison
+@section Suppressing Differences in Blank and Tab Spacing
+@cindex blank and tab difference suppression
+@cindex tab and blank difference suppression
+
+The @samp{-b} and @samp{--ignore-space-change} options ignore white space
+at line end, and considers all other sequences of one or more
+white space characters to be equivalent. With these options,
+@code{diff} considers the following two lines to be equivalent, where
+@samp{$} denotes the line end:
+
+@example
+Here lyeth muche rychnesse in lytell space. -- John Heywood$
+Here lyeth muche rychnesse in lytell space. -- John Heywood $
+@end example
+
+The @samp{-w} and @samp{--ignore-all-space} options are stronger than
+@samp{-b}. They ignore difference even if one file has white space where
+the other file has none. @dfn{White space} characters include
+tab, newline, vertical tab, form feed, carriage return, and space;
+some locales may define additional characters to be white space.
+With these options, @code{diff} considers the
+following two lines to be equivalent, where @samp{$} denotes the line
+end and @samp{^M} denotes a carriage return:
+
+@example
+Here lyeth muche rychnesse in lytell space.-- John Heywood$
+ He relyeth much erychnes seinly tells pace. --John Heywood ^M$
+@end example
+
+@node Blank Lines, Case Folding, White Space, Comparison
+@section Suppressing Differences in Blank Lines
+@cindex blank line difference suppression
+
+The @samp{-B} and @samp{--ignore-blank-lines} options ignore insertions
+or deletions of blank lines. These options normally affect only lines
+that are completely empty; they do not affect lines that look empty but
+contain space or tab characters. With these options, for example, a
+file containing
+@example
+1. A point is that which has no part.
+
+2. A line is breadthless length.
+-- Euclid, The Elements, I
+@end example
+@noindent
+is considered identical to a file containing
+@example
+1. A point is that which has no part.
+2. A line is breadthless length.
+
+
+-- Euclid, The Elements, I
+@end example
+
+@node Case Folding, Specified Folding, Blank Lines, Comparison
+@section Suppressing Case Differences
+@cindex case difference suppression
+
+GNU @code{diff} can treat lowercase letters as equivalent to their
+uppercase counterparts, so that, for example, it considers @samp{Funky
+Stuff}, @samp{funky STUFF}, and @samp{fUNKy stuFf} to all be the same.
+To request this, use the @samp{-i} or @samp{--ignore-case} option.
+
+@node Specified Folding, Brief, Case Folding, Comparison
+@section Suppressing Lines Matching a Regular Expression
+@cindex regular expression suppression
+
+To ignore insertions and deletions of lines that match a regular
+expression, use the @samp{-I @var{regexp}} or
+@samp{--ignore-matching-lines=@var{regexp}} option. You should escape
+regular expressions that contain shell metacharacters to prevent the
+shell from expanding them. For example, @samp{diff -I '^[0-9]'} ignores
+all changes to lines beginning with a digit.
+
+However, @samp{-I} only ignores the insertion or deletion of lines that
+contain the regular expression if every changed line in the hunk---every
+insertion and every deletion---matches the regular expression. In other
+words, for each nonignorable change, @code{diff} prints the complete set
+of changes in its vicinity, including the ignorable ones.
+
+You can specify more than one regular expression for lines to ignore by
+using more than one @samp{-I} option. @code{diff} tries to match each
+line against each regular expression, starting with the last one given.
+
+@node Brief, Binary, Specified Folding, Comparison
+@section Summarizing Which Files Differ
+@cindex summarizing which files differ
+@cindex brief difference reports
+
+When you only want to find out whether files are different, and you
+don't care what the differences are, you can use the summary output
+format. In this format, instead of showing the differences between the
+files, @code{diff} simply reports whether files differ. The @samp{-q}
+and @samp{--brief} options select this output format.
+
+This format is especially useful when comparing the contents of two
+directories. It is also much faster than doing the normal line by line
+comparisons, because @code{diff} can stop analyzing the files as soon as
+it knows that there are any differences.
+
+You can also get a brief indication of whether two files differ by using
+@code{cmp}. For files that are identical, @code{cmp} produces no
+output. When the files differ, by default, @code{cmp} outputs the byte
+offset and line number where the first difference occurs. You can use
+the @samp{-s} option to suppress that information, so that @code{cmp}
+produces no output and reports whether the files differ using only its
+exit status (@pxref{Invoking cmp}).
+
+@c Fix this.
+Unlike @code{diff}, @code{cmp} cannot compare directories; it can only
+compare two files.
+
+@node Binary, , Brief, Comparison
+@section Binary Files and Forcing Text Comparisons
+@cindex binary file diff
+@cindex text versus binary diff
+
+If @code{diff} thinks that either of the two files it is comparing is
+binary (a non-text file), it normally treats that pair of files much as
+if the summary output format had been selected (@pxref{Brief}), and
+reports only that the binary files are different. This is because line
+by line comparisons are usually not meaningful for binary files.
+
+@code{diff} determines whether a file is text or binary by checking the
+first few bytes in the file; the exact number of bytes is system
+dependent, but it is typically several thousand. If every character in
+that part of the file is non-null, @code{diff} considers the file to be
+text; otherwise it considers the file to be binary.
+
+Sometimes you might want to force @code{diff} to consider files to be
+text. For example, you might be comparing text files that contain
+null characters; @code{diff} would erroneously decide that those are
+non-text files. Or you might be comparing documents that are in a
+format used by a word processing system that uses null characters to
+indicate special formatting. You can force @code{diff} to consider all
+files to be text files, and compare them line by line, by using the
+@samp{-a} or @samp{--text} option. If the files you compare using this
+option do not in fact contain text, they will probably contain few
+newline characters, and the @code{diff} output will consist of hunks
+showing differences between long lines of whatever characters the files
+contain.
+
+You can also force @code{diff} to consider all files to be binary files,
+and report only whether they differ (but not how). Use the
+@samp{--brief} option for this.
+
+In operating systems that distinguish between text and binary files,
+@code{diff} normally reads and writes all data as text. Use the
+@samp{--binary} option to force @code{diff} to read and write binary
+data instead. This option has no effect on a Posix-compliant system
+like GNU or traditional Unix. However, many personal computer
+operating systems represent the end of a line with a carriage return
+followed by a newline. On such systems, @code{diff} normally ignores
+these carriage returns on input and generates them at the end of each
+output line, but with the @samp{--binary} option @code{diff} treats
+each carriage return as just another input character, and does not
+generate a carriage return at the end of each output line. This can be
+useful when dealing with non-text files that are meant to be
+interchanged with Posix-compliant systems.
+
+If you want to compare two files byte by byte, you can use the
+@code{cmp} program with the @samp{-l} option to show the values of each
+differing byte in the two files. With GNU @code{cmp}, you can also use
+the @samp{-c} option to show the ASCII representation of those bytes.
+@xref{Invoking cmp}, for more information.
+
+If @code{diff3} thinks that any of the files it is comparing is binary
+(a non-text file), it normally reports an error, because such
+comparisons are usually not useful. @code{diff3} uses the same test as
+@code{diff} to decide whether a file is binary. As with @code{diff}, if
+the input files contain a few non-text characters but otherwise are like
+text files, you can force @code{diff3} to consider all files to be text
+files and compare them line by line by using the @samp{-a} or
+@samp{--text} options.
+
+@node Output Formats, Comparing Directories, Comparison, Top
+@chapter @code{diff} Output Formats
+@cindex output formats
+@cindex format of @code{diff} output
+
+@code{diff} has several mutually exclusive options for output format.
+The following sections describe each format, illustrating how
+@code{diff} reports the differences between two sample input files.
+
+@menu
+* Sample diff Input:: Sample @code{diff} input files for examples.
+* Normal:: Showing differences without surrounding text.
+* Context:: Showing differences with the surrounding text.
+* Side by Side:: Showing differences in two columns.
+* Scripts:: Generating scripts for other programs.
+* If-then-else:: Merging files with if-then-else.
+@end menu
+
+@node Sample diff Input, Normal, , Output Formats
+@section Two Sample Input Files
+@cindex @code{diff} sample input
+@cindex sample input for @code{diff}
+
+Here are two sample files that we will use in numerous examples to
+illustrate the output of @code{diff} and how various options can change
+it.
+
+This is the file @file{lao}:
+
+@example
+The Way that can be told of is not the eternal Way;
+The name that can be named is not the eternal name.
+The Nameless is the origin of Heaven and Earth;
+The Named is the mother of all things.
+Therefore let there always be non-being,
+ so we may see their subtlety,
+And let there always be being,
+ so we may see their outcome.
+The two are the same,
+But after they are produced,
+ they have different names.
+@end example
+
+This is the file @file{tzu}:
+
+@example
+The Nameless is the origin of Heaven and Earth;
+The named is the mother of all things.
+
+Therefore let there always be non-being,
+ so we may see their subtlety,
+And let there always be being,
+ so we may see their outcome.
+The two are the same,
+But after they are produced,
+ they have different names.
+They both may be called deep and profound.
+Deeper and more profound,
+The door of all subtleties!
+@end example
+
+In this example, the first hunk contains just the first two lines of
+@file{lao}, the second hunk contains the fourth line of @file{lao}
+opposing the second and third lines of @file{tzu}, and the last hunk
+contains just the last three lines of @file{tzu}.
+
+@node Normal, Context, Sample diff Input, Output Formats
+@section Showing Differences Without Context
+@cindex normal output format
+@cindex @samp{<} output format
+
+The ``normal'' @code{diff} output format shows each hunk of differences
+without any surrounding context. Sometimes such output is the clearest
+way to see how lines have changed, without the clutter of nearby
+unchanged lines (although you can get similar results with the context
+or unified formats by using 0 lines of context). However, this format
+is no longer widely used for sending out patches; for that purpose, the
+context format (@pxref{Context Format}) and the unified format
+(@pxref{Unified Format}) are superior. Normal format is the default for
+compatibility with older versions of @code{diff} and the Posix standard.
+
+@menu
+* Detailed Normal:: A detailed description of normal output format.
+* Example Normal:: Sample output in the normal format.
+@end menu
+
+@node Detailed Normal, Example Normal, , Normal
+@subsection Detailed Description of Normal Format
+
+The normal output format consists of one or more hunks of differences;
+each hunk shows one area where the files differ. Normal format hunks
+look like this:
+
+@example
+@var{change-command}
+< @var{from-file-line}
+< @var{from-file-line}@dots{}
+---
+> @var{to-file-line}
+> @var{to-file-line}@dots{}
+@end example
+
+There are three types of change commands. Each consists of a line
+number or comma-separated range of lines in the first file, a single
+character indicating the kind of change to make, and a line number or
+comma-separated range of lines in the second file. All line numbers are
+the original line numbers in each file. The types of change commands
+are:
+
+@table @samp
+@item @var{l}a@var{r}
+Add the lines in range @var{r} of the second file after line @var{l} of
+the first file. For example, @samp{8a12,15} means append lines 12--15
+of file 2 after line 8 of file 1; or, if changing file 2 into file 1,
+delete lines 12--15 of file 2.
+
+@item @var{f}c@var{t}
+Replace the lines in range @var{f} of the first file with lines in range
+@var{t} of the second file. This is like a combined add and delete, but
+more compact. For example, @samp{5,7c8,10} means change lines 5--7 of
+file 1 to read as lines 8--10 of file 2; or, if changing file 2 into
+file 1, change lines 8--10 of file 2 to read as lines 5--7 of file 1.
+
+@item @var{r}d@var{l}
+Delete the lines in range @var{r} from the first file; line @var{l} is where
+they would have appeared in the second file had they not been deleted.
+For example, @samp{5,7d3} means delete lines 5--7 of file 1; or, if
+changing file 2 into file 1, append lines 5--7 of file 1 after line 3 of
+file 2.
+@end table
+
+@node Example Normal, , Detailed Normal, Normal
+@subsection An Example of Normal Format
+
+Here is the output of the command @samp{diff lao tzu}
+(@pxref{Sample diff Input}, for the complete contents of the two files).
+Notice that it shows only the lines that are different between the two
+files.
+
+@example
+1,2d0
+< The Way that can be told of is not the eternal Way;
+< The name that can be named is not the eternal name.
+4c2,3
+< The Named is the mother of all things.
+---
+> The named is the mother of all things.
+>
+11a11,13
+> They both may be called deep and profound.
+> Deeper and more profound,
+> The door of all subtleties!
+@end example
+
+@node Context, Side by Side, Normal, Output Formats
+@section Showing Differences in Their Context
+@cindex context output format
+@cindex @samp{!} output format
+
+Usually, when you are looking at the differences between files, you will
+also want to see the parts of the files near the lines that differ, to
+help you understand exactly what has changed. These nearby parts of the
+files are called the @dfn{context}.
+
+GNU @code{diff} provides two output formats that show context around the
+differing lines: @dfn{context format} and @dfn{unified format}. It can
+optionally show in which function or section of the file the differing
+lines are found.
+
+If you are distributing new versions of files to other people in the
+form of @code{diff} output, you should use one of the output formats
+that show context so that they can apply the diffs even if they have
+made small changes of their own to the files. @code{patch} can apply
+the diffs in this case by searching in the files for the lines of
+context around the differing lines; if those lines are actually a few
+lines away from where the diff says they are, @code{patch} can adjust
+the line numbers accordingly and still apply the diff correctly.
+@xref{Imperfect}, for more information on using @code{patch} to apply
+imperfect diffs.
+
+@menu
+* Context Format:: An output format that shows surrounding lines.
+* Unified Format:: A more compact output format that shows context.
+* Sections:: Showing which sections of the files differences are in.
+* Alternate Names:: Showing alternate file names in context headers.
+@end menu
+
+@node Context Format, Unified Format, , Context
+@subsection Context Format
+
+The context output format shows several lines of context around the
+lines that differ. It is the standard format for distributing updates
+to source code.
+
+To select this output format, use the @samp{-C @var{lines}},
+@samp{--context@r{[}=@var{lines}@r{]}}, or @samp{-c} option. The
+argument @var{lines} that some of these options take is the number of
+lines of context to show. If you do not specify @var{lines}, it
+defaults to three. For proper operation, @code{patch} typically needs
+at least two lines of context.
+
+@menu
+* Detailed Context:: A detailed description of the context output format.
+* Example Context:: Sample output in context format.
+* Less Context:: Another sample with less context.
+@end menu
+
+@node Detailed Context, Example Context, , Context Format
+@subsubsection Detailed Description of Context Format
+
+The context output format starts with a two-line header, which looks
+like this:
+
+@example
+*** @var{from-file} @var{from-file-modification-time}
+--- @var{to-file} @var{to-file-modification time}
+@end example
+
+@noindent
+You can change the header's content with the @samp{-L @var{label}} or
+@samp{--label=@var{label}} option; see @ref{Alternate Names}.
+
+Next come one or more hunks of differences; each hunk shows one area
+where the files differ. Context format hunks look like this:
+
+@example
+***************
+*** @var{from-file-line-range} ****
+ @var{from-file-line}
+ @var{from-file-line}@dots{}
+--- @var{to-file-line-range} ----
+ @var{to-file-line}
+ @var{to-file-line}@dots{}
+@end example
+
+The lines of context around the lines that differ start with two space
+characters. The lines that differ between the two files start with one
+of the following indicator characters, followed by a space character:
+
+@table @samp
+@item !
+A line that is part of a group of one or more lines that changed between
+the two files. There is a corresponding group of lines marked with
+@samp{!} in the part of this hunk for the other file.
+
+@item +
+An ``inserted'' line in the second file that corresponds to nothing in
+the first file.
+
+@item -
+A ``deleted'' line in the first file that corresponds to nothing in the
+second file.
+@end table
+
+If all of the changes in a hunk are insertions, the lines of
+@var{from-file} are omitted. If all of the changes are deletions, the
+lines of @var{to-file} are omitted.
+
+@node Example Context, Less Context, Detailed Context, Context Format
+@subsubsection An Example of Context Format
+
+Here is the output of @samp{diff -c lao tzu} (@pxref{Sample diff Input},
+for the complete contents of the two files). Notice that up to three
+lines that are not different are shown around each line that is
+different; they are the context lines. Also notice that the first two
+hunks have run together, because their contents overlap.
+
+@example
+*** lao Sat Jan 26 23:30:39 1991
+--- tzu Sat Jan 26 23:30:50 1991
+***************
+*** 1,7 ****
+- The Way that can be told of is not the eternal Way;
+- The name that can be named is not the eternal name.
+ The Nameless is the origin of Heaven and Earth;
+! The Named is the mother of all things.
+ Therefore let there always be non-being,
+ so we may see their subtlety,
+ And let there always be being,
+--- 1,6 ----
+ The Nameless is the origin of Heaven and Earth;
+! The named is the mother of all things.
+!
+ Therefore let there always be non-being,
+ so we may see their subtlety,
+ And let there always be being,
+***************
+*** 9,11 ****
+--- 8,13 ----
+ The two are the same,
+ But after they are produced,
+ they have different names.
++ They both may be called deep and profound.
++ Deeper and more profound,
++ The door of all subtleties!
+@end example
+
+@node Less Context, , Example Context, Context Format
+@subsubsection An Example of Context Format with Less Context
+
+Here is the output of @samp{diff --context=1 lao tzu} (@pxref{Sample
+diff Input}, for the complete contents of the two files). Notice that
+at most one context line is reported here.
+
+@example
+*** lao Sat Jan 26 23:30:39 1991
+--- tzu Sat Jan 26 23:30:50 1991
+***************
+*** 1,5 ****
+- The Way that can be told of is not the eternal Way;
+- The name that can be named is not the eternal name.
+ The Nameless is the origin of Heaven and Earth;
+! The Named is the mother of all things.
+ Therefore let there always be non-being,
+--- 1,4 ----
+ The Nameless is the origin of Heaven and Earth;
+! The named is the mother of all things.
+!
+ Therefore let there always be non-being,
+***************
+*** 11 ****
+--- 10,13 ----
+ they have different names.
++ They both may be called deep and profound.
++ Deeper and more profound,
++ The door of all subtleties!
+@end example
+
+@node Unified Format, Sections, Context Format, Context
+@subsection Unified Format
+@cindex unified output format
+@cindex @samp{+-} output format
+
+The unified output format is a variation on the context format that is
+more compact because it omits redundant context lines. To select this
+output format, use the @samp{-U @var{lines}},
+@samp{--unified@r{[}=@var{lines}@r{]}}, or @samp{-u}
+option. The argument @var{lines} is the number of lines of context to
+show. When it is not given, it defaults to three.
+
+At present, only GNU @code{diff} can produce this format and only GNU
+@code{patch} can automatically apply diffs in this format. For proper
+operation, @code{patch} typically needs at least two lines of context.
+
+@menu
+* Detailed Unified:: A detailed description of unified format.
+* Example Unified:: Sample output in unified format.
+@end menu
+
+@node Detailed Unified, Example Unified, , Unified Format
+@subsubsection Detailed Description of Unified Format
+
+The unified output format starts with a two-line header, which looks
+like this:
+
+@example
+--- @var{from-file} @var{from-file-modification-time}
++++ @var{to-file} @var{to-file-modification-time}
+@end example
+
+@noindent
+You can change the header's content with the @samp{-L @var{label}} or
+@samp{--label=@var{label}} option; see @xref{Alternate Names}.
+
+Next come one or more hunks of differences; each hunk shows one area
+where the files differ. Unified format hunks look like this:
+
+@example
+@@@@ @var{from-file-range} @var{to-file-range} @@@@
+ @var{line-from-either-file}
+ @var{line-from-either-file}@dots{}
+@end example
+
+The lines common to both files begin with a space character. The lines
+that actually differ between the two files have one of the following
+indicator characters in the left column:
+
+@table @samp
+@item +
+A line was added here to the first file.
+
+@item -
+A line was removed here from the first file.
+@end table
+
+@node Example Unified, , Detailed Unified, Unified Format
+@subsubsection An Example of Unified Format
+
+Here is the output of the command @samp{diff -u lao tzu}
+(@pxref{Sample diff Input}, for the complete contents of the two files):
+
+@example
+--- lao Sat Jan 26 23:30:39 1991
++++ tzu Sat Jan 26 23:30:50 1991
+@@@@ -1,7 +1,6 @@@@
+-The Way that can be told of is not the eternal Way;
+-The name that can be named is not the eternal name.
+ The Nameless is the origin of Heaven and Earth;
+-The Named is the mother of all things.
++The named is the mother of all things.
++
+ Therefore let there always be non-being,
+ so we may see their subtlety,
+ And let there always be being,
+@@@@ -9,3 +8,6 @@@@
+ The two are the same,
+ But after they are produced,
+ they have different names.
++They both may be called deep and profound.
++Deeper and more profound,
++The door of all subtleties!
+@end example
+
+@node Sections, Alternate Names, Unified Format, Context
+@subsection Showing Which Sections Differences Are in
+@cindex headings
+@cindex section headings
+
+Sometimes you might want to know which part of the files each change
+falls in. If the files are source code, this could mean which function
+was changed. If the files are documents, it could mean which chapter or
+appendix was changed. GNU @code{diff} can show this by displaying the
+nearest section heading line that precedes the differing lines. Which
+lines are ``section headings'' is determined by a regular expression.
+
+@menu
+* Specified Headings:: Showing headings that match regular expressions.
+* C Function Headings:: Showing headings of C functions.
+@end menu
+
+@node Specified Headings, C Function Headings, , Sections
+@subsubsection Showing Lines That Match Regular Expressions
+@cindex specified headings
+@cindex regular expression matching headings
+
+To show in which sections differences occur for files that are not
+source code for C or similar languages, use the @samp{-F @var{regexp}}
+or @samp{--show-function-line=@var{regexp}} option. @code{diff}
+considers lines that match the argument @var{regexp} to be the beginning
+of a section of the file. Here are suggested regular expressions for
+some common languages:
+
+@c Please add to this list, e.g. Fortran, Pascal.
+@table @samp
+@item ^[A-Za-z_]
+C, C++, Prolog
+@item ^(
+Lisp
+@item ^@@\(chapter\|appendix\|unnumbered\|chapheading\)
+Texinfo
+@end table
+
+This option does not automatically select an output format; in order to
+use it, you must select the context format (@pxref{Context Format}) or
+unified format (@pxref{Unified Format}). In other output formats it
+has no effect.
+
+The @samp{-F} and @samp{--show-function-line} options find the nearest
+unchanged line that precedes each hunk of differences and matches the
+given regular expression. Then they add that line to the end of the
+line of asterisks in the context format, or to the @samp{@@@@} line in
+unified format. If no matching line exists, they leave the output for
+that hunk unchanged. If that line is more than 40 characters long, they
+output only the first 40 characters. You can specify more than one
+regular expression for such lines; @code{diff} tries to match each line
+against each regular expression, starting with the last one given. This
+means that you can use @samp{-p} and @samp{-F} together, if you wish.
+
+@node C Function Headings, , Specified Headings, Sections
+@subsubsection Showing C Function Headings
+@cindex C function headings
+@cindex function headings, C
+
+To show in which functions differences occur for C and similar
+languages, you can use the @samp{-p} or @samp{--show-c-function} option.
+This option automatically defaults to the context output format
+(@pxref{Context Format}), with the default number of lines of context.
+You can override that number with @samp{-C @var{lines}} elsewhere in the
+command line. You can override both the format and the number with
+@samp{-U @var{lines}} elsewhere in the command line.
+
+The @samp{-p} and @samp{--show-c-function} options are equivalent to
+@samp{-F'^[_a-zA-Z$]'} if the unified format is specified, otherwise
+@samp{-c -F'^[_a-zA-Z$]'} (@pxref{Specified Headings}). GNU @code{diff}
+provides them for the sake of convenience.
+
+@node Alternate Names, , Sections, Context
+@subsection Showing Alternate File Names
+@cindex alternate file names
+@cindex file name alternates
+
+If you are comparing two files that have meaningless or uninformative
+names, you might want @code{diff} to show alternate names in the header
+of the context and unified output formats. To do this, use the @samp{-L
+@var{label}} or @samp{--label=@var{label}} option. The first time
+you give this option, its argument replaces the name and date of the
+first file in the header; the second time, its argument replaces the
+name and date of the second file. If you give this option more than
+twice, @code{diff} reports an error. The @samp{-L} option does not
+affect the file names in the @code{pr} header when the @samp{-l} or
+@samp{--paginate} option is used (@pxref{Pagination}).
+
+Here are the first two lines of the output from @samp{diff -C2
+-Loriginal -Lmodified lao tzu}:
+
+@example
+*** original
+--- modified
+@end example
+
+@node Side by Side, Scripts, Context, Output Formats
+@section Showing Differences Side by Side
+@cindex side by side
+@cindex two-column output
+@cindex columnar output
+
+@code{diff} can produce a side by side difference listing of two files.
+The files are listed in two columns with a gutter between them. The
+gutter contains one of the following markers:
+
+@table @asis
+@item white space
+The corresponding lines are in common. That is, either the lines are
+identical, or the difference is ignored because of one of the
+@samp{--ignore} options (@pxref{White Space}).
+
+@item @samp{|}
+The corresponding lines differ, and they are either both complete
+or both incomplete.
+
+@item @samp{<}
+The files differ and only the first file contains the line.
+
+@item @samp{>}
+The files differ and only the second file contains the line.
+
+@item @samp{(}
+Only the first file contains the line, but the difference is ignored.
+
+@item @samp{)}
+Only the second file contains the line, but the difference is ignored.
+
+@item @samp{\}
+The corresponding lines differ, and only the first line is incomplete.
+
+@item @samp{/}
+The corresponding lines differ, and only the second line is incomplete.
+@end table
+
+Normally, an output line is incomplete if and only if the lines that it
+contains are incomplete; @xref{Incomplete Lines}. However, when an
+output line represents two differing lines, one might be incomplete
+while the other is not. In this case, the output line is complete,
+but its the gutter is marked @samp{\} if the first line is incomplete,
+@samp{/} if the second line is.
+
+Side by side format is sometimes easiest to read, but it has limitations.
+It generates much wider output than usual, and truncates lines that are
+too long to fit. Also, it relies on lining up output more heavily than
+usual, so its output looks particularly bad if you use varying
+width fonts, nonstandard tab stops, or nonprinting characters.
+
+You can use the @code{sdiff} command to interactively merge side by side
+differences. @xref{Interactive Merging}, for more information on merging files.
+
+@menu
+* Side by Side Format:: Controlling side by side output format.
+* Example Side by Side:: Sample side by side output.
+@end menu
+
+@node Side by Side Format, Example Side by Side, , Side by Side
+@section Controlling Side by Side Format
+@cindex side by side format
+
+The @samp{-y} or @samp{--side-by-side} option selects side by side
+format. Because side by side output lines contain two input lines, they
+are wider than usual. They are normally 130 columns, which can fit onto
+a traditional printer line. You can set the length of output lines with
+the @samp{-W @var{columns}} or @samp{--width=@var{columns}} option. The
+output line is split into two halves of equal length, separated by a
+small gutter to mark differences; the right half is aligned to a tab
+stop so that tabs line up. Input lines that are too long to fit in half
+of an output line are truncated for output.
+
+The @samp{--left-column} option prints only the left column of two
+common lines. The @samp{--suppress-common-lines} option suppresses
+common lines entirely.
+
+@node Example Side by Side, , Side by Side Format, Side by Side
+@subsection An Example of Side by Side Format
+
+Here is the output of the command @samp{diff -y -W 72 lao tzu}
+(@pxref{Sample diff Input}, for the complete contents of the two files).
+
+@example
+The Way that can be told of is n <
+The name that can be named is no <
+The Nameless is the origin of He The Nameless is the origin of He
+The Named is the mother of all t | The named is the mother of all t
+ >
+Therefore let there always be no Therefore let there always be no
+ so we may see their subtlety, so we may see their subtlety,
+And let there always be being, And let there always be being,
+ so we may see their outcome. so we may see their outcome.
+The two are the same, The two are the same,
+But after they are produced, But after they are produced,
+ they have different names. they have different names.
+ > They both may be called deep and
+ > Deeper and more profound,
+ > The door of all subtleties!
+@end example
+
+@node Scripts, If-then-else, Side by Side, Output Formats
+@section Making Edit Scripts
+@cindex script output formats
+
+Several output modes produce command scripts for editing @var{from-file}
+to produce @var{to-file}.
+
+@menu
+* ed Scripts:: Using @code{diff} to produce commands for @code{ed}.
+* Forward ed:: Making forward @code{ed} scripts.
+* RCS:: A special @code{diff} output format used by RCS.
+@end menu
+
+@node ed Scripts, Forward ed, , Scripts
+@subsection @code{ed} Scripts
+@cindex @code{ed} script output format
+
+@code{diff} can produce commands that direct the @code{ed} text editor
+to change the first file into the second file. Long ago, this was the
+only output mode that was suitable for editing one file into another
+automatically; today, with @code{patch}, it is almost obsolete. Use the
+@samp{-e} or @samp{--ed} option to select this output format.
+
+Like the normal format (@pxref{Normal}), this output format does not
+show any context; unlike the normal format, it does not include the
+information necessary to apply the diff in reverse (to produce the first
+file if all you have is the second file and the diff).
+
+If the file @file{d} contains the output of @samp{diff -e old new}, then
+the command @samp{(cat d && echo w) | ed - old} edits @file{old} to make
+it a copy of @file{new}. More generally, if @file{d1}, @file{d2},
+@dots{}, @file{dN} contain the outputs of @samp{diff -e old new1},
+@samp{diff -e new1 new2}, @dots{}, @samp{diff -e newN-1 newN},
+respectively, then the command @samp{(cat d1 d2 @dots{} dN && echo w) |
+ed - old} edits @file{old} to make it a copy of @file{newN}.
+
+@menu
+* Detailed ed:: A detailed description of @code{ed} format.
+* Example ed:: A sample @code{ed} script.
+@end menu
+
+@node Detailed ed, Example ed, , ed Scripts
+@subsubsection Detailed Description of @code{ed} Format
+
+The @code{ed} output format consists of one or more hunks of
+differences. The changes closest to the ends of the files come first so
+that commands that change the number of lines do not affect how
+@code{ed} interprets line numbers in succeeding commands. @code{ed}
+format hunks look like this:
+
+@example
+@var{change-command}
+@var{to-file-line}
+@var{to-file-line}@dots{}
+.
+@end example
+
+Because @code{ed} uses a single period on a line to indicate the end of
+input, GNU @code{diff} protects lines of changes that contain a single
+period on a line by writing two periods instead, then writing a
+subsequent @code{ed} command to change the two periods into one. The
+@code{ed} format cannot represent an incomplete line, so if the second
+file ends in a changed incomplete line, @code{diff} reports an error and
+then pretends that a newline was appended.
+
+There are three types of change commands. Each consists of a line
+number or comma-separated range of lines in the first file and a single
+character indicating the kind of change to make. All line numbers are
+the original line numbers in the file. The types of change commands
+are:
+
+@table @samp
+@item @var{l}a
+Add text from the second file after line @var{l} in the first file. For
+example, @samp{8a} means to add the following lines after line 8 of file
+1.
+
+@item @var{r}c
+Replace the lines in range @var{r} in the first file with the following
+lines. Like a combined add and delete, but more compact. For example,
+@samp{5,7c} means change lines 5--7 of file 1 to read as the text file
+2.
+
+@item @var{r}d
+Delete the lines in range @var{r} from the first file. For example,
+@samp{5,7d} means delete lines 5--7 of file 1.
+@end table
+
+@node Example ed, , Detailed ed, ed Scripts
+@subsubsection Example @code{ed} Script
+
+Here is the output of @samp{diff -e lao tzu} (@pxref{Sample
+diff Input}, for the complete contents of the two files):
+
+@example
+11a
+They both may be called deep and profound.
+Deeper and more profound,
+The door of all subtleties!
+.
+4c
+The named is the mother of all things.
+
+.
+1,2d
+@end example
+
+@node Forward ed, RCS, ed Scripts, Scripts
+@subsection Forward @code{ed} Scripts
+@cindex forward @code{ed} script output format
+
+@code{diff} can produce output that is like an @code{ed} script, but
+with hunks in forward (front to back) order. The format of the commands
+is also changed slightly: command characters precede the lines they
+modify, spaces separate line numbers in ranges, and no attempt is made
+to disambiguate hunk lines consisting of a single period. Like
+@code{ed} format, forward @code{ed} format cannot represent incomplete
+lines.
+
+Forward @code{ed} format is not very useful, because neither @code{ed}
+nor @code{patch} can apply diffs in this format. It exists mainly for
+compatibility with older versions of @code{diff}. Use the @samp{-f} or
+@samp{--forward-ed} option to select it.
+
+@node RCS, , Forward ed, Scripts
+@subsection RCS Scripts
+@cindex RCS script output format
+
+The RCS output format is designed specifically for use by the Revision
+Control System, which is a set of free programs used for organizing
+different versions and systems of files. Use the @samp{-n} or
+@samp{--rcs} option to select this output format. It is like the
+forward @code{ed} format (@pxref{Forward ed}), but it can represent
+arbitrary changes to the contents of a file because it avoids the
+forward @code{ed} format's problems with lines consisting of a single
+period and with incomplete lines. Instead of ending text sections with
+a line consisting of a single period, each command specifies the number
+of lines it affects; a combination of the @samp{a} and @samp{d}
+commands are used instead of @samp{c}. Also, if the second file ends
+in a changed incomplete line, then the output also ends in an
+incomplete line.
+
+Here is the output of @samp{diff -n lao tzu} (@pxref{Sample
+diff Input}, for the complete contents of the two files):
+
+@example
+d1 2
+d4 1
+a4 2
+The named is the mother of all things.
+
+a11 3
+They both may be called deep and profound.
+Deeper and more profound,
+The door of all subtleties!
+@end example
+
+@node If-then-else, , Scripts, Output Formats
+@section Merging Files with If-then-else
+@cindex merged output format
+@cindex if-then-else output format
+@cindex C if-then-else output format
+@cindex @code{ifdef} output format
+
+You can use @code{diff} to merge two files of C source code. The output
+of @code{diff} in this format contains all the lines of both files.
+Lines common to both files are output just once; the differing parts are
+separated by the C preprocessor directives @code{#ifdef @var{name}} or
+@code{#ifndef @var{name}}, @code{#else}, and @code{#endif}. When
+compiling the output, you select which version to use by either defining
+or leaving undefined the macro @var{name}.
+
+To merge two files, use @code{diff} with the @samp{-D @var{name}} or
+@samp{--ifdef=@var{name}} option. The argument @var{name} is the C
+preprocessor identifier to use in the @code{#ifdef} and @code{#ifndef}
+directives.
+
+For example, if you change an instance of @code{wait (&s)} to
+@code{waitpid (-1, &s, 0)} and then merge the old and new files with
+the @samp{--ifdef=HAVE_WAITPID} option, then the affected part of your code
+might look like this:
+
+@example
+ do @{
+#ifndef HAVE_WAITPID
+ if ((w = wait (&s)) < 0 && errno != EINTR)
+#else /* HAVE_WAITPID */
+ if ((w = waitpid (-1, &s, 0)) < 0 && errno != EINTR)
+#endif /* HAVE_WAITPID */
+ return w;
+ @} while (w != child);
+@end example
+
+You can specify formats for languages other than C by using line group
+formats and line formats, as described in the next sections.
+
+@menu
+* Line Group Formats:: Formats for general if-then-else line groups.
+* Line Formats:: Formats for each line in a line group.
+* Detailed If-then-else:: A detailed description of if-then-else format.
+* Example If-then-else:: Sample if-then-else format output.
+@end menu
+
+@node Line Group Formats, Line Formats, , If-then-else
+@subsection Line Group Formats
+@cindex line group formats
+@cindex formats for if-then-else line groups
+
+Line group formats let you specify formats suitable for many
+applications that allow if-then-else input, including programming
+languages and text formatting languages. A line group format specifies
+the output format for a contiguous group of similar lines.
+
+For example, the following command compares the TeX files @file{old}
+and @file{new}, and outputs a merged file in which old regions are
+surrounded by @samp{\begin@{em@}}-@samp{\end@{em@}} lines, and new
+regions are surrounded by @samp{\begin@{bf@}}-@samp{\end@{bf@}} lines.
+
+@example
+diff \
+ --old-group-format='\begin@{em@}
+%<\end@{em@}
+' \
+ --new-group-format='\begin@{bf@}
+%>\end@{bf@}
+' \
+ old new
+@end example
+
+The following command is equivalent to the above example, but it is a
+little more verbose, because it spells out the default line group formats.
+
+@example
+diff \
+ --old-group-format='\begin@{em@}
+%<\end@{em@}
+' \
+ --new-group-format='\begin@{bf@}
+%>\end@{bf@}
+' \
+ --unchanged-group-format='%=' \
+ --changed-group-format='\begin@{em@}
+%<\end@{em@}
+\begin@{bf@}
+%>\end@{bf@}
+' \
+ old new
+@end example
+
+Here is a more advanced example, which outputs a diff listing with
+headers containing line numbers in a ``plain English'' style.
+
+@example
+diff \
+ --unchanged-group-format='' \
+ --old-group-format='-------- %dn line%(n=1?:s) deleted at %df:
+%<' \
+ --new-group-format='-------- %dN line%(N=1?:s) added after %de:
+%>' \
+ --changed-group-format='-------- %dn line%(n=1?:s) changed at %df:
+%<-------- to:
+%>' \
+ old new
+@end example
+
+To specify a line group format, use @code{diff} with one of the options
+listed below. You can specify up to four line group formats, one for
+each kind of line group. You should quote @var{format}, because it
+typically contains shell metacharacters.
+
+@table @samp
+@item --old-group-format=@var{format}
+These line groups are hunks containing only lines from the first file.
+The default old group format is the same as the changed group format if
+it is specified; otherwise it is a format that outputs the line group as-is.
+
+@item --new-group-format=@var{format}
+These line groups are hunks containing only lines from the second
+file. The default new group format is same as the the changed group
+format if it is specified; otherwise it is a format that outputs the
+line group as-is.
+
+@item --changed-group-format=@var{format}
+These line groups are hunks containing lines from both files. The
+default changed group format is the concatenation of the old and new
+group formats.
+
+@item --unchanged-group-format=@var{format}
+These line groups contain lines common to both files. The default
+unchanged group format is a format that outputs the line group as-is.
+@end table
+
+In a line group format, ordinary characters represent themselves;
+conversion specifications start with @samp{%} and have one of the
+following forms.
+
+@table @samp
+@item %<
+stands for the lines from the first file, including the trailing newline.
+Each line is formatted according to the old line format (@pxref{Line Formats}).
+
+@item %>
+stands for the lines from the second file, including the trailing newline.
+Each line is formatted according to the new line format.
+
+@item %=
+stands for the lines common to both files, including the trailing newline.
+Each line is formatted according to the unchanged line format.
+
+@item %%
+stands for @samp{%}.
+
+@item %c'@var{C}'
+where @var{C} is a single character, stands for @var{C}.
+@var{C} may not be a backslash or an apostrophe.
+For example, @samp{%c':'} stands for a colon, even inside
+the then-part of an if-then-else format, which a colon would
+normally terminate.
+
+@item %c'\@var{O}'
+where @var{O} is a string of 1, 2, or 3 octal digits,
+stands for the character with octal code @var{O}.
+For example, @samp{%c'\0'} stands for a null character.
+
+@item @var{F}@var{n}
+where @var{F} is a @code{printf} conversion specification and @var{n} is one
+of the following letters, stands for @var{n}'s value formatted with @var{F}.
+
+@table @samp
+@item e
+The line number of the line just before the group in the old file.
+
+@item f
+The line number of the first line in the group in the old file;
+equals @var{e} + 1.
+
+@item l
+The line number of the last line in the group in the old file.
+
+@item m
+The line number of the line just after the group in the old file;
+equals @var{l} + 1.
+
+@item n
+The number of lines in the group in the old file; equals @var{l} - @var{f} + 1.
+
+@item E, F, L, M, N
+Likewise, for lines in the new file.
+
+@end table
+
+The @code{printf} conversion specification can be @samp{%d},
+@samp{%o}, @samp{%x}, or @samp{%X}, specifying decimal, octal,
+lower case hexadecimal, or upper case hexadecimal output
+respectively. After the @samp{%} the following options can appear in
+sequence: a @samp{-} specifying left-justification; an integer
+specifying the minimum field width; and a period followed by an
+optional integer specifying the minimum number of digits.
+For example, @samp{%5dN} prints the number of new lines in the group
+in a field of width 5 characters, using the @code{printf} format @code{"%5d"}.
+
+@item (@var{A}=@var{B}?@var{T}:@var{E})
+If @var{A} equals @var{B} then @var{T} else @var{E}.
+@var{A} and @var{B} are each either a decimal constant
+or a single letter interpreted as above.
+This format spec is equivalent to @var{T} if
+@var{A}'s value equals @var{B}'s; otherwise it is equivalent to @var{E}.
+
+For example, @samp{%(N=0?no:%dN) line%(N=1?:s)} is equivalent to
+@samp{no lines} if @var{N} (the number of lines in the group in the the
+new file) is 0, to @samp{1 line} if @var{N} is 1, and to @samp{%dN lines}
+otherwise.
+@end table
+
+@node Line Formats, Detailed If-then-else, Line Group Formats, If-then-else
+@subsection Line Formats
+@cindex line formats
+
+Line formats control how each line taken from an input file is
+output as part of a line group in if-then-else format.
+
+For example, the following command outputs text with a one-column
+change indicator to the left of the text. The first column of output
+is @samp{-} for deleted lines, @samp{|} for added lines, and a space
+for unchanged lines. The formats contain newline characters where
+newlines are desired on output.
+
+@example
+diff \
+ --old-line-format='-%l
+' \
+ --new-line-format='|%l
+' \
+ --unchanged-line-format=' %l
+' \
+ old new
+@end example
+
+To specify a line format, use one of the following options. You should
+quote @var{format}, since it often contains shell metacharacters.
+
+@table @samp
+@item --old-line-format=@var{format}
+formats lines just from the first file.
+
+@item --new-line-format=@var{format}
+formats lines just from the second file.
+
+@item --unchanged-line-format=@var{format}
+formats lines common to both files.
+
+@item --line-format=@var{format}
+formats all lines; in effect, it sets all three above options simultaneously.
+@end table
+
+In a line format, ordinary characters represent themselves;
+conversion specifications start with @samp{%} and have one of the
+following forms.
+
+@table @samp
+@item %l
+stands for the the contents of the line, not counting its trailing
+newline (if any). This format ignores whether the line is incomplete;
+@xref{Incomplete Lines}.
+
+@item %L
+stands for the the contents of the line, including its trailing newline
+(if any). If a line is incomplete, this format preserves its
+incompleteness.
+
+@item %%
+stands for @samp{%}.
+
+@item %c'@var{C}'
+where @var{C} is a single character, stands for @var{C}.
+@var{C} may not be a backslash or an apostrophe.
+For example, @samp{%c':'} stands for a colon.
+
+@item %c'\@var{O}'
+where @var{O} is a string of 1, 2, or 3 octal digits,
+stands for the character with octal code @var{O}.
+For example, @samp{%c'\0'} stands for a null character.
+
+@item @var{F}n
+where @var{F} is a @code{printf} conversion specification,
+stands for the line number formatted with @var{F}.
+For example, @samp{%.5dn} prints the line number using the
+@code{printf} format @code{"%.5d"}. @xref{Line Group Formats}, for
+more about printf conversion specifications.
+
+@end table
+
+The default line format is @samp{%l} followed by a newline character.
+
+If the input contains tab characters and it is important that they line
+up on output, you should ensure that @samp{%l} or @samp{%L} in a line
+format is just after a tab stop (e.g.@: by preceding @samp{%l} or
+@samp{%L} with a tab character), or you should use the @samp{-t} or
+@samp{--expand-tabs} option.
+
+Taken together, the line and line group formats let you specify many
+different formats. For example, the following command uses a format
+similar to @code{diff}'s normal format. You can tailor this command
+to get fine control over @code{diff}'s output.
+
+@example
+diff \
+ --old-line-format='< %l
+' \
+ --new-line-format='> %l
+' \
+ --old-group-format='%df%(f=l?:,%dl)d%dE
+%<' \
+ --new-group-format='%dea%dF%(F=L?:,%dL)
+%>' \
+ --changed-group-format='%df%(f=l?:,%dl)c%dF%(F=L?:,%dL)
+%<---
+%>' \
+ --unchanged-group-format='' \
+ old new
+@end example
+
+@node Detailed If-then-else, Example If-then-else, Line Formats, If-then-else
+@subsection Detailed Description of If-then-else Format
+
+For lines common to both files, @code{diff} uses the unchanged line
+group format. For each hunk of differences in the merged output
+format, if the hunk contains only lines from the first file,
+@code{diff} uses the old line group format; if the hunk contains only
+lines from the second file, @code{diff} uses the new group format;
+otherwise, @code{diff} uses the changed group format.
+
+The old, new, and unchanged line formats specify the output format of
+lines from the first file, lines from the second file, and lines common
+to both files, respectively.
+
+The option @samp{--ifdef=@var{name}} is equivalent to
+the following sequence of options using shell syntax:
+
+@example
+--old-group-format='#ifndef @var{name}
+%<#endif /* not @var{name} */
+' \
+--new-group-format='#ifdef @var{name}
+%>#endif /* @var{name} */
+' \
+--unchanged-group-format='%=' \
+--changed-group-format='#ifndef @var{name}
+%<#else /* @var{name} */
+%>#endif /* @var{name} */
+'
+@end example
+
+You should carefully check the @code{diff} output for proper nesting.
+For example, when using the the @samp{-D @var{name}} or
+@samp{--ifdef=@var{name}} option, you should check that if the
+differing lines contain any of the C preprocessor directives
+@samp{#ifdef}, @samp{#ifndef}, @samp{#else}, @samp{#elif}, or
+@samp{#endif}, they are nested properly and match. If they don't, you
+must make corrections manually. It is a good idea to carefully check
+the resulting code anyway to make sure that it really does what you
+want it to; depending on how the input files were produced, the output
+might contain duplicate or otherwise incorrect code.
+
+The @code{patch} @samp{-D @var{name}} option behaves just like
+the @code{diff} @samp{-D @var{name}} option, except it operates on
+a file and a diff to produce a merged file; @xref{patch Options}.
+
+@node Example If-then-else, , Detailed If-then-else, If-then-else
+@subsection An Example of If-then-else Format
+
+Here is the output of @samp{diff -DTWO lao tzu} (@pxref{Sample
+diff Input}, for the complete contents of the two files):
+
+@example
+#ifndef TWO
+The Way that can be told of is not the eternal Way;
+The name that can be named is not the eternal name.
+#endif /* not TWO */
+The Nameless is the origin of Heaven and Earth;
+#ifndef TWO
+The Named is the mother of all things.
+#else /* TWO */
+The named is the mother of all things.
+
+#endif /* TWO */
+Therefore let there always be non-being,
+ so we may see their subtlety,
+And let there always be being,
+ so we may see their outcome.
+The two are the same,
+But after they are produced,
+ they have different names.
+#ifdef TWO
+They both may be called deep and profound.
+Deeper and more profound,
+The door of all subtleties!
+#endif /* TWO */
+@end example
+
+@node Comparing Directories, Adjusting Output, Output Formats, Top
+@chapter Comparing Directories
+
+You can use @code{diff} to compare some or all of the files in two
+directory trees. When both file name arguments to @code{diff} are
+directories, it compares each file that is contained in both
+directories, examining file names in alphabetical order. Normally
+@code{diff} is silent about pairs of files that contain no differences,
+but if you use the @samp{-s} or @samp{--report-identical-files} option,
+it reports pairs of identical files. Normally @code{diff} reports
+subdirectories common to both directories without comparing
+subdirectories' files, but if you use the @samp{-r} or
+@samp{--recursive} option, it compares every corresponding pair of files
+in the directory trees, as many levels deep as they go.
+
+For file names that are in only one of the directories, @code{diff}
+normally does not show the contents of the file that exists; it reports
+only that the file exists in that directory and not in the other. You
+can make @code{diff} act as though the file existed but was empty in the
+other directory, so that it outputs the entire contents of the file that
+actually exists. (It is output as either an insertion or a
+deletion, depending on whether it is in the first or the second
+directory given.) To do this, use the @samp{-N} or @samp{--new-file}
+option.
+
+If the older directory contains one or more large files that are not in
+the newer directory, you can make the patch smaller by using the
+@samp{-P} or @samp{--unidirectional-new-file} option instead of @samp{-N}.
+This option is like @samp{-N} except that it only inserts the contents
+of files that appear in the second directory but not the first (that is,
+files that were added). At the top of the patch, write instructions for
+the user applying the patch to remove the files that were deleted before
+applying the patch. @xref{Making Patches}, for more discussion of
+making patches for distribution.
+
+To ignore some files while comparing directories, use the @samp{-x
+@var{pattern}} or @samp{--exclude=@var{pattern}} option. This option
+ignores any files or subdirectories whose base names match the shell
+pattern @var{pattern}. Unlike in the shell, a period at the start of
+the base of a file name matches a wildcard at the start of a pattern.
+You should enclose @var{pattern} in quotes so that the shell does not
+expand it. For example, the option @samp{-x '*.[ao]'} ignores any file
+whose name ends with @samp{.a} or @samp{.o}.
+
+This option accumulates if you specify it more than once. For example,
+using the options @samp{-x 'RCS' -x '*,v'} ignores any file or
+subdirectory whose base name is @samp{RCS} or ends with @samp{,v}.
+
+If you need to give this option many times, you can instead put the
+patterns in a file, one pattern per line, and use the @samp{-X
+@var{file}} or @samp{--exclude-from=@var{file}} option.
+
+If you have been comparing two directories and stopped partway through,
+later you might want to continue where you left off. You can do this by
+using the @samp{-S @var{file}} or @samp{--starting-file=@var{file}}
+option. This compares only the file @var{file} and all alphabetically
+later files in the topmost directory level.
+
+@node Adjusting Output, diff Performance, Comparing Directories, Top
+@chapter Making @code{diff} Output Prettier
+
+@code{diff} provides several ways to adjust the appearance of its output.
+These adjustments can be applied to any output format.
+
+@menu
+* Tabs:: Preserving the alignment of tabstops.
+* Pagination:: Page numbering and timestamping @code{diff} output.
+@end menu
+
+@node Tabs, Pagination, , Adjusting Output
+@section Preserving Tabstop Alignment
+@cindex tabstop alignment
+@cindex aligning tabstops
+
+The lines of text in some of the @code{diff} output formats are preceded
+by one or two characters that indicate whether the text is inserted,
+deleted, or changed. The addition of those characters can cause tabs to
+move to the next tabstop, throwing off the alignment of columns in the
+line. GNU @code{diff} provides two ways to make tab-aligned columns
+line up correctly.
+
+The first way is to have @code{diff} convert all tabs into the correct
+number of spaces before outputting them; select this method with the
+@samp{-t} or @samp{--expand-tabs} option. @code{diff} assumes that
+tabstops are set every 8 columns. To use this form of output with
+@code{patch}, you must give @code{patch} the @samp{-l} or
+@samp{--ignore-white-space} option (@pxref{Changed White Space}, for more
+information).
+
+The other method for making tabs line up correctly is to add a tab
+character instead of a space after the indicator character at the
+beginning of the line. This ensures that all following tab characters
+are in the same position relative to tabstops that they were in the
+original files, so that the output is aligned correctly. Its
+disadvantage is that it can make long lines too long to fit on one line
+of the screen or the paper. It also does not work with the unified
+output format, which does not have a space character after the change
+type indicator character. Select this method with the @samp{-T} or
+@samp{--initial-tab} option.
+
+@node Pagination, , Tabs, Adjusting Output
+@section Paginating @code{diff} Output
+@cindex paginating @code{diff} output
+
+It can be convenient to have long output page-numbered and time-stamped.
+The @samp{-l} and @samp{--paginate} options do this by sending the
+@code{diff} output through the @code{pr} program. Here is what the page
+header might look like for @samp{diff -lc lao tzu}:
+
+@example
+Mar 11 13:37 1991 diff -lc lao tzu Page 1
+@end example
+
+@node diff Performance, Comparing Three Files, Adjusting Output, Top
+@chapter @code{diff} Performance Tradeoffs
+@cindex performance of @code{diff}
+
+GNU @code{diff} runs quite efficiently; however, in some circumstances
+you can cause it to run faster or produce a more compact set of changes.
+There are two ways that you can affect the performance of GNU
+@code{diff} by changing the way it compares files.
+
+Performance has more than one dimension. These options improve one
+aspect of performance at the cost of another, or they improve
+performance in some cases while hurting it in others.
+
+The way that GNU @code{diff} determines which lines have changed always
+comes up with a near-minimal set of differences. Usually it is good
+enough for practical purposes. If the @code{diff} output is large, you
+might want @code{diff} to use a modified algorithm that sometimes
+produces a smaller set of differences. The @samp{-d} or
+@samp{--minimal} option does this; however, it can also cause
+@code{diff} to run more slowly than usual, so it is not the default
+behavior.
+
+When the files you are comparing are large and have small groups of
+changes scattered throughout them, you can use the @samp{-H} or
+@samp{--speed-large-files} option to make a different modification to
+the algorithm that @code{diff} uses. If the input files have a constant
+small density of changes, this option speeds up the comparisons without
+changing the output. If not, @code{diff} might produce a larger set of
+differences; however, the output will still be correct.
+
+Normally @code{diff} discards the prefix and suffix that is common to
+both files before it attempts to find a minimal set of differences.
+This makes @code{diff} run faster, but occasionally it may produce
+non-minimal output. The @samp{--horizon-lines=@var{lines}} option
+prevents @code{diff} from discarding the last @var{lines} lines of the
+prefix and the first @var{lines} lines of the suffix. This gives
+@code{diff} further opportunities to find a minimal output.
+
+@node Comparing Three Files, diff3 Merging, diff Performance, Top
+@chapter Comparing Three Files
+@cindex comparing three files
+@cindex format of @code{diff3} output
+
+Use the program @code{diff3} to compare three files and show any
+differences among them. (@code{diff3} can also merge files; see
+@ref{diff3 Merging}).
+
+The ``normal'' @code{diff3} output format shows each hunk of
+differences without surrounding context. Hunks are labeled depending
+on whether they are two-way or three-way, and lines are annotated by
+their location in the input files.
+
+@xref{Invoking diff3}, for more information on how to run @code{diff3}.
+
+@menu
+* Sample diff3 Input:: Sample @code{diff3} input for examples.
+* Detailed diff3 Normal:: A detailed description of normal output format.
+* diff3 Hunks:: The format of normal output format.
+* Example diff3 Normal:: Sample output in the normal format.
+@end menu
+
+@node Sample diff3 Input, Detailed diff3 Normal, , Comparing Three Files
+@section A Third Sample Input File
+@cindex @code{diff3} sample input
+@cindex sample input for @code{diff3}
+
+Here is a third sample file that will be used in examples to illustrate
+the output of @code{diff3} and how various options can change it. The
+first two files are the same that we used for @code{diff} (@pxref{Sample
+diff Input}). This is the third sample file, called @file{tao}:
+
+@example
+The Way that can be told of is not the eternal Way;
+The name that can be named is not the eternal name.
+The Nameless is the origin of Heaven and Earth;
+The named is the mother of all things.
+
+Therefore let there always be non-being,
+ so we may see their subtlety,
+And let there always be being,
+ so we may see their result.
+The two are the same,
+But after they are produced,
+ they have different names.
+
+ -- The Way of Lao-Tzu, tr. Wing-tsit Chan
+@end example
+
+@node Detailed diff3 Normal, diff3 Hunks, Sample diff3 Input, Comparing Three Files
+@section Detailed Description of @code{diff3} Normal Format
+
+Each hunk begins with a line marked @samp{====}. Three-way hunks have
+plain @samp{====} lines, and two-way hunks have @samp{1}, @samp{2}, or
+@samp{3} appended to specify which of the three input files differ in
+that hunk. The hunks contain copies of two or three sets of input
+lines each preceded by one or two commands identifying where the lines
+came from.
+
+Normally, two spaces precede each copy of an input line to distinguish
+it from the commands. But with the @samp{-T} or @samp{--initial-tab}
+option, @code{diff3} uses a tab instead of two spaces; this lines up
+tabs correctly. @xref{Tabs}, for more information.
+
+Commands take the following forms:
+
+@table @samp
+@item @var{file}:@var{l}a
+This hunk appears after line @var{l} of file @var{file}, and
+contains no lines in that file. To edit this file to yield the other
+files, one must append hunk lines taken from the other files. For
+example, @samp{1:11a} means that the hunk follows line 11 in the first
+file and contains no lines from that file.
+
+@item @var{file}:@var{r}c
+This hunk contains the lines in the range @var{r} of file @var{file}.
+The range @var{r} is a comma-separated pair of line numbers, or just one
+number if the range is a singleton. To edit this file to yield the
+other files, one must change the specified lines to be the lines taken
+from the other files. For example, @samp{2:11,13c} means that the hunk
+contains lines 11 through 13 from the second file.
+@end table
+
+If the last line in a set of input lines is incomplete
+(@pxref{Incomplete Lines}), it is distinguished on output from a full
+line by a following line that starts with @samp{\}.
+
+@node diff3 Hunks, Example diff3 Normal, Detailed diff3 Normal, Comparing Three Files
+@section @code{diff3} Hunks
+@cindex hunks for @code{diff3}
+@cindex @code{diff3} hunks
+
+Groups of lines that differ in two or three of the input files are
+called @dfn{diff3 hunks}, by analogy with @code{diff} hunks
+(@pxref{Hunks}). If all three input files differ in a @code{diff3}
+hunk, the hunk is called a @dfn{three-way hunk}; if just two input files
+differ, it is a @dfn{two-way hunk}.
+
+As with @code{diff}, several solutions are possible. When comparing the
+files @samp{A}, @samp{B}, and @samp{C}, @code{diff3} normally finds
+@code{diff3} hunks by merging the two-way hunks output by the two
+commands @samp{diff A B} and @samp{diff A C}. This does not necessarily
+minimize the size of the output, but exceptions should be rare.
+
+For example, suppose @file{F} contains the three lines @samp{a},
+@samp{b}, @samp{f}, @file{G} contains the lines @samp{g}, @samp{b},
+@samp{g}, and @file{H} contains the lines @samp{a}, @samp{b},
+@samp{h}. @samp{diff3 F G H} might output the following:
+
+@example
+====2
+1:1c
+3:1c
+ a
+2:1c
+ g
+====
+1:3c
+ f
+2:3c
+ g
+3:3c
+ h
+@end example
+
+@noindent
+because it found a two-way hunk containing @samp{a} in the first and
+third files and @samp{g} in the second file, then the single line
+@samp{b} common to all three files, then a three-way hunk containing
+the last line of each file.
+
+@node Example diff3 Normal, , diff3 Hunks, Comparing Three Files
+@section An Example of @code{diff3} Normal Format
+
+Here is the output of the command @samp{diff3 lao tzu tao}
+(@pxref{Sample diff3 Input}, for the complete contents of the files).
+Notice that it shows only the lines that are different among the three
+files.
+
+@example
+====2
+1:1,2c
+3:1,2c
+ The Way that can be told of is not the eternal Way;
+ The name that can be named is not the eternal name.
+2:0a
+====1
+1:4c
+ The Named is the mother of all things.
+2:2,3c
+3:4,5c
+ The named is the mother of all things.
+
+====3
+1:8c
+2:7c
+ so we may see their outcome.
+3:9c
+ so we may see their result.
+====
+1:11a
+2:11,13c
+ They both may be called deep and profound.
+ Deeper and more profound,
+ The door of all subtleties!
+3:13,14c
+
+ -- The Way of Lao-Tzu, tr. Wing-tsit Chan
+@end example
+
+@node diff3 Merging, Interactive Merging, Comparing Three Files, Top
+@chapter Merging From a Common Ancestor
+@cindex merging from a common ancestor
+
+When two people have made changes to copies of the same file,
+@code{diff3} can produce a merged output that contains both sets of
+changes together with warnings about conflicts.
+
+One might imagine programs with names like @code{diff4} and @code{diff5}
+to compare more than three files simultaneously, but in practice the
+need rarely arises. You can use @code{diff3} to merge three or more
+sets of changes to a file by merging two change sets at a time.
+
+@code{diff3} can incorporate changes from two modified versions into a
+common preceding version. This lets you merge the sets of changes
+represented by the two newer files. Specify the common ancestor version
+as the second argument and the two newer versions as the first and third
+arguments, like this:
+
+@example
+diff3 @var{mine} @var{older} @var{yours}
+@end example
+
+@noindent
+You can remember the order of the arguments by noting that they are in
+alphabetical order.
+
+@cindex conflict
+@cindex overlap
+You can think of this as subtracting @var{older} from @var{yours} and
+adding the result to @var{mine}, or as merging into @var{mine} the
+changes that would turn @var{older} into @var{yours}. This merging is
+well-defined as long as @var{mine} and @var{older} match in the
+neighborhood of each such change. This fails to be true when all three
+input files differ or when only @var{older} differs; we call this
+a @dfn{conflict}. When all three input files differ, we call the
+conflict an @dfn{overlap}.
+
+@code{diff3} gives you several ways to handle overlaps and conflicts.
+You can omit overlaps or conflicts, or select only overlaps,
+or mark conflicts with special @samp{<<<<<<<} and @samp{>>>>>>>} lines.
+
+@code{diff3} can output the merge results as an @code{ed} script that
+that can be applied to the first file to yield the merged output.
+However, it is usually better to have @code{diff3} generate the merged
+output directly; this bypasses some problems with @code{ed}.
+
+@menu
+* Which Changes:: Selecting changes to incorporate.
+* Marking Conflicts:: Marking conflicts.
+* Bypassing ed:: Generating merged output directly.
+* Merging Incomplete Lines:: How @code{diff3} merges incomplete lines.
+* Saving the Changed File:: Emulating System V behavior.
+@end menu
+
+@node Which Changes, Marking Conflicts, , diff3 Merging
+@section Selecting Which Changes to Incorporate
+@cindex overlapping change, selection of
+@cindex unmerged change
+
+You can select all unmerged changes from @var{older} to @var{yours} for merging
+into @var{mine} with the @samp{-e} or @samp{--ed} option. You can
+select only the nonoverlapping unmerged changes with @samp{-3} or
+@samp{--easy-only}, and you can select only the overlapping changes with
+@samp{-x} or @samp{--overlap-only}.
+
+The @samp{-e}, @samp{-3} and @samp{-x} options select only
+@dfn{unmerged changes}, i.e.@: changes where @var{mine} and @var{yours}
+differ; they ignore changes from @var{older} to @var{yours} where
+@var{mine} and @var{yours} are identical, because they assume that such
+changes have already been merged. If this assumption is not a safe
+one, you can use the @samp{-A} or @samp{--show-all} option
+(@pxref{Marking Conflicts}).
+
+Here is the output of the command @code{diff3} with each of these three
+options (@pxref{Sample diff3 Input}, for the complete contents of the files).
+Notice that @samp{-e} outputs the union of the disjoint sets of changes
+output by @samp{-3} and @samp{-x}.
+
+Output of @samp{diff3 -e lao tzu tao}:
+@example
+11a
+
+ -- The Way of Lao-Tzu, tr. Wing-tsit Chan
+.
+8c
+ so we may see their result.
+.
+@end example
+
+Output of @samp{diff3 -3 lao tzu tao}:
+@example
+8c
+ so we may see their result.
+.
+@end example
+
+Output of @samp{diff3 -x lao tzu tao}:
+@example
+11a
+
+ -- The Way of Lao-Tzu, tr. Wing-tsit Chan
+.
+@end example
+
+@node Marking Conflicts, Bypassing ed, Which Changes, diff3 Merging
+@section Marking Conflicts
+@cindex conflict marking
+@cindex @samp{<<<<<<<} for marking conflicts
+
+@code{diff3} can mark conflicts in the merged output by
+bracketing them with special marker lines. A conflict
+that comes from two files @var{A} and @var{B} is marked as follows:
+
+@example
+<<<<<<< @var{A}
+@r{lines from @var{A}}
+=======
+@r{lines from @var{B}}
+>>>>>>> @var{B}
+@end example
+
+A conflict that comes from three files @var{A}, @var{B} and @var{C} is
+marked as follows:
+
+@example
+<<<<<<< @var{A}
+@r{lines from @var{A}}
+||||||| @var{B}
+@r{lines from @var{B}}
+=======
+@r{lines from @var{C}}
+>>>>>>> @var{C}
+@end example
+
+The @samp{-A} or @samp{--show-all} option acts like the @samp{-e}
+option, except that it brackets conflicts, and it outputs all changes
+from @var{older} to @var{yours}, not just the unmerged changes. Thus,
+given the sample input files (@pxref{Sample diff3 Input}), @samp{diff3
+-A lao tzu tao} puts brackets around the conflict where only @file{tzu}
+differs:
+
+@example
+<<<<<<< tzu
+=======
+The Way that can be told of is not the eternal Way;
+The name that can be named is not the eternal name.
+>>>>>>> tao
+@end example
+
+And it outputs the three-way conflict as follows:
+
+@example
+<<<<<<< lao
+||||||| tzu
+They both may be called deep and profound.
+Deeper and more profound,
+The door of all subtleties!
+=======
+
+ -- The Way of Lao-Tzu, tr. Wing-tsit Chan
+>>>>>>> tao
+@end example
+
+The @samp{-E} or @samp{--show-overlap} option outputs less information
+than the @samp{-A} or @samp{--show-all} option, because it outputs only
+unmerged changes, and it never outputs the contents of the second
+file. Thus the @samp{-E} option acts like the @samp{-e} option,
+except that it brackets the first and third files from three-way
+overlapping changes. Similarly, @samp{-X} acts like @samp{-x}, except
+it brackets all its (necessarily overlapping) changes. For example,
+for the three-way overlapping change above, the @samp{-E} and @samp{-X}
+options output the following:
+
+@example
+<<<<<<< lao
+=======
+
+ -- The Way of Lao-Tzu, tr. Wing-tsit Chan
+>>>>>>> tao
+@end example
+
+If you are comparing files that have meaningless or uninformative names,
+you can use the @samp{-L @var{label}} or @samp{--label=@var{label}}
+option to show alternate names in the @samp{<<<<<<<}, @samp{|||||||}
+and @samp{>>>>>>>} brackets. This option can be given up to three
+times, once for each input file. Thus @samp{diff3 -A -L X -L Y -L Z A
+B C} acts like @samp{diff3 -A A B C}, except that the output looks like
+it came from files named @samp{X}, @samp{Y} and @samp{Z} rather than
+from files named @samp{A}, @samp{B} and @samp{C}.
+
+@node Bypassing ed, Merging Incomplete Lines, Marking Conflicts, diff3 Merging
+@section Generating the Merged Output Directly
+@cindex merged @code{diff3} format
+
+With the @samp{-m} or @samp{--merge} option, @code{diff3} outputs the
+merged file directly. This is more efficient than using @code{ed} to
+generate it, and works even with non-text files that @code{ed} would
+reject. If you specify @samp{-m} without an @code{ed} script option,
+@samp{-A} (@samp{--show-all}) is assumed.
+
+For example, the command @samp{diff3 -m lao tzu tao}
+(@pxref{Sample diff3 Input} for a copy of the input files) would output
+the following:
+
+@example
+<<<<<<< tzu
+=======
+The Way that can be told of is not the eternal Way;
+The name that can be named is not the eternal name.
+>>>>>>> tao
+The Nameless is the origin of Heaven and Earth;
+The Named is the mother of all things.
+Therefore let there always be non-being,
+ so we may see their subtlety,
+And let there always be being,
+ so we may see their result.
+The two are the same,
+But after they are produced,
+ they have different names.
+<<<<<<< lao
+||||||| tzu
+They both may be called deep and profound.
+Deeper and more profound,
+The door of all subtleties!
+=======
+
+ -- The Way of Lao-Tzu, tr. Wing-tsit Chan
+>>>>>>> tao
+@end example
+
+@node Merging Incomplete Lines, Saving the Changed File, Bypassing ed, diff3 Merging
+@section How @code{diff3} Merges Incomplete Lines
+@cindex incomplete line merging
+
+With @samp{-m}, incomplete lines (@pxref{Incomplete Lines}) are simply
+copied to the output as they are found; if the merged output ends in an
+conflict and one of the input files ends in an incomplete
+line, succeeding @samp{|||||||}, @samp{=======} or @samp{>>>>>>>}
+brackets appear somewhere other than the start of a line because
+they are appended to the incomplete line.
+
+Without @samp{-m}, if an @code{ed} script option is specified and an
+incomplete line is found, @code{diff3} generates a warning and acts as
+if a newline had been present.
+
+@node Saving the Changed File, , Merging Incomplete Lines, diff3 Merging
+@section Saving the Changed File
+@cindex System V @code{diff3} compatibility
+
+Traditional Unix @code{diff3} generates an @code{ed} script without the
+trailing @samp{w} and and @samp{q} commands that save the changes.
+System V @code{diff3} generates these extra commands. GNU @code{diff3}
+normally behaves like traditional Unix @code{diff3}, but with the
+@samp{-i} option it behaves like System V @code{diff3} and appends the
+@samp{w} and @samp{q} commands.
+
+The @samp{-i} option requires one of the @code{ed} script options
+@samp{-AeExX3}, and is incompatible with the merged output option
+@samp{-m}.
+
+@node Interactive Merging, Merging with patch, diff3 Merging, Top
+@chapter Interactive Merging with @code{sdiff}
+@cindex diff merging
+@cindex interactive merging
+
+With @code{sdiff}, you can merge two files interactively based on a
+side-by-side @samp{-y} format comparison (@pxref{Side by Side}). Use
+@samp{-o @var{file}} or @samp{--output=@var{file}} to specify where to
+put the merged text. @xref{Invoking sdiff}, for more details on the
+options to @code{sdiff}.
+
+Another way to merge files interactively is to use the Emacs Lisp
+package @code{emerge}. @xref{emerge, , emerge, emacs, The GNU Emacs
+Manual}, for more information.
+
+@menu
+* sdiff Option Summary::Summary of @code{sdiff} options.
+* Merge Commands:: Merging two files interactively.
+@end menu
+
+@node sdiff Option Summary, Merge Commands, , Interactive Merging
+@section Specifying @code{diff} Options to @code{sdiff}
+@cindex @code{sdiff} output format
+
+The following @code{sdiff} options have the same meaning as for
+@code{diff}. @xref{diff Options}, for the use of these options.
+
+@example
+-a -b -d -i -t -v
+-B -H -I @var{regexp}
+
+--ignore-blank-lines --ignore-case
+--ignore-matching-lines=@var{regexp} --ignore-space-change
+--left-column --minimal --speed-large-files
+--suppress-common-lines --expand-tabs
+--text --version --width=@var{columns}
+@end example
+
+For historical reasons, @code{sdiff} has alternate names for some
+options. The @samp{-l} option is equivalent to the @samp{--left-column}
+option, and similarly @samp{-s} is equivalent to
+@samp{--suppress-common-lines}. The meaning of the @code{sdiff}
+@samp{-w} and @samp{-W} options is interchanged from that of
+@code{diff}: with @code{sdiff}, @samp{-w @var{columns}} is equivalent to
+@samp{--width=@var{columns}}, and @samp{-W} is equivalent to
+@samp{--ignore-all-space}. @code{sdiff} without the @samp{-o} option is
+equivalent to @code{diff} with the @samp{-y} or @samp{--side-by-side}
+option (@pxref{Side by Side}).
+
+@node Merge Commands, , sdiff Option Summary, Interactive Merging
+@section Merge Commands
+@cindex merge commands
+@cindex merging interactively
+
+Groups of common lines, with a blank gutter, are copied from the first
+file to the output. After each group of differing lines, @code{sdiff}
+prompts with @samp{%} and pauses, waiting for one of the following
+commands. Follow each command with @key{RET}.
+
+@table @samp
+@item e
+Discard both versions.
+Invoke a text editor on an empty temporary file,
+then copy the resulting file to the output.
+
+@item eb
+Concatenate the two versions, edit the result in a temporary file,
+then copy the edited result to the output.
+
+@item el
+Edit a copy of the left version, then copy the result to the output.
+
+@item er
+Edit a copy of the right version, then copy the result to the output.
+
+@item l
+Copy the left version to the output.
+
+@item q
+Quit.
+
+@item r
+Copy the right version to the output.
+
+@item s
+Silently copy common lines.
+
+@item v
+Verbosely copy common lines. This is the default.
+@end table
+
+The text editor invoked is specified by the @code{EDITOR} environment
+variable if it is set. The default is system-dependent.
+
+@node Merging with patch, Making Patches, Interactive Merging, Top
+@chapter Merging with @code{patch}
+
+@code{patch} takes comparison output produced by @code{diff} and applies
+the differences to a copy of the original file, producing a patched
+version. With @code{patch}, you can distribute just the changes to a
+set of files instead of distributing the entire file set; your
+correspondents can apply @code{patch} to update their copy of the files
+with your changes. @code{patch} automatically determines the diff
+format, skips any leading or trailing headers, and uses the headers to
+determine which file to patch. This lets your correspondents feed an
+article or message containing a difference listing directly to
+@code{patch}.
+
+@code{patch} detects and warns about common problems like forward
+patches. It saves the original version of the files it patches, and
+saves any patches that it could not apply. It can also maintain a
+@code{patchlevel.h} file to ensures that your correspondents apply
+diffs in the proper order.
+
+@code{patch} accepts a series of diffs in its standard input, usually
+separated by headers that specify which file to patch. It applies
+@code{diff} hunks (@pxref{Hunks}) one by one. If a hunk does not
+exactly match the original file, @code{patch} uses heuristics to try to
+patch the file as well as it can. If no approximate match can be found,
+@code{patch} rejects the hunk and skips to the next hunk. @code{patch}
+normally replaces each file @var{f} with its new version, saving the
+original file in @samp{@var{f}.orig}, and putting reject hunks (if any)
+into @samp{@var{f}.rej}.
+
+@xref{Invoking patch}, for detailed information on the options to
+@code{patch}. @xref{Backups}, for more information on how
+@code{patch} names backup files. @xref{Rejects}, for more information
+on where @code{patch} puts reject hunks.
+
+@menu
+* patch Input:: Selecting the type of @code{patch} input.
+* Imperfect:: Dealing with imperfect patches.
+* Empty Files:: Removing empty files after patching.
+* Multiple Patches:: Handling multiple patches in a file specially.
+* patch Messages:: Messages and questions @code{patch} can produce.
+@end menu
+
+@node patch Input, Imperfect, , Merging with patch
+@section Selecting the @code{patch} Input Format
+@cindex @code{patch} input format
+
+@code{patch} normally determines which @code{diff} format the patch
+file uses by examining its contents. For patch files that contain
+particularly confusing leading text, you might need to use one of the
+following options to force @code{patch} to interpret the patch file as a
+certain format of diff. The output formats listed here are the only
+ones that @code{patch} can understand.
+
+@table @samp
+@item -c
+@itemx --context
+context diff.
+
+@item -e
+@itemx --ed
+@code{ed} script.
+
+@item -n
+@itemx --normal
+normal diff.
+
+@item -u
+@itemx --unified
+unified diff.
+@end table
+
+@node Imperfect, Empty Files, patch Input, Merging with patch
+@section Applying Imperfect Patches
+@cindex imperfect patch application
+
+@code{patch} tries to skip any leading text in the patch file, apply the
+diff, and then skip any trailing text. Thus you can feed a news article
+or mail message directly to @code{patch}, and it should work. If the
+entire diff is indented by a constant amount of white space, @code{patch}
+automatically ignores the indentation.
+
+However, certain other types of imperfect input require user
+intervention.
+
+@menu
+* Changed White Space:: When tabs and spaces don't match exactly.
+* Reversed Patches:: Applying reversed patches correctly.
+* Inexact:: Helping @code{patch} find close matches.
+@end menu
+
+@node Changed White Space, Reversed Patches, , Imperfect
+@subsection Applying Patches with Changed White Space
+@cindex white space in patches
+
+Sometimes mailers, editors, or other programs change spaces into tabs,
+or vice versa. If this happens to a patch file or an input file, the
+files might look the same, but @code{patch} will not be able to match
+them properly. If this problem occurs, use the @samp{-l} or
+@samp{--ignore-white-space} option, which makes @code{patch} compare
+white space loosely so that any sequence of white space in the patch file
+matches any sequence of white space in the input files. Non-white-space
+characters must still match exactly. Each line of the context must
+still match a line in the input file.
+
+@node Reversed Patches, Inexact, Changed White Space, Imperfect
+@subsection Applying Reversed Patches
+@cindex reversed patches
+
+Sometimes people run @code{diff} with the new file first instead of
+second. This creates a diff that is ``reversed''. To apply such
+patches, give @code{patch} the @samp{-R} or @samp{--reverse} option.
+@code{patch} then attempts to swap each hunk around before applying it.
+Rejects come out in the swapped format. The @samp{-R} option does not
+work with @code{ed} scripts because there is too little information in
+them to reconstruct the reverse operation.
+
+Often @code{patch} can guess that the patch is reversed. If the first
+hunk of a patch fails, @code{patch} reverses the hunk to see if it can
+apply it that way. If it can, @code{patch} asks you if you want to have
+the @samp{-R} option set; if it can't, @code{patch} continues to apply
+the patch normally. This method cannot detect a reversed patch if it is
+a normal diff and the first command is an append (which should have been
+a delete) since appends always succeed, because a null context matches
+anywhere. But most patches add or change lines rather than delete them,
+so most reversed normal diffs begin with a delete, which fails, and
+@code{patch} notices.
+
+If you apply a patch that you have already applied, @code{patch} thinks
+it is a reversed patch and offers to un-apply the patch. This could be
+construed as a feature. If you did this inadvertently and you don't
+want to un-apply the patch, just answer @samp{n} to this offer and to
+the subsequent ``apply anyway'' question---or type @kbd{C-c} to kill the
+@code{patch} process.
+
+@node Inexact, , Reversed Patches, Imperfect
+@subsection Helping @code{patch} Find Inexact Matches
+@cindex inexact patches
+@cindex fuzz factor when patching
+
+For context diffs, and to a lesser extent normal diffs, @code{patch} can
+detect when the line numbers mentioned in the patch are incorrect, and
+it attempts to find the correct place to apply each hunk of the patch.
+As a first guess, it takes the line number mentioned in the hunk, plus
+or minus any offset used in applying the previous hunk. If that is not
+the correct place, @code{patch} scans both forward and backward for a
+set of lines matching the context given in the hunk.
+
+First @code{patch} looks for a place where all lines of the context
+match. If it cannot find such a place, and it is reading a context or
+unified diff, and the maximum fuzz factor is set to 1 or more, then
+@code{patch} makes another scan, ignoring the first and last line of
+context. If that fails, and the maximum fuzz factor is set to 2 or
+more, it makes another scan, ignoring the first two and last two lines
+of context are ignored. It continues similarly if the maximum fuzz
+factor is larger.
+
+The @samp{-F @var{lines}} or @samp{--fuzz=@var{lines}} option sets the
+maximum fuzz factor to @var{lines}. This option only applies to context
+and unified diffs; it ignores up to @var{lines} lines while looking for
+the place to install a hunk. Note that a larger fuzz factor increases
+the odds of making a faulty patch. The default fuzz factor is 2; it may
+not be set to more than the number of lines of context in the diff,
+ordinarily 3.
+
+If @code{patch} cannot find a place to install a hunk of the patch, it
+writes the hunk out to a reject file (@pxref{Rejects}, for information
+on how reject files are named). It writes out rejected hunks in context
+format no matter what form the input patch is in. If the input is a
+normal or @code{ed} diff, many of the contexts are simply null. The
+line numbers on the hunks in the reject file may be different from those
+in the patch file: they show the approximate location where @code{patch}
+thinks the failed hunks belong in the new file rather than in the old
+one.
+
+As it completes each hunk, @code{patch} tells you whether the hunk
+succeeded or failed, and if it failed, on which line (in the new file)
+@code{patch} thinks the hunk should go. If this is different from the
+line number specified in the diff, it tells you the offset. A single
+large offset @emph{may} indicate that @code{patch} installed a hunk in
+the wrong place. @code{patch} also tells you if it used a fuzz factor
+to make the match, in which case you should also be slightly suspicious.
+
+@code{patch} cannot tell if the line numbers are off in an @code{ed}
+script, and can only detect wrong line numbers in a normal diff when it
+finds a change or delete command. It may have the same problem with a
+context diff using a fuzz factor equal to or greater than the number of
+lines of context shown in the diff (typically 3). In these cases, you
+should probably look at a context diff between your original and patched
+input files to see if the changes make sense. Compiling without errors
+is a pretty good indication that the patch worked, but not a guarantee.
+
+@code{patch} usually produces the correct results, even when it must
+make many guesses. However, the results are guaranteed only when
+the patch is applied to an exact copy of the file that the patch was
+generated from.
+
+@node Empty Files, Multiple Patches, Imperfect, Merging with patch
+@section Removing Empty Files
+@cindex empty files, removing
+@cindex removing empty files
+
+Sometimes when comparing two directories, the first directory contains a
+file that the second directory does not. If you give @code{diff} the
+@samp{-N} or @samp{--new-file} option, it outputs a diff that deletes
+the contents of this file. By default, @code{patch} leaves an empty
+file after applying such a diff. The @samp{-E} or
+@samp{--remove-empty-files} option to @code{patch} deletes output files
+that are empty after applying the diff.
+
+@node Multiple Patches, patch Messages, Empty Files, Merging with patch
+@section Multiple Patches in a File
+@cindex multiple patches
+
+If the patch file contains more than one patch, @code{patch} tries to
+apply each of them as if they came from separate patch files. This
+means that it determines the name of the file to patch for each patch,
+and that it examines the leading text before each patch for file names
+and prerequisite revision level (@pxref{Making Patches}, for more on
+that topic).
+
+For the second and subsequent patches in the patch file, you can give
+options and another original file name by separating their argument
+lists with a @samp{+}. However, the argument list for a second or
+subsequent patch may not specify a new patch file, since that does not
+make sense.
+
+For example, to tell @code{patch} to strip the first three slashes from
+the name of the first patch in the patch file and none from subsequent
+patches, and to use @file{code.c} as the first input file, you can use:
+
+@example
+patch -p3 code.c + -p0 < patchfile
+@end example
+
+The @samp{-S} or @samp{--skip} option ignores the current patch from the
+patch file, but continue looking for the next patch in the file. Thus,
+to ignore the first and third patches in the patch file, you can use:
+
+@example
+patch -S + + -S + < patch file
+@end example
+
+@node patch Messages, , Multiple Patches, Merging with patch
+@section Messages and Questions from @code{patch}
+@cindex @code{patch} messages and questions
+@cindex diagnostics from @code{patch}
+@cindex messages from @code{patch}
+
+@code{patch} can produce a variety of messages, especially if it has
+trouble decoding its input. In a few situations where it's not sure how
+to proceed, @code{patch} normally prompts you for more information from
+the keyboard. There are options to suppress printing non-fatal messages
+and stopping for keyboard input.
+
+The message @samp{Hmm...} indicates that @code{patch} is reading text in
+the patch file, attempting to determine whether there is a patch in that
+text, and if so, what kind of patch it is.
+
+You can inhibit all terminal output from @code{patch}, unless an error
+occurs, by using the @samp{-s}, @samp{--quiet}, or @samp{--silent}
+option.
+
+There are two ways you can prevent @code{patch} from asking you any
+questions. The @samp{-f} or @samp{--force} option assumes that you know
+what you are doing. It assumes the following:
+
+@itemize @bullet
+@item
+skip patches that do not contain file names in their headers;
+
+@item
+patch files even though they have the wrong version for the
+@samp{Prereq:} line in the patch;
+
+@item
+assume that patches are not reversed even if they look like they are.
+@end itemize
+
+The @samp{-t} or @samp{--batch} option is similar to @samp{-f}, in that
+it suppresses questions, but it makes somewhat different assumptions:
+
+@itemize @bullet
+@item
+skip patches that do not contain file names in their headers
+(the same as @samp{-f});
+
+@item
+skip patches for which the file has the wrong version for the
+@samp{Prereq:} line in the patch;
+
+@item
+assume that patches are reversed if they look like they are.
+@end itemize
+
+@code{patch} exits with a non-zero status if it creates any reject
+files. When applying a set of patches in a loop, you should check the
+exit status, so you don't apply a later patch to a partially patched
+file.
+
+@node Making Patches, Invoking cmp, Merging with patch, Top
+@chapter Tips for Making Patch Distributions
+@cindex patch making tips
+@cindex tips for patch making
+
+Here are some things you should keep in mind if you are going to
+distribute patches for updating a software package.
+
+Make sure you have specified the file names correctly, either in a
+context diff header or with an @samp{Index:} line. If you are patching
+files in a subdirectory, be sure to tell the patch user to specify a
+@samp{-p} or @samp{--strip} option as needed. Take care to not send out
+reversed patches, since these make people wonder whether they have
+already applied the patch.
+
+To save people from partially applying a patch before other patches that
+should have gone before it, you can make the first patch in the patch
+file update a file with a name like @file{patchlevel.h} or
+@file{version.c}, which contains a patch level or version number. If
+the input file contains the wrong version number, @code{patch} will
+complain immediately.
+
+An even clearer way to prevent this problem is to put a @samp{Prereq:}
+line before the patch. If the leading text in the patch file contains a
+line that starts with @samp{Prereq:}, @code{patch} takes the next word
+from that line (normally a version number) and checks whether the next
+input file contains that word, preceded and followed by either
+white space or a newline. If not, @code{patch} prompts you for
+confirmation before proceeding. This makes it difficult to accidentally
+apply patches in the wrong order.
+
+Since @code{patch} does not handle incomplete lines properly, make sure
+that all the source files in your program end with a newline whenever
+you release a version.
+
+To create a patch that changes an older version of a package into a
+newer version, first make a copy of the older version in a scratch
+directory. Typically you do that by unpacking a @code{tar} or
+@code{shar} archive of the older version.
+
+You might be able to reduce the size of the patch by renaming or
+removing some files before making the patch. If the older version of
+the package contains any files that the newer version does not, or if
+any files have been renamed between the two versions, make a list of
+@code{rm} and @code{mv} commands for the user to execute in the old
+version directory before applying the patch. Then run those commands
+yourself in the scratch directory.
+
+If there are any files that you don't need to include in the patch
+because they can easily be rebuilt from other files (for example,
+@file{TAGS} and output from @code{yacc} and @code{makeinfo}), replace
+the versions in the scratch directory with the newer versions, using
+@code{rm} and @code{ln} or @code{cp}.
+
+Now you can create the patch. The de-facto standard @code{diff} format
+for patch distributions is context format with two lines of context,
+produced by giving @code{diff} the @samp{-C 2} option. Do not use less
+than two lines of context, because @code{patch} typically needs at
+least two lines for proper operation. Give @code{diff} the @samp{-P}
+option in case the newer version of the package contains any files that
+the older one does not. Make sure to specify the scratch directory
+first and the newer directory second.
+
+Add to the top of the patch a note telling the user any @code{rm} and
+@code{mv} commands to run before applying the patch. Then you can
+remove the scratch directory.
+
+@node Invoking cmp, Invoking diff, Making Patches, Top
+@chapter Invoking @code{cmp}
+@cindex invoking @code{cmp}
+@cindex @code{cmp} invocation
+
+The @code{cmp} command compares two files, and if they differ, tells the
+first byte and line number where they differ. Its arguments are as
+follows:
+
+@example
+cmp @var{options}@dots{} @var{from-file} @r{[}@var{to-file}@var{]}
+@end example
+
+The file name @samp{-} is always the standard input. @code{cmp} also
+uses the standard input if one file name is omitted.
+
+An exit status of 0 means no differences were found, 1 means some
+differences were found, and 2 means trouble.
+
+@menu
+* cmp Options:: Summary of options to @code{cmp}.
+@end menu
+
+@node cmp Options, , , Invoking cmp
+@section Options to @code{cmp}
+@cindex @code{cmp} options
+@cindex options for @code{cmp}
+
+Below is a summary of all of the options that GNU @code{cmp} accepts.
+Most options have two equivalent names, one of which is a single letter
+preceded by @samp{-}, and the other of which is a long name preceded by
+@samp{--}. Multiple single letter options (unless they take an
+argument) can be combined into a single command line word: @samp{-cl} is
+equivalent to @samp{-c -l}.
+
+@table @samp
+@item -c
+Print the differing characters. Display control characters as a
+@samp{^} followed by a letter of the alphabet and precede characters
+that have the high bit set with @samp{M-} (which stands for ``meta'').
+
+@item --ignore-initial=@var{bytes}
+Ignore any differences in the the first @var{bytes} bytes of the input files.
+Treat files with fewer than @var{bytes} bytes as if they are empty.
+
+@item -l
+Print the (decimal) offsets and (octal) values of all differing bytes.
+
+@item --print-chars
+Print the differing characters. Display control characters as a
+@samp{^} followed by a letter of the alphabet and precede characters
+that have the high bit set with @samp{M-} (which stands for ``meta'').
+
+@item --quiet
+@itemx -s
+@itemx --silent
+Do not print anything; only return an exit status indicating whether
+the files differ.
+
+@item --verbose
+Print the (decimal) offsets and (octal) values of all differing bytes.
+
+@item -v
+@item --version
+Output the version number of @code{cmp}.
+@end table
+
+@node Invoking diff, Invoking diff3, Invoking cmp, Top
+@chapter Invoking @code{diff}
+@cindex invoking @code{diff}
+@cindex @code{diff} invocation
+
+The format for running the @code{diff} command is:
+
+@example
+diff @var{options}@dots{} @var{from-file} @var{to-file}
+@end example
+
+In the simplest case, @code{diff} compares the contents of the two files
+@var{from-file} and @var{to-file}. A file name of @samp{-} stands for
+text read from the standard input. As a special case, @samp{diff - -}
+compares a copy of standard input to itself.
+
+If @var{from-file} is a directory and @var{to-file} is not, @code{diff}
+compares the file in @var{from-file} whose file name is that of @var{to-file},
+and vice versa. The non-directory file must not be @samp{-}.
+
+If both @var{from-file} and @var{to-file} are directories,
+@code{diff} compares corresponding files in both directories, in
+alphabetical order; this comparison is not recursive unless the
+@samp{-r} or @samp{--recursive} option is given. @code{diff} never
+compares the actual contents of a directory as if it were a file. The
+file that is fully specified may not be standard input, because standard
+input is nameless and the notion of ``file with the same name'' does not
+apply.
+
+@code{diff} options begin with @samp{-}, so normally @var{from-file} and
+@var{to-file} may not begin with @samp{-}. However, @samp{--} as an
+argument by itself treats the remaining arguments as file names even if
+they begin with @samp{-}.
+
+An exit status of 0 means no differences were found, 1 means some
+differences were found, and 2 means trouble.
+
+@menu
+* diff Options:: Summary of options to @code{diff}.
+@end menu
+
+@node diff Options, , , Invoking diff
+@section Options to @code{diff}
+@cindex @code{diff} options
+@cindex options for @code{diff}
+
+Below is a summary of all of the options that GNU @code{diff} accepts.
+Most options have two equivalent names, one of which is a single letter
+preceded by @samp{-}, and the other of which is a long name preceded by
+@samp{--}. Multiple single letter options (unless they take an
+argument) can be combined into a single command line word: @samp{-ac} is
+equivalent to @samp{-a -c}. Long named options can be abbreviated to
+any unique prefix of their name. Brackets ([ and ]) indicate that an
+option takes an optional argument.
+
+@table @samp
+@item -@var{lines}
+Show @var{lines} (an integer) lines of context. This option does not
+specify an output format by itself; it has no effect unless it is
+combined with @samp{-c} (@pxref{Context Format}) or @samp{-u}
+(@pxref{Unified Format}). This option is obsolete. For proper
+operation, @code{patch} typically needs at least two lines of context.
+
+@item -a
+Treat all files as text and compare them line-by-line, even if they
+do not seem to be text. @xref{Binary}.
+
+@item -b
+Ignore changes in amount of white space. @xref{White Space}.
+
+@item -B
+Ignore changes that just insert or delete blank lines. @xref{Blank
+Lines}.
+
+@item --binary
+Read and write data in binary mode. @xref{Binary}.
+
+@item --brief
+Report only whether the files differ, not the details of the
+differences. @xref{Brief}.
+
+@item -c
+Use the context output format. @xref{Context Format}.
+
+@item -C @var{lines}
+@itemx --context@r{[}=@var{lines}@r{]}
+Use the context output format, showing @var{lines} (an integer) lines of
+context, or three if @var{lines} is not given. @xref{Context Format}.
+For proper operation, @code{patch} typically needs at least two lines of
+context.
+
+@item --changed-group-format=@var{format}
+Use @var{format} to output a line group containing differing lines from
+both files in if-then-else format. @xref{Line Group Formats}.
+
+@item -d
+Change the algorithm perhaps find a smaller set of changes. This makes
+@code{diff} slower (sometimes much slower). @xref{diff Performance}.
+
+@item -D @var{name}
+Make merged @samp{#ifdef} format output, conditional on the preprocessor
+macro @var{name}. @xref{If-then-else}.
+
+@item -e
+@itemx --ed
+Make output that is a valid @code{ed} script. @xref{ed Scripts}.
+
+@item --exclude=@var{pattern}
+When comparing directories, ignore files and subdirectories whose basenames
+match @var{pattern}. @xref{Comparing Directories}.
+
+@item --exclude-from=@var{file}
+When comparing directories, ignore files and subdirectories whose basenames
+match any pattern contained in @var{file}. @xref{Comparing Directories}.
+
+@item --expand-tabs
+Expand tabs to spaces in the output, to preserve the alignment of tabs
+in the input files. @xref{Tabs}.
+
+@item -f
+Make output that looks vaguely like an @code{ed} script but has changes
+in the order they appear in the file. @xref{Forward ed}.
+
+@item -F @var{regexp}
+In context and unified format, for each hunk of differences, show some
+of the last preceding line that matches @var{regexp}. @xref{Specified
+Headings}.
+
+@item --forward-ed
+Make output that looks vaguely like an @code{ed} script but has changes
+in the order they appear in the file. @xref{Forward ed}.
+
+@item -h
+This option currently has no effect; it is present for Unix
+compatibility.
+
+@item -H
+Use heuristics to speed handling of large files that have numerous
+scattered small changes. @xref{diff Performance}.
+
+@item --horizon-lines=@var{lines}
+Do not discard the last @var{lines} lines of the common prefix
+and the first @var{lines} lines of the common suffix.
+@xref{diff Performance}.
+
+@item -i
+Ignore changes in case; consider upper- and lower-case letters
+equivalent. @xref{Case Folding}.
+
+@item -I @var{regexp}
+Ignore changes that just insert or delete lines that match @var{regexp}.
+@xref{Specified Folding}.
+
+@item --ifdef=@var{name}
+Make merged if-then-else output using @var{name}. @xref{If-then-else}.
+
+@item --ignore-all-space
+Ignore white space when comparing lines. @xref{White Space}.
+
+@item --ignore-blank-lines
+Ignore changes that just insert or delete blank lines. @xref{Blank
+Lines}.
+
+@item --ignore-case
+Ignore changes in case; consider upper- and lower-case to be the same.
+@xref{Case Folding}.
+
+@item --ignore-matching-lines=@var{regexp}
+Ignore changes that just insert or delete lines that match @var{regexp}.
+@xref{Specified Folding}.
+
+@item --ignore-space-change
+Ignore changes in amount of white space.
+@xref{White Space}.
+
+@item --initial-tab
+Output a tab rather than a space before the text of a line in normal or
+context format. This causes the alignment of tabs in the line to look
+normal. @xref{Tabs}.
+
+@item -l
+Pass the output through @code{pr} to paginate it. @xref{Pagination}.
+
+@item -L @var{label}
+Use @var{label} instead of the file name in the context format
+(@pxref{Context Format}) and unified format (@pxref{Unified Format})
+headers. @xref{RCS}.
+
+@item --label=@var{label}
+Use @var{label} instead of the file name in the context format
+(@pxref{Context Format}) and unified format (@pxref{Unified Format})
+headers.
+
+@item --left-column
+Print only the left column of two common lines in side by side format.
+@xref{Side by Side Format}.
+
+@item --line-format=@var{format}
+Use @var{format} to output all input lines in if-then-else format.
+@xref{Line Formats}.
+
+@item --minimal
+Change the algorithm to perhaps find a smaller set of changes. This
+makes @code{diff} slower (sometimes much slower). @xref{diff
+Performance}.
+
+@item -n
+Output RCS-format diffs; like @samp{-f} except that each command
+specifies the number of lines affected. @xref{RCS}.
+
+@item -N
+@itemx --new-file
+In directory comparison, if a file is found in only one directory,
+treat it as present but empty in the other directory. @xref{Comparing
+Directories}.
+
+@item --new-group-format=@var{format}
+Use @var{format} to output a group of lines taken from just the second
+file in if-then-else format. @xref{Line Group Formats}.
+
+@item --new-line-format=@var{format}
+Use @var{format} to output a line taken from just the second file in
+if-then-else format. @xref{Line Formats}.
+
+@item --old-group-format=@var{format}
+Use @var{format} to output a group of lines taken from just the first
+file in if-then-else format. @xref{Line Group Formats}.
+
+@item --old-line-format=@var{format}
+Use @var{format} to output a line taken from just the first file in
+if-then-else format. @xref{Line Formats}.
+
+@item -p
+Show which C function each change is in. @xref{C Function Headings}.
+
+@item -P
+When comparing directories, if a file appears only in the second
+directory of the two, treat it as present but empty in the other.
+@xref{Comparing Directories}.
+
+@item --paginate
+Pass the output through @code{pr} to paginate it. @xref{Pagination}.
+
+@item -q
+Report only whether the files differ, not the details of the
+differences. @xref{Brief}.
+
+@item -r
+When comparing directories, recursively compare any subdirectories
+found. @xref{Comparing Directories}.
+
+@item --rcs
+Output RCS-format diffs; like @samp{-f} except that each command
+specifies the number of lines affected. @xref{RCS}.
+
+@item --recursive
+When comparing directories, recursively compare any subdirectories
+found. @xref{Comparing Directories}.
+
+@item --report-identical-files
+Report when two files are the same. @xref{Comparing Directories}.
+
+@item -s
+Report when two files are the same. @xref{Comparing Directories}.
+
+@item -S @var{file}
+When comparing directories, start with the file @var{file}. This is
+used for resuming an aborted comparison. @xref{Comparing Directories}.
+
+@item --sdiff-merge-assist
+Print extra information to help @code{sdiff}. @code{sdiff} uses this
+option when it runs @code{diff}. This option is not intended for users
+to use directly.
+
+@item --show-c-function
+Show which C function each change is in. @xref{C Function Headings}.
+
+@item --show-function-line=@var{regexp}
+In context and unified format, for each hunk of differences, show some
+of the last preceding line that matches @var{regexp}. @xref{Specified
+Headings}.
+
+@item --side-by-side
+Use the side by side output format. @xref{Side by Side Format}.
+
+@item --speed-large-files
+Use heuristics to speed handling of large files that have numerous
+scattered small changes. @xref{diff Performance}.
+
+@item --starting-file=@var{file}
+When comparing directories, start with the file @var{file}. This is
+used for resuming an aborted comparison. @xref{Comparing Directories}.
+
+@item --suppress-common-lines
+Do not print common lines in side by side format.
+@xref{Side by Side Format}.
+
+@item -t
+Expand tabs to spaces in the output, to preserve the alignment of tabs
+in the input files. @xref{Tabs}.
+
+@item -T
+Output a tab rather than a space before the text of a line in normal or
+context format. This causes the alignment of tabs in the line to look
+normal. @xref{Tabs}.
+
+@item --text
+Treat all files as text and compare them line-by-line, even if they
+do not appear to be text. @xref{Binary}.
+
+@item -u
+Use the unified output format. @xref{Unified Format}.
+
+@item --unchanged-group-format=@var{format}
+Use @var{format} to output a group of common lines taken from both files
+in if-then-else format. @xref{Line Group Formats}.
+
+@item --unchanged-line-format=@var{format}
+Use @var{format} to output a line common to both files in if-then-else
+format. @xref{Line Formats}.
+
+@item --unidirectional-new-file
+When comparing directories, if a file appears only in the second
+directory of the two, treat it as present but empty in the other.
+@xref{Comparing Directories}.
+
+@item -U @var{lines}
+@itemx --unified@r{[}=@var{lines}@r{]}
+Use the unified output format, showing @var{lines} (an integer) lines of
+context, or three if @var{lines} is not given. @xref{Unified Format}.
+For proper operation, @code{patch} typically needs at least two lines of
+context.
+
+@item -v
+@itemx --version
+Output the version number of @code{diff}.
+
+@item -w
+Ignore white space when comparing lines. @xref{White Space}.
+
+@item -W @var{columns}
+@itemx --width=@var{columns}
+Use an output width of @var{columns} in side by side format.
+@xref{Side by Side Format}.
+
+@item -x @var{pattern}
+When comparing directories, ignore files and subdirectories whose basenames
+match @var{pattern}. @xref{Comparing Directories}.
+
+@item -X @var{file}
+When comparing directories, ignore files and subdirectories whose basenames
+match any pattern contained in @var{file}. @xref{Comparing Directories}.
+
+@item -y
+Use the side by side output format. @xref{Side by Side Format}.
+@end table
+
+@node Invoking diff3, Invoking patch, Invoking diff, Top
+@chapter Invoking @code{diff3}
+@cindex invoking @code{diff3}
+@cindex @code{diff3} invocation
+
+The @code{diff3} command compares three files and outputs descriptions
+of their differences. Its arguments are as follows:
+
+@example
+diff3 @var{options}@dots{} @var{mine} @var{older} @var{yours}
+@end example
+
+The files to compare are @var{mine}, @var{older}, and @var{yours}.
+At most one of these three file names may be @samp{-},
+which tells @code{diff3} to read the standard input for that file.
+
+An exit status of 0 means @code{diff3} was successful, 1 means some
+conflicts were found, and 2 means trouble.
+
+@menu
+* diff3 Options:: Summary of options to @code{diff3}.
+@end menu
+
+@node diff3 Options, , , Invoking diff3
+@section Options to @code{diff3}
+@cindex @code{diff3} options
+@cindex options for @code{diff3}
+
+Below is a summary of all of the options that GNU @code{diff3}
+accepts. Multiple single letter options (unless they take an argument)
+can be combined into a single command line argument.
+
+@table @samp
+@item -a
+Treat all files as text and compare them line-by-line, even if they
+do not appear to be text. @xref{Binary}.
+
+@item -A
+Incorporate all changes from @var{older} to @var{yours} into @var{mine},
+surrounding all conflicts with bracket lines.
+@xref{Marking Conflicts}.
+
+@item -e
+Generate an @code{ed} script that incorporates all the changes from
+@var{older} to @var{yours} into @var{mine}. @xref{Which Changes}.
+
+@item -E
+Like @samp{-e}, except bracket lines from overlapping changes' first
+and third files.
+@xref{Marking Conflicts}.
+With @samp{-e}, an overlapping change looks like this:
+
+@example
+<<<<<<< @var{mine}
+@r{lines from @var{mine}}
+=======
+@r{lines from @var{yours}}
+>>>>>>> @var{yours}
+@end example
+
+@item --ed
+Generate an @code{ed} script that incorporates all the changes from
+@var{older} to @var{yours} into @var{mine}. @xref{Which Changes}.
+
+@item --easy-only
+Like @samp{-e}, except output only the nonoverlapping changes.
+@xref{Which Changes}.
+
+@item -i
+Generate @samp{w} and @samp{q} commands at the end of the @code{ed}
+script for System V compatibility. This option must be combined with
+one of the @samp{-AeExX3} options, and may not be combined with @samp{-m}.
+@xref{Saving the Changed File}.
+
+@item --initial-tab
+Output a tab rather than two spaces before the text of a line in normal format.
+This causes the alignment of tabs in the line to look normal. @xref{Tabs}.
+
+@item -L @var{label}
+@itemx --label=@var{label}
+Use the label @var{label} for the brackets output by the @samp{-A},
+@samp{-E} and @samp{-X} options. This option may be given up to three
+times, one for each input file. The default labels are the names of
+the input files. Thus @samp{diff3 -L X -L Y -L Z -m A B C} acts like
+@samp{diff3 -m A B C}, except that the output looks like it came from
+files named @samp{X}, @samp{Y} and @samp{Z} rather than from files
+named @samp{A}, @samp{B} and @samp{C}. @xref{Marking Conflicts}.
+
+@item -m
+@itemx --merge
+Apply the edit script to the first file and send the result to standard
+output. Unlike piping the output from @code{diff3} to @code{ed}, this
+works even for binary files and incomplete lines. @samp{-A} is assumed
+if no edit script option is specified. @xref{Bypassing ed}.
+
+@item --overlap-only
+Like @samp{-e}, except output only the overlapping changes.
+@xref{Which Changes}.
+
+@item --show-all
+Incorporate all unmerged changes from @var{older} to @var{yours} into
+@var{mine}, surrounding all overlapping changes with bracket lines.
+@xref{Marking Conflicts}.
+
+@item --show-overlap
+Like @samp{-e}, except bracket lines from overlapping changes' first
+and third files.
+@xref{Marking Conflicts}.
+
+@item -T
+Output a tab rather than two spaces before the text of a line in normal format.
+This causes the alignment of tabs in the line to look normal. @xref{Tabs}.
+
+@item --text
+Treat all files as text and compare them line-by-line, even if they
+do not appear to be text. @xref{Binary}.
+
+@item -v
+@itemx --version
+Output the version number of @code{diff3}.
+
+@item -x
+Like @samp{-e}, except output only the overlapping changes.
+@xref{Which Changes}.
+
+@item -X
+Like @samp{-E}, except output only the overlapping changes.
+In other words, like @samp{-x}, except bracket changes as in @samp{-E}.
+@xref{Marking Conflicts}.
+
+@item -3
+Like @samp{-e}, except output only the nonoverlapping changes.
+@xref{Which Changes}.
+@end table
+
+@node Invoking patch, Invoking sdiff, Invoking diff3, Top
+@chapter Invoking @code{patch}
+@cindex invoking @code{patch}
+@cindex @code{patch} invocation
+
+Normally @code{patch} is invoked like this:
+
+@example
+patch <@var{patchfile}
+@end example
+
+The full format for invoking @code{patch} is:
+
+@example
+patch @var{options}@dots{} @r{[}@var{origfile} @r{[}@var{patchfile}@r{]}@r{]} @r{[}+ @var{options}@dots{} @r{[}@var{origfile}@r{]}@r{]}@dots{}
+@end example
+
+If you do not specify @var{patchfile}, or if @var{patchfile} is
+@samp{-}, @code{patch} reads the patch (that is, the @code{diff} output)
+from the standard input.
+
+You can specify one or more of the original files as @var{orig} arguments;
+each one and options for interpreting it is separated from the others with a
+@samp{+}. @xref{Multiple Patches}, for more information.
+
+If you do not specify an input file on the command line, @code{patch}
+tries to figure out from the @dfn{leading text} (any text in the patch
+that comes before the @code{diff} output) which file to edit. In the
+header of a context or unified diff, @code{patch} looks in lines
+beginning with @samp{***}, @samp{---}, or @samp{+++}; among those, it
+chooses the shortest name of an existing file. Otherwise, if there is
+an @samp{Index:} line in the leading text, @code{patch} tries to use the
+file name from that line. If @code{patch} cannot figure out the name of
+an existing file from the leading text, it prompts you for the name of
+the file to patch.
+
+If the input file does not exist or is read-only, and a suitable RCS or
+SCCS file exists, @code{patch} attempts to check out or get the file
+before proceeding.
+
+By default, @code{patch} replaces the original input file with the
+patched version, after renaming the original file into a backup file
+(@pxref{Backups}, for a description of how @code{patch} names backup
+files). You can also specify where to put the output with the @samp{-o
+@var{output-file}} or @samp{--output=@var{output-file}} option.
+
+@menu
+* patch Directories:: Changing directory and stripping directories.
+* Backups:: Backup file names.
+* Rejects:: Reject file names.
+* patch Options:: Summary table of options to @code{patch}.
+@end menu
+
+@node patch Directories, Backups, , Invoking patch
+@section Applying Patches in Other Directories
+@cindex directories and patch
+@cindex patching directories
+
+The @samp{-d @var{directory}} or @samp{--directory=@var{directory}}
+option to @code{patch} makes directory @var{directory} the current
+directory for interpreting both file names in the patch file, and file
+names given as arguments to other options (such as @samp{-B} and
+@samp{-o}). For example, while in a news reading program, you can patch
+a file in the @file{/usr/src/emacs} directory directly from the article
+containing the patch like this:
+
+@example
+| patch -d /usr/src/emacs
+@end example
+
+Sometimes the file names given in a patch contain leading directories,
+but you keep your files in a directory different from the one given in
+the patch. In those cases, you can use the
+@samp{-p@r{[}@var{number}@r{]}} or @samp{--strip@r{[}=@var{number}@r{]}}
+option to set the file name strip count to @var{number}. The strip
+count tells @code{patch} how many slashes, along with the directory
+names between them, to strip from the front of file names. @samp{-p}
+with no @var{number} given is equivalent to @samp{-p0}. By default,
+@code{patch} strips off all leading directories, leaving just the base file
+names, except that when a file name given in the patch is a relative
+file name and all of its leading directories already exist, @code{patch} does
+not strip off the leading directory. (A @dfn{relative} file name is one
+that does not start with a slash.)
+
+@code{patch} looks for each file (after any slashes have been stripped)
+in the current directory, or if you used the @samp{-d @var{directory}}
+option, in that directory.
+
+For example, suppose the file name in the patch file is
+@file{/gnu/src/emacs/etc/NEWS}. Using @samp{-p} or @samp{-p0} gives the
+entire file name unmodified, @samp{-p1} gives
+@file{gnu/src/emacs/etc/NEWS} (no leading slash), @samp{-p4} gives
+@file{etc/NEWS}, and not specifying @samp{-p} at all gives @file{NEWS}.
+
+@node Backups, Rejects, patch Directories, Invoking patch
+@section Backup File Names
+@cindex backup file names
+
+Normally, @code{patch} renames an original input file into a backup file
+by appending to its name the extension @samp{.orig}, or @samp{~} on
+systems that do not support long file names. The @samp{-b
+@var{backup-suffix}} or @samp{--suffix=@var{backup-suffix}} option uses
+@var{backup-suffix} as the backup extension instead.
+
+Alternately, you can specify the extension for backup files with the
+@code{SIMPLE_BACKUP_SUFFIX} environment variable, which the options
+override.
+
+@code{patch} can also create numbered backup files the way GNU Emacs
+does. With this method, instead of having a single backup of each file,
+@code{patch} makes a new backup file name each time it patches a file.
+For example, the backups of a file named @file{sink} would be called,
+successively, @file{sink.~1~}, @file{sink.~2~}, @file{sink.~3~}, etc.
+
+The @samp{-V @var{backup-style}} or
+@samp{--version-control=@var{backup-style}} option takes as an argument
+a method for creating backup file names. You can alternately control
+the type of backups that @code{patch} makes with the
+@code{VERSION_CONTROL} environment variable, which the @samp{-V} option
+overrides. The value of the @code{VERSION_CONTROL} environment variable
+and the argument to the @samp{-V} option are like the GNU Emacs
+@code{version-control} variable (@pxref{Backups,
+emacs, The GNU Emacs Manual}, for more information on backup versions in
+Emacs). They also recognize synonyms that are more descriptive. The
+valid values are listed below; unique abbreviations are acceptable.
+
+@table @samp
+@item t
+@itemx numbered
+Always make numbered backups.
+
+@item nil
+@itemx existing
+Make numbered backups of files that already have them, simple backups of
+the others. This is the default.
+
+@item never
+@itemx simple
+Always make simple backups.
+@end table
+
+Alternately, you can tell @code{patch} to prepend a prefix, such as a
+directory name, to produce backup file names. The @samp{-B
+@var{backup-prefix}} or @samp{--prefix=@var{backup-prefix}} option makes
+backup files by prepending @var{backup-prefix} to them. If you use this
+option, @code{patch} ignores any @samp{-b} option that you give.
+
+If the backup file already exists, @code{patch} creates a new backup
+file name by changing the first lowercase letter in the last component
+of the file name into uppercase. If there are no more lowercase letters
+in the name, it removes the first character from the name. It repeats
+this process until it comes up with a backup file name that does not
+already exist.
+
+If you specify the output file with the @samp{-o} option, that file is
+the one that is backed up, not the input file.
+
+@node Rejects, patch Options, Backups, Invoking patch
+@section Reject File Names
+@cindex reject file names
+
+The names for reject files (files containing patches that @code{patch}
+could not find a place to apply) are normally the name of the output
+file with @samp{.rej} appended (or @samp{#} on systems that do not
+support long file names).
+
+Alternatively, you can tell @code{patch} to place all of the rejected
+patches in a single file. The @samp{-r @var{reject-file}} or
+@samp{--reject-file=@var{reject-file}} option uses @var{reject-file} as
+the reject file name.
+
+@node patch Options, , Rejects, Invoking patch
+@section Options to @code{patch}
+@cindex @code{patch} options
+@cindex options for @code{patch}
+
+Here is a summary of all of the options that @code{patch} accepts.
+Older versions of @code{patch} do not accept long-named options or the
+@samp{-t}, @samp{-E}, or @samp{-V} options.
+
+Multiple single-letter options that do not take an argument can be
+combined into a single command line argument (with only one dash).
+Brackets ([ and ]) indicate that an option takes an optional argument.
+
+@table @samp
+@item -b @var{backup-suffix}
+Use @var{backup-suffix} as the backup extension instead of
+@samp{.orig} or @samp{~}. @xref{Backups}.
+
+@item -B @var{backup-prefix}
+Use @var{backup-prefix} as a prefix to the backup file name. If this
+option is specified, any @samp{-b} option is ignored. @xref{Backups}.
+
+@item --batch
+Do not ask any questions. @xref{patch Messages}.
+
+@item -c
+@itemx --context
+Interpret the patch file as a context diff. @xref{patch Input}.
+
+@item -d @var{directory}
+@itemx --directory=@var{directory}
+Makes directory @var{directory} the current directory for interpreting
+both file names in the patch file, and file names given as arguments to
+other options. @xref{patch Directories}.
+
+@item -D @var{name}
+Make merged if-then-else output using @var{format}. @xref{If-then-else}.
+
+@item --debug=@var{number}
+Set internal debugging flags. Of interest only to @code{patch}
+patchers.
+
+@item -e
+@itemx --ed
+Interpret the patch file as an @code{ed} script. @xref{patch Input}.
+
+@item -E
+Remove output files that are empty after the patches have been applied.
+@xref{Empty Files}.
+
+@item -f
+Assume that the user knows exactly what he or she is doing, and do not
+ask any questions. @xref{patch Messages}.
+
+@item -F @var{lines}
+Set the maximum fuzz factor to @var{lines}. @xref{Inexact}.
+
+@item --force
+Assume that the user knows exactly what he or she is doing, and do not
+ask any questions. @xref{patch Messages}.
+
+@item --forward
+Ignore patches that @code{patch} thinks are reversed or already applied.
+See also @samp{-R}. @xref{Reversed Patches}.
+
+@item --fuzz=@var{lines}
+Set the maximum fuzz factor to @var{lines}. @xref{Inexact}.
+
+@item --help
+Print a summary of the options that @code{patch} recognizes, then exit.
+
+@item --ifdef=@var{name}
+Make merged if-then-else output using @var{format}. @xref{If-then-else}.
+
+@item --ignore-white-space
+@itemx -l
+Let any sequence of white space in the patch file match any sequence of
+white space in the input file. @xref{Changed White Space}.
+
+@item -n
+@itemx --normal
+Interpret the patch file as a normal diff. @xref{patch Input}.
+
+@item -N
+Ignore patches that @code{patch} thinks are reversed or already applied.
+See also @samp{-R}. @xref{Reversed Patches}.
+
+@item -o @var{output-file}
+@itemx --output=@var{output-file}
+Use @var{output-file} as the output file name. @xref{patch Options}.
+
+@item -p@r{[}@var{number}@r{]}
+Set the file name strip count to @var{number}. @xref{patch Directories}.
+
+@item --prefix=@var{backup-prefix}
+Use @var{backup-prefix} as a prefix to the backup file name. If this
+option is specified, any @samp{-b} option is ignored. @xref{Backups}.
+
+@item --quiet
+Work silently unless an error occurs. @xref{patch Messages}.
+
+@item -r @var{reject-file}
+Use @var{reject-file} as the reject file name. @xref{Rejects}.
+
+@item -R
+Assume that this patch was created with the old and new files swapped.
+@xref{Reversed Patches}.
+
+@item --reject-file=@var{reject-file}
+Use @var{reject-file} as the reject file name. @xref{Rejects}.
+
+@item --remove-empty-files
+Remove output files that are empty after the patches have been applied.
+@xref{Empty Files}.
+
+@item --reverse
+Assume that this patch was created with the old and new files swapped.
+@xref{Reversed Patches}.
+
+@item -s
+Work silently unless an error occurs. @xref{patch Messages}.
+
+@item -S
+Ignore this patch from the patch file, but continue looking for the next
+patch in the file. @xref{Multiple Patches}.
+
+@item --silent
+Work silently unless an error occurs. @xref{patch Messages}.
+
+@item --skip
+Ignore this patch from the patch file, but continue looking for the next
+patch in the file. @xref{Multiple Patches}.
+
+@item --strip@r{[}=@var{number}@r{]}
+Set the file name strip count to @var{number}. @xref{patch Directories}.
+
+@item --suffix=@var{backup-suffix}
+Use @var{backup-suffix} as the backup extension instead of
+@samp{.orig} or @samp{~}. @xref{Backups}.
+
+@item -t
+Do not ask any questions. @xref{patch Messages}.
+
+@item -u
+@itemx --unified
+Interpret the patch file as a unified diff. @xref{patch Input}.
+
+@item -v
+Output the revision header and patch level of @code{patch}.
+
+@item -V @var{backup-style}
+Select the kind of backups to make. @xref{Backups}.
+
+@item --version
+Output the revision header and patch level of @code{patch}, then exit.
+
+@item --version=control=@var{backup-style}
+Select the kind of backups to make. @xref{Backups}.
+
+@item -x @var{number}
+Set internal debugging flags. Of interest only to @code{patch}
+patchers.
+@end table
+
+@node Invoking sdiff, Incomplete Lines, Invoking patch, Top
+@chapter Invoking @code{sdiff}
+@cindex invoking @code{sdiff}
+@cindex @code{sdiff} invocation
+
+The @code{sdiff} command merges two files and interactively outputs the
+results. Its arguments are as follows:
+
+@example
+sdiff -o @var{outfile} @var{options}@dots{} @var{from-file} @var{to-file}
+@end example
+
+This merges @var{from-file} with @var{to-file}, with output to @var{outfile}.
+If @var{from-file} is a directory and @var{to-file} is not, @code{sdiff}
+compares the file in @var{from-file} whose file name is that of @var{to-file},
+and vice versa. @var{from-file} and @var{to-file} may not both be
+directories.
+
+@code{sdiff} options begin with @samp{-}, so normally @var{from-file}
+and @var{to-file} may not begin with @samp{-}. However, @samp{--} as an
+argument by itself treats the remaining arguments as file names even if
+they begin with @samp{-}. You may not use @samp{-} as an input file.
+
+An exit status of 0 means no differences were found, 1 means some
+differences were found, and 2 means trouble.
+
+@code{sdiff} without @samp{-o} (or @samp{--output}) produces a
+side-by-side difference. This usage is obsolete; use @samp{diff
+--side-by-side} instead.
+
+@menu
+* sdiff Options:: Summary of options to @code{diff}.
+@end menu
+
+@node sdiff Options, , , Invoking sdiff
+@section Options to @code{sdiff}
+@cindex @code{sdiff} options
+@cindex options for @code{sdiff}
+
+Below is a summary of all of the options that GNU @code{sdiff} accepts.
+Each option has two equivalent names, one of which is a single
+letter preceded by @samp{-}, and the other of which is a long name
+preceded by @samp{--}. Multiple single letter options (unless they take
+an argument) can be combined into a single command line argument. Long
+named options can be abbreviated to any unique prefix of their name.
+
+@table @samp
+@item -a
+Treat all files as text and compare them line-by-line, even if they
+do not appear to be text. @xref{Binary}.
+
+@item -b
+Ignore changes in amount of white space. @xref{White Space}.
+
+@item -B
+Ignore changes that just insert or delete blank lines. @xref{Blank
+Lines}.
+
+@item -d
+Change the algorithm to perhaps find a smaller set of changes. This
+makes @code{sdiff} slower (sometimes much slower). @xref{diff
+Performance}.
+
+@item -H
+Use heuristics to speed handling of large files that have numerous
+scattered small changes. @xref{diff Performance}.
+
+@item --expand-tabs
+Expand tabs to spaces in the output, to preserve the alignment of tabs
+in the input files. @xref{Tabs}.
+
+@item -i
+Ignore changes in case; consider upper- and lower-case to be the same.
+@xref{Case Folding}.
+
+@item -I @var{regexp}
+Ignore changes that just insert or delete lines that match @var{regexp}.
+@xref{Specified Folding}.
+
+@item --ignore-all-space
+Ignore white space when comparing lines. @xref{White Space}.
+
+@item --ignore-blank-lines
+Ignore changes that just insert or delete blank lines. @xref{Blank
+Lines}.
+
+@item --ignore-case
+Ignore changes in case; consider upper- and lower-case to be the same.
+@xref{Case Folding}.
+
+@item --ignore-matching-lines=@var{regexp}
+Ignore changes that just insert or delete lines that match @var{regexp}.
+@xref{Specified Folding}.
+
+@item --ignore-space-change
+Ignore changes in amount of white space.
+@xref{White Space}.
+
+@item -l
+@itemx --left-column
+Print only the left column of two common lines.
+@xref{Side by Side Format}.
+
+@item --minimal
+Change the algorithm to perhaps find a smaller set of changes. This
+makes @code{sdiff} slower (sometimes much slower). @xref{diff
+Performance}.
+
+@item -o @var{file}
+@itemx --output=@var{file}
+Put merged output into @var{file}. This option is required for merging.
+
+@item -s
+@itemx --suppress-common-lines
+Do not print common lines. @xref{Side by Side Format}.
+
+@item --speed-large-files
+Use heuristics to speed handling of large files that have numerous
+scattered small changes. @xref{diff Performance}.
+
+@item -t
+Expand tabs to spaces in the output, to preserve the alignment of tabs
+in the input files. @xref{Tabs}.
+
+@item --text
+Treat all files as text and compare them line-by-line, even if they
+do not appear to be text. @xref{Binary}.
+
+@item -v
+@itemx --version
+Output the version number of @code{sdiff}.
+
+@item -w @var{columns}
+@itemx --width=@var{columns}
+Use an output width of @var{columns}. @xref{Side by Side Format}.
+Note that for historical reasons, this option is @samp{-W} in @code{diff},
+@samp{-w} in @code{sdiff}.
+
+@item -W
+Ignore horizontal white space when comparing lines. @xref{White Space}.
+Note that for historical reasons, this option is @samp{-w} in @code{diff},
+@samp{-W} in @code{sdiff}.
+@end table
+
+@node Incomplete Lines, Projects, Invoking sdiff, Top
+@chapter Incomplete Lines
+@cindex incomplete lines
+@cindex full lines
+@cindex newline treatment by @code{diff}
+
+When an input file ends in a non-newline character, its last line is
+called an @dfn{incomplete line} because its last character is not a
+newline. All other lines are called @dfn{full lines} and end in a
+newline character. Incomplete lines do not match full lines unless
+differences in white space are ignored (@pxref{White Space}).
+
+An incomplete line is normally distinguished on output from a full line
+by a following line that starts with @samp{\}. However, the RCS format
+(@pxref{RCS}) outputs the incomplete line as-is, without any trailing
+newline or following line. The side by side format normally represents
+incomplete lines as-is, but in some cases uses a @samp{\} or @samp{/}
+gutter marker; @xref{Side by Side}. The if-then-else line format
+preserves a line's incompleteness with @samp{%L}, and discards the
+newline with @samp{%l}; @xref{Line Formats}. Finally, with the
+@code{ed} and forward @code{ed} output formats (@pxref{Output Formats})
+@code{diff} cannot represent an incomplete line, so it pretends there
+was a newline and reports an error.
+
+For example, suppose @file{F} and @file{G} are one-byte files that
+contain just @samp{f} and @samp{g}, respectively. Then @samp{diff F G}
+outputs
+
+@example
+1c1
+< f
+\ No newline at end of file
+---
+> g
+\ No newline at end of file
+@end example
+
+@noindent
+(The exact message may differ in non-English locales.)
+@samp{diff -n F G} outputs the following without a trailing newline:
+
+@example
+d1 1
+a1 1
+g
+@end example
+
+@samp{diff -e F G} reports two errors and outputs the following:
+
+@example
+1c
+g
+.
+@end example
+
+@node Projects, Concept Index, Incomplete Lines, Top
+@chapter Future Projects
+
+Here are some ideas for improving GNU @code{diff} and @code{patch}. The
+GNU project has identified some improvements as potential programming
+projects for volunteers. You can also help by reporting any bugs that
+you find.
+
+If you are a programmer and would like to contribute something to the
+GNU project, please consider volunteering for one of these projects. If
+you are seriously contemplating work, please write to
+@samp{gnu@@prep.ai.mit.edu} to coordinate with other volunteers.
+
+@menu
+* Shortcomings:: Suggested projects for improvements.
+* Bugs:: Reporting bugs.
+@end menu
+
+@node Shortcomings, Bugs, , Projects
+@section Suggested Projects for Improving GNU @code{diff} and @code{patch}
+@cindex projects for directories
+
+One should be able to use GNU @code{diff} to generate a patch from any
+pair of directory trees, and given the patch and a copy of one such
+tree, use @code{patch} to generate a faithful copy of the other.
+Unfortunately, some changes to directory trees cannot be expressed using
+current patch formats; also, @code{patch} does not handle some of the
+existing formats. These shortcomings motivate the following suggested
+projects.
+
+@menu
+* Changing Structure:: Handling changes to the directory structure.
+* Special Files:: Handling symbolic links, device special files, etc.
+* Unusual File Names:: Handling file names that contain unusual characters.
+* Arbitrary Limits:: Patching non-text files.
+* Large Files:: Handling files that do not fit in memory.
+* Ignoring Changes:: Ignoring certain changes while showing others.
+@end menu
+
+@node Changing Structure, Special Files, , Shortcomings
+@subsection Handling Changes to the Directory Structure
+@cindex directory structure changes
+
+@code{diff} and @code{patch} do not handle some changes to directory
+structure. For example, suppose one directory tree contains a directory
+named @samp{D} with some subsidiary files, and another contains a file
+with the same name @samp{D}. @samp{diff -r} does not output enough
+information for @code{patch} to transform the the directory subtree into
+the file.
+
+There should be a way to specify that a file has been deleted without
+having to include its entire contents in the patch file. There should
+also be a way to tell @code{patch} that a file was renamed, even if
+there is no way for @code{diff} to generate such information.
+
+These problems can be fixed by extending the @code{diff} output format
+to represent changes in directory structure, and extending @code{patch}
+to understand these extensions.
+
+@node Special Files, Unusual File Names, Changing Structure, Shortcomings
+@subsection Files that are Neither Directories Nor Regular Files
+@cindex special files
+
+Some files are neither directories nor regular files: they are unusual
+files like symbolic links, device special files, named pipes, and
+sockets. Currently, @code{diff} treats symbolic links like regular files;
+it treats other special files like regular files if they are specified
+at the top level, but simply reports their presence when comparing
+directories. This means that @code{patch} cannot represent changes
+to such files. For example, if you change which file a symbolic link
+points to, @code{diff} outputs the difference between the two files,
+instead of the change to the symbolic link.
+
+@c This might not be a good idea; is it wise for root to install devices
+@c this way?
+@code{diff} should optionally report changes to special files specially,
+and @code{patch} should be extended to understand these extensions.
+
+@node Unusual File Names, Arbitrary Limits, Special Files, Shortcomings
+@subsection File Names that Contain Unusual Characters
+@cindex file names with unusual characters
+
+When a file name contains an unusual character like a newline or
+white space, @samp{diff -r} generates a patch that @code{patch} cannot
+parse. The problem is with format of @code{diff} output, not just with
+@code{patch}, because with odd enough file names one can cause
+@code{diff} to generate a patch that is syntactically correct but
+patches the wrong files. The format of @code{diff} output should be
+extended to handle all possible file names.
+
+@node Arbitrary Limits, Large Files, Unusual File Names, Shortcomings
+@subsection Arbitrary Limits
+@cindex binary file patching
+
+GNU @code{diff} can analyze files with arbitrarily long lines and files
+that end in incomplete lines. However, @code{patch} cannot patch such
+files. The @code{patch} internal limits on line lengths should be
+removed, and @code{patch} should be extended to parse @code{diff}
+reports of incomplete lines.
+
+@node Large Files, Ignoring Changes, Arbitrary Limits, Shortcomings
+@subsection Handling Files that Do Not Fit in Memory
+@cindex large files
+
+@code{diff} operates by reading both files into memory. This method
+fails if the files are too large, and @code{diff} should have a fallback.
+
+One way to do this is to scan the files sequentially to compute hash
+codes of the lines and put the lines in equivalence classes based only
+on hash code. Then compare the files normally. This does produce some
+false matches.
+
+Then scan the two files sequentially again, checking each match to see
+whether it is real. When a match is not real, mark both the
+``matching'' lines as changed. Then build an edit script as usual.
+
+The output routines would have to be changed to scan the files
+sequentially looking for the text to print.
+
+@node Ignoring Changes,, Large Files, Shortcomings
+@subsection Ignoring Certain Changes
+
+It would be nice to have a feature for specifying two strings, one in
+@var{from-file} and one in @var{to-file}, which should be considered to
+match. Thus, if the two strings are @samp{foo} and @samp{bar}, then if
+two lines differ only in that @samp{foo} in file 1 corresponds to
+@samp{bar} in file 2, the lines are treated as identical.
+
+It is not clear how general this feature can or should be, or
+what syntax should be used for it.
+
+@node Bugs, , Shortcomings, Projects
+@section Reporting Bugs
+@cindex bug reports
+@cindex reporting bugs
+
+If you think you have found a bug in GNU @code{cmp}, @code{diff},
+@code{diff3}, @code{sdiff}, or @code{patch}, please report it by
+electronic mail to @samp{bug-gnu-utils@@prep.ai.mit.edu}. Send as
+precise a description of the problem as you can, including sample input
+files that produce the bug, if applicable.
+
+Because Larry Wall has not released a new version of @code{patch} since
+mid 1988 and the GNU version of @code{patch} has been changed since
+then, please send bug reports for @code{patch} by electronic mail to
+both @samp{bug-gnu-utils@@prep.ai.mit.edu} and
+@samp{lwall@@netlabs.com}.
+
+@node Concept Index, , Projects, Top
+@unnumbered Concept Index
+
+@printindex cp
+
+@shortcontents
+@contents
+@bye
diff --git a/gnu/dist/diffutils/diff3.c b/gnu/dist/diffutils/diff3.c
new file mode 100644
index 00000000000..5d94ab866db
--- /dev/null
+++ b/gnu/dist/diffutils/diff3.c
@@ -0,0 +1,1778 @@
+/* Three way file comparison program (diff3) for Project GNU.
+ Copyright (C) 1988, 1989, 1992, 1993, 1994 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 */
+
+#include "system.h"
+#include <stdio.h>
+#include <signal.h>
+#include "getopt.h"
+
+extern char const version_string[];
+
+/*
+ * 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) */
+ size_t *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) */
+ size_t *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;
+
+/* Use a tab to align output lines (-T). */
+static int tab_align_flag;
+
+/* 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 *program_name;
+
+static VOID *xmalloc PARAMS((size_t));
+static VOID *xrealloc PARAMS((VOID *, size_t));
+
+static char *read_diff PARAMS((char const *, char const *, char **));
+static char *scan_diff_line PARAMS((char *, char **, size_t *, char *, int));
+static enum diff_type process_diff_control PARAMS((char **, struct diff_block *));
+static int compare_line_list PARAMS((char * const[], size_t const[], char * const[], size_t const[], int));
+static int copy_stringlist PARAMS((char * const[], size_t const[], char *[], size_t[], int));
+static int dotlines PARAMS((FILE *, struct diff3_block *, int));
+static int output_diff3_edscript PARAMS((FILE *, struct diff3_block *, int const[3], int const[3], char const *, char const *, char const *));
+static int output_diff3_merge PARAMS((FILE *, FILE *, struct diff3_block *, int const[3], int const[3], char const *, char const *, char const *));
+static size_t myread PARAMS((int, char *, size_t));
+static struct diff3_block *create_diff3_block PARAMS((int, int, int, int, int, int));
+static struct diff3_block *make_3way_diff PARAMS((struct diff_block *, struct diff_block *));
+static struct diff3_block *reverse_diff3_blocklist PARAMS((struct diff3_block *));
+static struct diff3_block *using_to_diff3_block PARAMS((struct diff_block *[2], struct diff_block *[2], int, int, struct diff3_block const *));
+static struct diff_block *process_diff PARAMS((char const *, char const *, struct diff_block **));
+static void check_stdout PARAMS((void));
+static void fatal PARAMS((char const *));
+static void output_diff3 PARAMS((FILE *, struct diff3_block *, int const[3], int const[3]));
+static void perror_with_exit PARAMS((char const *));
+static void try_help PARAMS((char const *));
+static void undotlines PARAMS((FILE *, int, int, int));
+static void usage PARAMS((void));
+
+static char const diff_program[] = DIFF_PROGRAM;
+
+static struct option const longopts[] =
+{
+ {"text", 0, 0, 'a'},
+ {"show-all", 0, 0, 'A'},
+ {"ed", 0, 0, 'e'},
+ {"show-overlap", 0, 0, 'E'},
+ {"label", 1, 0, 'L'},
+ {"merge", 0, 0, 'm'},
+ {"initial-tab", 0, 0, 'T'},
+ {"overlap-only", 0, 0, 'x'},
+ {"easy-only", 0, 0, '3'},
+ {"version", 0, 0, 'v'},
+ {"help", 0, 0, 129},
+ {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;
+{
+ int c, i;
+ int mapping[3];
+ int rev_mapping[3];
+ int incompat = 0;
+ int conflicts_found;
+ struct diff_block *thread0, *thread1, *last_block;
+ struct diff3_block *diff3;
+ int tag_count = 0;
+ char *tag_strings[3];
+ char *commonname;
+ char **file;
+ struct stat statb;
+
+ initialize_main (&argc, &argv);
+ program_name = argv[0];
+
+ while ((c = getopt_long (argc, argv, "aeimvx3AEL:TX", longopts, 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 'T':
+ tab_align_flag = 1;
+ break;
+ case 'v':
+ printf ("diff3 - GNU diffutils version %s\n", version_string);
+ exit (0);
+ case 129:
+ usage ();
+ check_stdout ();
+ exit (0);
+ case 'L':
+ /* Handle up to three -L options. */
+ if (tag_count < 3)
+ {
+ tag_strings[tag_count++] = optarg;
+ break;
+ }
+ try_help ("Too many labels were given. The limit is 3.");
+ default:
+ try_help (0);
+ }
+ }
+
+ 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. */
+ try_help ("incompatible options");
+
+ if (argc - optind != 3)
+ try_help (argc - optind < 3 ? "missing operand" : "extra operand");
+
+ 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",
+ program_name, file[i]);
+ exit (2);
+ }
+ }
+
+#if !defined(SIGCHLD) && defined(SIGCLD)
+#define SIGCHLD SIGCLD
+#endif
+#ifdef SIGCHLD
+ /* System V fork+wait does not work if SIGCHLD is ignored. */
+ signal (SIGCHLD, SIG_DFL);
+#endif
+
+ 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;
+ }
+
+ check_stdout ();
+ exit (conflicts_found);
+ return conflicts_found;
+}
+
+static void
+try_help (reason)
+ char const *reason;
+{
+ if (reason)
+ fprintf (stderr, "%s: %s\n", program_name, reason);
+ fprintf (stderr, "%s: Try `%s --help' for more information.\n",
+ program_name, program_name);
+ exit (2);
+}
+
+static void
+check_stdout ()
+{
+ if (ferror (stdout) || fclose (stdout) != 0)
+ fatal ("write error");
+}
+
+/*
+ * Explain, patiently and kindly, how to use this program.
+ */
+static void
+usage ()
+{
+ printf ("Usage: %s [OPTION]... MYFILE OLDFILE YOURFILE\n\n", program_name);
+
+ printf ("%s", "\
+ -e --ed Output unmerged changes from OLDFILE to YOURFILE into MYFILE.\n\
+ -E --show-overlap Output unmerged changes, bracketing conflicts.\n\
+ -A --show-all Output all changes, bracketing conflicts.\n\
+ -x --overlap-only Output overlapping changes.\n\
+ -X Output overlapping changes, bracketing them.\n\
+ -3 --easy-only Output unmerged nonoverlapping changes.\n\n");
+ printf ("%s", "\
+ -m --merge Output merged file instead of ed script (default -A).\n\
+ -L LABEL --label=LABEL Use LABEL instead of file name.\n\
+ -i Append `w' and `q' commands to ed scripts.\n\
+ -a --text Treat all files as text.\n\
+ -T --initial-tab Make tabs line up by prepending a tab.\n\n");
+ printf ("%s", "\
+ -v --version Output version info.\n\
+ --help Output this help.\n\n");
+ printf ("If a FILE is `-', read standard input.\n");
+}
+
+/*
+ * 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 memcmp'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 memcmp's (if a
+ * memcmp 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;
+
+ struct diff3_block const *last_diff3;
+
+ static struct diff3_block const zero_diff3;
+
+ /* 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] = 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 = 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 = 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 const *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 * const fromptrs[];
+ char *toptrs[];
+ size_t const fromlengths[];
+ size_t tolengths[];
+ int copynum;
+{
+ register char * const *f = fromptrs;
+ register char **t = toptrs;
+ register size_t const *fl = fromlengths;
+ register size_t *tl = tolengths;
+
+ while (copynum--)
+ {
+ if (*t)
+ { if (*fl != *tl || memcmp (*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, size_t);
+ bzero (D_LINEARRAY (result, FILE0), (numlines * sizeof (char *)));
+ bzero (D_LENARRAY (result, FILE0), (numlines * sizeof (size_t)));
+ }
+ else
+ {
+ D_LINEARRAY (result, FILE0) = 0;
+ D_LENARRAY (result, FILE0) = 0;
+ }
+
+ numlines = D_NUMLINES (result, FILE1);
+ if (numlines)
+ {
+ D_LINEARRAY (result, FILE1) = ALLOCATE (numlines, char *);
+ D_LENARRAY (result, FILE1) = ALLOCATE (numlines, size_t);
+ bzero (D_LINEARRAY (result, FILE1), (numlines * sizeof (char *)));
+ bzero (D_LENARRAY (result, FILE1), (numlines * sizeof (size_t)));
+ }
+ else
+ {
+ D_LINEARRAY (result, FILE1) = 0;
+ D_LENARRAY (result, FILE1) = 0;
+ }
+
+ numlines = D_NUMLINES (result, FILE2);
+ if (numlines)
+ {
+ D_LINEARRAY (result, FILE2) = ALLOCATE (numlines, char *);
+ D_LENARRAY (result, FILE2) = ALLOCATE (numlines, size_t);
+ bzero (D_LINEARRAY (result, FILE2), (numlines * sizeof (char *)));
+ bzero (D_LENARRAY (result, FILE2), (numlines * sizeof (size_t)));
+ }
+ else
+ {
+ D_LINEARRAY (result, FILE2) = 0;
+ D_LENARRAY (result, FILE2) = 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 * const list1[], * const list2[];
+ size_t const lengths1[], lengths2[];
+ int nl;
+{
+ char
+ * const *l1 = list1,
+ * const *l2 = list2;
+ size_t const
+ *lgths1 = lengths1,
+ *lgths2 = lengths2;
+
+ while (nl--)
+ if (!*l1 || !*l2 || *lgths1 != *lgths2++
+ || memcmp (*l1++, *l2++, *lgths1++))
+ return 0;
+ return 1;
+}
+
+/*
+ * Routines to input and parse two way diffs.
+ */
+
+extern char **environ;
+
+static struct diff_block *
+process_diff (filea, fileb, last_block)
+ char const *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;
+ bptr = 0; /* Pacify `gcc -W'. */
+
+ while (scan_diff < diff_limit)
+ {
+ bptr = ALLOCATE (1, struct diff_block);
+ bptr->lines[0] = bptr->lines[1] = 0;
+ bptr->lengths[0] = bptr->lengths[1] = 0;
+
+ dt = process_diff_control (&scan_diff, bptr);
+ if (dt == ERROR || *scan_diff != '\n')
+ {
+ fprintf (stderr, "%s: diff error: ", program_name);
+ 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, size_t);
+ 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, size_t);
+ 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) \
+ { unsigned char c = *s; if (!ISDIGIT (c)) return ERROR; holdnum = 0; \
+ do { holdnum = (c - '0' + holdnum * 10); } \
+ while (ISDIGIT (c = *++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 const *filea, *fileb;
+ char **output_placement;
+{
+ char *diff_result;
+ size_t bytes, current_chunk_size, total;
+ int fd, wstatus;
+ struct stat pipestat;
+
+ /* 302 / 1000 is log10(2.0) rounded up. Subtract 1 for the sign bit;
+ add 1 for integer division truncation; add 1 more for a minus sign. */
+#define INT_STRLEN_BOUND(type) ((sizeof(type)*CHAR_BIT - 1) * 302 / 1000 + 2)
+
+#if HAVE_FORK
+
+ char const *argv[7];
+ char horizon_arg[17 + INT_STRLEN_BOUND (int)];
+ char const **ap;
+ int fds[2];
+ pid_t pid;
+
+ 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 = 0;
+
+ if (pipe (fds) != 0)
+ perror_with_exit ("pipe");
+
+ pid = vfork ();
+ if (pid == 0)
+ {
+ /* Child */
+ close (fds[0]);
+ if (fds[1] != STDOUT_FILENO)
+ {
+ dup2 (fds[1], STDOUT_FILENO);
+ close (fds[1]);
+ }
+ execve (diff_program, (char **) argv, environ);
+ /* Avoid stdio, because the parent process's buffers are inherited. */
+ write (STDERR_FILENO, diff_program, strlen (diff_program));
+ write (STDERR_FILENO, ": not found\n", 12);
+ _exit (2);
+ }
+
+ if (pid == -1)
+ perror_with_exit ("fork failed");
+
+ close (fds[1]); /* Prevent erroneous lack of EOF */
+ fd = fds[0];
+
+#else /* ! HAVE_FORK */
+
+ FILE *fpipe;
+ char *command = xmalloc (sizeof (diff_program) + 30 + INT_STRLEN_BOUND (int)
+ + 4 * (strlen (filea) + strlen (fileb)));
+ char *p;
+ sprintf (command, "%s -a --horizon-lines=%d -- ",
+ diff_program, horizon_lines);
+ p = command + strlen (command);
+ SYSTEM_QUOTE_ARG (p, filea);
+ *p++ = ' ';
+ SYSTEM_QUOTE_ARG (p, fileb);
+ *p = '\0';
+ fpipe = popen (command, "r");
+ if (!fpipe)
+ perror_with_exit (command);
+ free (command);
+ fd = fileno (fpipe);
+
+#endif /* ! HAVE_FORK */
+
+ current_chunk_size = 8 * 1024;
+ if (fstat (fd, &pipestat) == 0)
+ current_chunk_size = max (current_chunk_size, STAT_BLOCKSIZE (pipestat));
+
+ diff_result = xmalloc (current_chunk_size);
+ total = 0;
+ do {
+ bytes = myread (fd,
+ diff_result + total,
+ current_chunk_size - total);
+ total += bytes;
+ if (total == current_chunk_size)
+ {
+ if (current_chunk_size < 2 * current_chunk_size)
+ current_chunk_size = 2 * current_chunk_size;
+ else if (current_chunk_size < (size_t) -1)
+ current_chunk_size = (size_t) -1;
+ else
+ fatal ("files are too large to fit into memory");
+ diff_result = 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;
+
+#if ! HAVE_FORK
+
+ wstatus = pclose (fpipe);
+
+#else /* HAVE_FORK */
+
+ if (close (fd) != 0)
+ perror_with_exit ("pipe close");
+ if (waitpid (pid, &wstatus, 0) < 0)
+ perror_with_exit ("waitpid failed");
+
+#endif /* HAVE_FORK */
+
+ 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, leadingchar)
+ char *scan_ptr, **set_start;
+ size_t *set_length;
+ char *limit;
+ int leadingchar;
+{
+ char *line_ptr;
+
+ if (!(scan_ptr[0] == leadingchar
+ && 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:", program_name);
+ 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 const mapping[3], rev_mapping[3];
+{
+ int i;
+ int oddoneout;
+ char *cp;
+ struct diff3_block *ptr;
+ int line;
+ size_t length;
+ int dontprint;
+ static int skew_increment[3] = { 2, 3, 1 }; /* 0==>2==>1==>3 */
+ char const *line_prefix = tab_align_flag ? "\t" : " ";
+
+ 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;
+
+ if (lowt <= hight)
+ {
+ line = 0;
+ do
+ {
+ fprintf (outputfile, line_prefix);
+ cp = D_RELNUM (ptr, realfile, line);
+ length = D_RELLEN (ptr, realfile, line);
+ fwrite (cp, sizeof (char), length, outputfile);
+ }
+ while (++line < hight - lowt + 1);
+ if (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 const mapping[3], rev_mapping[3];
+ char const *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 const mapping[3], rev_mapping[3];
+ char const *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 const *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 = 0; tmp; tmp = next)
+ {
+ next = tmp->next;
+ tmp->next = prev;
+ prev = tmp;
+ }
+
+ return prev;
+}
+
+static size_t
+myread (fd, ptr, size)
+ int fd;
+ char *ptr;
+ size_t size;
+{
+ size_t result = read (fd, ptr, size);
+ if (result == -1)
+ perror_with_exit ("read failed");
+ return result;
+}
+
+static VOID *
+xmalloc (size)
+ size_t size;
+{
+ VOID *result = (VOID *) malloc (size ? size : 1);
+ if (!result)
+ fatal ("memory exhausted");
+ return result;
+}
+
+static VOID *
+xrealloc (ptr, size)
+ VOID *ptr;
+ size_t size;
+{
+ VOID *result = (VOID *) realloc (ptr, size ? size : 1);
+ if (!result)
+ fatal ("memory exhausted");
+ return result;
+}
+
+static void
+fatal (string)
+ char const *string;
+{
+ fprintf (stderr, "%s: %s\n", program_name, string);
+ exit (2);
+}
+
+static void
+perror_with_exit (string)
+ char const *string;
+{
+ int e = errno;
+ fprintf (stderr, "%s: ", program_name);
+ errno = e;
+ perror (string);
+ exit (2);
+}
diff --git a/gnu/dist/diffutils/dir.c b/gnu/dist/diffutils/dir.c
new file mode 100644
index 00000000000..036a86f1128
--- /dev/null
+++ b/gnu/dist/diffutils/dir.c
@@ -0,0 +1,216 @@
+/* Read, sort and compare two directories. Used for GNU DIFF.
+ Copyright (C) 1988, 1989, 1992, 1993, 1994 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 "diff.h"
+
+/* Read the directory named by DIR and store into DIRDATA a sorted vector
+ of filenames for its contents. DIR->desc == -1 means this directory is
+ known to be nonexistent, so set DIRDATA to an empty vector.
+ Return -1 (setting errno) if error, 0 otherwise. */
+
+struct dirdata
+{
+ char const **names; /* Sorted names of files in dir, 0-terminated. */
+ char *data; /* Allocated storage for file names. */
+};
+
+static int compare_names PARAMS((void const *, void const *));
+static int dir_sort PARAMS((struct file_data const *, struct dirdata *));
+
+static int
+dir_sort (dir, dirdata)
+ struct file_data const *dir;
+ struct dirdata *dirdata;
+{
+ register struct dirent *next;
+ register int i;
+
+ /* Address of block containing the files that are described. */
+ char const **names;
+
+ /* Number of files in directory. */
+ size_t nnames;
+
+ /* Allocated and used storage for file name data. */
+ char *data;
+ size_t data_alloc, data_used;
+
+ dirdata->names = 0;
+ dirdata->data = 0;
+ nnames = 0;
+ data = 0;
+
+ if (dir->desc != -1)
+ {
+ /* Open the directory and check for errors. */
+ register DIR *reading = opendir (dir->name);
+ if (!reading)
+ return -1;
+
+ /* Initialize the table of filenames. */
+
+ data_alloc = max (1, (size_t) dir->stat.st_size);
+ data_used = 0;
+ dirdata->data = data = xmalloc (data_alloc);
+
+ /* Read the directory entries, and insert the subfiles
+ into the `data' table. */
+
+ while ((errno = 0, (next = readdir (reading)) != 0))
+ {
+ char *d_name = next->d_name;
+ size_t d_size = NAMLEN (next) + 1;
+
+ /* Ignore the files `.' and `..' */
+ if (d_name[0] == '.'
+ && (d_name[1] == 0 || (d_name[1] == '.' && d_name[2] == 0)))
+ continue;
+
+ if (excluded_filename (d_name))
+ continue;
+
+ while (data_alloc < data_used + d_size)
+ dirdata->data = data = xrealloc (data, data_alloc *= 2);
+ memcpy (data + data_used, d_name, d_size);
+ data_used += d_size;
+ nnames++;
+ }
+ if (errno)
+ {
+ int e = errno;
+ closedir (reading);
+ errno = e;
+ return -1;
+ }
+#if CLOSEDIR_VOID
+ closedir (reading);
+#else
+ if (closedir (reading) != 0)
+ return -1;
+#endif
+ }
+
+ /* Create the `names' table from the `data' table. */
+ dirdata->names = names = (char const **) xmalloc (sizeof (char *)
+ * (nnames + 1));
+ for (i = 0; i < nnames; i++)
+ {
+ names[i] = data;
+ data += strlen (data) + 1;
+ }
+ names[nnames] = 0;
+
+ /* Sort the table. */
+ qsort (names, nnames, sizeof (char *), compare_names);
+
+ return 0;
+}
+
+/* Sort the files now in the table. */
+
+static int
+compare_names (file1, file2)
+ void const *file1, *file2;
+{
+ return filename_cmp (* (char const *const *) file1,
+ * (char const *const *) file2);
+}
+
+/* Compare the contents of two directories named in FILEVEC[0] and FILEVEC[1].
+ This is a top-level routine; it does everything necessary for diff
+ on two directories.
+
+ FILEVEC[0].desc == -1 says directory FILEVEC[0] doesn't exist,
+ but pretend it is empty. Likewise for FILEVEC[1].
+
+ HANDLE_FILE is a caller-provided subroutine called to handle each file.
+ It gets five operands: dir and name (rel to original working dir) of file
+ in dir 0, dir and name pathname of file in dir 1, and the recursion depth.
+
+ For a file that appears in only one of the dirs, one of the name-args
+ to HANDLE_FILE is zero.
+
+ DEPTH is the current depth in recursion, used for skipping top-level
+ files by the -S option.
+
+ Returns the maximum of all the values returned by HANDLE_FILE,
+ or 2 if trouble is encountered in opening files. */
+
+int
+diff_dirs (filevec, handle_file, depth)
+ struct file_data const filevec[];
+ int (*handle_file) PARAMS((char const *, char const *, char const *, char const *, int));
+ int depth;
+{
+ struct dirdata dirdata[2];
+ int val = 0; /* Return value. */
+ int i;
+
+ /* Get sorted contents of both dirs. */
+ for (i = 0; i < 2; i++)
+ if (dir_sort (&filevec[i], &dirdata[i]) != 0)
+ {
+ perror_with_name (filevec[i].name);
+ val = 2;
+ }
+
+ if (val == 0)
+ {
+ register char const * const *names0 = dirdata[0].names;
+ register char const * const *names1 = dirdata[1].names;
+ char const *name0 = filevec[0].name;
+ char const *name1 = filevec[1].name;
+
+ /* If `-S name' was given, and this is the topmost level of comparison,
+ ignore all file names less than the specified starting name. */
+
+ if (dir_start_file && depth == 0)
+ {
+ while (*names0 && filename_cmp (*names0, dir_start_file) < 0)
+ names0++;
+ while (*names1 && filename_cmp (*names1, dir_start_file) < 0)
+ names1++;
+ }
+
+ /* Loop while files remain in one or both dirs. */
+ while (*names0 || *names1)
+ {
+ /* Compare next name in dir 0 with next name in dir 1.
+ At the end of a dir,
+ pretend the "next name" in that dir is very large. */
+ int nameorder = (!*names0 ? 1 : !*names1 ? -1
+ : filename_cmp (*names0, *names1));
+ int v1 = (*handle_file) (name0, 0 < nameorder ? 0 : *names0++,
+ name1, nameorder < 0 ? 0 : *names1++,
+ depth + 1);
+ if (v1 > val)
+ val = v1;
+ }
+ }
+
+ for (i = 0; i < 2; i++)
+ {
+ if (dirdata[i].names)
+ free (dirdata[i].names);
+ if (dirdata[i].data)
+ free (dirdata[i].data);
+ }
+
+ return val;
+}
diff --git a/gnu/dist/diffutils/ed.c b/gnu/dist/diffutils/ed.c
new file mode 100644
index 00000000000..717ef358d0e
--- /dev/null
+++ b/gnu/dist/diffutils/ed.c
@@ -0,0 +1,200 @@
+/* Output routines for ed-script format.
+ Copyright (C) 1988, 89, 91, 92, 93 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 "diff.h"
+
+static void print_ed_hunk PARAMS((struct change *));
+static void print_rcs_hunk PARAMS((struct change *));
+static void pr_forward_ed_hunk PARAMS((struct change *));
+
+/* Print our script as ed commands. */
+
+void
+print_ed_script (script)
+ struct change *script;
+{
+ print_script (script, find_reverse_change, print_ed_hunk);
+}
+
+/* Print a hunk of an ed diff */
+
+static void
+print_ed_hunk (hunk)
+ struct change *hunk;
+{
+ int f0, l0, f1, l1;
+ int deletes, inserts;
+
+#if 0
+ hunk = flip_script (hunk);
+#endif
+#ifdef DEBUG
+ debug_script (hunk);
+#endif
+
+ /* Determine range of line numbers involved in each file. */
+ analyze_hunk (hunk, &f0, &l0, &f1, &l1, &deletes, &inserts);
+ if (!deletes && !inserts)
+ return;
+
+ begin_output ();
+
+ /* Print out the line number header for this hunk */
+ print_number_range (',', &files[0], f0, l0);
+ fprintf (outfile, "%c\n", change_letter (inserts, deletes));
+
+ /* Print new/changed lines from second file, if needed */
+ if (inserts)
+ {
+ int i;
+ int inserting = 1;
+ for (i = f1; i <= l1; i++)
+ {
+ /* Resume the insert, if we stopped. */
+ if (! inserting)
+ fprintf (outfile, "%da\n",
+ i - f1 + translate_line_number (&files[0], f0) - 1);
+ inserting = 1;
+
+ /* If the file's line is just a dot, it would confuse `ed'.
+ So output it with a double dot, and set the flag LEADING_DOT
+ so that we will output another ed-command later
+ to change the double dot into a single dot. */
+
+ if (files[1].linbuf[i][0] == '.'
+ && files[1].linbuf[i][1] == '\n')
+ {
+ fprintf (outfile, "..\n");
+ fprintf (outfile, ".\n");
+ /* Now change that double dot to the desired single dot. */
+ fprintf (outfile, "%ds/^\\.\\././\n",
+ i - f1 + translate_line_number (&files[0], f0));
+ inserting = 0;
+ }
+ else
+ /* Line is not `.', so output it unmodified. */
+ print_1_line ("", &files[1].linbuf[i]);
+ }
+
+ /* End insert mode, if we are still in it. */
+ if (inserting)
+ fprintf (outfile, ".\n");
+ }
+}
+
+/* Print change script in the style of ed commands,
+ but print the changes in the order they appear in the input files,
+ which means that the commands are not truly useful with ed. */
+
+void
+pr_forward_ed_script (script)
+ struct change *script;
+{
+ print_script (script, find_change, pr_forward_ed_hunk);
+}
+
+static void
+pr_forward_ed_hunk (hunk)
+ struct change *hunk;
+{
+ int i;
+ int f0, l0, f1, l1;
+ int deletes, inserts;
+
+ /* Determine range of line numbers involved in each file. */
+ analyze_hunk (hunk, &f0, &l0, &f1, &l1, &deletes, &inserts);
+ if (!deletes && !inserts)
+ return;
+
+ begin_output ();
+
+ fprintf (outfile, "%c", change_letter (inserts, deletes));
+ print_number_range (' ', files, f0, l0);
+ fprintf (outfile, "\n");
+
+ /* If deletion only, print just the number range. */
+
+ if (!inserts)
+ return;
+
+ /* For insertion (with or without deletion), print the number range
+ and the lines from file 2. */
+
+ for (i = f1; i <= l1; i++)
+ print_1_line ("", &files[1].linbuf[i]);
+
+ fprintf (outfile, ".\n");
+}
+
+/* Print in a format somewhat like ed commands
+ except that each insert command states the number of lines it inserts.
+ This format is used for RCS. */
+
+void
+print_rcs_script (script)
+ struct change *script;
+{
+ print_script (script, find_change, print_rcs_hunk);
+}
+
+/* Print a hunk of an RCS diff */
+
+static void
+print_rcs_hunk (hunk)
+ struct change *hunk;
+{
+ int i;
+ int f0, l0, f1, l1;
+ int deletes, inserts;
+ int tf0, tl0, tf1, tl1;
+
+ /* Determine range of line numbers involved in each file. */
+ analyze_hunk (hunk, &f0, &l0, &f1, &l1, &deletes, &inserts);
+ if (!deletes && !inserts)
+ return;
+
+ begin_output ();
+
+ translate_range (&files[0], f0, l0, &tf0, &tl0);
+
+ if (deletes)
+ {
+ fprintf (outfile, "d");
+ /* For deletion, print just the starting line number from file 0
+ and the number of lines deleted. */
+ fprintf (outfile, "%d %d\n",
+ tf0,
+ (tl0 >= tf0 ? tl0 - tf0 + 1 : 1));
+ }
+
+ if (inserts)
+ {
+ fprintf (outfile, "a");
+
+ /* Take last-line-number from file 0 and # lines from file 1. */
+ translate_range (&files[1], f1, l1, &tf1, &tl1);
+ fprintf (outfile, "%d %d\n",
+ tl0,
+ (tl1 >= tf1 ? tl1 - tf1 + 1 : 1));
+
+ /* Print the inserted lines. */
+ for (i = f1; i <= l1; i++)
+ print_1_line ("", &files[1].linbuf[i]);
+ }
+}
diff --git a/gnu/dist/diffutils/error.c b/gnu/dist/diffutils/error.c
new file mode 100644
index 00000000000..e1d24dfce8e
--- /dev/null
+++ b/gnu/dist/diffutils/error.c
@@ -0,0 +1,111 @@
+/* error.c -- error handler for noninteractive utilities
+ Copyright (C) 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+/* Written by David MacKenzie. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef HAVE_VPRINTF
+
+#if __STDC__
+#include <stdarg.h>
+#define VA_START(args, lastarg) va_start(args, lastarg)
+#else /* !__STDC__ */
+#include <varargs.h>
+#define VA_START(args, lastarg) va_start(args)
+#endif /* !__STDC__ */
+
+#else /* !HAVE_VPRINTF */
+
+#ifdef HAVE_DOPRNT
+#define va_alist args
+#define va_dcl int args;
+#else /* !HAVE_DOPRNT */
+#define va_alist a1, a2, a3, a4, a5, a6, a7, a8
+#define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
+#endif /* !HAVE_DOPRNT */
+
+#endif /* !HAVE_VPRINTF */
+
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#include <string.h>
+#else /* !STDC_HEADERS */
+void exit ();
+#endif /* !STDC_HEADERS */
+
+extern char *program_name;
+
+#ifndef HAVE_STRERROR
+static char *
+private_strerror (errnum)
+ int errnum;
+{
+ extern char *sys_errlist[];
+ extern int sys_nerr;
+
+ if (errnum > 0 && errnum <= sys_nerr)
+ return sys_errlist[errnum];
+ return "Unknown system error";
+}
+#define strerror private_strerror
+#endif /* !HAVE_STRERROR */
+
+/* Print the program name and error message MESSAGE, which is a printf-style
+ format string with optional args.
+ If ERRNUM is nonzero, print its corresponding system error message.
+ Exit with status STATUS if it is nonzero. */
+/* VARARGS */
+void
+#if defined (HAVE_VPRINTF) && __STDC__
+error (int status, int errnum, char *message, ...)
+#else /* !HAVE_VPRINTF or !__STDC__ */
+error (status, errnum, message, va_alist)
+ int status;
+ int errnum;
+ char *message;
+ va_dcl
+#endif /* !HAVE_VPRINTF or !__STDC__ */
+{
+#ifdef HAVE_VPRINTF
+ va_list args;
+#endif /* HAVE_VPRINTF */
+
+ fflush (stdout);
+ fprintf (stderr, "%s: ", program_name);
+#ifdef HAVE_VPRINTF
+ VA_START (args, message);
+ vfprintf (stderr, message, args);
+ va_end (args);
+#else /* !HAVE_VPRINTF */
+#ifdef HAVE_DOPRNT
+ _doprnt (message, &args, stderr);
+#else /* !HAVE_DOPRNT */
+ fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8);
+#endif /* !HAVE_DOPRNT */
+#endif /* !HAVE_VPRINTF */
+ if (errnum)
+ fprintf (stderr, ": %s", strerror (errnum));
+ putc ('\n', stderr);
+ fflush (stderr);
+ if (status)
+ exit (status);
+}
diff --git a/gnu/dist/diffutils/fnmatch.c b/gnu/dist/diffutils/fnmatch.c
new file mode 100644
index 00000000000..22fa9df624d
--- /dev/null
+++ b/gnu/dist/diffutils/fnmatch.c
@@ -0,0 +1,209 @@
+/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
+
+NOTE: The canonical source of this file is maintained with the GNU C Library.
+Bugs can be reported to bug-glibc@prep.ai.mit.edu.
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifdef HAVE_CONFIG_H
+#if defined (CONFIG_BROKETS)
+/* We use <config.h> instead of "config.h" so that a compilation
+ using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
+ (which it would do because it found this file in $srcdir). */
+#include <config.h>
+#else
+#include "config.h"
+#endif
+#endif
+
+#include <errno.h>
+#include <fnmatch.h>
+#include <ctype.h>
+
+
+/* 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__)
+
+
+#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
+extern int errno;
+#endif
+
+/* Match STRING against the filename pattern PATTERN, returning zero if
+ it matches, nonzero if not. */
+int
+fnmatch (pattern, string, flags)
+ const char *pattern;
+ const char *string;
+ int flags;
+{
+ register const char *p = pattern, *n = string;
+ register char c;
+
+/* Note that this evalutes C many times. */
+#define FOLD(c) ((flags & FNM_CASEFOLD) && isupper (c) ? tolower (c) : (c))
+
+ while ((c = *p++) != '\0')
+ {
+ c = FOLD (c);
+
+ switch (c)
+ {
+ case '?':
+ if (*n == '\0')
+ return FNM_NOMATCH;
+ else if ((flags & FNM_FILE_NAME) && *n == '/')
+ return FNM_NOMATCH;
+ else if ((flags & FNM_PERIOD) && *n == '.' &&
+ (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+ return FNM_NOMATCH;
+ break;
+
+ case '\\':
+ if (!(flags & FNM_NOESCAPE))
+ {
+ c = *p++;
+ c = FOLD (c);
+ }
+ if (FOLD (*n) != c)
+ return FNM_NOMATCH;
+ break;
+
+ case '*':
+ if ((flags & FNM_PERIOD) && *n == '.' &&
+ (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+ return FNM_NOMATCH;
+
+ for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
+ if (((flags & FNM_FILE_NAME) && *n == '/') ||
+ (c == '?' && *n == '\0'))
+ return FNM_NOMATCH;
+
+ if (c == '\0')
+ return 0;
+
+ {
+ char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
+ c1 = FOLD (c1);
+ for (--p; *n != '\0'; ++n)
+ if ((c == '[' || FOLD (*n) == c1) &&
+ fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
+ return 0;
+ return FNM_NOMATCH;
+ }
+
+ case '[':
+ {
+ /* Nonzero if the sense of the character class is inverted. */
+ register int not;
+
+ if (*n == '\0')
+ return FNM_NOMATCH;
+
+ if ((flags & FNM_PERIOD) && *n == '.' &&
+ (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+ return FNM_NOMATCH;
+
+ not = (*p == '!' || *p == '^');
+ if (not)
+ ++p;
+
+ c = *p++;
+ for (;;)
+ {
+ register char cstart = c, cend = c;
+
+ if (!(flags & FNM_NOESCAPE) && c == '\\')
+ cstart = cend = *p++;
+
+ cstart = cend = FOLD (cstart);
+
+ if (c == '\0')
+ /* [ (unterminated) loses. */
+ return FNM_NOMATCH;
+
+ c = *p++;
+ c = FOLD (c);
+
+ if ((flags & FNM_FILE_NAME) && c == '/')
+ /* [/] can never match. */
+ return FNM_NOMATCH;
+
+ if (c == '-' && *p != ']')
+ {
+ cend = *p++;
+ if (!(flags & FNM_NOESCAPE) && cend == '\\')
+ cend = *p++;
+ if (cend == '\0')
+ return FNM_NOMATCH;
+ cend = FOLD (cend);
+
+ c = *p++;
+ }
+
+ if (FOLD (*n) >= cstart && FOLD (*n) <= cend)
+ goto matched;
+
+ if (c == ']')
+ break;
+ }
+ if (!not)
+ return FNM_NOMATCH;
+ break;
+
+ matched:;
+ /* Skip the rest of the [...] that already matched. */
+ while (c != ']')
+ {
+ if (c == '\0')
+ /* [... (unterminated) loses. */
+ return FNM_NOMATCH;
+
+ c = *p++;
+ if (!(flags & FNM_NOESCAPE) && c == '\\')
+ /* XXX 1003.2d11 is unclear if this is right. */
+ ++p;
+ }
+ if (not)
+ return FNM_NOMATCH;
+ }
+ break;
+
+ default:
+ if (c != FOLD (*n))
+ return FNM_NOMATCH;
+ }
+
+ ++n;
+ }
+
+ if (*n == '\0')
+ return 0;
+
+ if ((flags & FNM_LEADING_DIR) && *n == '/')
+ /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
+ return 0;
+
+ return FNM_NOMATCH;
+}
+
+#endif /* _LIBC or not __GNU_LIBRARY__. */
diff --git a/gnu/dist/diffutils/fnmatch.h b/gnu/dist/diffutils/fnmatch.h
new file mode 100644
index 00000000000..1a653ab6314
--- /dev/null
+++ b/gnu/dist/diffutils/fnmatch.h
@@ -0,0 +1,69 @@
+/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
+
+NOTE: The canonical source of this file is maintained with the GNU C Library.
+Bugs can be reported to bug-glibc@prep.ai.mit.edu.
+
+This program is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef _FNMATCH_H
+
+#define _FNMATCH_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
+#undef __P
+#define __P(args) args
+#else /* Not C++ or ANSI C. */
+#undef __P
+#define __P(args) ()
+/* We can get away without defining `const' here only because in this file
+ it is used only inside the prototype for `fnmatch', which is elided in
+ non-ANSI C where `const' is problematical. */
+#endif /* C++ or ANSI C. */
+
+
+/* We #undef these before defining them because some losing systems
+ (HP-UX A.08.07 for example) define these in <unistd.h>. */
+#undef FNM_PATHNAME
+#undef FNM_NOESCAPE
+#undef FNM_PERIOD
+
+/* Bits set in the FLAGS argument to `fnmatch'. */
+#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */
+#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */
+#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */
+
+#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_GNU_SOURCE)
+#define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
+#define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
+#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
+#endif
+
+/* Value returned by `fnmatch' if STRING does not match PATTERN. */
+#define FNM_NOMATCH 1
+
+/* Match STRING against the filename pattern PATTERN,
+ returning zero if it matches, FNM_NOMATCH if not. */
+extern int fnmatch __P ((const char *__pattern, const char *__string,
+ int __flags));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* fnmatch.h */
diff --git a/gnu/dist/diffutils/getopt.c b/gnu/dist/diffutils/getopt.c
new file mode 100644
index 00000000000..964189d2dd4
--- /dev/null
+++ b/gnu/dist/diffutils/getopt.c
@@ -0,0 +1,748 @@
+/* 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, 93, 94
+ 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. */
+
+/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
+ Ditto for AIX 3.2 and <stdlib.h>. */
+#ifndef _NO_PROTO
+#define _NO_PROTO
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifndef __STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+#ifndef const
+#define const
+#endif
+#endif
+
+#include <stdio.h>
+
+/* 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__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+ contain conflicting prototypes for getopt. */
+#include <stdlib.h>
+#endif /* GNU C library. */
+
+/* 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 = NULL;
+
+/* 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;
+
+/* Value of POSIXLY_CORRECT environment variable. */
+static char *posixly_correct;
+
+#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 <string.h>
+#define my_index strchr
+#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;
+}
+
+/* If using GCC, we can safely declare strlen this way.
+ If not using GCC, it is ok not to declare it. */
+#ifdef __GNUC__
+/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
+ That was relevant to code that was here before. */
+#ifndef __STDC__
+/* gcc with -traditional declares the built-in strlen to return int,
+ and has done so at least since version 2.4.5. -- rms. */
+extern int strlen (const char *);
+#endif /* not __STDC__ */
+#endif /* __GNUC__ */
+
+#endif /* not __GNU_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 bottom = first_nonopt;
+ int middle = last_nonopt;
+ int top = optind;
+ char *tem;
+
+ /* Exchange the shorter segment with the far end of the longer segment.
+ That puts the shorter segment into the right place.
+ It leaves the longer segment in the right place overall,
+ but it consists of two parts that need to be swapped next. */
+
+ while (top > middle && middle > bottom)
+ {
+ if (top - middle > middle - bottom)
+ {
+ /* Bottom segment is the short one. */
+ int len = middle - bottom;
+ register int i;
+
+ /* Swap it with the top part of the top segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[top - (middle - bottom) + i];
+ argv[top - (middle - bottom) + i] = tem;
+ }
+ /* Exclude the moved bottom segment from further swapping. */
+ top -= len;
+ }
+ else
+ {
+ /* Top segment is the short one. */
+ int len = top - middle;
+ register int i;
+
+ /* Swap it with the bottom part of the bottom segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[middle + i];
+ argv[middle + i] = tem;
+ }
+ /* Exclude the moved top segment from further swapping. */
+ bottom += len;
+ }
+ }
+
+ /* Update records for the slots the non-options now occupy. */
+
+ first_nonopt += (optind - last_nonopt);
+ last_nonopt = optind;
+}
+
+/* Initialize the internal data when the first call is made. */
+
+static const char *
+_getopt_initialize (optstring)
+ const char *optstring;
+{
+ /* 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. */
+
+ first_nonopt = last_nonopt = optind = 1;
+
+ nextchar = NULL;
+
+ posixly_correct = getenv ("POSIXLY_CORRECT");
+
+ /* 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 (posixly_correct != NULL)
+ ordering = REQUIRE_ORDER;
+ else
+ ordering = PERMUTE;
+
+ return optstring;
+}
+
+/* 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;
+{
+ optarg = NULL;
+
+ if (optind == 0)
+ optstring = _getopt_initialize (optstring);
+
+ if (nextchar == NULL || *nextchar == '\0')
+ {
+ /* Advance to the next ARGV-element. */
+
+ 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;
+
+ /* Skip any additional non-options
+ and extend the range of non-options previously skipped. */
+
+ while (optind < argc
+ && (argv[optind][0] != '-' || argv[optind][1] == '\0'))
+ optind++;
+ last_nonopt = optind;
+ }
+
+ /* The 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'))
+ {
+ if (ordering == REQUIRE_ORDER)
+ return EOF;
+ optarg = argv[optind++];
+ return 1;
+ }
+
+ /* We have found another option-ARGV-element.
+ Skip the initial punctuation. */
+
+ nextchar = (argv[optind] + 1
+ + (longopts != NULL && argv[optind][1] == '-'));
+ }
+
+ /* Decode the current option-ARGV-element. */
+
+ /* Check whether the ARGV-element is a long option.
+
+ If long_only and the ARGV-element has the form "-f", where f is
+ a valid short option, don't consider it an abbreviated form of
+ a long option that starts with f. Otherwise there would be no
+ way to give the -f short option.
+
+ On the other hand, if there's a long option "fubar" and
+ the ARGV-element is "-fu", do consider that an abbreviation of
+ the long option, just like "--fu", and not "-f" with arg "u".
+
+ This distinction seems to be the most useful approach. */
+
+ if (longopts != NULL
+ && (argv[optind][1] == '-'
+ || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound;
+ int option_index;
+
+ for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if (nameend - 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 or later 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 (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ optarg = nameend + 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] == '-'
+ || 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 short 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 (posixly_correct)
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
+ else
+ fprintf (stderr, "%s: invalid option -- %c\n", argv[0], c);
+ }
+ 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 = NULL;
+ 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)
+ {
+ /* 1003.2 specifies the format of this message. */
+ fprintf (stderr, "%s: option requires an argument -- %c\n",
+ argv[0], c);
+ }
+ 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/dist/diffutils/getopt.h b/gnu/dist/diffutils/getopt.h
new file mode 100644
index 00000000000..45541f5ac0f
--- /dev/null
+++ b/gnu/dist/diffutils/getopt.h
@@ -0,0 +1,129 @@
+/* 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/dist/diffutils/getopt1.c b/gnu/dist/diffutils/getopt1.c
new file mode 100644
index 00000000000..725c653bbcc
--- /dev/null
+++ b/gnu/dist/diffutils/getopt1.c
@@ -0,0 +1,180 @@
+/* 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"
+
+#ifndef __STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+#ifndef const
+#define const
+#endif
+#endif
+
+#include <stdio.h>
+
+/* 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 <stdlib.h>
+#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 <stdio.h>
+
+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/dist/diffutils/ifdef.c b/gnu/dist/diffutils/ifdef.c
new file mode 100644
index 00000000000..2834cbdfa23
--- /dev/null
+++ b/gnu/dist/diffutils/ifdef.c
@@ -0,0 +1,428 @@
+/* #ifdef-format output routines for GNU DIFF.
+ Copyright (C) 1989, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
+
+This file is part of GNU DIFF.
+
+GNU DIFF is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY. No author or distributor
+accepts responsibility to anyone for the consequences of using it
+or for whether it serves any particular purpose or works at all,
+unless he says so in writing. Refer to the GNU DIFF General Public
+License for full details.
+
+Everyone is granted permission to copy, modify and redistribute
+GNU DIFF, but only under the conditions described in the
+GNU DIFF General Public License. A copy of this license is
+supposed to have been given to you along with GNU DIFF so you
+can know your rights and responsibilities. It should be in a
+file named COPYING. Among other things, the copyright notice
+and this notice must be preserved on all copies. */
+
+
+#include "diff.h"
+
+struct group
+{
+ struct file_data const *file;
+ int from, upto; /* start and limit lines for this group of lines */
+};
+
+static char *format_group PARAMS((FILE *, char *, int, struct group const *));
+static char *scan_char_literal PARAMS((char *, int *));
+static char *scan_printf_spec PARAMS((char *));
+static int groups_letter_value PARAMS((struct group const *, int));
+static void format_ifdef PARAMS((char *, int, int, int, int));
+static void print_ifdef_hunk PARAMS((struct change *));
+static void print_ifdef_lines PARAMS((FILE *, char *, struct group const *));
+
+static int next_line;
+
+/* Print the edit-script SCRIPT as a merged #ifdef file. */
+
+void
+print_ifdef_script (script)
+ struct change *script;
+{
+ next_line = - files[0].prefix_lines;
+ print_script (script, find_change, print_ifdef_hunk);
+ if (next_line < files[0].valid_lines)
+ {
+ begin_output ();
+ format_ifdef (group_format[UNCHANGED], next_line, files[0].valid_lines,
+ next_line - files[0].valid_lines + files[1].valid_lines,
+ files[1].valid_lines);
+ }
+}
+
+/* Print a hunk of an ifdef diff.
+ This is a contiguous portion of a complete edit script,
+ describing changes in consecutive lines. */
+
+static void
+print_ifdef_hunk (hunk)
+ struct change *hunk;
+{
+ int first0, last0, first1, last1, deletes, inserts;
+ char *format;
+
+ /* Determine range of line numbers involved in each file. */
+ analyze_hunk (hunk, &first0, &last0, &first1, &last1, &deletes, &inserts);
+ if (inserts)
+ format = deletes ? group_format[CHANGED] : group_format[NEW];
+ else if (deletes)
+ format = group_format[OLD];
+ else
+ return;
+
+ begin_output ();
+
+ /* Print lines up to this change. */
+ if (next_line < first0)
+ format_ifdef (group_format[UNCHANGED], next_line, first0,
+ next_line - first0 + first1, first1);
+
+ /* Print this change. */
+ next_line = last0 + 1;
+ format_ifdef (format, first0, next_line, first1, last1 + 1);
+}
+
+/* Print a set of lines according to FORMAT.
+ Lines BEG0 up to END0 are from the first file;
+ lines BEG1 up to END1 are from the second file. */
+
+static void
+format_ifdef (format, beg0, end0, beg1, end1)
+ char *format;
+ int beg0, end0, beg1, end1;
+{
+ struct group groups[2];
+
+ groups[0].file = &files[0];
+ groups[0].from = beg0;
+ groups[0].upto = end0;
+ groups[1].file = &files[1];
+ groups[1].from = beg1;
+ groups[1].upto = end1;
+ format_group (outfile, format, '\0', groups);
+}
+
+/* Print to file OUT a set of lines according to FORMAT.
+ The format ends at the first free instance of ENDCHAR.
+ Yield the address of the terminating character.
+ GROUPS specifies which lines to print.
+ If OUT is zero, do not actually print anything; just scan the format. */
+
+static char *
+format_group (out, format, endchar, groups)
+ register FILE *out;
+ char *format;
+ int endchar;
+ struct group const *groups;
+{
+ register char c;
+ register char *f = format;
+
+ while ((c = *f) != endchar && c != 0)
+ {
+ f++;
+ if (c == '%')
+ {
+ char *spec = f;
+ switch ((c = *f++))
+ {
+ case '%':
+ break;
+
+ case '(':
+ /* Print if-then-else format e.g. `%(n=1?thenpart:elsepart)'. */
+ {
+ int i, value[2];
+ FILE *thenout, *elseout;
+
+ for (i = 0; i < 2; i++)
+ {
+ unsigned char f0 = f[0];
+ if (ISDIGIT (f0))
+ {
+ value[i] = atoi (f);
+ while (ISDIGIT ((unsigned char) *++f))
+ continue;
+ }
+ else
+ {
+ value[i] = groups_letter_value (groups, f0);
+ if (value[i] < 0)
+ goto bad_format;
+ f++;
+ }
+ if (*f++ != "=?"[i])
+ goto bad_format;
+ }
+ if (value[0] == value[1])
+ thenout = out, elseout = 0;
+ else
+ thenout = 0, elseout = out;
+ f = format_group (thenout, f, ':', groups);
+ if (*f)
+ {
+ f = format_group (elseout, f + 1, ')', groups);
+ if (*f)
+ f++;
+ }
+ }
+ continue;
+
+ case '<':
+ /* Print lines deleted from first file. */
+ print_ifdef_lines (out, line_format[OLD], &groups[0]);
+ continue;
+
+ case '=':
+ /* Print common lines. */
+ print_ifdef_lines (out, line_format[UNCHANGED], &groups[0]);
+ continue;
+
+ case '>':
+ /* Print lines inserted from second file. */
+ print_ifdef_lines (out, line_format[NEW], &groups[1]);
+ continue;
+
+ default:
+ {
+ int value;
+ char *speclim;
+
+ f = scan_printf_spec (spec);
+ if (!f)
+ goto bad_format;
+ speclim = f;
+ c = *f++;
+ switch (c)
+ {
+ case '\'':
+ f = scan_char_literal (f, &value);
+ if (!f)
+ goto bad_format;
+ break;
+
+ default:
+ value = groups_letter_value (groups, c);
+ if (value < 0)
+ goto bad_format;
+ break;
+ }
+ if (out)
+ {
+ /* Temporarily replace e.g. "%3dnx" with "%3d\0x". */
+ *speclim = 0;
+ fprintf (out, spec - 1, value);
+ /* Undo the temporary replacement. */
+ *speclim = c;
+ }
+ }
+ continue;
+
+ bad_format:
+ c = '%';
+ f = spec;
+ break;
+ }
+ }
+ if (out)
+ putc (c, out);
+ }
+ return f;
+}
+
+/* For the line group pair G, return the number corresponding to LETTER.
+ Return -1 if LETTER is not a group format letter. */
+static int
+groups_letter_value (g, letter)
+ struct group const *g;
+ int letter;
+{
+ if (ISUPPER (letter))
+ {
+ g++;
+ letter = tolower (letter);
+ }
+ switch (letter)
+ {
+ case 'e': return translate_line_number (g->file, g->from) - 1;
+ case 'f': return translate_line_number (g->file, g->from);
+ case 'l': return translate_line_number (g->file, g->upto) - 1;
+ case 'm': return translate_line_number (g->file, g->upto);
+ case 'n': return g->upto - g->from;
+ default: return -1;
+ }
+}
+
+/* Print to file OUT, using FORMAT to print the line group GROUP.
+ But do nothing if OUT is zero. */
+static void
+print_ifdef_lines (out, format, group)
+ register FILE *out;
+ char *format;
+ struct group const *group;
+{
+ struct file_data const *file = group->file;
+ char const * const *linbuf = file->linbuf;
+ int from = group->from, upto = group->upto;
+
+ if (!out)
+ return;
+
+ /* If possible, use a single fwrite; it's faster. */
+ if (!tab_expand_flag && format[0] == '%')
+ {
+ if (format[1] == 'l' && format[2] == '\n' && !format[3])
+ {
+ fwrite (linbuf[from], sizeof (char),
+ linbuf[upto] + (linbuf[upto][-1] != '\n') - linbuf[from],
+ out);
+ return;
+ }
+ if (format[1] == 'L' && !format[2])
+ {
+ fwrite (linbuf[from], sizeof (char),
+ linbuf[upto] - linbuf[from], out);
+ return;
+ }
+ }
+
+ for (; from < upto; from++)
+ {
+ register char c;
+ register char *f = format;
+
+ while ((c = *f++) != 0)
+ {
+ if (c == '%')
+ {
+ char *spec = f;
+ switch ((c = *f++))
+ {
+ case '%':
+ break;
+
+ case 'l':
+ output_1_line (linbuf[from],
+ linbuf[from + 1]
+ - (linbuf[from + 1][-1] == '\n'), 0, 0);
+ continue;
+
+ case 'L':
+ output_1_line (linbuf[from], linbuf[from + 1], 0, 0);
+ continue;
+
+ default:
+ {
+ int value;
+ char *speclim;
+
+ f = scan_printf_spec (spec);
+ if (!f)
+ goto bad_format;
+ speclim = f;
+ c = *f++;
+ switch (c)
+ {
+ case '\'':
+ f = scan_char_literal (f, &value);
+ if (!f)
+ goto bad_format;
+ break;
+
+ case 'n':
+ value = translate_line_number (file, from);
+ break;
+
+ default:
+ goto bad_format;
+ }
+ /* Temporarily replace e.g. "%3dnx" with "%3d\0x". */
+ *speclim = 0;
+ fprintf (out, spec - 1, value);
+ /* Undo the temporary replacement. */
+ *speclim = c;
+ }
+ continue;
+
+ bad_format:
+ c = '%';
+ f = spec;
+ break;
+ }
+ }
+ putc (c, out);
+ }
+ }
+}
+
+/* Scan the character literal represented in the string LIT; LIT points just
+ after the initial apostrophe. Put the literal's value into *INTPTR.
+ Yield the address of the first character after the closing apostrophe,
+ or zero if the literal is ill-formed. */
+static char *
+scan_char_literal (lit, intptr)
+ char *lit;
+ int *intptr;
+{
+ register char *p = lit;
+ int value, digits;
+ char c = *p++;
+
+ switch (c)
+ {
+ case 0:
+ case '\'':
+ return 0;
+
+ case '\\':
+ value = 0;
+ while ((c = *p++) != '\'')
+ {
+ unsigned digit = c - '0';
+ if (8 <= digit)
+ return 0;
+ value = 8 * value + digit;
+ }
+ digits = p - lit - 2;
+ if (! (1 <= digits && digits <= 3))
+ return 0;
+ break;
+
+ default:
+ value = c;
+ if (*p++ != '\'')
+ return 0;
+ break;
+ }
+ *intptr = value;
+ return p;
+}
+
+/* Scan optional printf-style SPEC of the form `-*[0-9]*(.[0-9]*)?[cdoxX]'.
+ Return the address of the character following SPEC, or zero if failure. */
+static char *
+scan_printf_spec (spec)
+ register char *spec;
+{
+ register unsigned char c;
+
+ while ((c = *spec++) == '-')
+ continue;
+ while (ISDIGIT (c))
+ c = *spec++;
+ if (c == '.')
+ while (ISDIGIT (c = *spec++))
+ continue;
+ switch (c)
+ {
+ case 'c': case 'd': case 'o': case 'x': case 'X':
+ return spec;
+
+ default:
+ return 0;
+ }
+}
diff --git a/gnu/dist/diffutils/install-sh b/gnu/dist/diffutils/install-sh
new file mode 100644
index 00000000000..ab74c882e92
--- /dev/null
+++ b/gnu/dist/diffutils/install-sh
@@ -0,0 +1,238 @@
+#!/bin/sh
+#
+# install - install a program, script, or datafile
+# This comes from X11R5.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+tranformbasename=""
+transform_arg=""
+instcmd="$mvprog"
+chmodcmd="$chmodprog 0755"
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+dir_arg=""
+
+while [ x"$1" != x ]; do
+ case $1 in
+ -c) instcmd="$cpprog"
+ shift
+ continue;;
+
+ -d) dir_arg=true
+ shift
+ continue;;
+
+ -m) chmodcmd="$chmodprog $2"
+ shift
+ shift
+ continue;;
+
+ -o) chowncmd="$chownprog $2"
+ shift
+ shift
+ continue;;
+
+ -g) chgrpcmd="$chgrpprog $2"
+ shift
+ shift
+ continue;;
+
+ -s) stripcmd="$stripprog"
+ shift
+ continue;;
+
+ -t=*) transformarg=`echo $1 | sed 's/-t=//'`
+ shift
+ continue;;
+
+ -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
+ shift
+ continue;;
+
+ *) if [ x"$src" = x ]
+ then
+ src=$1
+ else
+ # this colon is to work around a 386BSD /bin/sh bug
+ :
+ dst=$1
+ fi
+ shift
+ continue;;
+ esac
+done
+
+if [ x"$src" = x ]
+then
+ echo "install: no input file specified"
+ exit 1
+else
+ true
+fi
+
+if [ x"$dir_arg" != x ]; then
+ dst=$src
+ src=""
+
+ if [ -d $dst ]; then
+ instcmd=:
+ else
+ instcmd=mkdir
+ fi
+else
+
+# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
+# might cause directories to be created, which would be especially bad
+# if $src (and thus $dsttmp) contains '*'.
+
+ if [ -f $src -o -d $src ]
+ then
+ true
+ else
+ echo "install: $src does not exist"
+ exit 1
+ fi
+
+ if [ x"$dst" = x ]
+ then
+ echo "install: no destination specified"
+ exit 1
+ else
+ true
+ fi
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+ if [ -d $dst ]
+ then
+ dst="$dst"/`basename $src`
+ else
+ true
+ fi
+fi
+
+## this sed command emulates the dirname command
+dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
+
+# Make sure that the destination directory exists.
+# this part is taken from Noah Friedman's mkinstalldirs script
+
+# Skip lots of stat calls in the usual case.
+if [ ! -d "$dstdir" ]; then
+defaultIFS='
+'
+IFS="${IFS-${defaultIFS}}"
+
+oIFS="${IFS}"
+# Some sh's can't handle IFS=/ for some reason.
+IFS='%'
+set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
+IFS="${oIFS}"
+
+pathcomp=''
+
+while [ $# -ne 0 ] ; do
+ pathcomp="${pathcomp}${1}"
+ shift
+
+ if [ ! -d "${pathcomp}" ] ;
+ then
+ $mkdirprog "${pathcomp}"
+ else
+ true
+ fi
+
+ pathcomp="${pathcomp}/"
+done
+fi
+
+if [ x"$dir_arg" != x ]
+then
+ $doit $instcmd $dst &&
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
+else
+
+# If we're going to rename the final executable, determine the name now.
+
+ if [ x"$transformarg" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ dstfile=`basename $dst $transformbasename |
+ sed $transformarg`$transformbasename
+ fi
+
+# don't allow the sed command to completely eliminate the filename
+
+ if [ x"$dstfile" = x ]
+ then
+ dstfile=`basename $dst`
+ else
+ true
+ fi
+
+# Make a temp file name in the proper directory.
+
+ dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+ $doit $instcmd $src $dsttmp &&
+
+ trap "rm -f ${dsttmp}" 0 &&
+
+# and set any options; do chmod last to preserve setuid bits
+
+# If any of these fail, we abort the whole thing. If we want to
+# ignore errors from any of these, just make sure not to ignore
+# errors from the above "$doit $instcmd $src $dsttmp" command.
+
+ if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
+ if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
+ if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
+ if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
+
+# Now rename the file to the real destination.
+
+ $doit $rmcmd -f $dstdir/$dstfile &&
+ $doit $mvcmd $dsttmp $dstdir/$dstfile
+
+fi &&
+
+
+exit 0
diff --git a/gnu/dist/diffutils/io.c b/gnu/dist/diffutils/io.c
new file mode 100644
index 00000000000..66059155109
--- /dev/null
+++ b/gnu/dist/diffutils/io.c
@@ -0,0 +1,714 @@
+/* File I/O for GNU DIFF.
+ Copyright (C) 1988, 1989, 1992, 1993, 1994 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 "diff.h"
+
+/* Rotate a value n bits to the left. */
+#define UINT_BIT (sizeof (unsigned) * CHAR_BIT)
+#define ROL(v, n) ((v) << (n) | (v) >> (UINT_BIT - (n)))
+
+/* Given a hash value and a new character, return a new hash value. */
+#define HASH(h, c) ((c) + ROL (h, 7))
+
+/* Guess remaining number of lines from number N of lines so far,
+ size S so far, and total size T. */
+#define GUESS_LINES(n,s,t) (((t) - (s)) / ((n) < 10 ? 32 : (s) / ((n)-1)) + 5)
+
+/* Type used for fast prefix comparison in find_identical_ends. */
+#ifndef word
+#define word int
+#endif
+
+/* Lines are put into equivalence classes (of lines that match in line_cmp).
+ Each equivalence class is represented by one of these structures,
+ but only while the classes are being computed.
+ Afterward, each class is represented by a number. */
+struct equivclass
+{
+ int next; /* Next item in this bucket. */
+ unsigned hash; /* Hash of lines in this class. */
+ char const *line; /* A line that fits this class. */
+ size_t length; /* That line's length, not counting its newline. */
+};
+
+/* Hash-table: array of buckets, each being a chain of equivalence classes.
+ buckets[-1] is reserved for incomplete lines. */
+static int *buckets;
+
+/* Number of buckets in the hash table array, not counting buckets[-1]. */
+static int nbuckets;
+
+/* Array in which the equivalence classes are allocated.
+ The bucket-chains go through the elements in this array.
+ The number of an equivalence class is its index in this array. */
+static struct equivclass *equivs;
+
+/* Index of first free element in the array `equivs'. */
+static int equivs_index;
+
+/* Number of elements allocated in the array `equivs'. */
+static int equivs_alloc;
+
+static void find_and_hash_each_line PARAMS((struct file_data *));
+static void find_identical_ends PARAMS((struct file_data[]));
+static void prepare_text_end PARAMS((struct file_data *));
+
+/* Check for binary files and compare them for exact identity. */
+
+/* Return 1 if BUF contains a non text character.
+ SIZE is the number of characters in BUF. */
+
+#define binary_file_p(buf, size) (memchr (buf, '\0', size) != 0)
+
+/* Get ready to read the current file.
+ Return nonzero if SKIP_TEST is zero,
+ and if it appears to be a binary file. */
+
+int
+sip (current, skip_test)
+ struct file_data *current;
+ int skip_test;
+{
+ /* If we have a nonexistent file at this stage, treat it as empty. */
+ if (current->desc < 0)
+ {
+ /* Leave room for a sentinel. */
+ current->bufsize = sizeof (word);
+ current->buffer = xmalloc (current->bufsize);
+ }
+ else
+ {
+ current->bufsize = STAT_BLOCKSIZE (current->stat);
+ current->buffer = xmalloc (current->bufsize);
+
+ if (! skip_test)
+ {
+ /* Check first part of file to see if it's a binary file. */
+#if HAVE_SETMODE
+ int oldmode = setmode (current->desc, O_BINARY);
+#endif
+ size_t n = read (current->desc, current->buffer, current->bufsize);
+ if (n == -1)
+ pfatal_with_name (current->name);
+ current->buffered_chars = n;
+#if HAVE_SETMODE
+ if (oldmode != O_BINARY)
+ {
+ if (lseek (current->desc, - (off_t) n, SEEK_CUR) == -1)
+ pfatal_with_name (current->name);
+ setmode (current->desc, oldmode);
+ current->buffered_chars = 0;
+ }
+#endif
+ return binary_file_p (current->buffer, n);
+ }
+ }
+
+ current->buffered_chars = 0;
+ return 0;
+}
+
+/* Slurp the rest of the current file completely into memory. */
+
+void
+slurp (current)
+ struct file_data *current;
+{
+ size_t cc;
+
+ if (current->desc < 0)
+ /* The file is nonexistent. */
+ ;
+ else if (S_ISREG (current->stat.st_mode))
+ {
+ /* It's a regular file; slurp in the rest all at once. */
+
+ /* Get the size out of the stat block.
+ Allocate enough room for appended newline and sentinel. */
+ cc = current->stat.st_size + 1 + sizeof (word);
+ if (current->bufsize < cc)
+ {
+ current->bufsize = cc;
+ current->buffer = xrealloc (current->buffer, cc);
+ }
+
+ if (current->buffered_chars < current->stat.st_size)
+ {
+ cc = read (current->desc,
+ current->buffer + current->buffered_chars,
+ current->stat.st_size - current->buffered_chars);
+ if (cc == -1)
+ pfatal_with_name (current->name);
+ current->buffered_chars += cc;
+ }
+ }
+ /* It's not a regular file; read it, growing the buffer as needed. */
+ else if (always_text_flag || current->buffered_chars != 0)
+ {
+ for (;;)
+ {
+ if (current->buffered_chars == current->bufsize)
+ {
+ current->bufsize = current->bufsize * 2;
+ current->buffer = xrealloc (current->buffer, current->bufsize);
+ }
+ cc = read (current->desc,
+ current->buffer + current->buffered_chars,
+ current->bufsize - current->buffered_chars);
+ if (cc == 0)
+ break;
+ if (cc == -1)
+ pfatal_with_name (current->name);
+ current->buffered_chars += cc;
+ }
+ /* Allocate just enough room for appended newline and sentinel. */
+ current->bufsize = current->buffered_chars + 1 + sizeof (word);
+ current->buffer = xrealloc (current->buffer, current->bufsize);
+ }
+}
+
+/* Split the file into lines, simultaneously computing the equivalence class for
+ each line. */
+
+static void
+find_and_hash_each_line (current)
+ struct file_data *current;
+{
+ unsigned h;
+ unsigned char const *p = (unsigned char const *) current->prefix_end;
+ unsigned char c;
+ int i, *bucket;
+ size_t length;
+
+ /* Cache often-used quantities in local variables to help the compiler. */
+ char const **linbuf = current->linbuf;
+ int alloc_lines = current->alloc_lines;
+ int line = 0;
+ int linbuf_base = current->linbuf_base;
+ int *cureqs = (int *) xmalloc (alloc_lines * sizeof (int));
+ struct equivclass *eqs = equivs;
+ int eqs_index = equivs_index;
+ int eqs_alloc = equivs_alloc;
+ char const *suffix_begin = current->suffix_begin;
+ char const *bufend = current->buffer + current->buffered_chars;
+ int use_line_cmp = ignore_some_line_changes;
+
+ while ((char const *) p < suffix_begin)
+ {
+ char const *ip = (char const *) p;
+
+ /* Compute the equivalence class for this line. */
+
+ h = 0;
+
+ /* Hash this line until we find a newline. */
+ if (ignore_case_flag)
+ {
+ if (ignore_all_space_flag)
+ while ((c = *p++) != '\n')
+ {
+ if (! ISSPACE (c))
+ h = HASH (h, ISUPPER (c) ? tolower (c) : c);
+ }
+ else if (ignore_space_change_flag)
+ while ((c = *p++) != '\n')
+ {
+ if (ISSPACE (c))
+ {
+ for (;;)
+ {
+ c = *p++;
+ if (!ISSPACE (c))
+ break;
+ if (c == '\n')
+ goto hashing_done;
+ }
+ h = HASH (h, ' ');
+ }
+ /* C is now the first non-space. */
+ h = HASH (h, ISUPPER (c) ? tolower (c) : c);
+ }
+ else
+ while ((c = *p++) != '\n')
+ h = HASH (h, ISUPPER (c) ? tolower (c) : c);
+ }
+ else
+ {
+ if (ignore_all_space_flag)
+ while ((c = *p++) != '\n')
+ {
+ if (! ISSPACE (c))
+ h = HASH (h, c);
+ }
+ else if (ignore_space_change_flag)
+ while ((c = *p++) != '\n')
+ {
+ if (ISSPACE (c))
+ {
+ for (;;)
+ {
+ c = *p++;
+ if (!ISSPACE (c))
+ break;
+ if (c == '\n')
+ goto hashing_done;
+ }
+ h = HASH (h, ' ');
+ }
+ /* C is now the first non-space. */
+ h = HASH (h, c);
+ }
+ else
+ while ((c = *p++) != '\n')
+ h = HASH (h, c);
+ }
+ hashing_done:;
+
+ bucket = &buckets[h % nbuckets];
+ length = (char const *) p - ip - 1;
+
+ if ((char const *) p == bufend
+ && current->missing_newline
+ && ROBUST_OUTPUT_STYLE (output_style))
+ {
+ /* This line is incomplete. If this is significant,
+ put the line into bucket[-1]. */
+ if (! (ignore_space_change_flag | ignore_all_space_flag))
+ bucket = &buckets[-1];
+
+ /* Omit the inserted newline when computing linbuf later. */
+ p--;
+ bufend = suffix_begin = (char const *) p;
+ }
+
+ for (i = *bucket; ; i = eqs[i].next)
+ if (!i)
+ {
+ /* Create a new equivalence class in this bucket. */
+ i = eqs_index++;
+ if (i == eqs_alloc)
+ eqs = (struct equivclass *)
+ xrealloc (eqs, (eqs_alloc*=2) * sizeof(*eqs));
+ eqs[i].next = *bucket;
+ eqs[i].hash = h;
+ eqs[i].line = ip;
+ eqs[i].length = length;
+ *bucket = i;
+ break;
+ }
+ else if (eqs[i].hash == h)
+ {
+ char const *eqline = eqs[i].line;
+
+ /* Reuse existing equivalence class if the lines are identical.
+ This detects the common case of exact identity
+ faster than complete comparison would. */
+ if (eqs[i].length == length && memcmp (eqline, ip, length) == 0)
+ break;
+
+ /* Reuse existing class if line_cmp reports the lines equal. */
+ if (use_line_cmp && line_cmp (eqline, ip) == 0)
+ break;
+ }
+
+ /* Maybe increase the size of the line table. */
+ if (line == alloc_lines)
+ {
+ /* Double (alloc_lines - linbuf_base) by adding to alloc_lines. */
+ alloc_lines = 2 * alloc_lines - linbuf_base;
+ cureqs = (int *) xrealloc (cureqs, alloc_lines * sizeof (*cureqs));
+ linbuf = (char const **) xrealloc (linbuf + linbuf_base,
+ (alloc_lines - linbuf_base)
+ * sizeof (*linbuf))
+ - linbuf_base;
+ }
+ linbuf[line] = ip;
+ cureqs[line] = i;
+ ++line;
+ }
+
+ current->buffered_lines = line;
+
+ for (i = 0; ; i++)
+ {
+ /* Record the line start for lines in the suffix that we care about.
+ Record one more line start than lines,
+ so that we can compute the length of any buffered line. */
+ if (line == alloc_lines)
+ {
+ /* Double (alloc_lines - linbuf_base) by adding to alloc_lines. */
+ alloc_lines = 2 * alloc_lines - linbuf_base;
+ linbuf = (char const **) xrealloc (linbuf + linbuf_base,
+ (alloc_lines - linbuf_base)
+ * sizeof (*linbuf))
+ - linbuf_base;
+ }
+ linbuf[line] = (char const *) p;
+
+ if ((char const *) p == bufend)
+ break;
+
+ if (context <= i && no_diff_means_no_output)
+ break;
+
+ line++;
+
+ while (*p++ != '\n')
+ ;
+ }
+
+ /* Done with cache in local variables. */
+ current->linbuf = linbuf;
+ current->valid_lines = line;
+ current->alloc_lines = alloc_lines;
+ current->equivs = cureqs;
+ equivs = eqs;
+ equivs_alloc = eqs_alloc;
+ equivs_index = eqs_index;
+}
+
+/* Prepare the end of the text. Make sure it's initialized.
+ Make sure text ends in a newline,
+ but remember that we had to add one. */
+
+static void
+prepare_text_end (current)
+ struct file_data *current;
+{
+ size_t buffered_chars = current->buffered_chars;
+ char *p = current->buffer;
+
+ if (buffered_chars == 0 || p[buffered_chars - 1] == '\n')
+ current->missing_newline = 0;
+ else
+ {
+ p[buffered_chars++] = '\n';
+ current->buffered_chars = buffered_chars;
+ current->missing_newline = 1;
+ }
+
+ /* Don't use uninitialized storage when planting or using sentinels. */
+ if (p)
+ bzero (p + buffered_chars, sizeof (word));
+}
+
+/* Given a vector of two file_data objects, find the identical
+ prefixes and suffixes of each object. */
+
+static void
+find_identical_ends (filevec)
+ struct file_data filevec[];
+{
+ word *w0, *w1;
+ char *p0, *p1, *buffer0, *buffer1;
+ char const *end0, *beg0;
+ char const **linbuf0, **linbuf1;
+ int i, lines;
+ size_t n0, n1, tem;
+ int alloc_lines0, alloc_lines1;
+ int buffered_prefix, prefix_count, prefix_mask;
+
+ slurp (&filevec[0]);
+ if (filevec[0].desc != filevec[1].desc)
+ slurp (&filevec[1]);
+ else
+ {
+ filevec[1].buffer = filevec[0].buffer;
+ filevec[1].bufsize = filevec[0].bufsize;
+ filevec[1].buffered_chars = filevec[0].buffered_chars;
+ }
+ for (i = 0; i < 2; i++)
+ prepare_text_end (&filevec[i]);
+
+ /* Find identical prefix. */
+
+ p0 = buffer0 = filevec[0].buffer;
+ p1 = buffer1 = filevec[1].buffer;
+
+ n0 = filevec[0].buffered_chars;
+ n1 = filevec[1].buffered_chars;
+
+ if (p0 == p1)
+ /* The buffers are the same; sentinels won't work. */
+ p0 = p1 += n1;
+ else
+ {
+ /* Insert end sentinels, in this case characters that are guaranteed
+ to make the equality test false, and thus terminate the loop. */
+
+ if (n0 < n1)
+ p0[n0] = ~p1[n0];
+ else
+ p1[n1] = ~p0[n1];
+
+ /* Loop until first mismatch, or to the sentinel characters. */
+
+ /* Compare a word at a time for speed. */
+ w0 = (word *) p0;
+ w1 = (word *) p1;
+ while (*w0++ == *w1++)
+ ;
+ --w0, --w1;
+
+ /* Do the last few bytes of comparison a byte at a time. */
+ p0 = (char *) w0;
+ p1 = (char *) w1;
+ while (*p0++ == *p1++)
+ ;
+ --p0, --p1;
+
+ /* Don't mistakenly count missing newline as part of prefix. */
+ if (ROBUST_OUTPUT_STYLE (output_style)
+ && (buffer0 + n0 - filevec[0].missing_newline < p0)
+ !=
+ (buffer1 + n1 - filevec[1].missing_newline < p1))
+ --p0, --p1;
+ }
+
+ /* Now P0 and P1 point at the first nonmatching characters. */
+
+ /* Skip back to last line-beginning in the prefix,
+ and then discard up to HORIZON_LINES lines from the prefix. */
+ i = horizon_lines;
+ while (p0 != buffer0 && (p0[-1] != '\n' || i--))
+ --p0, --p1;
+
+ /* Record the prefix. */
+ filevec[0].prefix_end = p0;
+ filevec[1].prefix_end = p1;
+
+ /* Find identical suffix. */
+
+ /* P0 and P1 point beyond the last chars not yet compared. */
+ p0 = buffer0 + n0;
+ p1 = buffer1 + n1;
+
+ if (! ROBUST_OUTPUT_STYLE (output_style)
+ || filevec[0].missing_newline == filevec[1].missing_newline)
+ {
+ end0 = p0; /* Addr of last char in file 0. */
+
+ /* Get value of P0 at which we should stop scanning backward:
+ this is when either P0 or P1 points just past the last char
+ of the identical prefix. */
+ beg0 = filevec[0].prefix_end + (n0 < n1 ? 0 : n0 - n1);
+
+ /* Scan back until chars don't match or we reach that point. */
+ while (p0 != beg0)
+ if (*--p0 != *--p1)
+ {
+ /* Point at the first char of the matching suffix. */
+ ++p0, ++p1;
+ beg0 = p0;
+ break;
+ }
+
+ /* Are we at a line-beginning in both files? If not, add the rest of
+ this line to the main body. Discard up to HORIZON_LINES lines from
+ the identical suffix. Also, discard one extra line,
+ because shift_boundaries may need it. */
+ i = horizon_lines + !((buffer0 == p0 || p0[-1] == '\n')
+ &&
+ (buffer1 == p1 || p1[-1] == '\n'));
+ while (i-- && p0 != end0)
+ while (*p0++ != '\n')
+ ;
+
+ p1 += p0 - beg0;
+ }
+
+ /* Record the suffix. */
+ filevec[0].suffix_begin = p0;
+ filevec[1].suffix_begin = p1;
+
+ /* Calculate number of lines of prefix to save.
+
+ prefix_count == 0 means save the whole prefix;
+ we need this with for options like -D that output the whole file.
+ We also need it for options like -F that output some preceding line;
+ at least we will need to find the last few lines,
+ but since we don't know how many, it's easiest to find them all.
+
+ Otherwise, prefix_count != 0. Save just prefix_count lines at start
+ of the line buffer; they'll be moved to the proper location later.
+ Handle 1 more line than the context says (because we count 1 too many),
+ rounded up to the next power of 2 to speed index computation. */
+
+ if (no_diff_means_no_output && ! function_regexp_list)
+ {
+ for (prefix_count = 1; prefix_count < context + 1; prefix_count *= 2)
+ ;
+ prefix_mask = prefix_count - 1;
+ alloc_lines0
+ = prefix_count
+ + GUESS_LINES (0, 0, p0 - filevec[0].prefix_end)
+ + context;
+ }
+ else
+ {
+ prefix_count = 0;
+ prefix_mask = ~0;
+ alloc_lines0 = GUESS_LINES (0, 0, n0);
+ }
+
+ lines = 0;
+ linbuf0 = (char const **) xmalloc (alloc_lines0 * sizeof (*linbuf0));
+
+ /* If the prefix is needed, find the prefix lines. */
+ if (! (no_diff_means_no_output
+ && filevec[0].prefix_end == p0
+ && filevec[1].prefix_end == p1))
+ {
+ p0 = buffer0;
+ end0 = filevec[0].prefix_end;
+ while (p0 != end0)
+ {
+ int l = lines++ & prefix_mask;
+ if (l == alloc_lines0)
+ linbuf0 = (char const **) xrealloc (linbuf0, (alloc_lines0 *= 2)
+ * sizeof(*linbuf0));
+ linbuf0[l] = p0;
+ while (*p0++ != '\n')
+ ;
+ }
+ }
+ buffered_prefix = prefix_count && context < lines ? context : lines;
+
+ /* Allocate line buffer 1. */
+ tem = prefix_count ? filevec[1].suffix_begin - buffer1 : n1;
+
+ alloc_lines1
+ = (buffered_prefix
+ + GUESS_LINES (lines, filevec[1].prefix_end - buffer1, tem)
+ + context);
+ linbuf1 = (char const **) xmalloc (alloc_lines1 * sizeof (*linbuf1));
+
+ if (buffered_prefix != lines)
+ {
+ /* Rotate prefix lines to proper location. */
+ for (i = 0; i < buffered_prefix; i++)
+ linbuf1[i] = linbuf0[(lines - context + i) & prefix_mask];
+ for (i = 0; i < buffered_prefix; i++)
+ linbuf0[i] = linbuf1[i];
+ }
+
+ /* Initialize line buffer 1 from line buffer 0. */
+ for (i = 0; i < buffered_prefix; i++)
+ linbuf1[i] = linbuf0[i] - buffer0 + buffer1;
+
+ /* Record the line buffer, adjusted so that
+ linbuf*[0] points at the first differing line. */
+ filevec[0].linbuf = linbuf0 + buffered_prefix;
+ filevec[1].linbuf = linbuf1 + buffered_prefix;
+ filevec[0].linbuf_base = filevec[1].linbuf_base = - buffered_prefix;
+ filevec[0].alloc_lines = alloc_lines0 - buffered_prefix;
+ filevec[1].alloc_lines = alloc_lines1 - buffered_prefix;
+ filevec[0].prefix_lines = filevec[1].prefix_lines = lines;
+}
+
+/* Largest primes less than some power of two, for nbuckets. Values range
+ from useful to preposterous. If one of these numbers isn't prime
+ after all, don't blame it on me, blame it on primes (6) . . . */
+static int const primes[] =
+{
+ 509,
+ 1021,
+ 2039,
+ 4093,
+ 8191,
+ 16381,
+ 32749,
+#if 32767 < INT_MAX
+ 65521,
+ 131071,
+ 262139,
+ 524287,
+ 1048573,
+ 2097143,
+ 4194301,
+ 8388593,
+ 16777213,
+ 33554393,
+ 67108859, /* Preposterously large . . . */
+ 134217689,
+ 268435399,
+ 536870909,
+ 1073741789,
+ 2147483647,
+#endif
+ 0
+};
+
+/* Given a vector of two file_data objects, read the file associated
+ with each one, and build the table of equivalence classes.
+ Return 1 if either file appears to be a binary file.
+ If PRETEND_BINARY is nonzero, pretend they are binary regardless. */
+
+int
+read_files (filevec, pretend_binary)
+ struct file_data filevec[];
+ int pretend_binary;
+{
+ int i;
+ int skip_test = always_text_flag | pretend_binary;
+ int appears_binary = pretend_binary | sip (&filevec[0], skip_test);
+
+ if (filevec[0].desc != filevec[1].desc)
+ appears_binary |= sip (&filevec[1], skip_test | appears_binary);
+ else
+ {
+ filevec[1].buffer = filevec[0].buffer;
+ filevec[1].bufsize = filevec[0].bufsize;
+ filevec[1].buffered_chars = filevec[0].buffered_chars;
+ }
+ if (appears_binary)
+ {
+#if HAVE_SETMODE
+ setmode (filevec[0].desc, O_BINARY);
+ setmode (filevec[1].desc, O_BINARY);
+#endif
+ return 1;
+ }
+
+ find_identical_ends (filevec);
+
+ equivs_alloc = filevec[0].alloc_lines + filevec[1].alloc_lines + 1;
+ equivs = (struct equivclass *) xmalloc (equivs_alloc * sizeof (struct equivclass));
+ /* Equivalence class 0 is permanently safe for lines that were not
+ hashed. Real equivalence classes start at 1. */
+ equivs_index = 1;
+
+ for (i = 0; primes[i] < equivs_alloc / 3; i++)
+ if (! primes[i])
+ abort ();
+ nbuckets = primes[i];
+
+ buckets = (int *) xmalloc ((nbuckets + 1) * sizeof (*buckets));
+ bzero (buckets++, (nbuckets + 1) * sizeof (*buckets));
+
+ for (i = 0; i < 2; i++)
+ find_and_hash_each_line (&filevec[i]);
+
+ filevec[0].equiv_max = filevec[1].equiv_max = equivs_index;
+
+ free (equivs);
+ free (buckets - 1);
+
+ return 0;
+}
diff --git a/gnu/dist/diffutils/memchr.c b/gnu/dist/diffutils/memchr.c
new file mode 100644
index 00000000000..65ea2229ce1
--- /dev/null
+++ b/gnu/dist/diffutils/memchr.c
@@ -0,0 +1,19 @@
+/* Support memchr on systems where it doesn't work. */
+
+#include <config.h>
+#include <sys/types.h>
+
+void *
+memchr (s, c, n)
+ void const *s;
+ int c;
+ size_t n;
+{
+ unsigned char const *p = s;
+ unsigned char const *lim = p + n;
+
+ for (; p < lim; p++)
+ if (*p == c)
+ return p;
+ return 0;
+}
diff --git a/gnu/dist/diffutils/mkinstalldirs b/gnu/dist/diffutils/mkinstalldirs
new file mode 100644
index 00000000000..91f6d04e17c
--- /dev/null
+++ b/gnu/dist/diffutils/mkinstalldirs
@@ -0,0 +1,32 @@
+#!/bin/sh
+# mkinstalldirs --- make directory hierarchy
+# Author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Last modified: 1994-03-25
+# Public domain
+
+errstatus=0
+
+for file in ${1+"$@"} ; do
+ set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+ shift
+
+ pathcomp=
+ for d in ${1+"$@"} ; do
+ pathcomp="$pathcomp$d"
+ case "$pathcomp" in
+ -* ) pathcomp=./$pathcomp ;;
+ esac
+
+ if test ! -d "$pathcomp"; then
+ echo "mkdir $pathcomp" 1>&2
+ mkdir "$pathcomp" || errstatus=$?
+ fi
+
+ pathcomp="$pathcomp/"
+ done
+done
+
+exit $errstatus
+
+# mkinstalldirs ends here
diff --git a/gnu/dist/diffutils/normal.c b/gnu/dist/diffutils/normal.c
new file mode 100644
index 00000000000..4d9e23cb72a
--- /dev/null
+++ b/gnu/dist/diffutils/normal.c
@@ -0,0 +1,71 @@
+/* Normal-format output routines for GNU DIFF.
+ Copyright (C) 1988, 1989, 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 "diff.h"
+
+static void print_normal_hunk PARAMS((struct change *));
+
+/* Print the edit-script SCRIPT as a normal diff.
+ INF points to an array of descriptions of the two files. */
+
+void
+print_normal_script (script)
+ struct change *script;
+{
+ print_script (script, find_change, print_normal_hunk);
+}
+
+/* Print a hunk of a normal diff.
+ This is a contiguous portion of a complete edit script,
+ describing changes in consecutive lines. */
+
+static void
+print_normal_hunk (hunk)
+ struct change *hunk;
+{
+ int first0, last0, first1, last1, deletes, inserts;
+ register int i;
+
+ /* Determine range of line numbers involved in each file. */
+ analyze_hunk (hunk, &first0, &last0, &first1, &last1, &deletes, &inserts);
+ if (!deletes && !inserts)
+ return;
+
+ begin_output ();
+
+ /* Print out the line number header for this hunk */
+ print_number_range (',', &files[0], first0, last0);
+ fprintf (outfile, "%c", change_letter (inserts, deletes));
+ print_number_range (',', &files[1], first1, last1);
+ fprintf (outfile, "\n");
+
+ /* Print the lines that the first file has. */
+ if (deletes)
+ for (i = first0; i <= last0; i++)
+ print_1_line ("<", &files[0].linbuf[i]);
+
+ if (inserts && deletes)
+ fprintf (outfile, "---\n");
+
+ /* Print the lines that the second file has. */
+ if (inserts)
+ for (i = first1; i <= last1; i++)
+ print_1_line (">", &files[1].linbuf[i]);
+}
diff --git a/gnu/dist/diffutils/regex.c b/gnu/dist/diffutils/regex.c
new file mode 100644
index 00000000000..4b22b31a3c3
--- /dev/null
+++ b/gnu/dist/diffutils/regex.c
@@ -0,0 +1,5248 @@
+/* Extended regular expression matching and search library,
+ version 0.12.
+ (Implements POSIX draft P10003.2/D11.2, except for
+ internationalization features.)
+
+ Copyright (C) 1993, 1994 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. */
+
+/* AIX requires this to be the first thing in the file. */
+#if defined (_AIX) && !defined (REGEX_MALLOC)
+ #pragma alloca
+#endif
+
+#define _GNU_SOURCE
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+/* We need this for `regex.h', and perhaps for the Emacs include files. */
+#include <sys/types.h>
+
+/* The `emacs' switch turns on certain matching commands
+ that make sense only in Emacs. */
+#ifdef emacs
+
+#include "lisp.h"
+#include "buffer.h"
+#include "syntax.h"
+
+/* Emacs uses `NULL' as a predicate. */
+#undef NULL
+
+#else /* not emacs */
+
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#else
+char *malloc ();
+char *realloc ();
+#endif
+
+
+/* We used to test for `BSTRING' here, but only GCC and Emacs define
+ `BSTRING', as far as I know, and neither of them use this code. */
+#ifndef INHIBIT_STRING_HEADER
+#if HAVE_STRING_H || STDC_HEADERS
+#include <string.h>
+#ifndef bcmp
+#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
+#endif
+#ifndef bcopy
+#define bcopy(s, d, n) memcpy ((d), (s), (n))
+#endif
+#ifndef bzero
+#define bzero(s, n) memset ((s), 0, (n))
+#endif
+#else
+#include <strings.h>
+#endif
+#endif
+
+/* Define the syntax stuff for \<, \>, etc. */
+
+/* This must be nonzero for the wordchar and notwordchar pattern
+ commands in re_match_2. */
+#ifndef Sword
+#define Sword 1
+#endif
+
+#ifdef SYNTAX_TABLE
+
+extern char *re_syntax_table;
+
+#else /* not SYNTAX_TABLE */
+
+/* How many characters in the character set. */
+#define CHAR_SET_SIZE 256
+
+static char re_syntax_table[CHAR_SET_SIZE];
+
+static void
+init_syntax_once ()
+{
+ register int c;
+ static int done = 0;
+
+ if (done)
+ return;
+
+ bzero (re_syntax_table, sizeof re_syntax_table);
+
+ for (c = 'a'; c <= 'z'; c++)
+ re_syntax_table[c] = Sword;
+
+ for (c = 'A'; c <= 'Z'; c++)
+ re_syntax_table[c] = Sword;
+
+ for (c = '0'; c <= '9'; c++)
+ re_syntax_table[c] = Sword;
+
+ re_syntax_table['_'] = Sword;
+
+ done = 1;
+}
+
+#endif /* not SYNTAX_TABLE */
+
+#define SYNTAX(c) re_syntax_table[c]
+
+#endif /* not emacs */
+
+/* Get the interface, including the syntax bits. */
+#include "regex.h"
+
+/* isalpha etc. are used for the character classes. */
+#include <ctype.h>
+
+/* Jim Meyering writes:
+
+ "... Some ctype macros are valid only for character codes that
+ isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when
+ using /bin/cc or gcc but without giving an ansi option). So, all
+ ctype uses should be through macros like ISPRINT... If
+ STDC_HEADERS is defined, then autoconf has verified that the ctype
+ macros don't need to be guarded with references to isascii. ...
+ Defining isascii to 1 should let any compiler worth its salt
+ eliminate the && through constant folding." */
+
+#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII))
+#define ISASCII(c) 1
+#else
+#define ISASCII(c) isascii(c)
+#endif
+
+#ifdef isblank
+#define ISBLANK(c) (ISASCII (c) && isblank (c))
+#else
+#define ISBLANK(c) ((c) == ' ' || (c) == '\t')
+#endif
+#ifdef isgraph
+#define ISGRAPH(c) (ISASCII (c) && isgraph (c))
+#else
+#define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
+#endif
+
+#define ISPRINT(c) (ISASCII (c) && isprint (c))
+#define ISDIGIT(c) (ISASCII (c) && isdigit (c))
+#define ISALNUM(c) (ISASCII (c) && isalnum (c))
+#define ISALPHA(c) (ISASCII (c) && isalpha (c))
+#define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
+#define ISLOWER(c) (ISASCII (c) && islower (c))
+#define ISPUNCT(c) (ISASCII (c) && ispunct (c))
+#define ISSPACE(c) (ISASCII (c) && isspace (c))
+#define ISUPPER(c) (ISASCII (c) && isupper (c))
+#define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+/* We remove any previous definition of `SIGN_EXTEND_CHAR',
+ since ours (we hope) works properly with all combinations of
+ machines, compilers, `char' and `unsigned char' argument types.
+ (Per Bothner suggested the basic approach.) */
+#undef SIGN_EXTEND_CHAR
+#if __STDC__
+#define SIGN_EXTEND_CHAR(c) ((signed char) (c))
+#else /* not __STDC__ */
+/* As in Harbison and Steele. */
+#define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128)
+#endif
+
+/* Should we use malloc or alloca? If REGEX_MALLOC is not defined, we
+ use `alloca' instead of `malloc'. This is because using malloc in
+ re_search* or re_match* could cause memory leaks when C-g is used in
+ Emacs; also, malloc is slower and causes storage fragmentation. On
+ the other hand, malloc is more portable, and easier to debug.
+
+ Because we sometimes use alloca, some routines have to be macros,
+ not functions -- `alloca'-allocated space disappears at the end of the
+ function it is called in. */
+
+#ifdef REGEX_MALLOC
+
+#define REGEX_ALLOCATE malloc
+#define REGEX_REALLOCATE(source, osize, nsize) realloc (source, nsize)
+
+#else /* not REGEX_MALLOC */
+
+/* Emacs already defines alloca, sometimes. */
+#ifndef alloca
+
+/* Make alloca work the best possible way. */
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else /* not __GNUC__ */
+#if HAVE_ALLOCA_H
+#include <alloca.h>
+#else /* not __GNUC__ or HAVE_ALLOCA_H */
+#ifndef _AIX /* Already did AIX, up at the top. */
+char *alloca ();
+#endif /* not _AIX */
+#endif /* not HAVE_ALLOCA_H */
+#endif /* not __GNUC__ */
+
+#endif /* not alloca */
+
+#define REGEX_ALLOCATE alloca
+
+/* Assumes a `char *destination' variable. */
+#define REGEX_REALLOCATE(source, osize, nsize) \
+ (destination = (char *) alloca (nsize), \
+ bcopy (source, destination, osize), \
+ destination)
+
+#endif /* not REGEX_MALLOC */
+
+
+/* True if `size1' is non-NULL and PTR is pointing anywhere inside
+ `string1' or just past its end. This works if PTR is NULL, which is
+ a good thing. */
+#define FIRST_STRING_P(ptr) \
+ (size1 && string1 <= (ptr) && (ptr) <= string1 + size1)
+
+/* (Re)Allocate N items of type T using malloc, or fail. */
+#define TALLOC(n, t) ((t *) malloc ((n) * sizeof (t)))
+#define RETALLOC(addr, n, t) ((addr) = (t *) realloc (addr, (n) * sizeof (t)))
+#define RETALLOC_IF(addr, n, t) \
+ if (addr) RETALLOC((addr), (n), t); else (addr) = TALLOC ((n), t)
+#define REGEX_TALLOC(n, t) ((t *) REGEX_ALLOCATE ((n) * sizeof (t)))
+
+#define BYTEWIDTH 8 /* In bits. */
+
+#define STREQ(s1, s2) ((strcmp (s1, s2) == 0))
+
+#undef MAX
+#undef MIN
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+
+typedef char boolean;
+#define false 0
+#define true 1
+
+static int re_match_2_internal ();
+
+/* These are the command codes that appear in compiled regular
+ expressions. Some opcodes are followed by argument bytes. A
+ command code can specify any interpretation whatsoever for its
+ arguments. Zero bytes may appear in the compiled regular expression.
+
+ The value of `exactn' is needed in search.c (search_buffer) in Emacs.
+ So regex.h defines a symbol `RE_EXACTN_VALUE' to be 1; the value of
+ `exactn' we use here must also be 1. */
+
+typedef enum
+{
+ no_op = 0,
+
+ /* Followed by one byte giving n, then by n literal bytes. */
+ exactn = 1,
+
+ /* Matches any (more or less) character. */
+ anychar,
+
+ /* Matches any one char belonging to specified set. First
+ following byte is number of bitmap bytes. Then come bytes
+ for a bitmap saying which chars are in. Bits in each byte
+ are ordered low-bit-first. A character is in the set if its
+ bit is 1. A character too large to have a bit in the map is
+ automatically not in the set. */
+ charset,
+
+ /* Same parameters as charset, but match any character that is
+ not one of those specified. */
+ charset_not,
+
+ /* Start remembering the text that is matched, for storing in a
+ register. Followed by one byte with the register number, in
+ the range 0 to one less than the pattern buffer's re_nsub
+ field. Then followed by one byte with the number of groups
+ inner to this one. (This last has to be part of the
+ start_memory only because we need it in the on_failure_jump
+ of re_match_2.) */
+ start_memory,
+
+ /* Stop remembering the text that is matched and store it in a
+ memory register. Followed by one byte with the register
+ number, in the range 0 to one less than `re_nsub' in the
+ pattern buffer, and one byte with the number of inner groups,
+ just like `start_memory'. (We need the number of inner
+ groups here because we don't have any easy way of finding the
+ corresponding start_memory when we're at a stop_memory.) */
+ stop_memory,
+
+ /* Match a duplicate of something remembered. Followed by one
+ byte containing the register number. */
+ duplicate,
+
+ /* Fail unless at beginning of line. */
+ begline,
+
+ /* Fail unless at end of line. */
+ endline,
+
+ /* Succeeds if at beginning of buffer (if emacs) or at beginning
+ of string to be matched (if not). */
+ begbuf,
+
+ /* Analogously, for end of buffer/string. */
+ endbuf,
+
+ /* Followed by two byte relative address to which to jump. */
+ jump,
+
+ /* Same as jump, but marks the end of an alternative. */
+ jump_past_alt,
+
+ /* Followed by two-byte relative address of place to resume at
+ in case of failure. */
+ on_failure_jump,
+
+ /* Like on_failure_jump, but pushes a placeholder instead of the
+ current string position when executed. */
+ on_failure_keep_string_jump,
+
+ /* Throw away latest failure point and then jump to following
+ two-byte relative address. */
+ pop_failure_jump,
+
+ /* Change to pop_failure_jump if know won't have to backtrack to
+ match; otherwise change to jump. This is used to jump
+ back to the beginning of a repeat. If what follows this jump
+ clearly won't match what the repeat does, such that we can be
+ sure that there is no use backtracking out of repetitions
+ already matched, then we change it to a pop_failure_jump.
+ Followed by two-byte address. */
+ maybe_pop_jump,
+
+ /* Jump to following two-byte address, and push a dummy failure
+ point. This failure point will be thrown away if an attempt
+ is made to use it for a failure. A `+' construct makes this
+ before the first repeat. Also used as an intermediary kind
+ of jump when compiling an alternative. */
+ dummy_failure_jump,
+
+ /* Push a dummy failure point and continue. Used at the end of
+ alternatives. */
+ push_dummy_failure,
+
+ /* Followed by two-byte relative address and two-byte number n.
+ After matching N times, jump to the address upon failure. */
+ succeed_n,
+
+ /* Followed by two-byte relative address, and two-byte number n.
+ Jump to the address N times, then fail. */
+ jump_n,
+
+ /* Set the following two-byte relative address to the
+ subsequent two-byte number. The address *includes* the two
+ bytes of number. */
+ set_number_at,
+
+ wordchar, /* Matches any word-constituent character. */
+ notwordchar, /* Matches any char that is not a word-constituent. */
+
+ wordbeg, /* Succeeds if at word beginning. */
+ wordend, /* Succeeds if at word end. */
+
+ wordbound, /* Succeeds if at a word boundary. */
+ notwordbound /* Succeeds if not at a word boundary. */
+
+#ifdef emacs
+ ,before_dot, /* Succeeds if before point. */
+ at_dot, /* Succeeds if at point. */
+ after_dot, /* Succeeds if after point. */
+
+ /* Matches any character whose syntax is specified. Followed by
+ a byte which contains a syntax code, e.g., Sword. */
+ syntaxspec,
+
+ /* Matches any character whose syntax is not that specified. */
+ notsyntaxspec
+#endif /* emacs */
+} re_opcode_t;
+
+/* Common operations on the compiled pattern. */
+
+/* Store NUMBER in two contiguous bytes starting at DESTINATION. */
+
+#define STORE_NUMBER(destination, number) \
+ do { \
+ (destination)[0] = (number) & 0377; \
+ (destination)[1] = (number) >> 8; \
+ } while (0)
+
+/* Same as STORE_NUMBER, except increment DESTINATION to
+ the byte after where the number is stored. Therefore, DESTINATION
+ must be an lvalue. */
+
+#define STORE_NUMBER_AND_INCR(destination, number) \
+ do { \
+ STORE_NUMBER (destination, number); \
+ (destination) += 2; \
+ } while (0)
+
+/* Put into DESTINATION a number stored in two contiguous bytes starting
+ at SOURCE. */
+
+#define EXTRACT_NUMBER(destination, source) \
+ do { \
+ (destination) = *(source) & 0377; \
+ (destination) += SIGN_EXTEND_CHAR (*((source) + 1)) << 8; \
+ } while (0)
+
+#ifdef DEBUG
+static void
+extract_number (dest, source)
+ int *dest;
+ unsigned char *source;
+{
+ int temp = SIGN_EXTEND_CHAR (*(source + 1));
+ *dest = *source & 0377;
+ *dest += temp << 8;
+}
+
+#ifndef EXTRACT_MACROS /* To debug the macros. */
+#undef EXTRACT_NUMBER
+#define EXTRACT_NUMBER(dest, src) extract_number (&dest, src)
+#endif /* not EXTRACT_MACROS */
+
+#endif /* DEBUG */
+
+/* Same as EXTRACT_NUMBER, except increment SOURCE to after the number.
+ SOURCE must be an lvalue. */
+
+#define EXTRACT_NUMBER_AND_INCR(destination, source) \
+ do { \
+ EXTRACT_NUMBER (destination, source); \
+ (source) += 2; \
+ } while (0)
+
+#ifdef DEBUG
+static void
+extract_number_and_incr (destination, source)
+ int *destination;
+ unsigned char **source;
+{
+ extract_number (destination, *source);
+ *source += 2;
+}
+
+#ifndef EXTRACT_MACROS
+#undef EXTRACT_NUMBER_AND_INCR
+#define EXTRACT_NUMBER_AND_INCR(dest, src) \
+ extract_number_and_incr (&dest, &src)
+#endif /* not EXTRACT_MACROS */
+
+#endif /* DEBUG */
+
+/* If DEBUG is defined, Regex prints many voluminous messages about what
+ it is doing (if the variable `debug' is nonzero). If linked with the
+ main program in `iregex.c', you can enter patterns and strings
+ interactively. And if linked with the main program in `main.c' and
+ the other test files, you can run the already-written tests. */
+
+#ifdef DEBUG
+
+/* We use standard I/O for debugging. */
+#include <stdio.h>
+
+/* It is useful to test things that ``must'' be true when debugging. */
+#include <assert.h>
+
+static int debug = 0;
+
+#define DEBUG_STATEMENT(e) e
+#define DEBUG_PRINT1(x) if (debug) printf (x)
+#define DEBUG_PRINT2(x1, x2) if (debug) printf (x1, x2)
+#define DEBUG_PRINT3(x1, x2, x3) if (debug) printf (x1, x2, x3)
+#define DEBUG_PRINT4(x1, x2, x3, x4) if (debug) printf (x1, x2, x3, x4)
+#define DEBUG_PRINT_COMPILED_PATTERN(p, s, e) \
+ if (debug) print_partial_compiled_pattern (s, e)
+#define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2) \
+ if (debug) print_double_string (w, s1, sz1, s2, sz2)
+
+
+extern void printchar ();
+
+/* Print the fastmap in human-readable form. */
+
+void
+print_fastmap (fastmap)
+ char *fastmap;
+{
+ unsigned was_a_range = 0;
+ unsigned i = 0;
+
+ while (i < (1 << BYTEWIDTH))
+ {
+ if (fastmap[i++])
+ {
+ was_a_range = 0;
+ printchar (i - 1);
+ while (i < (1 << BYTEWIDTH) && fastmap[i])
+ {
+ was_a_range = 1;
+ i++;
+ }
+ if (was_a_range)
+ {
+ printf ("-");
+ printchar (i - 1);
+ }
+ }
+ }
+ putchar ('\n');
+}
+
+
+/* Print a compiled pattern string in human-readable form, starting at
+ the START pointer into it and ending just before the pointer END. */
+
+void
+print_partial_compiled_pattern (start, end)
+ unsigned char *start;
+ unsigned char *end;
+{
+ int mcnt, mcnt2;
+ unsigned char *p = start;
+ unsigned char *pend = end;
+
+ if (start == NULL)
+ {
+ printf ("(null)\n");
+ return;
+ }
+
+ /* Loop over pattern commands. */
+ while (p < pend)
+ {
+ printf ("%d:\t", p - start);
+
+ switch ((re_opcode_t) *p++)
+ {
+ case no_op:
+ printf ("/no_op");
+ break;
+
+ case exactn:
+ mcnt = *p++;
+ printf ("/exactn/%d", mcnt);
+ do
+ {
+ putchar ('/');
+ printchar (*p++);
+ }
+ while (--mcnt);
+ break;
+
+ case start_memory:
+ mcnt = *p++;
+ printf ("/start_memory/%d/%d", mcnt, *p++);
+ break;
+
+ case stop_memory:
+ mcnt = *p++;
+ printf ("/stop_memory/%d/%d", mcnt, *p++);
+ break;
+
+ case duplicate:
+ printf ("/duplicate/%d", *p++);
+ break;
+
+ case anychar:
+ printf ("/anychar");
+ break;
+
+ case charset:
+ case charset_not:
+ {
+ register int c, last = -100;
+ register int in_range = 0;
+
+ printf ("/charset [%s",
+ (re_opcode_t) *(p - 1) == charset_not ? "^" : "");
+
+ assert (p + *p < pend);
+
+ for (c = 0; c < 256; c++)
+ if (c / 8 < *p
+ && (p[1 + (c/8)] & (1 << (c % 8))))
+ {
+ /* Are we starting a range? */
+ if (last + 1 == c && ! in_range)
+ {
+ putchar ('-');
+ in_range = 1;
+ }
+ /* Have we broken a range? */
+ else if (last + 1 != c && in_range)
+ {
+ printchar (last);
+ in_range = 0;
+ }
+
+ if (! in_range)
+ printchar (c);
+
+ last = c;
+ }
+
+ if (in_range)
+ printchar (last);
+
+ putchar (']');
+
+ p += 1 + *p;
+ }
+ break;
+
+ case begline:
+ printf ("/begline");
+ break;
+
+ case endline:
+ printf ("/endline");
+ break;
+
+ case on_failure_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/on_failure_jump to %d", p + mcnt - start);
+ break;
+
+ case on_failure_keep_string_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/on_failure_keep_string_jump to %d", p + mcnt - start);
+ break;
+
+ case dummy_failure_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/dummy_failure_jump to %d", p + mcnt - start);
+ break;
+
+ case push_dummy_failure:
+ printf ("/push_dummy_failure");
+ break;
+
+ case maybe_pop_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/maybe_pop_jump to %d", p + mcnt - start);
+ break;
+
+ case pop_failure_jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/pop_failure_jump to %d", p + mcnt - start);
+ break;
+
+ case jump_past_alt:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/jump_past_alt to %d", p + mcnt - start);
+ break;
+
+ case jump:
+ extract_number_and_incr (&mcnt, &p);
+ printf ("/jump to %d", p + mcnt - start);
+ break;
+
+ case succeed_n:
+ extract_number_and_incr (&mcnt, &p);
+ extract_number_and_incr (&mcnt2, &p);
+ printf ("/succeed_n to %d, %d times", p + mcnt - start, mcnt2);
+ break;
+
+ case jump_n:
+ extract_number_and_incr (&mcnt, &p);
+ extract_number_and_incr (&mcnt2, &p);
+ printf ("/jump_n to %d, %d times", p + mcnt - start, mcnt2);
+ break;
+
+ case set_number_at:
+ extract_number_and_incr (&mcnt, &p);
+ extract_number_and_incr (&mcnt2, &p);
+ printf ("/set_number_at location %d to %d", p + mcnt - start, mcnt2);
+ break;
+
+ case wordbound:
+ printf ("/wordbound");
+ break;
+
+ case notwordbound:
+ printf ("/notwordbound");
+ break;
+
+ case wordbeg:
+ printf ("/wordbeg");
+ break;
+
+ case wordend:
+ printf ("/wordend");
+
+#ifdef emacs
+ case before_dot:
+ printf ("/before_dot");
+ break;
+
+ case at_dot:
+ printf ("/at_dot");
+ break;
+
+ case after_dot:
+ printf ("/after_dot");
+ break;
+
+ case syntaxspec:
+ printf ("/syntaxspec");
+ mcnt = *p++;
+ printf ("/%d", mcnt);
+ break;
+
+ case notsyntaxspec:
+ printf ("/notsyntaxspec");
+ mcnt = *p++;
+ printf ("/%d", mcnt);
+ break;
+#endif /* emacs */
+
+ case wordchar:
+ printf ("/wordchar");
+ break;
+
+ case notwordchar:
+ printf ("/notwordchar");
+ break;
+
+ case begbuf:
+ printf ("/begbuf");
+ break;
+
+ case endbuf:
+ printf ("/endbuf");
+ break;
+
+ default:
+ printf ("?%d", *(p-1));
+ }
+
+ putchar ('\n');
+ }
+
+ printf ("%d:\tend of pattern.\n", p - start);
+}
+
+
+void
+print_compiled_pattern (bufp)
+ struct re_pattern_buffer *bufp;
+{
+ unsigned char *buffer = bufp->buffer;
+
+ print_partial_compiled_pattern (buffer, buffer + bufp->used);
+ printf ("%d bytes used/%d bytes allocated.\n", bufp->used, bufp->allocated);
+
+ if (bufp->fastmap_accurate && bufp->fastmap)
+ {
+ printf ("fastmap: ");
+ print_fastmap (bufp->fastmap);
+ }
+
+ printf ("re_nsub: %d\t", bufp->re_nsub);
+ printf ("regs_alloc: %d\t", bufp->regs_allocated);
+ printf ("can_be_null: %d\t", bufp->can_be_null);
+ printf ("newline_anchor: %d\n", bufp->newline_anchor);
+ printf ("no_sub: %d\t", bufp->no_sub);
+ printf ("not_bol: %d\t", bufp->not_bol);
+ printf ("not_eol: %d\t", bufp->not_eol);
+ printf ("syntax: %d\n", bufp->syntax);
+ /* Perhaps we should print the translate table? */
+}
+
+
+void
+print_double_string (where, string1, size1, string2, size2)
+ const char *where;
+ const char *string1;
+ const char *string2;
+ int size1;
+ int size2;
+{
+ unsigned this_char;
+
+ if (where == NULL)
+ printf ("(null)");
+ else
+ {
+ if (FIRST_STRING_P (where))
+ {
+ for (this_char = where - string1; this_char < size1; this_char++)
+ printchar (string1[this_char]);
+
+ where = string2;
+ }
+
+ for (this_char = where - string2; this_char < size2; this_char++)
+ printchar (string2[this_char]);
+ }
+}
+
+#else /* not DEBUG */
+
+#undef assert
+#define assert(e)
+
+#define DEBUG_STATEMENT(e)
+#define DEBUG_PRINT1(x)
+#define DEBUG_PRINT2(x1, x2)
+#define DEBUG_PRINT3(x1, x2, x3)
+#define DEBUG_PRINT4(x1, x2, x3, x4)
+#define DEBUG_PRINT_COMPILED_PATTERN(p, s, e)
+#define DEBUG_PRINT_DOUBLE_STRING(w, s1, sz1, s2, sz2)
+
+#endif /* not DEBUG */
+
+/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can
+ also be assigned to arbitrarily: each pattern buffer stores its own
+ syntax, so it can be changed between regex compilations. */
+reg_syntax_t re_syntax_options = RE_SYNTAX_EMACS;
+
+
+/* Specify the precise syntax of regexps for compilation. This provides
+ for compatibility for various utilities which historically have
+ different, incompatible syntaxes.
+
+ The argument SYNTAX is a bit mask comprised of the various bits
+ defined in regex.h. We return the old syntax. */
+
+reg_syntax_t
+re_set_syntax (syntax)
+ reg_syntax_t syntax;
+{
+ reg_syntax_t ret = re_syntax_options;
+
+ re_syntax_options = syntax;
+ return ret;
+}
+
+/* This table gives an error message for each of the error codes listed
+ in regex.h. Obviously the order here has to be same as there. */
+
+static const char *re_error_msg[] =
+ { NULL, /* REG_NOERROR */
+ "No match", /* REG_NOMATCH */
+ "Invalid regular expression", /* REG_BADPAT */
+ "Invalid collation character", /* REG_ECOLLATE */
+ "Invalid character class name", /* REG_ECTYPE */
+ "Trailing backslash", /* REG_EESCAPE */
+ "Invalid back reference", /* REG_ESUBREG */
+ "Unmatched [ or [^", /* REG_EBRACK */
+ "Unmatched ( or \\(", /* REG_EPAREN */
+ "Unmatched \\{", /* REG_EBRACE */
+ "Invalid content of \\{\\}", /* REG_BADBR */
+ "Invalid range end", /* REG_ERANGE */
+ "Memory exhausted", /* REG_ESPACE */
+ "Invalid preceding regular expression", /* REG_BADRPT */
+ "Premature end of regular expression", /* REG_EEND */
+ "Regular expression too big", /* REG_ESIZE */
+ "Unmatched ) or \\)", /* REG_ERPAREN */
+ };
+
+/* Avoiding alloca during matching, to placate r_alloc. */
+
+/* Define MATCH_MAY_ALLOCATE unless we need to make sure that the
+ searching and matching functions should not call alloca. On some
+ systems, alloca is implemented in terms of malloc, and if we're
+ using the relocating allocator routines, then malloc could cause a
+ relocation, which might (if the strings being searched are in the
+ ralloc heap) shift the data out from underneath the regexp
+ routines.
+
+ Here's another reason to avoid allocation: Emacs
+ processes input from X in a signal handler; processing X input may
+ call malloc; if input arrives while a matching routine is calling
+ malloc, then we're scrod. But Emacs can't just block input while
+ calling matching routines; then we don't notice interrupts when
+ they come in. So, Emacs blocks input around all regexp calls
+ except the matching calls, which it leaves unprotected, in the
+ faith that they will not malloc. */
+
+/* Normally, this is fine. */
+#define MATCH_MAY_ALLOCATE
+
+/* The match routines may not allocate if (1) they would do it with malloc
+ and (2) it's not safe for htem to use malloc. */
+#if (defined (C_ALLOCA) || defined (REGEX_MALLOC)) && (defined (emacs) || defined (REL_ALLOC))
+#undef MATCH_MAY_ALLOCATE
+#endif
+
+
+/* Failure stack declarations and macros; both re_compile_fastmap and
+ re_match_2 use a failure stack. These have to be macros because of
+ REGEX_ALLOCATE. */
+
+
+/* Number of failure points for which to initially allocate space
+ when matching. If this number is exceeded, we allocate more
+ space, so it is not a hard limit. */
+#ifndef INIT_FAILURE_ALLOC
+#define INIT_FAILURE_ALLOC 5
+#endif
+
+/* Roughly the maximum number of failure points on the stack. Would be
+ exactly that if always used MAX_FAILURE_SPACE each time we failed.
+ This is a variable only so users of regex can assign to it; we never
+ change it ourselves. */
+int re_max_failures = 2000;
+
+typedef unsigned char *fail_stack_elt_t;
+
+typedef struct
+{
+ fail_stack_elt_t *stack;
+ unsigned size;
+ unsigned avail; /* Offset of next open position. */
+} fail_stack_type;
+
+#define FAIL_STACK_EMPTY() (fail_stack.avail == 0)
+#define FAIL_STACK_PTR_EMPTY() (fail_stack_ptr->avail == 0)
+#define FAIL_STACK_FULL() (fail_stack.avail == fail_stack.size)
+#define FAIL_STACK_TOP() (fail_stack.stack[fail_stack.avail])
+
+
+/* Initialize `fail_stack'. Do `return -2' if the alloc fails. */
+
+#ifdef MATCH_MAY_ALLOCATE
+#define INIT_FAIL_STACK() \
+ do { \
+ fail_stack.stack = (fail_stack_elt_t *) \
+ REGEX_ALLOCATE (INIT_FAILURE_ALLOC * sizeof (fail_stack_elt_t)); \
+ \
+ if (fail_stack.stack == NULL) \
+ return -2; \
+ \
+ fail_stack.size = INIT_FAILURE_ALLOC; \
+ fail_stack.avail = 0; \
+ } while (0)
+#else
+#define INIT_FAIL_STACK() \
+ do { \
+ fail_stack.avail = 0; \
+ } while (0)
+#endif
+
+
+/* Double the size of FAIL_STACK, up to approximately `re_max_failures' items.
+
+ Return 1 if succeeds, and 0 if either ran out of memory
+ allocating space for it or it was already too large.
+
+ REGEX_REALLOCATE requires `destination' be declared. */
+
+#define DOUBLE_FAIL_STACK(fail_stack) \
+ ((fail_stack).size > re_max_failures * MAX_FAILURE_ITEMS \
+ ? 0 \
+ : ((fail_stack).stack = (fail_stack_elt_t *) \
+ REGEX_REALLOCATE ((fail_stack).stack, \
+ (fail_stack).size * sizeof (fail_stack_elt_t), \
+ ((fail_stack).size << 1) * sizeof (fail_stack_elt_t)), \
+ \
+ (fail_stack).stack == NULL \
+ ? 0 \
+ : ((fail_stack).size <<= 1, \
+ 1)))
+
+
+/* Push PATTERN_OP on FAIL_STACK.
+
+ Return 1 if was able to do so and 0 if ran out of memory allocating
+ space to do so. */
+#define PUSH_PATTERN_OP(pattern_op, fail_stack) \
+ ((FAIL_STACK_FULL () \
+ && !DOUBLE_FAIL_STACK (fail_stack)) \
+ ? 0 \
+ : ((fail_stack).stack[(fail_stack).avail++] = pattern_op, \
+ 1))
+
+/* This pushes an item onto the failure stack. Must be a four-byte
+ value. Assumes the variable `fail_stack'. Probably should only
+ be called from within `PUSH_FAILURE_POINT'. */
+#define PUSH_FAILURE_ITEM(item) \
+ fail_stack.stack[fail_stack.avail++] = (fail_stack_elt_t) item
+
+/* The complement operation. Assumes `fail_stack' is nonempty. */
+#define POP_FAILURE_ITEM() fail_stack.stack[--fail_stack.avail]
+
+/* Used to omit pushing failure point id's when we're not debugging. */
+#ifdef DEBUG
+#define DEBUG_PUSH PUSH_FAILURE_ITEM
+#define DEBUG_POP(item_addr) *(item_addr) = POP_FAILURE_ITEM ()
+#else
+#define DEBUG_PUSH(item)
+#define DEBUG_POP(item_addr)
+#endif
+
+
+/* Push the information about the state we will need
+ if we ever fail back to it.
+
+ Requires variables fail_stack, regstart, regend, reg_info, and
+ num_regs be declared. DOUBLE_FAIL_STACK requires `destination' be
+ declared.
+
+ Does `return FAILURE_CODE' if runs out of memory. */
+
+#define PUSH_FAILURE_POINT(pattern_place, string_place, failure_code) \
+ do { \
+ char *destination; \
+ /* Must be int, so when we don't save any registers, the arithmetic \
+ of 0 + -1 isn't done as unsigned. */ \
+ int this_reg; \
+ \
+ DEBUG_STATEMENT (failure_id++); \
+ DEBUG_STATEMENT (nfailure_points_pushed++); \
+ DEBUG_PRINT2 ("\nPUSH_FAILURE_POINT #%u:\n", failure_id); \
+ DEBUG_PRINT2 (" Before push, next avail: %d\n", (fail_stack).avail);\
+ DEBUG_PRINT2 (" size: %d\n", (fail_stack).size);\
+ \
+ DEBUG_PRINT2 (" slots needed: %d\n", NUM_FAILURE_ITEMS); \
+ DEBUG_PRINT2 (" available: %d\n", REMAINING_AVAIL_SLOTS); \
+ \
+ /* Ensure we have enough space allocated for what we will push. */ \
+ while (REMAINING_AVAIL_SLOTS < NUM_FAILURE_ITEMS) \
+ { \
+ if (!DOUBLE_FAIL_STACK (fail_stack)) \
+ return failure_code; \
+ \
+ DEBUG_PRINT2 ("\n Doubled stack; size now: %d\n", \
+ (fail_stack).size); \
+ DEBUG_PRINT2 (" slots available: %d\n", REMAINING_AVAIL_SLOTS);\
+ } \
+ \
+ /* Push the info, starting with the registers. */ \
+ DEBUG_PRINT1 ("\n"); \
+ \
+ for (this_reg = lowest_active_reg; this_reg <= highest_active_reg; \
+ this_reg++) \
+ { \
+ DEBUG_PRINT2 (" Pushing reg: %d\n", this_reg); \
+ DEBUG_STATEMENT (num_regs_pushed++); \
+ \
+ DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \
+ PUSH_FAILURE_ITEM (regstart[this_reg]); \
+ \
+ DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \
+ PUSH_FAILURE_ITEM (regend[this_reg]); \
+ \
+ DEBUG_PRINT2 (" info: 0x%x\n ", reg_info[this_reg]); \
+ DEBUG_PRINT2 (" match_null=%d", \
+ REG_MATCH_NULL_STRING_P (reg_info[this_reg])); \
+ DEBUG_PRINT2 (" active=%d", IS_ACTIVE (reg_info[this_reg])); \
+ DEBUG_PRINT2 (" matched_something=%d", \
+ MATCHED_SOMETHING (reg_info[this_reg])); \
+ DEBUG_PRINT2 (" ever_matched=%d", \
+ EVER_MATCHED_SOMETHING (reg_info[this_reg])); \
+ DEBUG_PRINT1 ("\n"); \
+ PUSH_FAILURE_ITEM (reg_info[this_reg].word); \
+ } \
+ \
+ DEBUG_PRINT2 (" Pushing low active reg: %d\n", lowest_active_reg);\
+ PUSH_FAILURE_ITEM (lowest_active_reg); \
+ \
+ DEBUG_PRINT2 (" Pushing high active reg: %d\n", highest_active_reg);\
+ PUSH_FAILURE_ITEM (highest_active_reg); \
+ \
+ DEBUG_PRINT2 (" Pushing pattern 0x%x: ", pattern_place); \
+ DEBUG_PRINT_COMPILED_PATTERN (bufp, pattern_place, pend); \
+ PUSH_FAILURE_ITEM (pattern_place); \
+ \
+ DEBUG_PRINT2 (" Pushing string 0x%x: `", string_place); \
+ DEBUG_PRINT_DOUBLE_STRING (string_place, string1, size1, string2, \
+ size2); \
+ DEBUG_PRINT1 ("'\n"); \
+ PUSH_FAILURE_ITEM (string_place); \
+ \
+ DEBUG_PRINT2 (" Pushing failure id: %u\n", failure_id); \
+ DEBUG_PUSH (failure_id); \
+ } while (0)
+
+/* This is the number of items that are pushed and popped on the stack
+ for each register. */
+#define NUM_REG_ITEMS 3
+
+/* Individual items aside from the registers. */
+#ifdef DEBUG
+#define NUM_NONREG_ITEMS 5 /* Includes failure point id. */
+#else
+#define NUM_NONREG_ITEMS 4
+#endif
+
+/* We push at most this many items on the stack. */
+#define MAX_FAILURE_ITEMS ((num_regs - 1) * NUM_REG_ITEMS + NUM_NONREG_ITEMS)
+
+/* We actually push this many items. */
+#define NUM_FAILURE_ITEMS \
+ ((highest_active_reg - lowest_active_reg + 1) * NUM_REG_ITEMS \
+ + NUM_NONREG_ITEMS)
+
+/* How many items can still be added to the stack without overflowing it. */
+#define REMAINING_AVAIL_SLOTS ((fail_stack).size - (fail_stack).avail)
+
+
+/* Pops what PUSH_FAIL_STACK pushes.
+
+ We restore into the parameters, all of which should be lvalues:
+ STR -- the saved data position.
+ PAT -- the saved pattern position.
+ LOW_REG, HIGH_REG -- the highest and lowest active registers.
+ REGSTART, REGEND -- arrays of string positions.
+ REG_INFO -- array of information about each subexpression.
+
+ Also assumes the variables `fail_stack' and (if debugging), `bufp',
+ `pend', `string1', `size1', `string2', and `size2'. */
+
+#define POP_FAILURE_POINT(str, pat, low_reg, high_reg, regstart, regend, reg_info)\
+{ \
+ DEBUG_STATEMENT (fail_stack_elt_t failure_id;) \
+ int this_reg; \
+ const unsigned char *string_temp; \
+ \
+ assert (!FAIL_STACK_EMPTY ()); \
+ \
+ /* Remove failure points and point to how many regs pushed. */ \
+ DEBUG_PRINT1 ("POP_FAILURE_POINT:\n"); \
+ DEBUG_PRINT2 (" Before pop, next avail: %d\n", fail_stack.avail); \
+ DEBUG_PRINT2 (" size: %d\n", fail_stack.size); \
+ \
+ assert (fail_stack.avail >= NUM_NONREG_ITEMS); \
+ \
+ DEBUG_POP (&failure_id); \
+ DEBUG_PRINT2 (" Popping failure id: %u\n", failure_id); \
+ \
+ /* If the saved string location is NULL, it came from an \
+ on_failure_keep_string_jump opcode, and we want to throw away the \
+ saved NULL, thus retaining our current position in the string. */ \
+ string_temp = POP_FAILURE_ITEM (); \
+ if (string_temp != NULL) \
+ str = (const char *) string_temp; \
+ \
+ DEBUG_PRINT2 (" Popping string 0x%x: `", str); \
+ DEBUG_PRINT_DOUBLE_STRING (str, string1, size1, string2, size2); \
+ DEBUG_PRINT1 ("'\n"); \
+ \
+ pat = (unsigned char *) POP_FAILURE_ITEM (); \
+ DEBUG_PRINT2 (" Popping pattern 0x%x: ", pat); \
+ DEBUG_PRINT_COMPILED_PATTERN (bufp, pat, pend); \
+ \
+ /* Restore register info. */ \
+ high_reg = (unsigned) POP_FAILURE_ITEM (); \
+ DEBUG_PRINT2 (" Popping high active reg: %d\n", high_reg); \
+ \
+ low_reg = (unsigned) POP_FAILURE_ITEM (); \
+ DEBUG_PRINT2 (" Popping low active reg: %d\n", low_reg); \
+ \
+ for (this_reg = high_reg; this_reg >= low_reg; this_reg--) \
+ { \
+ DEBUG_PRINT2 (" Popping reg: %d\n", this_reg); \
+ \
+ reg_info[this_reg].word = POP_FAILURE_ITEM (); \
+ DEBUG_PRINT2 (" info: 0x%x\n", reg_info[this_reg]); \
+ \
+ regend[this_reg] = (const char *) POP_FAILURE_ITEM (); \
+ DEBUG_PRINT2 (" end: 0x%x\n", regend[this_reg]); \
+ \
+ regstart[this_reg] = (const char *) POP_FAILURE_ITEM (); \
+ DEBUG_PRINT2 (" start: 0x%x\n", regstart[this_reg]); \
+ } \
+ \
+ DEBUG_STATEMENT (nfailure_points_popped++); \
+} /* POP_FAILURE_POINT */
+
+
+
+/* Structure for per-register (a.k.a. per-group) information.
+ This must not be longer than one word, because we push this value
+ onto the failure stack. Other register information, such as the
+ starting and ending positions (which are addresses), and the list of
+ inner groups (which is a bits list) are maintained in separate
+ variables.
+
+ We are making a (strictly speaking) nonportable assumption here: that
+ the compiler will pack our bit fields into something that fits into
+ the type of `word', i.e., is something that fits into one item on the
+ failure stack. */
+typedef union
+{
+ fail_stack_elt_t word;
+ struct
+ {
+ /* This field is one if this group can match the empty string,
+ zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */
+#define MATCH_NULL_UNSET_VALUE 3
+ unsigned match_null_string_p : 2;
+ unsigned is_active : 1;
+ unsigned matched_something : 1;
+ unsigned ever_matched_something : 1;
+ } bits;
+} register_info_type;
+
+#define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p)
+#define IS_ACTIVE(R) ((R).bits.is_active)
+#define MATCHED_SOMETHING(R) ((R).bits.matched_something)
+#define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something)
+
+
+/* Call this when have matched a real character; it sets `matched' flags
+ for the subexpressions which we are currently inside. Also records
+ that those subexprs have matched. */
+#define SET_REGS_MATCHED() \
+ do \
+ { \
+ unsigned r; \
+ for (r = lowest_active_reg; r <= highest_active_reg; r++) \
+ { \
+ MATCHED_SOMETHING (reg_info[r]) \
+ = EVER_MATCHED_SOMETHING (reg_info[r]) \
+ = 1; \
+ } \
+ } \
+ while (0)
+
+
+/* Registers are set to a sentinel when they haven't yet matched. */
+#define REG_UNSET_VALUE ((char *) -1)
+#define REG_UNSET(e) ((e) == REG_UNSET_VALUE)
+
+
+
+/* How do we implement a missing MATCH_MAY_ALLOCATE?
+ We make the fail stack a global thing, and then grow it to
+ re_max_failures when we compile. */
+#ifndef MATCH_MAY_ALLOCATE
+static fail_stack_type fail_stack;
+
+static const char ** regstart, ** regend;
+static const char ** old_regstart, ** old_regend;
+static const char **best_regstart, **best_regend;
+static register_info_type *reg_info;
+static const char **reg_dummy;
+static register_info_type *reg_info_dummy;
+#endif
+
+
+/* Subroutine declarations and macros for regex_compile. */
+
+static void store_op1 (), store_op2 ();
+static void insert_op1 (), insert_op2 ();
+static boolean at_begline_loc_p (), at_endline_loc_p ();
+static boolean group_in_compile_stack ();
+static reg_errcode_t compile_range ();
+
+/* Fetch the next character in the uncompiled pattern---translating it
+ if necessary. Also cast from a signed character in the constant
+ string passed to us by the user to an unsigned char that we can use
+ as an array index (in, e.g., `translate'). */
+#define PATFETCH(c) \
+ do {if (p == pend) return REG_EEND; \
+ c = (unsigned char) *p++; \
+ if (translate) c = translate[c]; \
+ } while (0)
+
+/* Fetch the next character in the uncompiled pattern, with no
+ translation. */
+#define PATFETCH_RAW(c) \
+ do {if (p == pend) return REG_EEND; \
+ c = (unsigned char) *p++; \
+ } while (0)
+
+/* Go backwards one character in the pattern. */
+#define PATUNFETCH p--
+
+
+/* If `translate' is non-null, return translate[D], else just D. We
+ cast the subscript to translate because some data is declared as
+ `char *', to avoid warnings when a string constant is passed. But
+ when we use a character as a subscript we must make it unsigned. */
+#define TRANSLATE(d) (translate ? translate[(unsigned char) (d)] : (d))
+
+
+/* Macros for outputting the compiled pattern into `buffer'. */
+
+/* If the buffer isn't allocated when it comes in, use this. */
+#define INIT_BUF_SIZE 32
+
+/* Make sure we have at least N more bytes of space in buffer. */
+#define GET_BUFFER_SPACE(n) \
+ while (b - bufp->buffer + (n) > bufp->allocated) \
+ EXTEND_BUFFER ()
+
+/* Make sure we have one more byte of buffer space and then add C to it. */
+#define BUF_PUSH(c) \
+ do { \
+ GET_BUFFER_SPACE (1); \
+ *b++ = (unsigned char) (c); \
+ } while (0)
+
+
+/* Ensure we have two more bytes of buffer space and then append C1 and C2. */
+#define BUF_PUSH_2(c1, c2) \
+ do { \
+ GET_BUFFER_SPACE (2); \
+ *b++ = (unsigned char) (c1); \
+ *b++ = (unsigned char) (c2); \
+ } while (0)
+
+
+/* As with BUF_PUSH_2, except for three bytes. */
+#define BUF_PUSH_3(c1, c2, c3) \
+ do { \
+ GET_BUFFER_SPACE (3); \
+ *b++ = (unsigned char) (c1); \
+ *b++ = (unsigned char) (c2); \
+ *b++ = (unsigned char) (c3); \
+ } while (0)
+
+
+/* Store a jump with opcode OP at LOC to location TO. We store a
+ relative address offset by the three bytes the jump itself occupies. */
+#define STORE_JUMP(op, loc, to) \
+ store_op1 (op, loc, (to) - (loc) - 3)
+
+/* Likewise, for a two-argument jump. */
+#define STORE_JUMP2(op, loc, to, arg) \
+ store_op2 (op, loc, (to) - (loc) - 3, arg)
+
+/* Like `STORE_JUMP', but for inserting. Assume `b' is the buffer end. */
+#define INSERT_JUMP(op, loc, to) \
+ insert_op1 (op, loc, (to) - (loc) - 3, b)
+
+/* Like `STORE_JUMP2', but for inserting. Assume `b' is the buffer end. */
+#define INSERT_JUMP2(op, loc, to, arg) \
+ insert_op2 (op, loc, (to) - (loc) - 3, arg, b)
+
+
+/* This is not an arbitrary limit: the arguments which represent offsets
+ into the pattern are two bytes long. So if 2^16 bytes turns out to
+ be too small, many things would have to change. */
+#define MAX_BUF_SIZE (1L << 16)
+
+
+/* Extend the buffer by twice its current size via realloc and
+ reset the pointers that pointed into the old block to point to the
+ correct places in the new one. If extending the buffer results in it
+ being larger than MAX_BUF_SIZE, then flag memory exhausted. */
+#define EXTEND_BUFFER() \
+ do { \
+ unsigned char *old_buffer = bufp->buffer; \
+ if (bufp->allocated == MAX_BUF_SIZE) \
+ return REG_ESIZE; \
+ bufp->allocated <<= 1; \
+ if (bufp->allocated > MAX_BUF_SIZE) \
+ bufp->allocated = MAX_BUF_SIZE; \
+ bufp->buffer = (unsigned char *) realloc (bufp->buffer, bufp->allocated);\
+ if (bufp->buffer == NULL) \
+ return REG_ESPACE; \
+ /* If the buffer moved, move all the pointers into it. */ \
+ if (old_buffer != bufp->buffer) \
+ { \
+ b = (b - old_buffer) + bufp->buffer; \
+ begalt = (begalt - old_buffer) + bufp->buffer; \
+ if (fixup_alt_jump) \
+ fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer;\
+ if (laststart) \
+ laststart = (laststart - old_buffer) + bufp->buffer; \
+ if (pending_exact) \
+ pending_exact = (pending_exact - old_buffer) + bufp->buffer; \
+ } \
+ } while (0)
+
+
+/* Since we have one byte reserved for the register number argument to
+ {start,stop}_memory, the maximum number of groups we can report
+ things about is what fits in that byte. */
+#define MAX_REGNUM 255
+
+/* But patterns can have more than `MAX_REGNUM' registers. We just
+ ignore the excess. */
+typedef unsigned regnum_t;
+
+
+/* Macros for the compile stack. */
+
+/* Since offsets can go either forwards or backwards, this type needs to
+ be able to hold values from -(MAX_BUF_SIZE - 1) to MAX_BUF_SIZE - 1. */
+typedef int pattern_offset_t;
+
+typedef struct
+{
+ pattern_offset_t begalt_offset;
+ pattern_offset_t fixup_alt_jump;
+ pattern_offset_t inner_group_offset;
+ pattern_offset_t laststart_offset;
+ regnum_t regnum;
+} compile_stack_elt_t;
+
+
+typedef struct
+{
+ compile_stack_elt_t *stack;
+ unsigned size;
+ unsigned avail; /* Offset of next open position. */
+} compile_stack_type;
+
+
+#define INIT_COMPILE_STACK_SIZE 32
+
+#define COMPILE_STACK_EMPTY (compile_stack.avail == 0)
+#define COMPILE_STACK_FULL (compile_stack.avail == compile_stack.size)
+
+/* The next available element. */
+#define COMPILE_STACK_TOP (compile_stack.stack[compile_stack.avail])
+
+
+/* Set the bit for character C in a list. */
+#define SET_LIST_BIT(c) \
+ (b[((unsigned char) (c)) / BYTEWIDTH] \
+ |= 1 << (((unsigned char) c) % BYTEWIDTH))
+
+
+/* Get the next unsigned number in the uncompiled pattern. */
+#define GET_UNSIGNED_NUMBER(num) \
+ { if (p != pend) \
+ { \
+ PATFETCH (c); \
+ while (ISDIGIT (c)) \
+ { \
+ if (num < 0) \
+ num = 0; \
+ num = num * 10 + c - '0'; \
+ if (p == pend) \
+ break; \
+ PATFETCH (c); \
+ } \
+ } \
+ }
+
+#define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */
+
+#define IS_CHAR_CLASS(string) \
+ (STREQ (string, "alpha") || STREQ (string, "upper") \
+ || STREQ (string, "lower") || STREQ (string, "digit") \
+ || STREQ (string, "alnum") || STREQ (string, "xdigit") \
+ || STREQ (string, "space") || STREQ (string, "print") \
+ || STREQ (string, "punct") || STREQ (string, "graph") \
+ || STREQ (string, "cntrl") || STREQ (string, "blank"))
+
+/* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX.
+ Returns one of error codes defined in `regex.h', or zero for success.
+
+ Assumes the `allocated' (and perhaps `buffer') and `translate'
+ fields are set in BUFP on entry.
+
+ If it succeeds, results are put in BUFP (if it returns an error, the
+ contents of BUFP are undefined):
+ `buffer' is the compiled pattern;
+ `syntax' is set to SYNTAX;
+ `used' is set to the length of the compiled pattern;
+ `fastmap_accurate' is zero;
+ `re_nsub' is the number of subexpressions in PATTERN;
+ `not_bol' and `not_eol' are zero;
+
+ The `fastmap' and `newline_anchor' fields are neither
+ examined nor set. */
+
+/* Return, freeing storage we allocated. */
+#define FREE_STACK_RETURN(value) \
+ return (free (compile_stack.stack), value)
+
+static reg_errcode_t
+regex_compile (pattern, size, syntax, bufp)
+ const char *pattern;
+ int size;
+ reg_syntax_t syntax;
+ struct re_pattern_buffer *bufp;
+{
+ /* We fetch characters from PATTERN here. Even though PATTERN is
+ `char *' (i.e., signed), we declare these variables as unsigned, so
+ they can be reliably used as array indices. */
+ register unsigned char c, c1;
+
+ /* A random temporary spot in PATTERN. */
+ const char *p1;
+
+ /* Points to the end of the buffer, where we should append. */
+ register unsigned char *b;
+
+ /* Keeps track of unclosed groups. */
+ compile_stack_type compile_stack;
+
+ /* Points to the current (ending) position in the pattern. */
+ const char *p = pattern;
+ const char *pend = pattern + size;
+
+ /* How to translate the characters in the pattern. */
+ char *translate = bufp->translate;
+
+ /* Address of the count-byte of the most recently inserted `exactn'
+ command. This makes it possible to tell if a new exact-match
+ character can be added to that command or if the character requires
+ a new `exactn' command. */
+ unsigned char *pending_exact = 0;
+
+ /* Address of start of the most recently finished expression.
+ This tells, e.g., postfix * where to find the start of its
+ operand. Reset at the beginning of groups and alternatives. */
+ unsigned char *laststart = 0;
+
+ /* Address of beginning of regexp, or inside of last group. */
+ unsigned char *begalt;
+
+ /* Place in the uncompiled pattern (i.e., the {) to
+ which to go back if the interval is invalid. */
+ const char *beg_interval;
+
+ /* Address of the place where a forward jump should go to the end of
+ the containing expression. Each alternative of an `or' -- except the
+ last -- ends with a forward jump of this sort. */
+ unsigned char *fixup_alt_jump = 0;
+
+ /* Counts open-groups as they are encountered. Remembered for the
+ matching close-group on the compile stack, so the same register
+ number is put in the stop_memory as the start_memory. */
+ regnum_t regnum = 0;
+
+#ifdef DEBUG
+ DEBUG_PRINT1 ("\nCompiling pattern: ");
+ if (debug)
+ {
+ unsigned debug_count;
+
+ for (debug_count = 0; debug_count < size; debug_count++)
+ printchar (pattern[debug_count]);
+ putchar ('\n');
+ }
+#endif /* DEBUG */
+
+ /* Initialize the compile stack. */
+ compile_stack.stack = TALLOC (INIT_COMPILE_STACK_SIZE, compile_stack_elt_t);
+ if (compile_stack.stack == NULL)
+ return REG_ESPACE;
+
+ compile_stack.size = INIT_COMPILE_STACK_SIZE;
+ compile_stack.avail = 0;
+
+ /* Initialize the pattern buffer. */
+ bufp->syntax = syntax;
+ bufp->fastmap_accurate = 0;
+ bufp->not_bol = bufp->not_eol = 0;
+
+ /* Set `used' to zero, so that if we return an error, the pattern
+ printer (for debugging) will think there's no pattern. We reset it
+ at the end. */
+ bufp->used = 0;
+
+ /* Always count groups, whether or not bufp->no_sub is set. */
+ bufp->re_nsub = 0;
+
+#if !defined (emacs) && !defined (SYNTAX_TABLE)
+ /* Initialize the syntax table. */
+ init_syntax_once ();
+#endif
+
+ if (bufp->allocated == 0)
+ {
+ if (bufp->buffer)
+ { /* If zero allocated, but buffer is non-null, try to realloc
+ enough space. This loses if buffer's address is bogus, but
+ that is the user's responsibility. */
+ RETALLOC (bufp->buffer, INIT_BUF_SIZE, unsigned char);
+ }
+ else
+ { /* Caller did not allocate a buffer. Do it for them. */
+ bufp->buffer = TALLOC (INIT_BUF_SIZE, unsigned char);
+ }
+ if (!bufp->buffer) FREE_STACK_RETURN (REG_ESPACE);
+
+ bufp->allocated = INIT_BUF_SIZE;
+ }
+
+ begalt = b = bufp->buffer;
+
+ /* Loop through the uncompiled pattern until we're at the end. */
+ while (p != pend)
+ {
+ PATFETCH (c);
+
+ switch (c)
+ {
+ case '^':
+ {
+ if ( /* If at start of pattern, it's an operator. */
+ p == pattern + 1
+ /* If context independent, it's an operator. */
+ || syntax & RE_CONTEXT_INDEP_ANCHORS
+ /* Otherwise, depends on what's come before. */
+ || at_begline_loc_p (pattern, p, syntax))
+ BUF_PUSH (begline);
+ else
+ goto normal_char;
+ }
+ break;
+
+
+ case '$':
+ {
+ if ( /* If at end of pattern, it's an operator. */
+ p == pend
+ /* If context independent, it's an operator. */
+ || syntax & RE_CONTEXT_INDEP_ANCHORS
+ /* Otherwise, depends on what's next. */
+ || at_endline_loc_p (p, pend, syntax))
+ BUF_PUSH (endline);
+ else
+ goto normal_char;
+ }
+ break;
+
+
+ case '+':
+ case '?':
+ if ((syntax & RE_BK_PLUS_QM)
+ || (syntax & RE_LIMITED_OPS))
+ goto normal_char;
+ handle_plus:
+ case '*':
+ /* If there is no previous pattern... */
+ if (!laststart)
+ {
+ if (syntax & RE_CONTEXT_INVALID_OPS)
+ FREE_STACK_RETURN (REG_BADRPT);
+ else if (!(syntax & RE_CONTEXT_INDEP_OPS))
+ goto normal_char;
+ }
+
+ {
+ /* Are we optimizing this jump? */
+ boolean keep_string_p = false;
+
+ /* 1 means zero (many) matches is allowed. */
+ char zero_times_ok = 0, many_times_ok = 0;
+
+ /* If there is a sequence of repetition chars, collapse it
+ down to just one (the right one). We can't combine
+ interval operators with these because of, e.g., `a{2}*',
+ which should only match an even number of `a's. */
+
+ for (;;)
+ {
+ zero_times_ok |= c != '+';
+ many_times_ok |= c != '?';
+
+ if (p == pend)
+ break;
+
+ PATFETCH (c);
+
+ if (c == '*'
+ || (!(syntax & RE_BK_PLUS_QM) && (c == '+' || c == '?')))
+ ;
+
+ else if (syntax & RE_BK_PLUS_QM && c == '\\')
+ {
+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
+
+ PATFETCH (c1);
+ if (!(c1 == '+' || c1 == '?'))
+ {
+ PATUNFETCH;
+ PATUNFETCH;
+ break;
+ }
+
+ c = c1;
+ }
+ else
+ {
+ PATUNFETCH;
+ break;
+ }
+
+ /* If we get here, we found another repeat character. */
+ }
+
+ /* Star, etc. applied to an empty pattern is equivalent
+ to an empty pattern. */
+ if (!laststart)
+ break;
+
+ /* Now we know whether or not zero matches is allowed
+ and also whether or not two or more matches is allowed. */
+ if (many_times_ok)
+ { /* More than one repetition is allowed, so put in at the
+ end a backward relative jump from `b' to before the next
+ jump we're going to put in below (which jumps from
+ laststart to after this jump).
+
+ But if we are at the `*' in the exact sequence `.*\n',
+ insert an unconditional jump backwards to the .,
+ instead of the beginning of the loop. This way we only
+ push a failure point once, instead of every time
+ through the loop. */
+ assert (p - 1 > pattern);
+
+ /* Allocate the space for the jump. */
+ GET_BUFFER_SPACE (3);
+
+ /* We know we are not at the first character of the pattern,
+ because laststart was nonzero. And we've already
+ incremented `p', by the way, to be the character after
+ the `*'. Do we have to do something analogous here
+ for null bytes, because of RE_DOT_NOT_NULL? */
+ if (TRANSLATE (*(p - 2)) == TRANSLATE ('.')
+ && zero_times_ok
+ && p < pend && TRANSLATE (*p) == TRANSLATE ('\n')
+ && !(syntax & RE_DOT_NEWLINE))
+ { /* We have .*\n. */
+ STORE_JUMP (jump, b, laststart);
+ keep_string_p = true;
+ }
+ else
+ /* Anything else. */
+ STORE_JUMP (maybe_pop_jump, b, laststart - 3);
+
+ /* We've added more stuff to the buffer. */
+ b += 3;
+ }
+
+ /* On failure, jump from laststart to b + 3, which will be the
+ end of the buffer after this jump is inserted. */
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump
+ : on_failure_jump,
+ laststart, b + 3);
+ pending_exact = 0;
+ b += 3;
+
+ if (!zero_times_ok)
+ {
+ /* At least one repetition is required, so insert a
+ `dummy_failure_jump' before the initial
+ `on_failure_jump' instruction of the loop. This
+ effects a skip over that instruction the first time
+ we hit that loop. */
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (dummy_failure_jump, laststart, laststart + 6);
+ b += 3;
+ }
+ }
+ break;
+
+
+ case '.':
+ laststart = b;
+ BUF_PUSH (anychar);
+ break;
+
+
+ case '[':
+ {
+ boolean had_char_class = false;
+
+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
+
+ /* Ensure that we have enough space to push a charset: the
+ opcode, the length count, and the bitset; 34 bytes in all. */
+ GET_BUFFER_SPACE (34);
+
+ laststart = b;
+
+ /* We test `*p == '^' twice, instead of using an if
+ statement, so we only need one BUF_PUSH. */
+ BUF_PUSH (*p == '^' ? charset_not : charset);
+ if (*p == '^')
+ p++;
+
+ /* Remember the first position in the bracket expression. */
+ p1 = p;
+
+ /* Push the number of bytes in the bitmap. */
+ BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH);
+
+ /* Clear the whole map. */
+ bzero (b, (1 << BYTEWIDTH) / BYTEWIDTH);
+
+ /* charset_not matches newline according to a syntax bit. */
+ if ((re_opcode_t) b[-2] == charset_not
+ && (syntax & RE_HAT_LISTS_NOT_NEWLINE))
+ SET_LIST_BIT ('\n');
+
+ /* Read in characters and ranges, setting map bits. */
+ for (;;)
+ {
+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
+
+ PATFETCH (c);
+
+ /* \ might escape characters inside [...] and [^...]. */
+ if ((syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) && c == '\\')
+ {
+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
+
+ PATFETCH (c1);
+ SET_LIST_BIT (c1);
+ continue;
+ }
+
+ /* Could be the end of the bracket expression. If it's
+ not (i.e., when the bracket expression is `[]' so
+ far), the ']' character bit gets set way below. */
+ if (c == ']' && p != p1 + 1)
+ break;
+
+ /* Look ahead to see if it's a range when the last thing
+ was a character class. */
+ if (had_char_class && c == '-' && *p != ']')
+ FREE_STACK_RETURN (REG_ERANGE);
+
+ /* Look ahead to see if it's a range when the last thing
+ was a character: if this is a hyphen not at the
+ beginning or the end of a list, then it's the range
+ operator. */
+ if (c == '-'
+ && !(p - 2 >= pattern && p[-2] == '[')
+ && !(p - 3 >= pattern && p[-3] == '[' && p[-2] == '^')
+ && *p != ']')
+ {
+ reg_errcode_t ret
+ = compile_range (&p, pend, translate, syntax, b);
+ if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
+ }
+
+ else if (p[0] == '-' && p[1] != ']')
+ { /* This handles ranges made up of characters only. */
+ reg_errcode_t ret;
+
+ /* Move past the `-'. */
+ PATFETCH (c1);
+
+ ret = compile_range (&p, pend, translate, syntax, b);
+ if (ret != REG_NOERROR) FREE_STACK_RETURN (ret);
+ }
+
+ /* See if we're at the beginning of a possible character
+ class. */
+
+ else if (syntax & RE_CHAR_CLASSES && c == '[' && *p == ':')
+ { /* Leave room for the null. */
+ char str[CHAR_CLASS_MAX_LENGTH + 1];
+
+ PATFETCH (c);
+ c1 = 0;
+
+ /* If pattern is `[[:'. */
+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
+
+ for (;;)
+ {
+ PATFETCH (c);
+ if (c == ':' || c == ']' || p == pend
+ || c1 == CHAR_CLASS_MAX_LENGTH)
+ break;
+ str[c1++] = c;
+ }
+ str[c1] = '\0';
+
+ /* If isn't a word bracketed by `[:' and:`]':
+ undo the ending character, the letters, and leave
+ the leading `:' and `[' (but set bits for them). */
+ if (c == ':' && *p == ']')
+ {
+ int ch;
+ boolean is_alnum = STREQ (str, "alnum");
+ boolean is_alpha = STREQ (str, "alpha");
+ boolean is_blank = STREQ (str, "blank");
+ boolean is_cntrl = STREQ (str, "cntrl");
+ boolean is_digit = STREQ (str, "digit");
+ boolean is_graph = STREQ (str, "graph");
+ boolean is_lower = STREQ (str, "lower");
+ boolean is_print = STREQ (str, "print");
+ boolean is_punct = STREQ (str, "punct");
+ boolean is_space = STREQ (str, "space");
+ boolean is_upper = STREQ (str, "upper");
+ boolean is_xdigit = STREQ (str, "xdigit");
+
+ if (!IS_CHAR_CLASS (str))
+ FREE_STACK_RETURN (REG_ECTYPE);
+
+ /* Throw away the ] at the end of the character
+ class. */
+ PATFETCH (c);
+
+ if (p == pend) FREE_STACK_RETURN (REG_EBRACK);
+
+ for (ch = 0; ch < 1 << BYTEWIDTH; ch++)
+ {
+ /* This was split into 3 if's to
+ avoid an arbitrary limit in some compiler. */
+ if ( (is_alnum && ISALNUM (ch))
+ || (is_alpha && ISALPHA (ch))
+ || (is_blank && ISBLANK (ch))
+ || (is_cntrl && ISCNTRL (ch)))
+ SET_LIST_BIT (ch);
+ if ( (is_digit && ISDIGIT (ch))
+ || (is_graph && ISGRAPH (ch))
+ || (is_lower && ISLOWER (ch))
+ || (is_print && ISPRINT (ch)))
+ SET_LIST_BIT (ch);
+ if ( (is_punct && ISPUNCT (ch))
+ || (is_space && ISSPACE (ch))
+ || (is_upper && ISUPPER (ch))
+ || (is_xdigit && ISXDIGIT (ch)))
+ SET_LIST_BIT (ch);
+ }
+ had_char_class = true;
+ }
+ else
+ {
+ c1++;
+ while (c1--)
+ PATUNFETCH;
+ SET_LIST_BIT ('[');
+ SET_LIST_BIT (':');
+ had_char_class = false;
+ }
+ }
+ else
+ {
+ had_char_class = false;
+ SET_LIST_BIT (c);
+ }
+ }
+
+ /* Discard any (non)matching list bytes that are all 0 at the
+ end of the map. Decrease the map-length byte too. */
+ while ((int) b[-1] > 0 && b[b[-1] - 1] == 0)
+ b[-1]--;
+ b += b[-1];
+ }
+ break;
+
+
+ case '(':
+ if (syntax & RE_NO_BK_PARENS)
+ goto handle_open;
+ else
+ goto normal_char;
+
+
+ case ')':
+ if (syntax & RE_NO_BK_PARENS)
+ goto handle_close;
+ else
+ goto normal_char;
+
+
+ case '\n':
+ if (syntax & RE_NEWLINE_ALT)
+ goto handle_alt;
+ else
+ goto normal_char;
+
+
+ case '|':
+ if (syntax & RE_NO_BK_VBAR)
+ goto handle_alt;
+ else
+ goto normal_char;
+
+
+ case '{':
+ if (syntax & RE_INTERVALS && syntax & RE_NO_BK_BRACES)
+ goto handle_interval;
+ else
+ goto normal_char;
+
+
+ case '\\':
+ if (p == pend) FREE_STACK_RETURN (REG_EESCAPE);
+
+ /* Do not translate the character after the \, so that we can
+ distinguish, e.g., \B from \b, even if we normally would
+ translate, e.g., B to b. */
+ PATFETCH_RAW (c);
+
+ switch (c)
+ {
+ case '(':
+ if (syntax & RE_NO_BK_PARENS)
+ goto normal_backslash;
+
+ handle_open:
+ bufp->re_nsub++;
+ regnum++;
+
+ if (COMPILE_STACK_FULL)
+ {
+ RETALLOC (compile_stack.stack, compile_stack.size << 1,
+ compile_stack_elt_t);
+ if (compile_stack.stack == NULL) return REG_ESPACE;
+
+ compile_stack.size <<= 1;
+ }
+
+ /* These are the values to restore when we hit end of this
+ group. They are all relative offsets, so that if the
+ whole pattern moves because of realloc, they will still
+ be valid. */
+ COMPILE_STACK_TOP.begalt_offset = begalt - bufp->buffer;
+ COMPILE_STACK_TOP.fixup_alt_jump
+ = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0;
+ COMPILE_STACK_TOP.laststart_offset = b - bufp->buffer;
+ COMPILE_STACK_TOP.regnum = regnum;
+
+ /* We will eventually replace the 0 with the number of
+ groups inner to this one. But do not push a
+ start_memory for groups beyond the last one we can
+ represent in the compiled pattern. */
+ if (regnum <= MAX_REGNUM)
+ {
+ COMPILE_STACK_TOP.inner_group_offset = b - bufp->buffer + 2;
+ BUF_PUSH_3 (start_memory, regnum, 0);
+ }
+
+ compile_stack.avail++;
+
+ fixup_alt_jump = 0;
+ laststart = 0;
+ begalt = b;
+ /* If we've reached MAX_REGNUM groups, then this open
+ won't actually generate any code, so we'll have to
+ clear pending_exact explicitly. */
+ pending_exact = 0;
+ break;
+
+
+ case ')':
+ if (syntax & RE_NO_BK_PARENS) goto normal_backslash;
+
+ if (COMPILE_STACK_EMPTY)
+ if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
+ goto normal_backslash;
+ else
+ FREE_STACK_RETURN (REG_ERPAREN);
+
+ handle_close:
+ if (fixup_alt_jump)
+ { /* Push a dummy failure point at the end of the
+ alternative for a possible future
+ `pop_failure_jump' to pop. See comments at
+ `push_dummy_failure' in `re_match_2'. */
+ BUF_PUSH (push_dummy_failure);
+
+ /* We allocated space for this jump when we assigned
+ to `fixup_alt_jump', in the `handle_alt' case below. */
+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1);
+ }
+
+ /* See similar code for backslashed left paren above. */
+ if (COMPILE_STACK_EMPTY)
+ if (syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)
+ goto normal_char;
+ else
+ FREE_STACK_RETURN (REG_ERPAREN);
+
+ /* Since we just checked for an empty stack above, this
+ ``can't happen''. */
+ assert (compile_stack.avail != 0);
+ {
+ /* We don't just want to restore into `regnum', because
+ later groups should continue to be numbered higher,
+ as in `(ab)c(de)' -- the second group is #2. */
+ regnum_t this_group_regnum;
+
+ compile_stack.avail--;
+ begalt = bufp->buffer + COMPILE_STACK_TOP.begalt_offset;
+ fixup_alt_jump
+ = COMPILE_STACK_TOP.fixup_alt_jump
+ ? bufp->buffer + COMPILE_STACK_TOP.fixup_alt_jump - 1
+ : 0;
+ laststart = bufp->buffer + COMPILE_STACK_TOP.laststart_offset;
+ this_group_regnum = COMPILE_STACK_TOP.regnum;
+ /* If we've reached MAX_REGNUM groups, then this open
+ won't actually generate any code, so we'll have to
+ clear pending_exact explicitly. */
+ pending_exact = 0;
+
+ /* We're at the end of the group, so now we know how many
+ groups were inside this one. */
+ if (this_group_regnum <= MAX_REGNUM)
+ {
+ unsigned char *inner_group_loc
+ = bufp->buffer + COMPILE_STACK_TOP.inner_group_offset;
+
+ *inner_group_loc = regnum - this_group_regnum;
+ BUF_PUSH_3 (stop_memory, this_group_regnum,
+ regnum - this_group_regnum);
+ }
+ }
+ break;
+
+
+ case '|': /* `\|'. */
+ if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR)
+ goto normal_backslash;
+ handle_alt:
+ if (syntax & RE_LIMITED_OPS)
+ goto normal_char;
+
+ /* Insert before the previous alternative a jump which
+ jumps to this alternative if the former fails. */
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (on_failure_jump, begalt, b + 6);
+ pending_exact = 0;
+ b += 3;
+
+ /* The alternative before this one has a jump after it
+ which gets executed if it gets matched. Adjust that
+ jump so it will jump to this alternative's analogous
+ jump (put in below, which in turn will jump to the next
+ (if any) alternative's such jump, etc.). The last such
+ jump jumps to the correct final destination. A picture:
+ _____ _____
+ | | | |
+ | v | v
+ a | b | c
+
+ If we are at `b', then fixup_alt_jump right now points to a
+ three-byte space after `a'. We'll put in the jump, set
+ fixup_alt_jump to right after `b', and leave behind three
+ bytes which we'll fill in when we get to after `c'. */
+
+ if (fixup_alt_jump)
+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
+
+ /* Mark and leave space for a jump after this alternative,
+ to be filled in later either by next alternative or
+ when know we're at the end of a series of alternatives. */
+ fixup_alt_jump = b;
+ GET_BUFFER_SPACE (3);
+ b += 3;
+
+ laststart = 0;
+ begalt = b;
+ break;
+
+
+ case '{':
+ /* If \{ is a literal. */
+ if (!(syntax & RE_INTERVALS)
+ /* If we're at `\{' and it's not the open-interval
+ operator. */
+ || ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
+ || (p - 2 == pattern && p == pend))
+ goto normal_backslash;
+
+ handle_interval:
+ {
+ /* If got here, then the syntax allows intervals. */
+
+ /* At least (most) this many matches must be made. */
+ int lower_bound = -1, upper_bound = -1;
+
+ beg_interval = p - 1;
+
+ if (p == pend)
+ {
+ if (syntax & RE_NO_BK_BRACES)
+ goto unfetch_interval;
+ else
+ FREE_STACK_RETURN (REG_EBRACE);
+ }
+
+ GET_UNSIGNED_NUMBER (lower_bound);
+
+ if (c == ',')
+ {
+ GET_UNSIGNED_NUMBER (upper_bound);
+ if (upper_bound < 0) upper_bound = RE_DUP_MAX;
+ }
+ else
+ /* Interval such as `{1}' => match exactly once. */
+ upper_bound = lower_bound;
+
+ if (lower_bound < 0 || upper_bound > RE_DUP_MAX
+ || lower_bound > upper_bound)
+ {
+ if (syntax & RE_NO_BK_BRACES)
+ goto unfetch_interval;
+ else
+ FREE_STACK_RETURN (REG_BADBR);
+ }
+
+ if (!(syntax & RE_NO_BK_BRACES))
+ {
+ if (c != '\\') FREE_STACK_RETURN (REG_EBRACE);
+
+ PATFETCH (c);
+ }
+
+ if (c != '}')
+ {
+ if (syntax & RE_NO_BK_BRACES)
+ goto unfetch_interval;
+ else
+ FREE_STACK_RETURN (REG_BADBR);
+ }
+
+ /* We just parsed a valid interval. */
+
+ /* If it's invalid to have no preceding re. */
+ if (!laststart)
+ {
+ if (syntax & RE_CONTEXT_INVALID_OPS)
+ FREE_STACK_RETURN (REG_BADRPT);
+ else if (syntax & RE_CONTEXT_INDEP_OPS)
+ laststart = b;
+ else
+ goto unfetch_interval;
+ }
+
+ /* If the upper bound is zero, don't want to succeed at
+ all; jump from `laststart' to `b + 3', which will be
+ the end of the buffer after we insert the jump. */
+ if (upper_bound == 0)
+ {
+ GET_BUFFER_SPACE (3);
+ INSERT_JUMP (jump, laststart, b + 3);
+ b += 3;
+ }
+
+ /* Otherwise, we have a nontrivial interval. When
+ we're all done, the pattern will look like:
+ set_number_at <jump count> <upper bound>
+ set_number_at <succeed_n count> <lower bound>
+ succeed_n <after jump addr> <succeed_n count>
+ <body of loop>
+ jump_n <succeed_n addr> <jump count>
+ (The upper bound and `jump_n' are omitted if
+ `upper_bound' is 1, though.) */
+ else
+ { /* If the upper bound is > 1, we need to insert
+ more at the end of the loop. */
+ unsigned nbytes = 10 + (upper_bound > 1) * 10;
+
+ GET_BUFFER_SPACE (nbytes);
+
+ /* Initialize lower bound of the `succeed_n', even
+ though it will be set during matching by its
+ attendant `set_number_at' (inserted next),
+ because `re_compile_fastmap' needs to know.
+ Jump to the `jump_n' we might insert below. */
+ INSERT_JUMP2 (succeed_n, laststart,
+ b + 5 + (upper_bound > 1) * 5,
+ lower_bound);
+ b += 5;
+
+ /* Code to initialize the lower bound. Insert
+ before the `succeed_n'. The `5' is the last two
+ bytes of this `set_number_at', plus 3 bytes of
+ the following `succeed_n'. */
+ insert_op2 (set_number_at, laststart, 5, lower_bound, b);
+ b += 5;
+
+ if (upper_bound > 1)
+ { /* More than one repetition is allowed, so
+ append a backward jump to the `succeed_n'
+ that starts this interval.
+
+ When we've reached this during matching,
+ we'll have matched the interval once, so
+ jump back only `upper_bound - 1' times. */
+ STORE_JUMP2 (jump_n, b, laststart + 5,
+ upper_bound - 1);
+ b += 5;
+
+ /* The location we want to set is the second
+ parameter of the `jump_n'; that is `b-2' as
+ an absolute address. `laststart' will be
+ the `set_number_at' we're about to insert;
+ `laststart+3' the number to set, the source
+ for the relative address. But we are
+ inserting into the middle of the pattern --
+ so everything is getting moved up by 5.
+ Conclusion: (b - 2) - (laststart + 3) + 5,
+ i.e., b - laststart.
+
+ We insert this at the beginning of the loop
+ so that if we fail during matching, we'll
+ reinitialize the bounds. */
+ insert_op2 (set_number_at, laststart, b - laststart,
+ upper_bound - 1, b);
+ b += 5;
+ }
+ }
+ pending_exact = 0;
+ beg_interval = NULL;
+ }
+ break;
+
+ unfetch_interval:
+ /* If an invalid interval, match the characters as literals. */
+ assert (beg_interval);
+ p = beg_interval;
+ beg_interval = NULL;
+
+ /* normal_char and normal_backslash need `c'. */
+ PATFETCH (c);
+
+ if (!(syntax & RE_NO_BK_BRACES))
+ {
+ if (p > pattern && p[-1] == '\\')
+ goto normal_backslash;
+ }
+ goto normal_char;
+
+#ifdef emacs
+ /* There is no way to specify the before_dot and after_dot
+ operators. rms says this is ok. --karl */
+ case '=':
+ BUF_PUSH (at_dot);
+ break;
+
+ case 's':
+ laststart = b;
+ PATFETCH (c);
+ BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]);
+ break;
+
+ case 'S':
+ laststart = b;
+ PATFETCH (c);
+ BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]);
+ break;
+#endif /* emacs */
+
+
+ case 'w':
+ laststart = b;
+ BUF_PUSH (wordchar);
+ break;
+
+
+ case 'W':
+ laststart = b;
+ BUF_PUSH (notwordchar);
+ break;
+
+
+ case '<':
+ BUF_PUSH (wordbeg);
+ break;
+
+ case '>':
+ BUF_PUSH (wordend);
+ break;
+
+ case 'b':
+ BUF_PUSH (wordbound);
+ break;
+
+ case 'B':
+ BUF_PUSH (notwordbound);
+ break;
+
+ case '`':
+ BUF_PUSH (begbuf);
+ break;
+
+ case '\'':
+ BUF_PUSH (endbuf);
+ break;
+
+ case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ if (syntax & RE_NO_BK_REFS)
+ goto normal_char;
+
+ c1 = c - '0';
+
+ if (c1 > regnum)
+ FREE_STACK_RETURN (REG_ESUBREG);
+
+ /* Can't back reference to a subexpression if inside of it. */
+ if (group_in_compile_stack (compile_stack, c1))
+ goto normal_char;
+
+ laststart = b;
+ BUF_PUSH_2 (duplicate, c1);
+ break;
+
+
+ case '+':
+ case '?':
+ if (syntax & RE_BK_PLUS_QM)
+ goto handle_plus;
+ else
+ goto normal_backslash;
+
+ default:
+ normal_backslash:
+ /* You might think it would be useful for \ to mean
+ not to translate; but if we don't translate it
+ it will never match anything. */
+ c = TRANSLATE (c);
+ goto normal_char;
+ }
+ break;
+
+
+ default:
+ /* Expects the character in `c'. */
+ normal_char:
+ /* If no exactn currently being built. */
+ if (!pending_exact
+
+ /* If last exactn not at current position. */
+ || pending_exact + *pending_exact + 1 != b
+
+ /* We have only one byte following the exactn for the count. */
+ || *pending_exact == (1 << BYTEWIDTH) - 1
+
+ /* If followed by a repetition operator. */
+ || *p == '*' || *p == '^'
+ || ((syntax & RE_BK_PLUS_QM)
+ ? *p == '\\' && (p[1] == '+' || p[1] == '?')
+ : (*p == '+' || *p == '?'))
+ || ((syntax & RE_INTERVALS)
+ && ((syntax & RE_NO_BK_BRACES)
+ ? *p == '{'
+ : (p[0] == '\\' && p[1] == '{'))))
+ {
+ /* Start building a new exactn. */
+
+ laststart = b;
+
+ BUF_PUSH_2 (exactn, 0);
+ pending_exact = b - 1;
+ }
+
+ BUF_PUSH (c);
+ (*pending_exact)++;
+ break;
+ } /* switch (c) */
+ } /* while p != pend */
+
+
+ /* Through the pattern now. */
+
+ if (fixup_alt_jump)
+ STORE_JUMP (jump_past_alt, fixup_alt_jump, b);
+
+ if (!COMPILE_STACK_EMPTY)
+ FREE_STACK_RETURN (REG_EPAREN);
+
+ free (compile_stack.stack);
+
+ /* We have succeeded; set the length of the buffer. */
+ bufp->used = b - bufp->buffer;
+
+#ifdef DEBUG
+ if (debug)
+ {
+ DEBUG_PRINT1 ("\nCompiled pattern: \n");
+ print_compiled_pattern (bufp);
+ }
+#endif /* DEBUG */
+
+#ifndef MATCH_MAY_ALLOCATE
+ /* Initialize the failure stack to the largest possible stack. This
+ isn't necessary unless we're trying to avoid calling alloca in
+ the search and match routines. */
+ {
+ int num_regs = bufp->re_nsub + 1;
+
+ /* Since DOUBLE_FAIL_STACK refuses to double only if the current size
+ is strictly greater than re_max_failures, the largest possible stack
+ is 2 * re_max_failures failure points. */
+ if (fail_stack.size < (2 * re_max_failures * MAX_FAILURE_ITEMS))
+ {
+ fail_stack.size = (2 * re_max_failures * MAX_FAILURE_ITEMS);
+
+#ifdef emacs
+ if (! fail_stack.stack)
+ fail_stack.stack
+ = (fail_stack_elt_t *) xmalloc (fail_stack.size
+ * sizeof (fail_stack_elt_t));
+ else
+ fail_stack.stack
+ = (fail_stack_elt_t *) xrealloc (fail_stack.stack,
+ (fail_stack.size
+ * sizeof (fail_stack_elt_t)));
+#else /* not emacs */
+ if (! fail_stack.stack)
+ fail_stack.stack
+ = (fail_stack_elt_t *) malloc (fail_stack.size
+ * sizeof (fail_stack_elt_t));
+ else
+ fail_stack.stack
+ = (fail_stack_elt_t *) realloc (fail_stack.stack,
+ (fail_stack.size
+ * sizeof (fail_stack_elt_t)));
+#endif /* not emacs */
+ }
+
+ /* Initialize some other variables the matcher uses. */
+ RETALLOC_IF (regstart, num_regs, const char *);
+ RETALLOC_IF (regend, num_regs, const char *);
+ RETALLOC_IF (old_regstart, num_regs, const char *);
+ RETALLOC_IF (old_regend, num_regs, const char *);
+ RETALLOC_IF (best_regstart, num_regs, const char *);
+ RETALLOC_IF (best_regend, num_regs, const char *);
+ RETALLOC_IF (reg_info, num_regs, register_info_type);
+ RETALLOC_IF (reg_dummy, num_regs, const char *);
+ RETALLOC_IF (reg_info_dummy, num_regs, register_info_type);
+ }
+#endif
+
+ return REG_NOERROR;
+} /* regex_compile */
+
+/* Subroutines for `regex_compile'. */
+
+/* Store OP at LOC followed by two-byte integer parameter ARG. */
+
+static void
+store_op1 (op, loc, arg)
+ re_opcode_t op;
+ unsigned char *loc;
+ int arg;
+{
+ *loc = (unsigned char) op;
+ STORE_NUMBER (loc + 1, arg);
+}
+
+
+/* Like `store_op1', but for two two-byte parameters ARG1 and ARG2. */
+
+static void
+store_op2 (op, loc, arg1, arg2)
+ re_opcode_t op;
+ unsigned char *loc;
+ int arg1, arg2;
+{
+ *loc = (unsigned char) op;
+ STORE_NUMBER (loc + 1, arg1);
+ STORE_NUMBER (loc + 3, arg2);
+}
+
+
+/* Copy the bytes from LOC to END to open up three bytes of space at LOC
+ for OP followed by two-byte integer parameter ARG. */
+
+static void
+insert_op1 (op, loc, arg, end)
+ re_opcode_t op;
+ unsigned char *loc;
+ int arg;
+ unsigned char *end;
+{
+ register unsigned char *pfrom = end;
+ register unsigned char *pto = end + 3;
+
+ while (pfrom != loc)
+ *--pto = *--pfrom;
+
+ store_op1 (op, loc, arg);
+}
+
+
+/* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2. */
+
+static void
+insert_op2 (op, loc, arg1, arg2, end)
+ re_opcode_t op;
+ unsigned char *loc;
+ int arg1, arg2;
+ unsigned char *end;
+{
+ register unsigned char *pfrom = end;
+ register unsigned char *pto = end + 5;
+
+ while (pfrom != loc)
+ *--pto = *--pfrom;
+
+ store_op2 (op, loc, arg1, arg2);
+}
+
+
+/* P points to just after a ^ in PATTERN. Return true if that ^ comes
+ after an alternative or a begin-subexpression. We assume there is at
+ least one character before the ^. */
+
+static boolean
+at_begline_loc_p (pattern, p, syntax)
+ const char *pattern, *p;
+ reg_syntax_t syntax;
+{
+ const char *prev = p - 2;
+ boolean prev_prev_backslash = prev > pattern && prev[-1] == '\\';
+
+ return
+ /* After a subexpression? */
+ (*prev == '(' && (syntax & RE_NO_BK_PARENS || prev_prev_backslash))
+ /* After an alternative? */
+ || (*prev == '|' && (syntax & RE_NO_BK_VBAR || prev_prev_backslash));
+}
+
+
+/* The dual of at_begline_loc_p. This one is for $. We assume there is
+ at least one character after the $, i.e., `P < PEND'. */
+
+static boolean
+at_endline_loc_p (p, pend, syntax)
+ const char *p, *pend;
+ int syntax;
+{
+ const char *next = p;
+ boolean next_backslash = *next == '\\';
+ const char *next_next = p + 1 < pend ? p + 1 : NULL;
+
+ return
+ /* Before a subexpression? */
+ (syntax & RE_NO_BK_PARENS ? *next == ')'
+ : next_backslash && next_next && *next_next == ')')
+ /* Before an alternative? */
+ || (syntax & RE_NO_BK_VBAR ? *next == '|'
+ : next_backslash && next_next && *next_next == '|');
+}
+
+
+/* Returns true if REGNUM is in one of COMPILE_STACK's elements and
+ false if it's not. */
+
+static boolean
+group_in_compile_stack (compile_stack, regnum)
+ compile_stack_type compile_stack;
+ regnum_t regnum;
+{
+ int this_element;
+
+ for (this_element = compile_stack.avail - 1;
+ this_element >= 0;
+ this_element--)
+ if (compile_stack.stack[this_element].regnum == regnum)
+ return true;
+
+ return false;
+}
+
+
+/* Read the ending character of a range (in a bracket expression) from the
+ uncompiled pattern *P_PTR (which ends at PEND). We assume the
+ starting character is in `P[-2]'. (`P[-1]' is the character `-'.)
+ Then we set the translation of all bits between the starting and
+ ending characters (inclusive) in the compiled pattern B.
+
+ Return an error code.
+
+ We use these short variable names so we can use the same macros as
+ `regex_compile' itself. */
+
+static reg_errcode_t
+compile_range (p_ptr, pend, translate, syntax, b)
+ const char **p_ptr, *pend;
+ char *translate;
+ reg_syntax_t syntax;
+ unsigned char *b;
+{
+ unsigned this_char;
+
+ const char *p = *p_ptr;
+ int range_start, range_end;
+
+ if (p == pend)
+ return REG_ERANGE;
+
+ /* Even though the pattern is a signed `char *', we need to fetch
+ with unsigned char *'s; if the high bit of the pattern character
+ is set, the range endpoints will be negative if we fetch using a
+ signed char *.
+
+ We also want to fetch the endpoints without translating them; the
+ appropriate translation is done in the bit-setting loop below. */
+ /* The SVR4 compiler on the 3B2 had trouble with unsigned const char *. */
+ range_start = ((const unsigned char *) p)[-2];
+ range_end = ((const unsigned char *) p)[0];
+
+ /* Have to increment the pointer into the pattern string, so the
+ caller isn't still at the ending character. */
+ (*p_ptr)++;
+
+ /* If the start is after the end, the range is empty. */
+ if (range_start > range_end)
+ return syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR;
+
+ /* Here we see why `this_char' has to be larger than an `unsigned
+ char' -- the range is inclusive, so if `range_end' == 0xff
+ (assuming 8-bit characters), we would otherwise go into an infinite
+ loop, since all characters <= 0xff. */
+ for (this_char = range_start; this_char <= range_end; this_char++)
+ {
+ SET_LIST_BIT (TRANSLATE (this_char));
+ }
+
+ return REG_NOERROR;
+}
+
+/* re_compile_fastmap computes a ``fastmap'' for the compiled pattern in
+ BUFP. A fastmap records which of the (1 << BYTEWIDTH) possible
+ characters can start a string that matches the pattern. This fastmap
+ is used by re_search to skip quickly over impossible starting points.
+
+ The caller must supply the address of a (1 << BYTEWIDTH)-byte data
+ area as BUFP->fastmap.
+
+ We set the `fastmap', `fastmap_accurate', and `can_be_null' fields in
+ the pattern buffer.
+
+ Returns 0 if we succeed, -2 if an internal error. */
+
+int
+re_compile_fastmap (bufp)
+ struct re_pattern_buffer *bufp;
+{
+ int j, k;
+#ifdef MATCH_MAY_ALLOCATE
+ fail_stack_type fail_stack;
+#endif
+#ifndef REGEX_MALLOC
+ char *destination;
+#endif
+ /* We don't push any register information onto the failure stack. */
+ unsigned num_regs = 0;
+
+ register char *fastmap = bufp->fastmap;
+ unsigned char *pattern = bufp->buffer;
+ unsigned long size = bufp->used;
+ unsigned char *p = pattern;
+ register unsigned char *pend = pattern + size;
+
+ /* Assume that each path through the pattern can be null until
+ proven otherwise. We set this false at the bottom of switch
+ statement, to which we get only if a particular path doesn't
+ match the empty string. */
+ boolean path_can_be_null = true;
+
+ /* We aren't doing a `succeed_n' to begin with. */
+ boolean succeed_n_p = false;
+
+ assert (fastmap != NULL && p != NULL);
+
+ INIT_FAIL_STACK ();
+ bzero (fastmap, 1 << BYTEWIDTH); /* Assume nothing's valid. */
+ bufp->fastmap_accurate = 1; /* It will be when we're done. */
+ bufp->can_be_null = 0;
+
+ while (p != pend || !FAIL_STACK_EMPTY ())
+ {
+ if (p == pend)
+ {
+ bufp->can_be_null |= path_can_be_null;
+
+ /* Reset for next path. */
+ path_can_be_null = true;
+
+ p = fail_stack.stack[--fail_stack.avail];
+ }
+
+ /* We should never be about to go beyond the end of the pattern. */
+ assert (p < pend);
+
+#ifdef SWITCH_ENUM_BUG
+ switch ((int) ((re_opcode_t) *p++))
+#else
+ switch ((re_opcode_t) *p++)
+#endif
+ {
+
+ /* I guess the idea here is to simply not bother with a fastmap
+ if a backreference is used, since it's too hard to figure out
+ the fastmap for the corresponding group. Setting
+ `can_be_null' stops `re_search_2' from using the fastmap, so
+ that is all we do. */
+ case duplicate:
+ bufp->can_be_null = 1;
+ return 0;
+
+
+ /* Following are the cases which match a character. These end
+ with `break'. */
+
+ case exactn:
+ fastmap[p[1]] = 1;
+ break;
+
+
+ case charset:
+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+ if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))
+ fastmap[j] = 1;
+ break;
+
+
+ case charset_not:
+ /* Chars beyond end of map must be allowed. */
+ for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++)
+ fastmap[j] = 1;
+
+ for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--)
+ if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))))
+ fastmap[j] = 1;
+ break;
+
+
+ case wordchar:
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) == Sword)
+ fastmap[j] = 1;
+ break;
+
+
+ case notwordchar:
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) != Sword)
+ fastmap[j] = 1;
+ break;
+
+
+ case anychar:
+ {
+ int fastmap_newline = fastmap['\n'];
+
+ /* `.' matches anything ... */
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ fastmap[j] = 1;
+
+ /* ... except perhaps newline. */
+ if (!(bufp->syntax & RE_DOT_NEWLINE))
+ fastmap['\n'] = fastmap_newline;
+
+ /* Return if we have already set `can_be_null'; if we have,
+ then the fastmap is irrelevant. Something's wrong here. */
+ else if (bufp->can_be_null)
+ return 0;
+
+ /* Otherwise, have to check alternative paths. */
+ break;
+ }
+
+#ifdef emacs
+ case syntaxspec:
+ k = *p++;
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) == (enum syntaxcode) k)
+ fastmap[j] = 1;
+ break;
+
+
+ case notsyntaxspec:
+ k = *p++;
+ for (j = 0; j < (1 << BYTEWIDTH); j++)
+ if (SYNTAX (j) != (enum syntaxcode) k)
+ fastmap[j] = 1;
+ break;
+
+
+ /* All cases after this match the empty string. These end with
+ `continue'. */
+
+
+ case before_dot:
+ case at_dot:
+ case after_dot:
+ continue;
+#endif /* not emacs */
+
+
+ case no_op:
+ case begline:
+ case endline:
+ case begbuf:
+ case endbuf:
+ case wordbound:
+ case notwordbound:
+ case wordbeg:
+ case wordend:
+ case push_dummy_failure:
+ continue;
+
+
+ case jump_n:
+ case pop_failure_jump:
+ case maybe_pop_jump:
+ case jump:
+ case jump_past_alt:
+ case dummy_failure_jump:
+ EXTRACT_NUMBER_AND_INCR (j, p);
+ p += j;
+ if (j > 0)
+ continue;
+
+ /* Jump backward implies we just went through the body of a
+ loop and matched nothing. Opcode jumped to should be
+ `on_failure_jump' or `succeed_n'. Just treat it like an
+ ordinary jump. For a * loop, it has pushed its failure
+ point already; if so, discard that as redundant. */
+ if ((re_opcode_t) *p != on_failure_jump
+ && (re_opcode_t) *p != succeed_n)
+ continue;
+
+ p++;
+ EXTRACT_NUMBER_AND_INCR (j, p);
+ p += j;
+
+ /* If what's on the stack is where we are now, pop it. */
+ if (!FAIL_STACK_EMPTY ()
+ && fail_stack.stack[fail_stack.avail - 1] == p)
+ fail_stack.avail--;
+
+ continue;
+
+
+ case on_failure_jump:
+ case on_failure_keep_string_jump:
+ handle_on_failure_jump:
+ EXTRACT_NUMBER_AND_INCR (j, p);
+
+ /* For some patterns, e.g., `(a?)?', `p+j' here points to the
+ end of the pattern. We don't want to push such a point,
+ since when we restore it above, entering the switch will
+ increment `p' past the end of the pattern. We don't need
+ to push such a point since we obviously won't find any more
+ fastmap entries beyond `pend'. Such a pattern can match
+ the null string, though. */
+ if (p + j < pend)
+ {
+ if (!PUSH_PATTERN_OP (p + j, fail_stack))
+ return -2;
+ }
+ else
+ bufp->can_be_null = 1;
+
+ if (succeed_n_p)
+ {
+ EXTRACT_NUMBER_AND_INCR (k, p); /* Skip the n. */
+ succeed_n_p = false;
+ }
+
+ continue;
+
+
+ case succeed_n:
+ /* Get to the number of times to succeed. */
+ p += 2;
+
+ /* Increment p past the n for when k != 0. */
+ EXTRACT_NUMBER_AND_INCR (k, p);
+ if (k == 0)
+ {
+ p -= 4;
+ succeed_n_p = true; /* Spaghetti code alert. */
+ goto handle_on_failure_jump;
+ }
+ continue;
+
+
+ case set_number_at:
+ p += 4;
+ continue;
+
+
+ case start_memory:
+ case stop_memory:
+ p += 2;
+ continue;
+
+
+ default:
+ abort (); /* We have listed all the cases. */
+ } /* switch *p++ */
+
+ /* Getting here means we have found the possible starting
+ characters for one path of the pattern -- and that the empty
+ string does not match. We need not follow this path further.
+ Instead, look at the next alternative (remembered on the
+ stack), or quit if no more. The test at the top of the loop
+ does these things. */
+ path_can_be_null = false;
+ p = pend;
+ } /* while p */
+
+ /* Set `can_be_null' for the last path (also the first path, if the
+ pattern is empty). */
+ bufp->can_be_null |= path_can_be_null;
+ return 0;
+} /* re_compile_fastmap */
+
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+ ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use
+ this memory for recording register information. STARTS and ENDS
+ must be allocated using the malloc library routine, and must each
+ be at least NUM_REGS * sizeof (regoff_t) bytes long.
+
+ If NUM_REGS == 0, then subsequent matches should allocate their own
+ register data.
+
+ Unless this function is called, the first search or match using
+ PATTERN_BUFFER will allocate its own register data, without
+ freeing the old data. */
+
+void
+re_set_registers (bufp, regs, num_regs, starts, ends)
+ struct re_pattern_buffer *bufp;
+ struct re_registers *regs;
+ unsigned num_regs;
+ regoff_t *starts, *ends;
+{
+ if (num_regs)
+ {
+ bufp->regs_allocated = REGS_REALLOCATE;
+ regs->num_regs = num_regs;
+ regs->start = starts;
+ regs->end = ends;
+ }
+ else
+ {
+ bufp->regs_allocated = REGS_UNALLOCATED;
+ regs->num_regs = 0;
+ regs->start = regs->end = (regoff_t *) 0;
+ }
+}
+
+/* Searching routines. */
+
+/* Like re_search_2, below, but only one string is specified, and
+ doesn't let you say where to stop matching. */
+
+int
+re_search (bufp, string, size, startpos, range, regs)
+ struct re_pattern_buffer *bufp;
+ const char *string;
+ int size, startpos, range;
+ struct re_registers *regs;
+{
+ return re_search_2 (bufp, NULL, 0, string, size, startpos, range,
+ regs, size);
+}
+
+
+/* Using the compiled pattern in BUFP->buffer, first tries to match the
+ virtual concatenation of STRING1 and STRING2, starting first at index
+ STARTPOS, then at STARTPOS + 1, and so on.
+
+ STRING1 and STRING2 have length SIZE1 and SIZE2, respectively.
+
+ RANGE is how far to scan while trying to match. RANGE = 0 means try
+ only at STARTPOS; in general, the last start tried is STARTPOS +
+ RANGE.
+
+ In REGS, return the indices of the virtual concatenation of STRING1
+ and STRING2 that matched the entire BUFP->buffer and its contained
+ subexpressions.
+
+ Do not consider matching one past the index STOP in the virtual
+ concatenation of STRING1 and STRING2.
+
+ We return either the position in the strings at which the match was
+ found, -1 if no match, or -2 if error (such as failure
+ stack overflow). */
+
+int
+re_search_2 (bufp, string1, size1, string2, size2, startpos, range, regs, stop)
+ struct re_pattern_buffer *bufp;
+ const char *string1, *string2;
+ int size1, size2;
+ int startpos;
+ int range;
+ struct re_registers *regs;
+ int stop;
+{
+ int val;
+ register char *fastmap = bufp->fastmap;
+ register char *translate = bufp->translate;
+ int total_size = size1 + size2;
+ int endpos = startpos + range;
+
+ /* Check for out-of-range STARTPOS. */
+ if (startpos < 0 || startpos > total_size)
+ return -1;
+
+ /* Fix up RANGE if it might eventually take us outside
+ the virtual concatenation of STRING1 and STRING2. */
+ if (endpos < -1)
+ range = -1 - startpos;
+ else if (endpos > total_size)
+ range = total_size - startpos;
+
+ /* If the search isn't to be a backwards one, don't waste time in a
+ search for a pattern that must be anchored. */
+ if (bufp->used > 0 && (re_opcode_t) bufp->buffer[0] == begbuf && range > 0)
+ {
+ if (startpos > 0)
+ return -1;
+ else
+ range = 1;
+ }
+
+ /* Update the fastmap now if not correct already. */
+ if (fastmap && !bufp->fastmap_accurate)
+ if (re_compile_fastmap (bufp) == -2)
+ return -2;
+
+ /* Loop through the string, looking for a place to start matching. */
+ for (;;)
+ {
+ /* If a fastmap is supplied, skip quickly over characters that
+ cannot be the start of a match. If the pattern can match the
+ null string, however, we don't need to skip characters; we want
+ the first null string. */
+ if (fastmap && startpos < total_size && !bufp->can_be_null)
+ {
+ if (range > 0) /* Searching forwards. */
+ {
+ register const char *d;
+ register int lim = 0;
+ int irange = range;
+
+ if (startpos < size1 && startpos + range >= size1)
+ lim = range - (size1 - startpos);
+
+ d = (startpos >= size1 ? string2 - size1 : string1) + startpos;
+
+ /* Written out as an if-else to avoid testing `translate'
+ inside the loop. */
+ if (translate)
+ while (range > lim
+ && !fastmap[(unsigned char)
+ translate[(unsigned char) *d++]])
+ range--;
+ else
+ while (range > lim && !fastmap[(unsigned char) *d++])
+ range--;
+
+ startpos += irange - range;
+ }
+ else /* Searching backwards. */
+ {
+ register char c = (size1 == 0 || startpos >= size1
+ ? string2[startpos - size1]
+ : string1[startpos]);
+
+ if (!fastmap[(unsigned char) TRANSLATE (c)])
+ goto advance;
+ }
+ }
+
+ /* If can't match the null string, and that's all we have left, fail. */
+ if (range >= 0 && startpos == total_size && fastmap
+ && !bufp->can_be_null)
+ return -1;
+
+ val = re_match_2_internal (bufp, string1, size1, string2, size2,
+ startpos, regs, stop);
+#ifndef REGEX_MALLOC
+#ifdef C_ALLOCA
+ alloca (0);
+#endif
+#endif
+
+ if (val >= 0)
+ return startpos;
+
+ if (val == -2)
+ return -2;
+
+ advance:
+ if (!range)
+ break;
+ else if (range > 0)
+ {
+ range--;
+ startpos++;
+ }
+ else
+ {
+ range++;
+ startpos--;
+ }
+ }
+ return -1;
+} /* re_search_2 */
+
+/* Declarations and macros for re_match_2. */
+
+static int bcmp_translate ();
+static boolean alt_match_null_string_p (),
+ common_op_match_null_string_p (),
+ group_match_null_string_p ();
+
+/* This converts PTR, a pointer into one of the search strings `string1'
+ and `string2' into an offset from the beginning of that string. */
+#define POINTER_TO_OFFSET(ptr) \
+ (FIRST_STRING_P (ptr) \
+ ? ((regoff_t) ((ptr) - string1)) \
+ : ((regoff_t) ((ptr) - string2 + size1)))
+
+/* Macros for dealing with the split strings in re_match_2. */
+
+#define MATCHING_IN_FIRST_STRING (dend == end_match_1)
+
+/* Call before fetching a character with *d. This switches over to
+ string2 if necessary. */
+#define PREFETCH() \
+ while (d == dend) \
+ { \
+ /* End of string2 => fail. */ \
+ if (dend == end_match_2) \
+ goto fail; \
+ /* End of string1 => advance to string2. */ \
+ d = string2; \
+ dend = end_match_2; \
+ }
+
+
+/* Test if at very beginning or at very end of the virtual concatenation
+ of `string1' and `string2'. If only one string, it's `string2'. */
+#define AT_STRINGS_BEG(d) ((d) == (size1 ? string1 : string2) || !size2)
+#define AT_STRINGS_END(d) ((d) == end2)
+
+
+/* Test if D points to a character which is word-constituent. We have
+ two special cases to check for: if past the end of string1, look at
+ the first character in string2; and if before the beginning of
+ string2, look at the last character in string1. */
+#define WORDCHAR_P(d) \
+ (SYNTAX ((d) == end1 ? *string2 \
+ : (d) == string2 - 1 ? *(end1 - 1) : *(d)) \
+ == Sword)
+
+/* Test if the character before D and the one at D differ with respect
+ to being word-constituent. */
+#define AT_WORD_BOUNDARY(d) \
+ (AT_STRINGS_BEG (d) || AT_STRINGS_END (d) \
+ || WORDCHAR_P (d - 1) != WORDCHAR_P (d))
+
+
+/* Free everything we malloc. */
+#ifdef MATCH_MAY_ALLOCATE
+#ifdef REGEX_MALLOC
+#define FREE_VAR(var) if (var) free (var); var = NULL
+#define FREE_VARIABLES() \
+ do { \
+ FREE_VAR (fail_stack.stack); \
+ FREE_VAR (regstart); \
+ FREE_VAR (regend); \
+ FREE_VAR (old_regstart); \
+ FREE_VAR (old_regend); \
+ FREE_VAR (best_regstart); \
+ FREE_VAR (best_regend); \
+ FREE_VAR (reg_info); \
+ FREE_VAR (reg_dummy); \
+ FREE_VAR (reg_info_dummy); \
+ } while (0)
+#else /* not REGEX_MALLOC */
+/* This used to do alloca (0), but now we do that in the caller. */
+#define FREE_VARIABLES() /* Nothing */
+#endif /* not REGEX_MALLOC */
+#else
+#define FREE_VARIABLES() /* Do nothing! */
+#endif /* not MATCH_MAY_ALLOCATE */
+
+/* These values must meet several constraints. They must not be valid
+ register values; since we have a limit of 255 registers (because
+ we use only one byte in the pattern for the register number), we can
+ use numbers larger than 255. They must differ by 1, because of
+ NUM_FAILURE_ITEMS above. And the value for the lowest register must
+ be larger than the value for the highest register, so we do not try
+ to actually save any registers when none are active. */
+#define NO_HIGHEST_ACTIVE_REG (1 << BYTEWIDTH)
+#define NO_LOWEST_ACTIVE_REG (NO_HIGHEST_ACTIVE_REG + 1)
+
+/* Matching routines. */
+
+#ifndef emacs /* Emacs never uses this. */
+/* re_match is like re_match_2 except it takes only a single string. */
+
+int
+re_match (bufp, string, size, pos, regs)
+ struct re_pattern_buffer *bufp;
+ const char *string;
+ int size, pos;
+ struct re_registers *regs;
+{
+ int result = re_match_2_internal (bufp, NULL, 0, string, size,
+ pos, regs, size);
+ alloca (0);
+ return result;
+}
+#endif /* not emacs */
+
+
+/* re_match_2 matches the compiled pattern in BUFP against the
+ the (virtual) concatenation of STRING1 and STRING2 (of length SIZE1
+ and SIZE2, respectively). We start matching at POS, and stop
+ matching at STOP.
+
+ If REGS is non-null and the `no_sub' field of BUFP is nonzero, we
+ store offsets for the substring each group matched in REGS. See the
+ documentation for exactly how many groups we fill.
+
+ We return -1 if no match, -2 if an internal error (such as the
+ failure stack overflowing). Otherwise, we return the length of the
+ matched substring. */
+
+int
+re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop)
+ struct re_pattern_buffer *bufp;
+ const char *string1, *string2;
+ int size1, size2;
+ int pos;
+ struct re_registers *regs;
+ int stop;
+{
+ int result = re_match_2_internal (bufp, string1, size1, string2, size2,
+ pos, regs, stop);
+ alloca (0);
+ return result;
+}
+
+/* This is a separate function so that we can force an alloca cleanup
+ afterwards. */
+static int
+re_match_2_internal (bufp, string1, size1, string2, size2, pos, regs, stop)
+ struct re_pattern_buffer *bufp;
+ const char *string1, *string2;
+ int size1, size2;
+ int pos;
+ struct re_registers *regs;
+ int stop;
+{
+ /* General temporaries. */
+ int mcnt;
+ unsigned char *p1;
+
+ /* Just past the end of the corresponding string. */
+ const char *end1, *end2;
+
+ /* Pointers into string1 and string2, just past the last characters in
+ each to consider matching. */
+ const char *end_match_1, *end_match_2;
+
+ /* Where we are in the data, and the end of the current string. */
+ const char *d, *dend;
+
+ /* Where we are in the pattern, and the end of the pattern. */
+ unsigned char *p = bufp->buffer;
+ register unsigned char *pend = p + bufp->used;
+
+ /* Mark the opcode just after a start_memory, so we can test for an
+ empty subpattern when we get to the stop_memory. */
+ unsigned char *just_past_start_mem = 0;
+
+ /* We use this to map every character in the string. */
+ char *translate = bufp->translate;
+
+ /* Failure point stack. Each place that can handle a failure further
+ down the line pushes a failure point on this stack. It consists of
+ restart, regend, and reg_info for all registers corresponding to
+ the subexpressions we're currently inside, plus the number of such
+ registers, and, finally, two char *'s. The first char * is where
+ to resume scanning the pattern; the second one is where to resume
+ scanning the strings. If the latter is zero, the failure point is
+ a ``dummy''; if a failure happens and the failure point is a dummy,
+ it gets discarded and the next next one is tried. */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */
+ fail_stack_type fail_stack;
+#endif
+#ifdef DEBUG
+ static unsigned failure_id = 0;
+ unsigned nfailure_points_pushed = 0, nfailure_points_popped = 0;
+#endif
+
+ /* We fill all the registers internally, independent of what we
+ return, for use in backreferences. The number here includes
+ an element for register zero. */
+ unsigned num_regs = bufp->re_nsub + 1;
+
+ /* The currently active registers. */
+ unsigned lowest_active_reg = NO_LOWEST_ACTIVE_REG;
+ unsigned highest_active_reg = NO_HIGHEST_ACTIVE_REG;
+
+ /* Information on the contents of registers. These are pointers into
+ the input strings; they record just what was matched (on this
+ attempt) by a subexpression part of the pattern, that is, the
+ regnum-th regstart pointer points to where in the pattern we began
+ matching and the regnum-th regend points to right after where we
+ stopped matching the regnum-th subexpression. (The zeroth register
+ keeps track of what the whole pattern matches.) */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
+ const char **regstart, **regend;
+#endif
+
+ /* If a group that's operated upon by a repetition operator fails to
+ match anything, then the register for its start will need to be
+ restored because it will have been set to wherever in the string we
+ are when we last see its open-group operator. Similarly for a
+ register's end. */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
+ const char **old_regstart, **old_regend;
+#endif
+
+ /* The is_active field of reg_info helps us keep track of which (possibly
+ nested) subexpressions we are currently in. The matched_something
+ field of reg_info[reg_num] helps us tell whether or not we have
+ matched any of the pattern so far this time through the reg_num-th
+ subexpression. These two fields get reset each time through any
+ loop their register is in. */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, this is global. */
+ register_info_type *reg_info;
+#endif
+
+ /* The following record the register info as found in the above
+ variables when we find a match better than any we've seen before.
+ This happens as we backtrack through the failure points, which in
+ turn happens only if we have not yet matched the entire string. */
+ unsigned best_regs_set = false;
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
+ const char **best_regstart, **best_regend;
+#endif
+
+ /* Logically, this is `best_regend[0]'. But we don't want to have to
+ allocate space for that if we're not allocating space for anything
+ else (see below). Also, we never need info about register 0 for
+ any of the other register vectors, and it seems rather a kludge to
+ treat `best_regend' differently than the rest. So we keep track of
+ the end of the best match so far in a separate variable. We
+ initialize this to NULL so that when we backtrack the first time
+ and need to test it, it's not garbage. */
+ const char *match_end = NULL;
+
+ /* Used when we pop values we don't care about. */
+#ifdef MATCH_MAY_ALLOCATE /* otherwise, these are global. */
+ const char **reg_dummy;
+ register_info_type *reg_info_dummy;
+#endif
+
+#ifdef DEBUG
+ /* Counts the total number of registers pushed. */
+ unsigned num_regs_pushed = 0;
+#endif
+
+ DEBUG_PRINT1 ("\n\nEntering re_match_2.\n");
+
+ INIT_FAIL_STACK ();
+
+#ifdef MATCH_MAY_ALLOCATE
+ /* Do not bother to initialize all the register variables if there are
+ no groups in the pattern, as it takes a fair amount of time. If
+ there are groups, we include space for register 0 (the whole
+ pattern), even though we never use it, since it simplifies the
+ array indexing. We should fix this. */
+ if (bufp->re_nsub)
+ {
+ regstart = REGEX_TALLOC (num_regs, const char *);
+ regend = REGEX_TALLOC (num_regs, const char *);
+ old_regstart = REGEX_TALLOC (num_regs, const char *);
+ old_regend = REGEX_TALLOC (num_regs, const char *);
+ best_regstart = REGEX_TALLOC (num_regs, const char *);
+ best_regend = REGEX_TALLOC (num_regs, const char *);
+ reg_info = REGEX_TALLOC (num_regs, register_info_type);
+ reg_dummy = REGEX_TALLOC (num_regs, const char *);
+ reg_info_dummy = REGEX_TALLOC (num_regs, register_info_type);
+
+ if (!(regstart && regend && old_regstart && old_regend && reg_info
+ && best_regstart && best_regend && reg_dummy && reg_info_dummy))
+ {
+ FREE_VARIABLES ();
+ return -2;
+ }
+ }
+#if defined (REGEX_MALLOC)
+ else
+ {
+ /* We must initialize all our variables to NULL, so that
+ `FREE_VARIABLES' doesn't try to free them. */
+ regstart = regend = old_regstart = old_regend = best_regstart
+ = best_regend = reg_dummy = NULL;
+ reg_info = reg_info_dummy = (register_info_type *) NULL;
+ }
+#endif /* REGEX_MALLOC */
+#endif /* MATCH_MAY_ALLOCATE */
+
+ /* The starting position is bogus. */
+ if (pos < 0 || pos > size1 + size2)
+ {
+ FREE_VARIABLES ();
+ return -1;
+ }
+
+ /* Initialize subexpression text positions to -1 to mark ones that no
+ start_memory/stop_memory has been seen for. Also initialize the
+ register information struct. */
+ for (mcnt = 1; mcnt < num_regs; mcnt++)
+ {
+ regstart[mcnt] = regend[mcnt]
+ = old_regstart[mcnt] = old_regend[mcnt] = REG_UNSET_VALUE;
+
+ REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE;
+ IS_ACTIVE (reg_info[mcnt]) = 0;
+ MATCHED_SOMETHING (reg_info[mcnt]) = 0;
+ EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0;
+ }
+
+ /* We move `string1' into `string2' if the latter's empty -- but not if
+ `string1' is null. */
+ if (size2 == 0 && string1 != NULL)
+ {
+ string2 = string1;
+ size2 = size1;
+ string1 = 0;
+ size1 = 0;
+ }
+ end1 = string1 + size1;
+ end2 = string2 + size2;
+
+ /* Compute where to stop matching, within the two strings. */
+ if (stop <= size1)
+ {
+ end_match_1 = string1 + stop;
+ end_match_2 = string2;
+ }
+ else
+ {
+ end_match_1 = end1;
+ end_match_2 = string2 + stop - size1;
+ }
+
+ /* `p' scans through the pattern as `d' scans through the data.
+ `dend' is the end of the input string that `d' points within. `d'
+ is advanced into the following input string whenever necessary, but
+ this happens before fetching; therefore, at the beginning of the
+ loop, `d' can be pointing at the end of a string, but it cannot
+ equal `string2'. */
+ if (size1 > 0 && pos <= size1)
+ {
+ d = string1 + pos;
+ dend = end_match_1;
+ }
+ else
+ {
+ d = string2 + pos - size1;
+ dend = end_match_2;
+ }
+
+ DEBUG_PRINT1 ("The compiled pattern is: ");
+ DEBUG_PRINT_COMPILED_PATTERN (bufp, p, pend);
+ DEBUG_PRINT1 ("The string to match is: `");
+ DEBUG_PRINT_DOUBLE_STRING (d, string1, size1, string2, size2);
+ DEBUG_PRINT1 ("'\n");
+
+ /* This loops over pattern commands. It exits by returning from the
+ function if the match is complete, or it drops through if the match
+ fails at this starting point in the input data. */
+ for (;;)
+ {
+ DEBUG_PRINT2 ("\n0x%x: ", p);
+
+ if (p == pend)
+ { /* End of pattern means we might have succeeded. */
+ DEBUG_PRINT1 ("end of pattern ... ");
+
+ /* If we haven't matched the entire string, and we want the
+ longest match, try backtracking. */
+ if (d != end_match_2)
+ {
+ /* 1 if this match ends in the same string (string1 or string2)
+ as the best previous match. */
+ boolean same_str_p = (FIRST_STRING_P (match_end)
+ == MATCHING_IN_FIRST_STRING);
+ /* 1 if this match is the best seen so far. */
+ boolean best_match_p;
+
+ /* AIX compiler got confused when this was combined
+ with the previous declaration. */
+ if (same_str_p)
+ best_match_p = d > match_end;
+ else
+ best_match_p = !MATCHING_IN_FIRST_STRING;
+
+ DEBUG_PRINT1 ("backtracking.\n");
+
+ if (!FAIL_STACK_EMPTY ())
+ { /* More failure points to try. */
+
+ /* If exceeds best match so far, save it. */
+ if (!best_regs_set || best_match_p)
+ {
+ best_regs_set = true;
+ match_end = d;
+
+ DEBUG_PRINT1 ("\nSAVING match as best so far.\n");
+
+ for (mcnt = 1; mcnt < num_regs; mcnt++)
+ {
+ best_regstart[mcnt] = regstart[mcnt];
+ best_regend[mcnt] = regend[mcnt];
+ }
+ }
+ goto fail;
+ }
+
+ /* If no failure points, don't restore garbage. And if
+ last match is real best match, don't restore second
+ best one. */
+ else if (best_regs_set && !best_match_p)
+ {
+ restore_best_regs:
+ /* Restore best match. It may happen that `dend ==
+ end_match_1' while the restored d is in string2.
+ For example, the pattern `x.*y.*z' against the
+ strings `x-' and `y-z-', if the two strings are
+ not consecutive in memory. */
+ DEBUG_PRINT1 ("Restoring best registers.\n");
+
+ d = match_end;
+ dend = ((d >= string1 && d <= end1)
+ ? end_match_1 : end_match_2);
+
+ for (mcnt = 1; mcnt < num_regs; mcnt++)
+ {
+ regstart[mcnt] = best_regstart[mcnt];
+ regend[mcnt] = best_regend[mcnt];
+ }
+ }
+ } /* d != end_match_2 */
+
+ DEBUG_PRINT1 ("Accepting match.\n");
+
+ /* If caller wants register contents data back, do it. */
+ if (regs && !bufp->no_sub)
+ {
+ /* Have the register data arrays been allocated? */
+ if (bufp->regs_allocated == REGS_UNALLOCATED)
+ { /* No. So allocate them with malloc. We need one
+ extra element beyond `num_regs' for the `-1' marker
+ GNU code uses. */
+ regs->num_regs = MAX (RE_NREGS, num_regs + 1);
+ regs->start = TALLOC (regs->num_regs, regoff_t);
+ regs->end = TALLOC (regs->num_regs, regoff_t);
+ if (regs->start == NULL || regs->end == NULL)
+ return -2;
+ bufp->regs_allocated = REGS_REALLOCATE;
+ }
+ else if (bufp->regs_allocated == REGS_REALLOCATE)
+ { /* Yes. If we need more elements than were already
+ allocated, reallocate them. If we need fewer, just
+ leave it alone. */
+ if (regs->num_regs < num_regs + 1)
+ {
+ regs->num_regs = num_regs + 1;
+ RETALLOC (regs->start, regs->num_regs, regoff_t);
+ RETALLOC (regs->end, regs->num_regs, regoff_t);
+ if (regs->start == NULL || regs->end == NULL)
+ return -2;
+ }
+ }
+ else
+ {
+ /* These braces fend off a "empty body in an else-statement"
+ warning under GCC when assert expands to nothing. */
+ assert (bufp->regs_allocated == REGS_FIXED);
+ }
+
+ /* Convert the pointer data in `regstart' and `regend' to
+ indices. Register zero has to be set differently,
+ since we haven't kept track of any info for it. */
+ if (regs->num_regs > 0)
+ {
+ regs->start[0] = pos;
+ regs->end[0] = (MATCHING_IN_FIRST_STRING
+ ? ((regoff_t) (d - string1))
+ : ((regoff_t) (d - string2 + size1)));
+ }
+
+ /* Go through the first `min (num_regs, regs->num_regs)'
+ registers, since that is all we initialized. */
+ for (mcnt = 1; mcnt < MIN (num_regs, regs->num_regs); mcnt++)
+ {
+ if (REG_UNSET (regstart[mcnt]) || REG_UNSET (regend[mcnt]))
+ regs->start[mcnt] = regs->end[mcnt] = -1;
+ else
+ {
+ regs->start[mcnt]
+ = (regoff_t) POINTER_TO_OFFSET (regstart[mcnt]);
+ regs->end[mcnt]
+ = (regoff_t) POINTER_TO_OFFSET (regend[mcnt]);
+ }
+ }
+
+ /* If the regs structure we return has more elements than
+ were in the pattern, set the extra elements to -1. If
+ we (re)allocated the registers, this is the case,
+ because we always allocate enough to have at least one
+ -1 at the end. */
+ for (mcnt = num_regs; mcnt < regs->num_regs; mcnt++)
+ regs->start[mcnt] = regs->end[mcnt] = -1;
+ } /* regs && !bufp->no_sub */
+
+ FREE_VARIABLES ();
+ DEBUG_PRINT4 ("%u failure points pushed, %u popped (%u remain).\n",
+ nfailure_points_pushed, nfailure_points_popped,
+ nfailure_points_pushed - nfailure_points_popped);
+ DEBUG_PRINT2 ("%u registers pushed.\n", num_regs_pushed);
+
+ mcnt = d - pos - (MATCHING_IN_FIRST_STRING
+ ? string1
+ : string2 - size1);
+
+ DEBUG_PRINT2 ("Returning %d from re_match_2.\n", mcnt);
+
+ return mcnt;
+ }
+
+ /* Otherwise match next pattern command. */
+#ifdef SWITCH_ENUM_BUG
+ switch ((int) ((re_opcode_t) *p++))
+#else
+ switch ((re_opcode_t) *p++)
+#endif
+ {
+ /* Ignore these. Used to ignore the n of succeed_n's which
+ currently have n == 0. */
+ case no_op:
+ DEBUG_PRINT1 ("EXECUTING no_op.\n");
+ break;
+
+
+ /* Match the next n pattern characters exactly. The following
+ byte in the pattern defines n, and the n bytes after that
+ are the characters to match. */
+ case exactn:
+ mcnt = *p++;
+ DEBUG_PRINT2 ("EXECUTING exactn %d.\n", mcnt);
+
+ /* This is written out as an if-else so we don't waste time
+ testing `translate' inside the loop. */
+ if (translate)
+ {
+ do
+ {
+ PREFETCH ();
+ if (translate[(unsigned char) *d++] != (char) *p++)
+ goto fail;
+ }
+ while (--mcnt);
+ }
+ else
+ {
+ do
+ {
+ PREFETCH ();
+ if (*d++ != (char) *p++) goto fail;
+ }
+ while (--mcnt);
+ }
+ SET_REGS_MATCHED ();
+ break;
+
+
+ /* Match any character except possibly a newline or a null. */
+ case anychar:
+ DEBUG_PRINT1 ("EXECUTING anychar.\n");
+
+ PREFETCH ();
+
+ if ((!(bufp->syntax & RE_DOT_NEWLINE) && TRANSLATE (*d) == '\n')
+ || (bufp->syntax & RE_DOT_NOT_NULL && TRANSLATE (*d) == '\000'))
+ goto fail;
+
+ SET_REGS_MATCHED ();
+ DEBUG_PRINT2 (" Matched `%d'.\n", *d);
+ d++;
+ break;
+
+
+ case charset:
+ case charset_not:
+ {
+ register unsigned char c;
+ boolean not = (re_opcode_t) *(p - 1) == charset_not;
+
+ DEBUG_PRINT2 ("EXECUTING charset%s.\n", not ? "_not" : "");
+
+ PREFETCH ();
+ c = TRANSLATE (*d); /* The character to match. */
+
+ /* Cast to `unsigned' instead of `unsigned char' in case the
+ bit list is a full 32 bytes long. */
+ if (c < (unsigned) (*p * BYTEWIDTH)
+ && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
+ not = !not;
+
+ p += 1 + *p;
+
+ if (!not) goto fail;
+
+ SET_REGS_MATCHED ();
+ d++;
+ break;
+ }
+
+
+ /* The beginning of a group is represented by start_memory.
+ The arguments are the register number in the next byte, and the
+ number of groups inner to this one in the next. The text
+ matched within the group is recorded (in the internal
+ registers data structure) under the register number. */
+ case start_memory:
+ DEBUG_PRINT3 ("EXECUTING start_memory %d (%d):\n", *p, p[1]);
+
+ /* Find out if this group can match the empty string. */
+ p1 = p; /* To send to group_match_null_string_p. */
+
+ if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE)
+ REG_MATCH_NULL_STRING_P (reg_info[*p])
+ = group_match_null_string_p (&p1, pend, reg_info);
+
+ /* Save the position in the string where we were the last time
+ we were at this open-group operator in case the group is
+ operated upon by a repetition operator, e.g., with `(a*)*b'
+ against `ab'; then we want to ignore where we are now in
+ the string in case this attempt to match fails. */
+ old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
+ ? REG_UNSET (regstart[*p]) ? d : regstart[*p]
+ : regstart[*p];
+ DEBUG_PRINT2 (" old_regstart: %d\n",
+ POINTER_TO_OFFSET (old_regstart[*p]));
+
+ regstart[*p] = d;
+ DEBUG_PRINT2 (" regstart: %d\n", POINTER_TO_OFFSET (regstart[*p]));
+
+ IS_ACTIVE (reg_info[*p]) = 1;
+ MATCHED_SOMETHING (reg_info[*p]) = 0;
+
+ /* This is the new highest active register. */
+ highest_active_reg = *p;
+
+ /* If nothing was active before, this is the new lowest active
+ register. */
+ if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
+ lowest_active_reg = *p;
+
+ /* Move past the register number and inner group count. */
+ p += 2;
+ just_past_start_mem = p;
+ break;
+
+
+ /* The stop_memory opcode represents the end of a group. Its
+ arguments are the same as start_memory's: the register
+ number, and the number of inner groups. */
+ case stop_memory:
+ DEBUG_PRINT3 ("EXECUTING stop_memory %d (%d):\n", *p, p[1]);
+
+ /* We need to save the string position the last time we were at
+ this close-group operator in case the group is operated
+ upon by a repetition operator, e.g., with `((a*)*(b*)*)*'
+ against `aba'; then we want to ignore where we are now in
+ the string in case this attempt to match fails. */
+ old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p])
+ ? REG_UNSET (regend[*p]) ? d : regend[*p]
+ : regend[*p];
+ DEBUG_PRINT2 (" old_regend: %d\n",
+ POINTER_TO_OFFSET (old_regend[*p]));
+
+ regend[*p] = d;
+ DEBUG_PRINT2 (" regend: %d\n", POINTER_TO_OFFSET (regend[*p]));
+
+ /* This register isn't active anymore. */
+ IS_ACTIVE (reg_info[*p]) = 0;
+
+ /* If this was the only register active, nothing is active
+ anymore. */
+ if (lowest_active_reg == highest_active_reg)
+ {
+ lowest_active_reg = NO_LOWEST_ACTIVE_REG;
+ highest_active_reg = NO_HIGHEST_ACTIVE_REG;
+ }
+ else
+ { /* We must scan for the new highest active register, since
+ it isn't necessarily one less than now: consider
+ (a(b)c(d(e)f)g). When group 3 ends, after the f), the
+ new highest active register is 1. */
+ unsigned char r = *p - 1;
+ while (r > 0 && !IS_ACTIVE (reg_info[r]))
+ r--;
+
+ /* If we end up at register zero, that means that we saved
+ the registers as the result of an `on_failure_jump', not
+ a `start_memory', and we jumped to past the innermost
+ `stop_memory'. For example, in ((.)*) we save
+ registers 1 and 2 as a result of the *, but when we pop
+ back to the second ), we are at the stop_memory 1.
+ Thus, nothing is active. */
+ if (r == 0)
+ {
+ lowest_active_reg = NO_LOWEST_ACTIVE_REG;
+ highest_active_reg = NO_HIGHEST_ACTIVE_REG;
+ }
+ else
+ highest_active_reg = r;
+ }
+
+ /* If just failed to match something this time around with a
+ group that's operated on by a repetition operator, try to
+ force exit from the ``loop'', and restore the register
+ information for this group that we had before trying this
+ last match. */
+ if ((!MATCHED_SOMETHING (reg_info[*p])
+ || just_past_start_mem == p - 1)
+ && (p + 2) < pend)
+ {
+ boolean is_a_jump_n = false;
+
+ p1 = p + 2;
+ mcnt = 0;
+ switch ((re_opcode_t) *p1++)
+ {
+ case jump_n:
+ is_a_jump_n = true;
+ case pop_failure_jump:
+ case maybe_pop_jump:
+ case jump:
+ case dummy_failure_jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ if (is_a_jump_n)
+ p1 += 2;
+ break;
+
+ default:
+ /* do nothing */ ;
+ }
+ p1 += mcnt;
+
+ /* If the next operation is a jump backwards in the pattern
+ to an on_failure_jump right before the start_memory
+ corresponding to this stop_memory, exit from the loop
+ by forcing a failure after pushing on the stack the
+ on_failure_jump's jump in the pattern, and d. */
+ if (mcnt < 0 && (re_opcode_t) *p1 == on_failure_jump
+ && (re_opcode_t) p1[3] == start_memory && p1[4] == *p)
+ {
+ /* If this group ever matched anything, then restore
+ what its registers were before trying this last
+ failed match, e.g., with `(a*)*b' against `ab' for
+ regstart[1], and, e.g., with `((a*)*(b*)*)*'
+ against `aba' for regend[3].
+
+ Also restore the registers for inner groups for,
+ e.g., `((a*)(b*))*' against `aba' (register 3 would
+ otherwise get trashed). */
+
+ if (EVER_MATCHED_SOMETHING (reg_info[*p]))
+ {
+ unsigned r;
+
+ EVER_MATCHED_SOMETHING (reg_info[*p]) = 0;
+
+ /* Restore this and inner groups' (if any) registers. */
+ for (r = *p; r < *p + *(p + 1); r++)
+ {
+ regstart[r] = old_regstart[r];
+
+ /* xx why this test? */
+ if ((int) old_regend[r] >= (int) regstart[r])
+ regend[r] = old_regend[r];
+ }
+ }
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ PUSH_FAILURE_POINT (p1 + mcnt, d, -2);
+
+ goto fail;
+ }
+ }
+
+ /* Move past the register number and the inner group count. */
+ p += 2;
+ break;
+
+
+ /* \<digit> has been turned into a `duplicate' command which is
+ followed by the numeric value of <digit> as the register number. */
+ case duplicate:
+ {
+ register const char *d2, *dend2;
+ int regno = *p++; /* Get which register to match against. */
+ DEBUG_PRINT2 ("EXECUTING duplicate %d.\n", regno);
+
+ /* Can't back reference a group which we've never matched. */
+ if (REG_UNSET (regstart[regno]) || REG_UNSET (regend[regno]))
+ goto fail;
+
+ /* Where in input to try to start matching. */
+ d2 = regstart[regno];
+
+ /* Where to stop matching; if both the place to start and
+ the place to stop matching are in the same string, then
+ set to the place to stop, otherwise, for now have to use
+ the end of the first string. */
+
+ dend2 = ((FIRST_STRING_P (regstart[regno])
+ == FIRST_STRING_P (regend[regno]))
+ ? regend[regno] : end_match_1);
+ for (;;)
+ {
+ /* If necessary, advance to next segment in register
+ contents. */
+ while (d2 == dend2)
+ {
+ if (dend2 == end_match_2) break;
+ if (dend2 == regend[regno]) break;
+
+ /* End of string1 => advance to string2. */
+ d2 = string2;
+ dend2 = regend[regno];
+ }
+ /* At end of register contents => success */
+ if (d2 == dend2) break;
+
+ /* If necessary, advance to next segment in data. */
+ PREFETCH ();
+
+ /* How many characters left in this segment to match. */
+ mcnt = dend - d;
+
+ /* Want how many consecutive characters we can match in
+ one shot, so, if necessary, adjust the count. */
+ if (mcnt > dend2 - d2)
+ mcnt = dend2 - d2;
+
+ /* Compare that many; failure if mismatch, else move
+ past them. */
+ if (translate
+ ? bcmp_translate (d, d2, mcnt, translate)
+ : bcmp (d, d2, mcnt))
+ goto fail;
+ d += mcnt, d2 += mcnt;
+ }
+ }
+ break;
+
+
+ /* begline matches the empty string at the beginning of the string
+ (unless `not_bol' is set in `bufp'), and, if
+ `newline_anchor' is set, after newlines. */
+ case begline:
+ DEBUG_PRINT1 ("EXECUTING begline.\n");
+
+ if (AT_STRINGS_BEG (d))
+ {
+ if (!bufp->not_bol) break;
+ }
+ else if (d[-1] == '\n' && bufp->newline_anchor)
+ {
+ break;
+ }
+ /* In all other cases, we fail. */
+ goto fail;
+
+
+ /* endline is the dual of begline. */
+ case endline:
+ DEBUG_PRINT1 ("EXECUTING endline.\n");
+
+ if (AT_STRINGS_END (d))
+ {
+ if (!bufp->not_eol) break;
+ }
+
+ /* We have to ``prefetch'' the next character. */
+ else if ((d == end1 ? *string2 : *d) == '\n'
+ && bufp->newline_anchor)
+ {
+ break;
+ }
+ goto fail;
+
+
+ /* Match at the very beginning of the data. */
+ case begbuf:
+ DEBUG_PRINT1 ("EXECUTING begbuf.\n");
+ if (AT_STRINGS_BEG (d))
+ break;
+ goto fail;
+
+
+ /* Match at the very end of the data. */
+ case endbuf:
+ DEBUG_PRINT1 ("EXECUTING endbuf.\n");
+ if (AT_STRINGS_END (d))
+ break;
+ goto fail;
+
+
+ /* on_failure_keep_string_jump is used to optimize `.*\n'. It
+ pushes NULL as the value for the string on the stack. Then
+ `pop_failure_point' will keep the current value for the
+ string, instead of restoring it. To see why, consider
+ matching `foo\nbar' against `.*\n'. The .* matches the foo;
+ then the . fails against the \n. But the next thing we want
+ to do is match the \n against the \n; if we restored the
+ string value, we would be back at the foo.
+
+ Because this is used only in specific cases, we don't need to
+ check all the things that `on_failure_jump' does, to make
+ sure the right things get saved on the stack. Hence we don't
+ share its code. The only reason to push anything on the
+ stack at all is that otherwise we would have to change
+ `anychar's code to do something besides goto fail in this
+ case; that seems worse than this. */
+ case on_failure_keep_string_jump:
+ DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump");
+
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ DEBUG_PRINT3 (" %d (to 0x%x):\n", mcnt, p + mcnt);
+
+ PUSH_FAILURE_POINT (p + mcnt, NULL, -2);
+ break;
+
+
+ /* Uses of on_failure_jump:
+
+ Each alternative starts with an on_failure_jump that points
+ to the beginning of the next alternative. Each alternative
+ except the last ends with a jump that in effect jumps past
+ the rest of the alternatives. (They really jump to the
+ ending jump of the following alternative, because tensioning
+ these jumps is a hassle.)
+
+ Repeats start with an on_failure_jump that points past both
+ the repetition text and either the following jump or
+ pop_failure_jump back to this on_failure_jump. */
+ case on_failure_jump:
+ on_failure:
+ DEBUG_PRINT1 ("EXECUTING on_failure_jump");
+
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ DEBUG_PRINT3 (" %d (to 0x%x)", mcnt, p + mcnt);
+
+ /* If this on_failure_jump comes right before a group (i.e.,
+ the original * applied to a group), save the information
+ for that group and all inner ones, so that if we fail back
+ to this point, the group's information will be correct.
+ For example, in \(a*\)*\1, we need the preceding group,
+ and in \(\(a*\)b*\)\2, we need the inner group. */
+
+ /* We can't use `p' to check ahead because we push
+ a failure point to `p + mcnt' after we do this. */
+ p1 = p;
+
+ /* We need to skip no_op's before we look for the
+ start_memory in case this on_failure_jump is happening as
+ the result of a completed succeed_n, as in \(a\)\{1,3\}b\1
+ against aba. */
+ while (p1 < pend && (re_opcode_t) *p1 == no_op)
+ p1++;
+
+ if (p1 < pend && (re_opcode_t) *p1 == start_memory)
+ {
+ /* We have a new highest active register now. This will
+ get reset at the start_memory we are about to get to,
+ but we will have saved all the registers relevant to
+ this repetition op, as described above. */
+ highest_active_reg = *(p1 + 1) + *(p1 + 2);
+ if (lowest_active_reg == NO_LOWEST_ACTIVE_REG)
+ lowest_active_reg = *(p1 + 1);
+ }
+
+ DEBUG_PRINT1 (":\n");
+ PUSH_FAILURE_POINT (p + mcnt, d, -2);
+ break;
+
+
+ /* A smart repeat ends with `maybe_pop_jump'.
+ We change it to either `pop_failure_jump' or `jump'. */
+ case maybe_pop_jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ DEBUG_PRINT2 ("EXECUTING maybe_pop_jump %d.\n", mcnt);
+ {
+ register unsigned char *p2 = p;
+
+ /* Compare the beginning of the repeat with what in the
+ pattern follows its end. If we can establish that there
+ is nothing that they would both match, i.e., that we
+ would have to backtrack because of (as in, e.g., `a*a')
+ then we can change to pop_failure_jump, because we'll
+ never have to backtrack.
+
+ This is not true in the case of alternatives: in
+ `(a|ab)*' we do need to backtrack to the `ab' alternative
+ (e.g., if the string was `ab'). But instead of trying to
+ detect that here, the alternative has put on a dummy
+ failure point which is what we will end up popping. */
+
+ /* Skip over open/close-group commands.
+ If what follows this loop is a ...+ construct,
+ look at what begins its body, since we will have to
+ match at least one of that. */
+ while (1)
+ {
+ if (p2 + 2 < pend
+ && ((re_opcode_t) *p2 == stop_memory
+ || (re_opcode_t) *p2 == start_memory))
+ p2 += 3;
+ else if (p2 + 6 < pend
+ && (re_opcode_t) *p2 == dummy_failure_jump)
+ p2 += 6;
+ else
+ break;
+ }
+
+ p1 = p + mcnt;
+ /* p1[0] ... p1[2] are the `on_failure_jump' corresponding
+ to the `maybe_finalize_jump' of this case. Examine what
+ follows. */
+
+ /* If we're at the end of the pattern, we can change. */
+ if (p2 == pend)
+ {
+ /* Consider what happens when matching ":\(.*\)"
+ against ":/". I don't really understand this code
+ yet. */
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1
+ (" End of pattern: change to `pop_failure_jump'.\n");
+ }
+
+ else if ((re_opcode_t) *p2 == exactn
+ || (bufp->newline_anchor && (re_opcode_t) *p2 == endline))
+ {
+ register unsigned char c
+ = *p2 == (unsigned char) endline ? '\n' : p2[2];
+
+ if ((re_opcode_t) p1[3] == exactn && p1[5] != c)
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n",
+ c, p1[5]);
+ }
+
+ else if ((re_opcode_t) p1[3] == charset
+ || (re_opcode_t) p1[3] == charset_not)
+ {
+ int not = (re_opcode_t) p1[3] == charset_not;
+
+ if (c < (unsigned char) (p1[4] * BYTEWIDTH)
+ && p1[5 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH)))
+ not = !not;
+
+ /* `not' is equal to 1 if c would match, which means
+ that we can't change to pop_failure_jump. */
+ if (!not)
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
+ }
+ }
+ }
+ else if ((re_opcode_t) *p2 == charset)
+ {
+#ifdef DEBUG
+ register unsigned char c
+ = *p2 == (unsigned char) endline ? '\n' : p2[2];
+#endif
+
+ if ((re_opcode_t) p1[3] == exactn
+ && ! ((int) p2[1] * BYTEWIDTH > (int) p1[4]
+ && (p2[1 + p1[4] / BYTEWIDTH]
+ & (1 << (p1[4] % BYTEWIDTH)))))
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT3 (" %c != %c => pop_failure_jump.\n",
+ c, p1[5]);
+ }
+
+ else if ((re_opcode_t) p1[3] == charset_not)
+ {
+ int idx;
+ /* We win if the charset_not inside the loop
+ lists every character listed in the charset after. */
+ for (idx = 0; idx < (int) p2[1]; idx++)
+ if (! (p2[2 + idx] == 0
+ || (idx < (int) p1[4]
+ && ((p2[2 + idx] & ~ p1[5 + idx]) == 0))))
+ break;
+
+ if (idx == p2[1])
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
+ }
+ }
+ else if ((re_opcode_t) p1[3] == charset)
+ {
+ int idx;
+ /* We win if the charset inside the loop
+ has no overlap with the one after the loop. */
+ for (idx = 0;
+ idx < (int) p2[1] && idx < (int) p1[4];
+ idx++)
+ if ((p2[2 + idx] & p1[5 + idx]) != 0)
+ break;
+
+ if (idx == p2[1] || idx == p1[4])
+ {
+ p[-3] = (unsigned char) pop_failure_jump;
+ DEBUG_PRINT1 (" No match => pop_failure_jump.\n");
+ }
+ }
+ }
+ }
+ p -= 2; /* Point at relative address again. */
+ if ((re_opcode_t) p[-1] != pop_failure_jump)
+ {
+ p[-1] = (unsigned char) jump;
+ DEBUG_PRINT1 (" Match => jump.\n");
+ goto unconditional_jump;
+ }
+ /* Note fall through. */
+
+
+ /* The end of a simple repeat has a pop_failure_jump back to
+ its matching on_failure_jump, where the latter will push a
+ failure point. The pop_failure_jump takes off failure
+ points put on by this pop_failure_jump's matching
+ on_failure_jump; we got through the pattern to here from the
+ matching on_failure_jump, so didn't fail. */
+ case pop_failure_jump:
+ {
+ /* We need to pass separate storage for the lowest and
+ highest registers, even though we don't care about the
+ actual values. Otherwise, we will restore only one
+ register from the stack, since lowest will == highest in
+ `pop_failure_point'. */
+ unsigned dummy_low_reg, dummy_high_reg;
+ unsigned char *pdummy;
+ const char *sdummy;
+
+ DEBUG_PRINT1 ("EXECUTING pop_failure_jump.\n");
+ POP_FAILURE_POINT (sdummy, pdummy,
+ dummy_low_reg, dummy_high_reg,
+ reg_dummy, reg_dummy, reg_info_dummy);
+ }
+ /* Note fall through. */
+
+
+ /* Unconditionally jump (without popping any failure points). */
+ case jump:
+ unconditional_jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p); /* Get the amount to jump. */
+ DEBUG_PRINT2 ("EXECUTING jump %d ", mcnt);
+ p += mcnt; /* Do the jump. */
+ DEBUG_PRINT2 ("(to 0x%x).\n", p);
+ break;
+
+
+ /* We need this opcode so we can detect where alternatives end
+ in `group_match_null_string_p' et al. */
+ case jump_past_alt:
+ DEBUG_PRINT1 ("EXECUTING jump_past_alt.\n");
+ goto unconditional_jump;
+
+
+ /* Normally, the on_failure_jump pushes a failure point, which
+ then gets popped at pop_failure_jump. We will end up at
+ pop_failure_jump, also, and with a pattern of, say, `a+', we
+ are skipping over the on_failure_jump, so we have to push
+ something meaningless for pop_failure_jump to pop. */
+ case dummy_failure_jump:
+ DEBUG_PRINT1 ("EXECUTING dummy_failure_jump.\n");
+ /* It doesn't matter what we push for the string here. What
+ the code at `fail' tests is the value for the pattern. */
+ PUSH_FAILURE_POINT (0, 0, -2);
+ goto unconditional_jump;
+
+
+ /* At the end of an alternative, we need to push a dummy failure
+ point in case we are followed by a `pop_failure_jump', because
+ we don't want the failure point for the alternative to be
+ popped. For example, matching `(a|ab)*' against `aab'
+ requires that we match the `ab' alternative. */
+ case push_dummy_failure:
+ DEBUG_PRINT1 ("EXECUTING push_dummy_failure.\n");
+ /* See comments just above at `dummy_failure_jump' about the
+ two zeroes. */
+ PUSH_FAILURE_POINT (0, 0, -2);
+ break;
+
+ /* Have to succeed matching what follows at least n times.
+ After that, handle like `on_failure_jump'. */
+ case succeed_n:
+ EXTRACT_NUMBER (mcnt, p + 2);
+ DEBUG_PRINT2 ("EXECUTING succeed_n %d.\n", mcnt);
+
+ assert (mcnt >= 0);
+ /* Originally, this is how many times we HAVE to succeed. */
+ if (mcnt > 0)
+ {
+ mcnt--;
+ p += 2;
+ STORE_NUMBER_AND_INCR (p, mcnt);
+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p, mcnt);
+ }
+ else if (mcnt == 0)
+ {
+ DEBUG_PRINT2 (" Setting two bytes from 0x%x to no_op.\n", p+2);
+ p[2] = (unsigned char) no_op;
+ p[3] = (unsigned char) no_op;
+ goto on_failure;
+ }
+ break;
+
+ case jump_n:
+ EXTRACT_NUMBER (mcnt, p + 2);
+ DEBUG_PRINT2 ("EXECUTING jump_n %d.\n", mcnt);
+
+ /* Originally, this is how many times we CAN jump. */
+ if (mcnt)
+ {
+ mcnt--;
+ STORE_NUMBER (p + 2, mcnt);
+ goto unconditional_jump;
+ }
+ /* If don't have to jump any more, skip over the rest of command. */
+ else
+ p += 4;
+ break;
+
+ case set_number_at:
+ {
+ DEBUG_PRINT1 ("EXECUTING set_number_at.\n");
+
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ p1 = p + mcnt;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p);
+ DEBUG_PRINT3 (" Setting 0x%x to %d.\n", p1, mcnt);
+ STORE_NUMBER (p1, mcnt);
+ break;
+ }
+
+ case wordbound:
+ DEBUG_PRINT1 ("EXECUTING wordbound.\n");
+ if (AT_WORD_BOUNDARY (d))
+ break;
+ goto fail;
+
+ case notwordbound:
+ DEBUG_PRINT1 ("EXECUTING notwordbound.\n");
+ if (AT_WORD_BOUNDARY (d))
+ goto fail;
+ break;
+
+ case wordbeg:
+ DEBUG_PRINT1 ("EXECUTING wordbeg.\n");
+ if (WORDCHAR_P (d) && (AT_STRINGS_BEG (d) || !WORDCHAR_P (d - 1)))
+ break;
+ goto fail;
+
+ case wordend:
+ DEBUG_PRINT1 ("EXECUTING wordend.\n");
+ if (!AT_STRINGS_BEG (d) && WORDCHAR_P (d - 1)
+ && (!WORDCHAR_P (d) || AT_STRINGS_END (d)))
+ break;
+ goto fail;
+
+#ifdef emacs
+ case before_dot:
+ DEBUG_PRINT1 ("EXECUTING before_dot.\n");
+ if (PTR_CHAR_POS ((unsigned char *) d) >= point)
+ goto fail;
+ break;
+
+ case at_dot:
+ DEBUG_PRINT1 ("EXECUTING at_dot.\n");
+ if (PTR_CHAR_POS ((unsigned char *) d) != point)
+ goto fail;
+ break;
+
+ case after_dot:
+ DEBUG_PRINT1 ("EXECUTING after_dot.\n");
+ if (PTR_CHAR_POS ((unsigned char *) d) <= point)
+ goto fail;
+ break;
+#if 0 /* not emacs19 */
+ case at_dot:
+ DEBUG_PRINT1 ("EXECUTING at_dot.\n");
+ if (PTR_CHAR_POS ((unsigned char *) d) + 1 != point)
+ goto fail;
+ break;
+#endif /* not emacs19 */
+
+ case syntaxspec:
+ DEBUG_PRINT2 ("EXECUTING syntaxspec %d.\n", mcnt);
+ mcnt = *p++;
+ goto matchsyntax;
+
+ case wordchar:
+ DEBUG_PRINT1 ("EXECUTING Emacs wordchar.\n");
+ mcnt = (int) Sword;
+ matchsyntax:
+ PREFETCH ();
+ /* Can't use *d++ here; SYNTAX may be an unsafe macro. */
+ d++;
+ if (SYNTAX (d[-1]) != (enum syntaxcode) mcnt)
+ goto fail;
+ SET_REGS_MATCHED ();
+ break;
+
+ case notsyntaxspec:
+ DEBUG_PRINT2 ("EXECUTING notsyntaxspec %d.\n", mcnt);
+ mcnt = *p++;
+ goto matchnotsyntax;
+
+ case notwordchar:
+ DEBUG_PRINT1 ("EXECUTING Emacs notwordchar.\n");
+ mcnt = (int) Sword;
+ matchnotsyntax:
+ PREFETCH ();
+ /* Can't use *d++ here; SYNTAX may be an unsafe macro. */
+ d++;
+ if (SYNTAX (d[-1]) == (enum syntaxcode) mcnt)
+ goto fail;
+ SET_REGS_MATCHED ();
+ break;
+
+#else /* not emacs */
+ case wordchar:
+ DEBUG_PRINT1 ("EXECUTING non-Emacs wordchar.\n");
+ PREFETCH ();
+ if (!WORDCHAR_P (d))
+ goto fail;
+ SET_REGS_MATCHED ();
+ d++;
+ break;
+
+ case notwordchar:
+ DEBUG_PRINT1 ("EXECUTING non-Emacs notwordchar.\n");
+ PREFETCH ();
+ if (WORDCHAR_P (d))
+ goto fail;
+ SET_REGS_MATCHED ();
+ d++;
+ break;
+#endif /* not emacs */
+
+ default:
+ abort ();
+ }
+ continue; /* Successfully executed one pattern command; keep going. */
+
+
+ /* We goto here if a matching operation fails. */
+ fail:
+ if (!FAIL_STACK_EMPTY ())
+ { /* A restart point is known. Restore to that state. */
+ DEBUG_PRINT1 ("\nFAIL:\n");
+ POP_FAILURE_POINT (d, p,
+ lowest_active_reg, highest_active_reg,
+ regstart, regend, reg_info);
+
+ /* If this failure point is a dummy, try the next one. */
+ if (!p)
+ goto fail;
+
+ /* If we failed to the end of the pattern, don't examine *p. */
+ assert (p <= pend);
+ if (p < pend)
+ {
+ boolean is_a_jump_n = false;
+
+ /* If failed to a backwards jump that's part of a repetition
+ loop, need to pop this failure point and use the next one. */
+ switch ((re_opcode_t) *p)
+ {
+ case jump_n:
+ is_a_jump_n = true;
+ case maybe_pop_jump:
+ case pop_failure_jump:
+ case jump:
+ p1 = p + 1;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ p1 += mcnt;
+
+ if ((is_a_jump_n && (re_opcode_t) *p1 == succeed_n)
+ || (!is_a_jump_n
+ && (re_opcode_t) *p1 == on_failure_jump))
+ goto fail;
+ break;
+ default:
+ /* do nothing */ ;
+ }
+ }
+
+ if (d >= string1 && d <= end1)
+ dend = end_match_1;
+ }
+ else
+ break; /* Matching at this starting point really fails. */
+ } /* for (;;) */
+
+ if (best_regs_set)
+ goto restore_best_regs;
+
+ FREE_VARIABLES ();
+
+ return -1; /* Failure to match. */
+} /* re_match_2 */
+
+/* Subroutine definitions for re_match_2. */
+
+
+/* We are passed P pointing to a register number after a start_memory.
+
+ Return true if the pattern up to the corresponding stop_memory can
+ match the empty string, and false otherwise.
+
+ If we find the matching stop_memory, sets P to point to one past its number.
+ Otherwise, sets P to an undefined byte less than or equal to END.
+
+ We don't handle duplicates properly (yet). */
+
+static boolean
+group_match_null_string_p (p, end, reg_info)
+ unsigned char **p, *end;
+ register_info_type *reg_info;
+{
+ int mcnt;
+ /* Point to after the args to the start_memory. */
+ unsigned char *p1 = *p + 2;
+
+ while (p1 < end)
+ {
+ /* Skip over opcodes that can match nothing, and return true or
+ false, as appropriate, when we get to one that can't, or to the
+ matching stop_memory. */
+
+ switch ((re_opcode_t) *p1)
+ {
+ /* Could be either a loop or a series of alternatives. */
+ case on_failure_jump:
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+
+ /* If the next operation is not a jump backwards in the
+ pattern. */
+
+ if (mcnt >= 0)
+ {
+ /* Go through the on_failure_jumps of the alternatives,
+ seeing if any of the alternatives cannot match nothing.
+ The last alternative starts with only a jump,
+ whereas the rest start with on_failure_jump and end
+ with a jump, e.g., here is the pattern for `a|b|c':
+
+ /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6
+ /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3
+ /exactn/1/c
+
+ So, we have to first go through the first (n-1)
+ alternatives and then deal with the last one separately. */
+
+
+ /* Deal with the first (n-1) alternatives, which start
+ with an on_failure_jump (see above) that jumps to right
+ past a jump_past_alt. */
+
+ while ((re_opcode_t) p1[mcnt-3] == jump_past_alt)
+ {
+ /* `mcnt' holds how many bytes long the alternative
+ is, including the ending `jump_past_alt' and
+ its number. */
+
+ if (!alt_match_null_string_p (p1, p1 + mcnt - 3,
+ reg_info))
+ return false;
+
+ /* Move to right after this alternative, including the
+ jump_past_alt. */
+ p1 += mcnt;
+
+ /* Break if it's the beginning of an n-th alternative
+ that doesn't begin with an on_failure_jump. */
+ if ((re_opcode_t) *p1 != on_failure_jump)
+ break;
+
+ /* Still have to check that it's not an n-th
+ alternative that starts with an on_failure_jump. */
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ if ((re_opcode_t) p1[mcnt-3] != jump_past_alt)
+ {
+ /* Get to the beginning of the n-th alternative. */
+ p1 -= 3;
+ break;
+ }
+ }
+
+ /* Deal with the last alternative: go back and get number
+ of the `jump_past_alt' just before it. `mcnt' contains
+ the length of the alternative. */
+ EXTRACT_NUMBER (mcnt, p1 - 2);
+
+ if (!alt_match_null_string_p (p1, p1 + mcnt, reg_info))
+ return false;
+
+ p1 += mcnt; /* Get past the n-th alternative. */
+ } /* if mcnt > 0 */
+ break;
+
+
+ case stop_memory:
+ assert (p1[1] == **p);
+ *p = p1 + 2;
+ return true;
+
+
+ default:
+ if (!common_op_match_null_string_p (&p1, end, reg_info))
+ return false;
+ }
+ } /* while p1 < end */
+
+ return false;
+} /* group_match_null_string_p */
+
+
+/* Similar to group_match_null_string_p, but doesn't deal with alternatives:
+ It expects P to be the first byte of a single alternative and END one
+ byte past the last. The alternative can contain groups. */
+
+static boolean
+alt_match_null_string_p (p, end, reg_info)
+ unsigned char *p, *end;
+ register_info_type *reg_info;
+{
+ int mcnt;
+ unsigned char *p1 = p;
+
+ while (p1 < end)
+ {
+ /* Skip over opcodes that can match nothing, and break when we get
+ to one that can't. */
+
+ switch ((re_opcode_t) *p1)
+ {
+ /* It's a loop. */
+ case on_failure_jump:
+ p1++;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ p1 += mcnt;
+ break;
+
+ default:
+ if (!common_op_match_null_string_p (&p1, end, reg_info))
+ return false;
+ }
+ } /* while p1 < end */
+
+ return true;
+} /* alt_match_null_string_p */
+
+
+/* Deals with the ops common to group_match_null_string_p and
+ alt_match_null_string_p.
+
+ Sets P to one after the op and its arguments, if any. */
+
+static boolean
+common_op_match_null_string_p (p, end, reg_info)
+ unsigned char **p, *end;
+ register_info_type *reg_info;
+{
+ int mcnt;
+ boolean ret;
+ int reg_no;
+ unsigned char *p1 = *p;
+
+ switch ((re_opcode_t) *p1++)
+ {
+ case no_op:
+ case begline:
+ case endline:
+ case begbuf:
+ case endbuf:
+ case wordbeg:
+ case wordend:
+ case wordbound:
+ case notwordbound:
+#ifdef emacs
+ case before_dot:
+ case at_dot:
+ case after_dot:
+#endif
+ break;
+
+ case start_memory:
+ reg_no = *p1;
+ assert (reg_no > 0 && reg_no <= MAX_REGNUM);
+ ret = group_match_null_string_p (&p1, end, reg_info);
+
+ /* Have to set this here in case we're checking a group which
+ contains a group and a back reference to it. */
+
+ if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE)
+ REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret;
+
+ if (!ret)
+ return false;
+ break;
+
+ /* If this is an optimized succeed_n for zero times, make the jump. */
+ case jump:
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ if (mcnt >= 0)
+ p1 += mcnt;
+ else
+ return false;
+ break;
+
+ case succeed_n:
+ /* Get to the number of times to succeed. */
+ p1 += 2;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+
+ if (mcnt == 0)
+ {
+ p1 -= 4;
+ EXTRACT_NUMBER_AND_INCR (mcnt, p1);
+ p1 += mcnt;
+ }
+ else
+ return false;
+ break;
+
+ case duplicate:
+ if (!REG_MATCH_NULL_STRING_P (reg_info[*p1]))
+ return false;
+ break;
+
+ case set_number_at:
+ p1 += 4;
+
+ default:
+ /* All other opcodes mean we cannot match the empty string. */
+ return false;
+ }
+
+ *p = p1;
+ return true;
+} /* common_op_match_null_string_p */
+
+
+/* Return zero if TRANSLATE[S1] and TRANSLATE[S2] are identical for LEN
+ bytes; nonzero otherwise. */
+
+static int
+bcmp_translate (s1, s2, len, translate)
+ unsigned char *s1, *s2;
+ register int len;
+ char *translate;
+{
+ register unsigned char *p1 = s1, *p2 = s2;
+ while (len)
+ {
+ if (translate[*p1++] != translate[*p2++]) return 1;
+ len--;
+ }
+ return 0;
+}
+
+/* Entry points for GNU code. */
+
+/* re_compile_pattern is the GNU regular expression compiler: it
+ compiles PATTERN (of length SIZE) and puts the result in BUFP.
+ Returns 0 if the pattern was valid, otherwise an error string.
+
+ Assumes the `allocated' (and perhaps `buffer') and `translate' fields
+ are set in BUFP on entry.
+
+ We call regex_compile to do the actual compilation. */
+
+const char *
+re_compile_pattern (pattern, length, bufp)
+ const char *pattern;
+ int length;
+ struct re_pattern_buffer *bufp;
+{
+ reg_errcode_t ret;
+
+ /* GNU code is written to assume at least RE_NREGS registers will be set
+ (and at least one extra will be -1). */
+ bufp->regs_allocated = REGS_UNALLOCATED;
+
+ /* And GNU code determines whether or not to get register information
+ by passing null for the REGS argument to re_match, etc., not by
+ setting no_sub. */
+ bufp->no_sub = 0;
+
+ /* Match anchors at newline. */
+ bufp->newline_anchor = 1;
+
+ ret = regex_compile (pattern, length, re_syntax_options, bufp);
+
+ return re_error_msg[(int) ret];
+}
+
+/* Entry points compatible with 4.2 BSD regex library. We don't define
+ them if this is an Emacs or POSIX compilation. */
+
+#if !defined (emacs) && !defined (_POSIX_SOURCE)
+
+/* BSD has one and only one pattern buffer. */
+static struct re_pattern_buffer re_comp_buf;
+
+char *
+re_comp (s)
+ const char *s;
+{
+ reg_errcode_t ret;
+
+ if (!s)
+ {
+ if (!re_comp_buf.buffer)
+ return "No previous regular expression";
+ return 0;
+ }
+
+ if (!re_comp_buf.buffer)
+ {
+ re_comp_buf.buffer = (unsigned char *) malloc (200);
+ if (re_comp_buf.buffer == NULL)
+ return "Memory exhausted";
+ re_comp_buf.allocated = 200;
+
+ re_comp_buf.fastmap = (char *) malloc (1 << BYTEWIDTH);
+ if (re_comp_buf.fastmap == NULL)
+ return "Memory exhausted";
+ }
+
+ /* Since `re_exec' always passes NULL for the `regs' argument, we
+ don't need to initialize the pattern buffer fields which affect it. */
+
+ /* Match anchors at newlines. */
+ re_comp_buf.newline_anchor = 1;
+
+ ret = regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf);
+
+ /* Yes, we're discarding `const' here. */
+ return (char *) re_error_msg[(int) ret];
+}
+
+
+int
+re_exec (s)
+ const char *s;
+{
+ const int len = strlen (s);
+ return
+ 0 <= re_search (&re_comp_buf, s, len, 0, len, (struct re_registers *) 0);
+}
+#endif /* not emacs and not _POSIX_SOURCE */
+
+/* POSIX.2 functions. Don't define these for Emacs. */
+
+#ifndef emacs
+
+/* regcomp takes a regular expression as a string and compiles it.
+
+ PREG is a regex_t *. We do not expect any fields to be initialized,
+ since POSIX says we shouldn't. Thus, we set
+
+ `buffer' to the compiled pattern;
+ `used' to the length of the compiled pattern;
+ `syntax' to RE_SYNTAX_POSIX_EXTENDED if the
+ REG_EXTENDED bit in CFLAGS is set; otherwise, to
+ RE_SYNTAX_POSIX_BASIC;
+ `newline_anchor' to REG_NEWLINE being set in CFLAGS;
+ `fastmap' and `fastmap_accurate' to zero;
+ `re_nsub' to the number of subexpressions in PATTERN.
+
+ PATTERN is the address of the pattern string.
+
+ CFLAGS is a series of bits which affect compilation.
+
+ If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we
+ use POSIX basic syntax.
+
+ If REG_NEWLINE is set, then . and [^...] don't match newline.
+ Also, regexec will try a match beginning after every newline.
+
+ If REG_ICASE is set, then we considers upper- and lowercase
+ versions of letters to be equivalent when matching.
+
+ If REG_NOSUB is set, then when PREG is passed to regexec, that
+ routine will report only success or failure, and nothing about the
+ registers.
+
+ It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for
+ the return codes and their meanings.) */
+
+int
+regcomp (preg, pattern, cflags)
+ regex_t *preg;
+ const char *pattern;
+ int cflags;
+{
+ reg_errcode_t ret;
+ unsigned syntax
+ = (cflags & REG_EXTENDED) ?
+ RE_SYNTAX_POSIX_EXTENDED : RE_SYNTAX_POSIX_BASIC;
+
+ /* regex_compile will allocate the space for the compiled pattern. */
+ preg->buffer = 0;
+ preg->allocated = 0;
+ preg->used = 0;
+
+ /* Don't bother to use a fastmap when searching. This simplifies the
+ REG_NEWLINE case: if we used a fastmap, we'd have to put all the
+ characters after newlines into the fastmap. This way, we just try
+ every character. */
+ preg->fastmap = 0;
+
+ if (cflags & REG_ICASE)
+ {
+ unsigned i;
+
+ preg->translate = (char *) malloc (CHAR_SET_SIZE);
+ if (preg->translate == NULL)
+ return (int) REG_ESPACE;
+
+ /* Map uppercase characters to corresponding lowercase ones. */
+ for (i = 0; i < CHAR_SET_SIZE; i++)
+ preg->translate[i] = ISUPPER (i) ? tolower (i) : i;
+ }
+ else
+ preg->translate = NULL;
+
+ /* If REG_NEWLINE is set, newlines are treated differently. */
+ if (cflags & REG_NEWLINE)
+ { /* REG_NEWLINE implies neither . nor [^...] match newline. */
+ syntax &= ~RE_DOT_NEWLINE;
+ syntax |= RE_HAT_LISTS_NOT_NEWLINE;
+ /* It also changes the matching behavior. */
+ preg->newline_anchor = 1;
+ }
+ else
+ preg->newline_anchor = 0;
+
+ preg->no_sub = !!(cflags & REG_NOSUB);
+
+ /* POSIX says a null character in the pattern terminates it, so we
+ can use strlen here in compiling the pattern. */
+ ret = regex_compile (pattern, strlen (pattern), syntax, preg);
+
+ /* POSIX doesn't distinguish between an unmatched open-group and an
+ unmatched close-group: both are REG_EPAREN. */
+ if (ret == REG_ERPAREN) ret = REG_EPAREN;
+
+ return (int) ret;
+}
+
+
+/* regexec searches for a given pattern, specified by PREG, in the
+ string STRING.
+
+ If NMATCH is zero or REG_NOSUB was set in the cflags argument to
+ `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at
+ least NMATCH elements, and we set them to the offsets of the
+ corresponding matched substrings.
+
+ EFLAGS specifies `execution flags' which affect matching: if
+ REG_NOTBOL is set, then ^ does not match at the beginning of the
+ string; if REG_NOTEOL is set, then $ does not match at the end.
+
+ We return 0 if we find a match and REG_NOMATCH if not. */
+
+int
+regexec (preg, string, nmatch, pmatch, eflags)
+ const regex_t *preg;
+ const char *string;
+ size_t nmatch;
+ regmatch_t pmatch[];
+ int eflags;
+{
+ int ret;
+ struct re_registers regs;
+ regex_t private_preg;
+ int len = strlen (string);
+ boolean want_reg_info = !preg->no_sub && nmatch > 0;
+
+ private_preg = *preg;
+
+ private_preg.not_bol = !!(eflags & REG_NOTBOL);
+ private_preg.not_eol = !!(eflags & REG_NOTEOL);
+
+ /* The user has told us exactly how many registers to return
+ information about, via `nmatch'. We have to pass that on to the
+ matching routines. */
+ private_preg.regs_allocated = REGS_FIXED;
+
+ if (want_reg_info)
+ {
+ regs.num_regs = nmatch;
+ regs.start = TALLOC (nmatch, regoff_t);
+ regs.end = TALLOC (nmatch, regoff_t);
+ if (regs.start == NULL || regs.end == NULL)
+ return (int) REG_NOMATCH;
+ }
+
+ /* Perform the searching operation. */
+ ret = re_search (&private_preg, string, len,
+ /* start: */ 0, /* range: */ len,
+ want_reg_info ? &regs : (struct re_registers *) 0);
+
+ /* Copy the register information to the POSIX structure. */
+ if (want_reg_info)
+ {
+ if (ret >= 0)
+ {
+ unsigned r;
+
+ for (r = 0; r < nmatch; r++)
+ {
+ pmatch[r].rm_so = regs.start[r];
+ pmatch[r].rm_eo = regs.end[r];
+ }
+ }
+
+ /* If we needed the temporary register info, free the space now. */
+ free (regs.start);
+ free (regs.end);
+ }
+
+ /* We want zero return to mean success, unlike `re_search'. */
+ return ret >= 0 ? (int) REG_NOERROR : (int) REG_NOMATCH;
+}
+
+
+/* Returns a message corresponding to an error code, ERRCODE, returned
+ from either regcomp or regexec. We don't use PREG here. */
+
+size_t
+regerror (errcode, preg, errbuf, errbuf_size)
+ int errcode;
+ const regex_t *preg;
+ char *errbuf;
+ size_t errbuf_size;
+{
+ const char *msg;
+ size_t msg_size;
+
+ if (errcode < 0
+ || errcode >= (sizeof (re_error_msg) / sizeof (re_error_msg[0])))
+ /* Only error codes returned by the rest of the code should be passed
+ to this routine. If we are given anything else, or if other regex
+ code generates an invalid error code, then the program has a bug.
+ Dump core so we can fix it. */
+ abort ();
+
+ msg = re_error_msg[errcode];
+
+ /* POSIX doesn't require that we do anything in this case, but why
+ not be nice. */
+ if (! msg)
+ msg = "Success";
+
+ msg_size = strlen (msg) + 1; /* Includes the null. */
+
+ if (errbuf_size != 0)
+ {
+ if (msg_size > errbuf_size)
+ {
+ strncpy (errbuf, msg, errbuf_size - 1);
+ errbuf[errbuf_size - 1] = 0;
+ }
+ else
+ strcpy (errbuf, msg);
+ }
+
+ return msg_size;
+}
+
+
+/* Free dynamically allocated space used by PREG. */
+
+void
+regfree (preg)
+ regex_t *preg;
+{
+ if (preg->buffer != NULL)
+ free (preg->buffer);
+ preg->buffer = NULL;
+
+ preg->allocated = 0;
+ preg->used = 0;
+
+ if (preg->fastmap != NULL)
+ free (preg->fastmap);
+ preg->fastmap = NULL;
+ preg->fastmap_accurate = 0;
+
+ if (preg->translate != NULL)
+ free (preg->translate);
+ preg->translate = NULL;
+}
+
+#endif /* not emacs */
+
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/gnu/dist/diffutils/regex.h b/gnu/dist/diffutils/regex.h
new file mode 100644
index 00000000000..a495005ce93
--- /dev/null
+++ b/gnu/dist/diffutils/regex.h
@@ -0,0 +1,490 @@
+/* Definitions for data structures and routines for the regular
+ expression library, version 0.12.
+
+ Copyright (C) 1985, 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifndef __REGEXP_LIBRARY_H__
+#define __REGEXP_LIBRARY_H__
+
+/* POSIX says that <sys/types.h> must be included (by the caller) before
+ <regex.h>. */
+
+#ifdef VMS
+/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it
+ should be there. */
+#include <stddef.h>
+#endif
+
+
+/* The following bits are used to determine the regexp syntax we
+ recognize. The set/not-set meanings are chosen so that Emacs syntax
+ remains the value 0. The bits are given in alphabetical order, and
+ the definitions shifted by one from the previous bit; thus, when we
+ add or remove a bit, only one other definition need change. */
+typedef unsigned reg_syntax_t;
+
+/* If this bit is not set, then \ inside a bracket expression is literal.
+ If set, then such a \ quotes the following character. */
+#define RE_BACKSLASH_ESCAPE_IN_LISTS (1)
+
+/* If this bit is not set, then + and ? are operators, and \+ and \? are
+ literals.
+ If set, then \+ and \? are operators and + and ? are literals. */
+#define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
+
+/* If this bit is set, then character classes are supported. They are:
+ [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:],
+ [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
+ If not set, then character classes are not supported. */
+#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
+
+/* If this bit is set, then ^ and $ are always anchors (outside bracket
+ expressions, of course).
+ If this bit is not set, then it depends:
+ ^ is an anchor if it is at the beginning of a regular
+ expression or after an open-group or an alternation operator;
+ $ is an anchor if it is at the end of a regular expression, or
+ before a close-group or an alternation operator.
+
+ This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
+ POSIX draft 11.2 says that * etc. in leading positions is undefined.
+ We already implemented a previous draft which made those constructs
+ invalid, though, so we haven't changed the code back. */
+#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
+
+/* If this bit is set, then special characters are always special
+ regardless of where they are in the pattern.
+ If this bit is not set, then special characters are special only in
+ some contexts; otherwise they are ordinary. Specifically,
+ * + ? and intervals are only special when not after the beginning,
+ open-group, or alternation operator. */
+#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
+
+/* If this bit is set, then *, +, ?, and { cannot be first in an re or
+ immediately after an alternation or begin-group operator. */
+#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
+
+/* If this bit is set, then . matches newline.
+ If not set, then it doesn't. */
+#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
+
+/* If this bit is set, then . doesn't match NUL.
+ If not set, then it does. */
+#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
+
+/* If this bit is set, nonmatching lists [^...] do not match newline.
+ If not set, they do. */
+#define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
+
+/* If this bit is set, either \{...\} or {...} defines an
+ interval, depending on RE_NO_BK_BRACES.
+ If not set, \{, \}, {, and } are literals. */
+#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
+
+/* If this bit is set, +, ? and | aren't recognized as operators.
+ If not set, they are. */
+#define RE_LIMITED_OPS (RE_INTERVALS << 1)
+
+/* If this bit is set, newline is an alternation operator.
+ If not set, newline is literal. */
+#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
+
+/* If this bit is set, then `{...}' defines an interval, and \{ and \}
+ are literals.
+ If not set, then `\{...\}' defines an interval. */
+#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
+
+/* If this bit is set, (...) defines a group, and \( and \) are literals.
+ If not set, \(...\) defines a group, and ( and ) are literals. */
+#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
+
+/* If this bit is set, then \<digit> matches <digit>.
+ If not set, then \<digit> is a back-reference. */
+#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
+
+/* If this bit is set, then | is an alternation operator, and \| is literal.
+ If not set, then \| is an alternation operator, and | is literal. */
+#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
+
+/* If this bit is set, then an ending range point collating higher
+ than the starting range point, as in [z-a], is invalid.
+ If not set, then when ending range point collates higher than the
+ starting range point, the range is ignored. */
+#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
+
+/* If this bit is set, then an unmatched ) is ordinary.
+ If not set, then an unmatched ) is invalid. */
+#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
+
+/* This global variable defines the particular regexp syntax to use (for
+ some interfaces). When a regexp is compiled, the syntax used is
+ stored in the pattern buffer, so changing this does not affect
+ already-compiled regexps. */
+extern reg_syntax_t re_syntax_options;
+
+/* Define combinations of the above bits for the standard possibilities.
+ (The [[[ comments delimit what gets put into the Texinfo file, so
+ don't delete them!) */
+/* [[[begin syntaxes]]] */
+#define RE_SYNTAX_EMACS 0
+
+#define RE_SYNTAX_AWK \
+ (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \
+ | RE_NO_BK_PARENS | RE_NO_BK_REFS \
+ | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \
+ | RE_UNMATCHED_RIGHT_PAREN_ORD)
+
+#define RE_SYNTAX_POSIX_AWK \
+ (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS)
+
+#define RE_SYNTAX_GREP \
+ (RE_BK_PLUS_QM | RE_CHAR_CLASSES \
+ | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \
+ | RE_NEWLINE_ALT)
+
+#define RE_SYNTAX_EGREP \
+ (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \
+ | RE_NEWLINE_ALT | RE_NO_BK_PARENS \
+ | RE_NO_BK_VBAR)
+
+#define RE_SYNTAX_POSIX_EGREP \
+ (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES)
+
+/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */
+#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
+
+#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
+
+/* Syntax bits common to both basic and extended POSIX regex syntax. */
+#define _RE_SYNTAX_POSIX_COMMON \
+ (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \
+ | RE_INTERVALS | RE_NO_EMPTY_RANGES)
+
+#define RE_SYNTAX_POSIX_BASIC \
+ (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
+
+/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
+ RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this
+ isn't minimal, since other operators, such as \`, aren't disabled. */
+#define RE_SYNTAX_POSIX_MINIMAL_BASIC \
+ (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
+
+#define RE_SYNTAX_POSIX_EXTENDED \
+ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \
+ | RE_NO_BK_PARENS | RE_NO_BK_VBAR \
+ | RE_UNMATCHED_RIGHT_PAREN_ORD)
+
+/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS
+ replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */
+#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \
+ (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
+ | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \
+ | RE_NO_BK_PARENS | RE_NO_BK_REFS \
+ | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD)
+/* [[[end syntaxes]]] */
+
+/* Maximum number of duplicates an interval can allow. Some systems
+ (erroneously) define this in other header files, but we want our
+ value, so remove any previous define. */
+#ifdef RE_DUP_MAX
+#undef RE_DUP_MAX
+#endif
+#define RE_DUP_MAX ((1 << 15) - 1)
+
+
+/* POSIX `cflags' bits (i.e., information for `regcomp'). */
+
+/* If this bit is set, then use extended regular expression syntax.
+ If not set, then use basic regular expression syntax. */
+#define REG_EXTENDED 1
+
+/* If this bit is set, then ignore case when matching.
+ If not set, then case is significant. */
+#define REG_ICASE (REG_EXTENDED << 1)
+
+/* If this bit is set, then anchors do not match at newline
+ characters in the string.
+ If not set, then anchors do match at newlines. */
+#define REG_NEWLINE (REG_ICASE << 1)
+
+/* If this bit is set, then report only success or fail in regexec.
+ If not set, then returns differ between not matching and errors. */
+#define REG_NOSUB (REG_NEWLINE << 1)
+
+
+/* POSIX `eflags' bits (i.e., information for regexec). */
+
+/* If this bit is set, then the beginning-of-line operator doesn't match
+ the beginning of the string (presumably because it's not the
+ beginning of a line).
+ If not set, then the beginning-of-line operator does match the
+ beginning of the string. */
+#define REG_NOTBOL 1
+
+/* Like REG_NOTBOL, except for the end-of-line. */
+#define REG_NOTEOL (1 << 1)
+
+
+/* If any error codes are removed, changed, or added, update the
+ `re_error_msg' table in regex.c. */
+typedef enum
+{
+ REG_NOERROR = 0, /* Success. */
+ REG_NOMATCH, /* Didn't find a match (for regexec). */
+
+ /* POSIX regcomp return error codes. (In the order listed in the
+ standard.) */
+ REG_BADPAT, /* Invalid pattern. */
+ REG_ECOLLATE, /* Not implemented. */
+ REG_ECTYPE, /* Invalid character class name. */
+ REG_EESCAPE, /* Trailing backslash. */
+ REG_ESUBREG, /* Invalid back reference. */
+ REG_EBRACK, /* Unmatched left bracket. */
+ REG_EPAREN, /* Parenthesis imbalance. */
+ REG_EBRACE, /* Unmatched \{. */
+ REG_BADBR, /* Invalid contents of \{\}. */
+ REG_ERANGE, /* Invalid range end. */
+ REG_ESPACE, /* Ran out of memory. */
+ REG_BADRPT, /* No preceding re for repetition op. */
+
+ /* Error codes we've added. */
+ REG_EEND, /* Premature end. */
+ REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */
+ REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */
+} reg_errcode_t;
+
+/* This data structure represents a compiled pattern. Before calling
+ the pattern compiler, the fields `buffer', `allocated', `fastmap',
+ `translate', and `no_sub' can be set. After the pattern has been
+ compiled, the `re_nsub' field is available. All other fields are
+ private to the regex routines. */
+
+struct re_pattern_buffer
+{
+/* [[[begin pattern_buffer]]] */
+ /* Space that holds the compiled pattern. It is declared as
+ `unsigned char *' because its elements are
+ sometimes used as array indexes. */
+ unsigned char *buffer;
+
+ /* Number of bytes to which `buffer' points. */
+ unsigned long allocated;
+
+ /* Number of bytes actually used in `buffer'. */
+ unsigned long used;
+
+ /* Syntax setting with which the pattern was compiled. */
+ reg_syntax_t syntax;
+
+ /* Pointer to a fastmap, if any, otherwise zero. re_search uses
+ the fastmap, if there is one, to skip over impossible
+ starting points for matches. */
+ char *fastmap;
+
+ /* Either a translate table to apply to all characters before
+ comparing them, or zero for no translation. The translation
+ is applied to a pattern when it is compiled and to a string
+ when it is matched. */
+ char *translate;
+
+ /* Number of subexpressions found by the compiler. */
+ size_t re_nsub;
+
+ /* Zero if this pattern cannot match the empty string, one else.
+ Well, in truth it's used only in `re_search_2', to see
+ whether or not we should use the fastmap, so we don't set
+ this absolutely perfectly; see `re_compile_fastmap' (the
+ `duplicate' case). */
+ unsigned can_be_null : 1;
+
+ /* If REGS_UNALLOCATED, allocate space in the `regs' structure
+ for `max (RE_NREGS, re_nsub + 1)' groups.
+ If REGS_REALLOCATE, reallocate space if necessary.
+ If REGS_FIXED, use what's there. */
+#define REGS_UNALLOCATED 0
+#define REGS_REALLOCATE 1
+#define REGS_FIXED 2
+ unsigned regs_allocated : 2;
+
+ /* Set to zero when `regex_compile' compiles a pattern; set to one
+ by `re_compile_fastmap' if it updates the fastmap. */
+ unsigned fastmap_accurate : 1;
+
+ /* If set, `re_match_2' does not return information about
+ subexpressions. */
+ unsigned no_sub : 1;
+
+ /* If set, a beginning-of-line anchor doesn't match at the
+ beginning of the string. */
+ unsigned not_bol : 1;
+
+ /* Similarly for an end-of-line anchor. */
+ unsigned not_eol : 1;
+
+ /* If true, an anchor at a newline matches. */
+ unsigned newline_anchor : 1;
+
+/* [[[end pattern_buffer]]] */
+};
+
+typedef struct re_pattern_buffer regex_t;
+
+
+/* search.c (search_buffer) in Emacs needs this one opcode value. It is
+ defined both in `regex.c' and here. */
+#define RE_EXACTN_VALUE 1
+
+/* Type for byte offsets within the string. POSIX mandates this. */
+typedef int regoff_t;
+
+
+/* This is the structure we store register match data in. See
+ regex.texinfo for a full description of what registers match. */
+struct re_registers
+{
+ unsigned num_regs;
+ regoff_t *start;
+ regoff_t *end;
+};
+
+
+/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
+ `re_match_2' returns information about at least this many registers
+ the first time a `regs' structure is passed. */
+#ifndef RE_NREGS
+#define RE_NREGS 30
+#endif
+
+
+/* POSIX specification for registers. Aside from the different names than
+ `re_registers', POSIX uses an array of structures, instead of a
+ structure of arrays. */
+typedef struct
+{
+ regoff_t rm_so; /* Byte offset from string's start to substring's start. */
+ regoff_t rm_eo; /* Byte offset from string's start to substring's end. */
+} regmatch_t;
+
+/* Declarations for routines. */
+
+/* To avoid duplicating every routine declaration -- once with a
+ prototype (if we are ANSI), and once without (if we aren't) -- we
+ use the following macro to declare argument types. This
+ unfortunately clutters up the declarations a bit, but I think it's
+ worth it. */
+
+#if __STDC__
+
+#define _RE_ARGS(args) args
+
+#else /* not __STDC__ */
+
+#define _RE_ARGS(args) ()
+
+#endif /* not __STDC__ */
+
+/* Sets the current default syntax to SYNTAX, and return the old syntax.
+ You can also simply assign to the `re_syntax_options' variable. */
+extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax));
+
+/* Compile the regular expression PATTERN, with length LENGTH
+ and syntax given by the global `re_syntax_options', into the buffer
+ BUFFER. Return NULL if successful, and an error string if not. */
+extern const char *re_compile_pattern
+ _RE_ARGS ((const char *pattern, int length,
+ struct re_pattern_buffer *buffer));
+
+
+/* Compile a fastmap for the compiled pattern in BUFFER; used to
+ accelerate searches. Return 0 if successful and -2 if was an
+ internal error. */
+extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer));
+
+
+/* Search in the string STRING (with length LENGTH) for the pattern
+ compiled into BUFFER. Start searching at position START, for RANGE
+ characters. Return the starting position of the match, -1 for no
+ match, or -2 for an internal error. Also return register
+ information in REGS (if REGS and BUFFER->no_sub are nonzero). */
+extern int re_search
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
+ int length, int start, int range, struct re_registers *regs));
+
+
+/* Like `re_search', but search in the concatenation of STRING1 and
+ STRING2. Also, stop searching at index START + STOP. */
+extern int re_search_2
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
+ int length1, const char *string2, int length2,
+ int start, int range, struct re_registers *regs, int stop));
+
+
+/* Like `re_search', but return how many characters in STRING the regexp
+ in BUFFER matched, starting at position START. */
+extern int re_match
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
+ int length, int start, struct re_registers *regs));
+
+
+/* Relates to `re_match' as `re_search_2' relates to `re_search'. */
+extern int re_match_2
+ _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
+ int length1, const char *string2, int length2,
+ int start, struct re_registers *regs, int stop));
+
+
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+ ENDS. Subsequent matches using BUFFER and REGS will use this memory
+ for recording register information. STARTS and ENDS must be
+ allocated with malloc, and must each be at least `NUM_REGS * sizeof
+ (regoff_t)' bytes long.
+
+ If NUM_REGS == 0, then subsequent matches should allocate their own
+ register data.
+
+ Unless this function is called, the first search or match using
+ PATTERN_BUFFER will allocate its own register data, without
+ freeing the old data. */
+extern void re_set_registers
+ _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs,
+ unsigned num_regs, regoff_t *starts, regoff_t *ends));
+
+/* 4.2 bsd compatibility. */
+extern char *re_comp _RE_ARGS ((const char *));
+extern int re_exec _RE_ARGS ((const char *));
+
+/* POSIX compatibility. */
+extern int regcomp _RE_ARGS ((regex_t *preg, const char *pattern, int cflags));
+extern int regexec
+ _RE_ARGS ((const regex_t *preg, const char *string, size_t nmatch,
+ regmatch_t pmatch[], int eflags));
+extern size_t regerror
+ _RE_ARGS ((int errcode, const regex_t *preg, char *errbuf,
+ size_t errbuf_size));
+extern void regfree _RE_ARGS ((regex_t *preg));
+
+#endif /* not __REGEXP_LIBRARY_H__ */
+
+/*
+Local variables:
+make-backup-files: t
+version-control: t
+trim-versions-without-asking: nil
+End:
+*/
diff --git a/gnu/dist/diffutils/sdiff.c b/gnu/dist/diffutils/sdiff.c
new file mode 100644
index 00000000000..b64f1d03836
--- /dev/null
+++ b/gnu/dist/diffutils/sdiff.c
@@ -0,0 +1,1180 @@
+/* SDIFF -- interactive merge front end to diff
+ Copyright (C) 1992, 1993, 1994 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. */
+
+/* GNU SDIFF was written by Thomas Lord. */
+
+#include "system.h"
+#include <stdio.h>
+#include <signal.h>
+#include "getopt.h"
+
+/* Size of chunks read from files which must be parsed into lines. */
+#define SDIFF_BUFSIZE ((size_t) 65536)
+
+/* Default name of the diff program */
+#ifndef DIFF_PROGRAM
+#define DIFF_PROGRAM "/usr/bin/diff"
+#endif
+
+/* Users' editor of nonchoice */
+#ifndef DEFAULT_EDITOR_PROGRAM
+#define DEFAULT_EDITOR_PROGRAM "ed"
+#endif
+
+extern char version_string[];
+static char const *program_name;
+static char const *diffbin = DIFF_PROGRAM;
+static char const *edbin = DEFAULT_EDITOR_PROGRAM;
+static char const **diffargv;
+
+static char *tmpname;
+static int volatile tmpmade;
+
+#if HAVE_FORK
+static pid_t volatile diffpid;
+#endif
+
+struct line_filter;
+
+static FILE *ck_fopen PARAMS((char const *, char const *));
+static RETSIGTYPE catchsig PARAMS((int));
+static VOID *xmalloc PARAMS((size_t));
+static char const *expand_name PARAMS((char *, int, char const *));
+static int edit PARAMS((struct line_filter *, int, struct line_filter *, int, FILE*));
+static int interact PARAMS((struct line_filter *, struct line_filter *, struct line_filter *, FILE*));
+static int lf_snarf PARAMS((struct line_filter *, char *, size_t));
+static int skip_white PARAMS((void));
+static size_t ck_fread PARAMS((char *, size_t, FILE *));
+static size_t lf_refill PARAMS((struct line_filter *));
+static void checksigs PARAMS((void));
+static void ck_fclose PARAMS((FILE *));
+static void ck_fflush PARAMS((FILE *));
+static void ck_fwrite PARAMS((char const *, size_t, FILE *));
+static void cleanup PARAMS((void));
+static void diffarg PARAMS((char const *));
+static void execdiff PARAMS((void));
+static void exiterr PARAMS((void));
+static void fatal PARAMS((char const *));
+static void flush_line PARAMS((void));
+static void give_help PARAMS((void));
+static void lf_copy PARAMS((struct line_filter *, int, FILE *));
+static void lf_init PARAMS((struct line_filter *, FILE *));
+static void lf_skip PARAMS((struct line_filter *, int));
+static void perror_fatal PARAMS((char const *));
+static void trapsigs PARAMS((void));
+static void try_help PARAMS((char const *));
+static void untrapsig PARAMS((int));
+static void usage PARAMS((void));
+
+/* this lossage until the gnu libc conquers the universe */
+#if HAVE_TMPNAM
+#define private_tempnam() tmpnam ((char *) 0)
+#else
+#ifndef PVT_tmpdir
+#define PVT_tmpdir "/tmp"
+#endif
+#ifndef TMPDIR_ENV
+#define TMPDIR_ENV "TMPDIR"
+#endif
+static char *private_tempnam PARAMS((void));
+static int exists PARAMS((char const *));
+#endif
+static int diraccess PARAMS((char const *));
+
+/* Options: */
+
+/* name of output file if -o spec'd */
+static char *out_file;
+
+/* do not print common lines if true, set by -s option */
+static int suppress_common_flag;
+
+static struct option const longopts[] =
+{
+ {"ignore-blank-lines", 0, 0, 'B'},
+ {"speed-large-files", 0, 0, 'H'},
+ {"ignore-matching-lines", 1, 0, 'I'},
+ {"ignore-all-space", 0, 0, 'W'}, /* swap W and w for historical reasons */
+ {"text", 0, 0, 'a'},
+ {"ignore-space-change", 0, 0, 'b'},
+ {"minimal", 0, 0, 'd'},
+ {"ignore-case", 0, 0, 'i'},
+ {"left-column", 0, 0, 'l'},
+ {"output", 1, 0, 'o'},
+ {"suppress-common-lines", 0, 0, 's'},
+ {"expand-tabs", 0, 0, 't'},
+ {"width", 1, 0, 'w'},
+ {"version", 0, 0, 'v'},
+ {"help", 0, 0, 129},
+ {0, 0, 0, 0}
+};
+
+static void
+try_help (reason)
+ char const *reason;
+{
+ if (reason)
+ fprintf (stderr, "%s: %s\n", program_name, reason);
+ fprintf (stderr, "%s: Try `%s --help' for more information.\n",
+ program_name, program_name);
+ exit (2);
+}
+
+static void
+usage ()
+{
+ printf ("Usage: %s [OPTIONS]... FILE1 FILE2\n\n", program_name);
+ printf ("%s", "\
+ -o FILE --output=FILE Operate interactively, sending output to FILE.\n\n");
+ printf ("%s", "\
+ -i --ignore-case Consider upper- and lower-case to be the same.\n\
+ -W --ignore-all-space Ignore all white space.\n\
+ -b --ignore-space-change Ignore changes in the amount of white space.\n\
+ -B --ignore-blank-lines Ignore changes whose lines are all blank.\n\
+ -I RE --ignore-matching-lines=RE Ignore changes whose lines all match RE.\n\
+ -a --text Treat all files as text.\n\n");
+ printf ("%s", "\
+ -w NUM --width=NUM Output at most NUM (default 130) characters per line.\n\
+ -l --left-column Output only the left column of common lines.\n\
+ -s --suppress-common-lines Do not output common lines.\n\n");
+ printf ("\
+ -t --expand-tabs Expand tabs to spaces in output.\n\n");
+ printf ("%s", "\
+ -d --minimal Try hard to find a smaller set of changes.\n\
+ -H --speed-large-files Assume large files and many scattered small changes.\n\n");
+ printf ("%s", "\
+ -v --version Output version info.\n\
+ --help Output this help.\n\n\
+If FILE1 or FILE2 is `-', read standard input.\n");
+}
+
+static void
+cleanup ()
+{
+#if HAVE_FORK
+ if (0 < diffpid)
+ kill (diffpid, SIGPIPE);
+#endif
+ if (tmpmade)
+ unlink (tmpname);
+}
+
+static void
+exiterr ()
+{
+ cleanup ();
+ untrapsig (0);
+ checksigs ();
+ exit (2);
+}
+
+static void
+fatal (msg)
+ char const *msg;
+{
+ fprintf (stderr, "%s: %s\n", program_name, msg);
+ exiterr ();
+}
+
+static void
+perror_fatal (msg)
+ char const *msg;
+{
+ int e = errno;
+ checksigs ();
+ fprintf (stderr, "%s: ", program_name);
+ errno = e;
+ perror (msg);
+ exiterr ();
+}
+
+
+/* malloc freely or DIE! */
+static VOID *
+xmalloc (size)
+ size_t size;
+{
+ VOID *r = (VOID *) malloc (size);
+ if (!r)
+ fatal ("memory exhausted");
+ return r;
+}
+
+static FILE *
+ck_fopen (fname, type)
+ char const *fname, *type;
+{
+ FILE *r = fopen (fname, type);
+ if (!r)
+ perror_fatal (fname);
+ return r;
+}
+
+static void
+ck_fclose (f)
+ FILE *f;
+{
+ if (fclose (f))
+ perror_fatal ("input/output error");
+}
+
+static size_t
+ck_fread (buf, size, f)
+ char *buf;
+ size_t size;
+ FILE *f;
+{
+ size_t r = fread (buf, sizeof (char), size, f);
+ if (r == 0 && ferror (f))
+ perror_fatal ("input error");
+ return r;
+}
+
+static void
+ck_fwrite (buf, size, f)
+ char const *buf;
+ size_t size;
+ FILE *f;
+{
+ if (fwrite (buf, sizeof (char), size, f) != size)
+ perror_fatal ("output error");
+}
+
+static void
+ck_fflush (f)
+ FILE *f;
+{
+ if (fflush (f) != 0)
+ perror_fatal ("output error");
+}
+
+static char const *
+expand_name (name, is_dir, other_name)
+ char *name;
+ int is_dir;
+ char const *other_name;
+{
+ if (strcmp (name, "-") == 0)
+ fatal ("cannot interactively merge standard input");
+ if (!is_dir)
+ return name;
+ else
+ {
+ /* Yield NAME/BASE, where BASE is OTHER_NAME's basename. */
+ char const *p = filename_lastdirchar (other_name);
+ char const *base = p ? p+1 : other_name;
+ size_t namelen = strlen (name), baselen = strlen (base);
+ char *r = xmalloc (namelen + baselen + 2);
+ memcpy (r, name, namelen);
+ r[namelen] = '/';
+ memcpy (r + namelen + 1, base, baselen + 1);
+ return r;
+ }
+}
+
+
+
+struct line_filter {
+ FILE *infile;
+ char *bufpos;
+ char *buffer;
+ char *buflim;
+};
+
+static void
+lf_init (lf, infile)
+ struct line_filter *lf;
+ FILE *infile;
+{
+ lf->infile = infile;
+ lf->bufpos = lf->buffer = lf->buflim = xmalloc (SDIFF_BUFSIZE + 1);
+ lf->buflim[0] = '\n';
+}
+
+/* Fill an exhausted line_filter buffer from its INFILE */
+static size_t
+lf_refill (lf)
+ struct line_filter *lf;
+{
+ size_t s = ck_fread (lf->buffer, SDIFF_BUFSIZE, lf->infile);
+ lf->bufpos = lf->buffer;
+ lf->buflim = lf->buffer + s;
+ lf->buflim[0] = '\n';
+ checksigs ();
+ return s;
+}
+
+/* Advance LINES on LF's infile, copying lines to OUTFILE */
+static void
+lf_copy (lf, lines, outfile)
+ struct line_filter *lf;
+ int lines;
+ FILE *outfile;
+{
+ char *start = lf->bufpos;
+
+ while (lines)
+ {
+ lf->bufpos = (char *) memchr (lf->bufpos, '\n', lf->buflim - lf->bufpos);
+ if (! lf->bufpos)
+ {
+ ck_fwrite (start, lf->buflim - start, outfile);
+ if (! lf_refill (lf))
+ return;
+ start = lf->bufpos;
+ }
+ else
+ {
+ --lines;
+ ++lf->bufpos;
+ }
+ }
+
+ ck_fwrite (start, lf->bufpos - start, outfile);
+}
+
+/* Advance LINES on LF's infile without doing output */
+static void
+lf_skip (lf, lines)
+ struct line_filter *lf;
+ int lines;
+{
+ while (lines)
+ {
+ lf->bufpos = (char *) memchr (lf->bufpos, '\n', lf->buflim - lf->bufpos);
+ if (! lf->bufpos)
+ {
+ if (! lf_refill (lf))
+ break;
+ }
+ else
+ {
+ --lines;
+ ++lf->bufpos;
+ }
+ }
+}
+
+/* Snarf a line into a buffer. Return EOF if EOF, 0 if error, 1 if OK. */
+static int
+lf_snarf (lf, buffer, bufsize)
+ struct line_filter *lf;
+ char *buffer;
+ size_t bufsize;
+{
+ char *start = lf->bufpos;
+
+ for (;;)
+ {
+ char *next = (char *) memchr (start, '\n', lf->buflim + 1 - start);
+ size_t s = next - start;
+ if (bufsize <= s)
+ return 0;
+ memcpy (buffer, start, s);
+ if (next < lf->buflim)
+ {
+ buffer[s] = 0;
+ lf->bufpos = next + 1;
+ return 1;
+ }
+ if (! lf_refill (lf))
+ return s ? 0 : EOF;
+ buffer += s;
+ bufsize -= s;
+ start = next;
+ }
+}
+
+
+
+int
+main (argc, argv)
+ int argc;
+ char *argv[];
+{
+ int opt;
+ char *editor;
+ char *differ;
+
+ initialize_main (&argc, &argv);
+ program_name = argv[0];
+
+ editor = getenv ("EDITOR");
+ if (editor)
+ edbin = editor;
+ differ = getenv ("DIFF");
+ if (differ)
+ diffbin = differ;
+
+ diffarg ("diff");
+
+ /* parse command line args */
+ while ((opt = getopt_long (argc, argv, "abBdHiI:lo:stvw:W", longopts, 0))
+ != EOF)
+ {
+ switch (opt)
+ {
+ case 'a':
+ diffarg ("-a");
+ break;
+
+ case 'b':
+ diffarg ("-b");
+ break;
+
+ case 'B':
+ diffarg ("-B");
+ break;
+
+ case 'd':
+ diffarg ("-d");
+ break;
+
+ case 'H':
+ diffarg ("-H");
+ break;
+
+ case 'i':
+ diffarg ("-i");
+ break;
+
+ case 'I':
+ diffarg ("-I");
+ diffarg (optarg);
+ break;
+
+ case 'l':
+ diffarg ("--left-column");
+ break;
+
+ case 'o':
+ out_file = optarg;
+ break;
+
+ case 's':
+ suppress_common_flag = 1;
+ break;
+
+ case 't':
+ diffarg ("-t");
+ break;
+
+ case 'v':
+ printf ("sdiff - GNU diffutils version %s\n", version_string);
+ exit (0);
+
+ case 'w':
+ diffarg ("-W");
+ diffarg (optarg);
+ break;
+
+ case 'W':
+ diffarg ("-w");
+ break;
+
+ case 129:
+ usage ();
+ if (ferror (stdout) || fclose (stdout) != 0)
+ fatal ("write error");
+ exit (0);
+
+ default:
+ try_help (0);
+ }
+ }
+
+ if (argc - optind != 2)
+ try_help (argc - optind < 2 ? "missing operand" : "extra operand");
+
+ if (! out_file)
+ {
+ /* easy case: diff does everything for us */
+ if (suppress_common_flag)
+ diffarg ("--suppress-common-lines");
+ diffarg ("-y");
+ diffarg ("--");
+ diffarg (argv[optind]);
+ diffarg (argv[optind + 1]);
+ diffarg (0);
+ execdiff ();
+ }
+ else
+ {
+ FILE *left, *right, *out, *diffout;
+ int interact_ok;
+ struct line_filter lfilt;
+ struct line_filter rfilt;
+ struct line_filter diff_filt;
+ int leftdir = diraccess (argv[optind]);
+ int rightdir = diraccess (argv[optind + 1]);
+
+ if (leftdir && rightdir)
+ fatal ("both files to be compared are directories");
+
+ left = ck_fopen (expand_name (argv[optind], leftdir, argv[optind + 1]), "r");
+ ;
+ right = ck_fopen (expand_name (argv[optind + 1], rightdir, argv[optind]), "r");
+ out = ck_fopen (out_file, "w");
+
+ diffarg ("--sdiff-merge-assist");
+ diffarg ("--");
+ diffarg (argv[optind]);
+ diffarg (argv[optind + 1]);
+ diffarg (0);
+
+ trapsigs ();
+
+#if ! HAVE_FORK
+ {
+ size_t cmdsize = 1;
+ char *p, *command;
+ int i;
+
+ for (i = 0; diffargv[i]; i++)
+ cmdsize += 4 * strlen (diffargv[i]) + 3;
+ command = p = xmalloc (cmdsize);
+ for (i = 0; diffargv[i]; i++)
+ {
+ char const *a = diffargv[i];
+ SYSTEM_QUOTE_ARG (p, a);
+ *p++ = ' ';
+ }
+ p[-1] = '\0';
+ diffout = popen (command, "r");
+ if (!diffout)
+ perror_fatal (command);
+ free (command);
+ }
+#else /* HAVE_FORK */
+ {
+ int diff_fds[2];
+
+ if (pipe (diff_fds) != 0)
+ perror_fatal ("pipe");
+
+ diffpid = vfork ();
+ if (diffpid < 0)
+ perror_fatal ("fork failed");
+ if (!diffpid)
+ {
+ signal (SIGINT, SIG_IGN); /* in case user interrupts editor */
+ signal (SIGPIPE, SIG_DFL);
+
+ close (diff_fds[0]);
+ if (diff_fds[1] != STDOUT_FILENO)
+ {
+ dup2 (diff_fds[1], STDOUT_FILENO);
+ close (diff_fds[1]);
+ }
+
+ execdiff ();
+ }
+
+ close (diff_fds[1]);
+ diffout = fdopen (diff_fds[0], "r");
+ if (!diffout)
+ perror_fatal ("fdopen");
+ }
+#endif /* HAVE_FORK */
+
+ lf_init (&diff_filt, diffout);
+ lf_init (&lfilt, left);
+ lf_init (&rfilt, right);
+
+ interact_ok = interact (&diff_filt, &lfilt, &rfilt, out);
+
+ ck_fclose (left);
+ ck_fclose (right);
+ ck_fclose (out);
+
+ {
+ int wstatus;
+
+#if ! HAVE_FORK
+ wstatus = pclose (diffout);
+#else
+ ck_fclose (diffout);
+ while (waitpid (diffpid, &wstatus, 0) < 0)
+ if (errno == EINTR)
+ checksigs ();
+ else
+ perror_fatal ("wait failed");
+ diffpid = 0;
+#endif
+
+ if (tmpmade)
+ {
+ unlink (tmpname);
+ tmpmade = 0;
+ }
+
+ if (! interact_ok)
+ exiterr ();
+
+ if (! (WIFEXITED (wstatus) && WEXITSTATUS (wstatus) < 2))
+ fatal ("Subsidiary diff failed");
+
+ untrapsig (0);
+ checksigs ();
+ exit (WEXITSTATUS (wstatus));
+ }
+ }
+ return 0; /* Fool -Wall . . . */
+}
+
+static void
+diffarg (a)
+ char const *a;
+{
+ static unsigned diffargs, diffargsmax;
+
+ if (diffargs == diffargsmax)
+ {
+ if (! diffargsmax)
+ {
+ diffargv = (char const **) xmalloc (sizeof (char));
+ diffargsmax = 8;
+ }
+ diffargsmax *= 2;
+ diffargv = (char const **) realloc (diffargv,
+ diffargsmax * sizeof (char const *));
+ if (! diffargv)
+ fatal ("out of memory");
+ }
+ diffargv[diffargs++] = a;
+}
+
+static void
+execdiff ()
+{
+ execvp (diffbin, (char **) diffargv);
+ write (STDERR_FILENO, diffbin, strlen (diffbin));
+ write (STDERR_FILENO, ": not found\n", 12);
+ _exit (2);
+}
+
+
+
+
+/* Signal handling */
+
+#define NUM_SIGS (sizeof (sigs) / sizeof (*sigs))
+static int const sigs[] = {
+#ifdef SIGHUP
+ SIGHUP,
+#endif
+#ifdef SIGQUIT
+ SIGQUIT,
+#endif
+#ifdef SIGTERM
+ SIGTERM,
+#endif
+#ifdef SIGXCPU
+ SIGXCPU,
+#endif
+#ifdef SIGXFSZ
+ SIGXFSZ,
+#endif
+ SIGINT,
+ SIGPIPE
+};
+
+/* Prefer `sigaction' if it is available, since `signal' can lose signals. */
+#if HAVE_SIGACTION
+static struct sigaction initial_action[NUM_SIGS];
+#define initial_handler(i) (initial_action[i].sa_handler)
+#else
+static RETSIGTYPE (*initial_action[NUM_SIGS]) ();
+#define initial_handler(i) (initial_action[i])
+#endif
+
+static int volatile ignore_SIGINT;
+static int volatile signal_received;
+static int sigs_trapped;
+
+static RETSIGTYPE
+catchsig (s)
+ int s;
+{
+#if ! HAVE_SIGACTION
+ signal (s, SIG_IGN);
+#endif
+ if (! (s == SIGINT && ignore_SIGINT))
+ signal_received = s;
+}
+
+static void
+trapsigs ()
+{
+ int i;
+
+#if HAVE_SIGACTION
+ struct sigaction catchaction;
+ bzero (&catchaction, sizeof (catchaction));
+ catchaction.sa_handler = catchsig;
+#ifdef SA_INTERRUPT
+ /* Non-Posix BSD-style systems like SunOS 4.1.x need this
+ so that `read' calls are interrupted properly. */
+ catchaction.sa_flags = SA_INTERRUPT;
+#endif
+ sigemptyset (&catchaction.sa_mask);
+ for (i = 0; i < NUM_SIGS; i++)
+ sigaddset (&catchaction.sa_mask, sigs[i]);
+ for (i = 0; i < NUM_SIGS; i++)
+ {
+ sigaction (sigs[i], 0, &initial_action[i]);
+ if (initial_handler (i) != SIG_IGN
+ && sigaction (sigs[i], &catchaction, 0) != 0)
+ fatal ("signal error");
+ }
+#else /* ! HAVE_SIGACTION */
+ for (i = 0; i < NUM_SIGS; i++)
+ {
+ initial_action[i] = signal (sigs[i], SIG_IGN);
+ if (initial_handler (i) != SIG_IGN
+ && signal (sigs[i], catchsig) != SIG_IGN)
+ fatal ("signal error");
+ }
+#endif /* ! HAVE_SIGACTION */
+
+#if !defined(SIGCHLD) && defined(SIGCLD)
+#define SIGCHLD SIGCLD
+#endif
+#ifdef SIGCHLD
+ /* System V fork+wait does not work if SIGCHLD is ignored. */
+ signal (SIGCHLD, SIG_DFL);
+#endif
+
+ sigs_trapped = 1;
+}
+
+/* Untrap signal S, or all trapped signals if S is zero. */
+static void
+untrapsig (s)
+ int s;
+{
+ int i;
+
+ if (sigs_trapped)
+ for (i = 0; i < NUM_SIGS; i++)
+ if ((!s || sigs[i] == s) && initial_handler (i) != SIG_IGN)
+#if HAVE_SIGACTION
+ sigaction (sigs[i], &initial_action[i], 0);
+#else
+ signal (sigs[i], initial_action[i]);
+#endif
+}
+
+/* Exit if a signal has been received. */
+static void
+checksigs ()
+{
+ int s = signal_received;
+ if (s)
+ {
+ cleanup ();
+
+ /* Yield an exit status indicating that a signal was received. */
+ untrapsig (s);
+ kill (getpid (), s);
+
+ /* That didn't work, so exit with error status. */
+ exit (2);
+ }
+}
+
+
+
+static void
+give_help ()
+{
+ fprintf (stderr,"l:\tuse the left version\n");
+ fprintf (stderr,"r:\tuse the right version\n");
+ fprintf (stderr,"e l:\tedit then use the left version\n");
+ fprintf (stderr,"e r:\tedit then use the right version\n");
+ fprintf (stderr,"e b:\tedit then use the left and right versions concatenated\n");
+ fprintf (stderr,"e:\tedit a new version\n");
+ fprintf (stderr,"s:\tsilently include common lines\n");
+ fprintf (stderr,"v:\tverbosely include common lines\n");
+ fprintf (stderr,"q:\tquit\n");
+}
+
+static int
+skip_white ()
+{
+ int c;
+ for (;;)
+ {
+ c = getchar ();
+ if (!ISSPACE (c) || c == '\n')
+ break;
+ checksigs ();
+ }
+ if (ferror (stdin))
+ perror_fatal ("input error");
+ return c;
+}
+
+static void
+flush_line ()
+{
+ int c;
+ while ((c = getchar ()) != '\n' && c != EOF)
+ ;
+ if (ferror (stdin))
+ perror_fatal ("input error");
+}
+
+
+/* interpret an edit command */
+static int
+edit (left, lenl, right, lenr, outfile)
+ struct line_filter *left;
+ int lenl;
+ struct line_filter *right;
+ int lenr;
+ FILE *outfile;
+{
+ for (;;)
+ {
+ int cmd0, cmd1;
+ int gotcmd = 0;
+
+ cmd1 = 0; /* Pacify `gcc -W'. */
+
+ while (!gotcmd)
+ {
+ if (putchar ('%') != '%')
+ perror_fatal ("output error");
+ ck_fflush (stdout);
+
+ cmd0 = skip_white ();
+ switch (cmd0)
+ {
+ case 'l': case 'r': case 's': case 'v': case 'q':
+ if (skip_white () != '\n')
+ {
+ give_help ();
+ flush_line ();
+ continue;
+ }
+ gotcmd = 1;
+ break;
+
+ case 'e':
+ cmd1 = skip_white ();
+ switch (cmd1)
+ {
+ case 'l': case 'r': case 'b':
+ if (skip_white () != '\n')
+ {
+ give_help ();
+ flush_line ();
+ continue;
+ }
+ gotcmd = 1;
+ break;
+ case '\n':
+ gotcmd = 1;
+ break;
+ default:
+ give_help ();
+ flush_line ();
+ continue;
+ }
+ break;
+ case EOF:
+ if (feof (stdin))
+ {
+ gotcmd = 1;
+ cmd0 = 'q';
+ break;
+ }
+ /* falls through */
+ default:
+ flush_line ();
+ /* falls through */
+ case '\n':
+ give_help ();
+ continue;
+ }
+ }
+
+ switch (cmd0)
+ {
+ case 'l':
+ lf_copy (left, lenl, outfile);
+ lf_skip (right, lenr);
+ return 1;
+ case 'r':
+ lf_copy (right, lenr, outfile);
+ lf_skip (left, lenl);
+ return 1;
+ case 's':
+ suppress_common_flag = 1;
+ break;
+ case 'v':
+ suppress_common_flag = 0;
+ break;
+ case 'q':
+ return 0;
+ case 'e':
+ if (! tmpname && ! (tmpname = private_tempnam ()))
+ perror_fatal ("temporary file name");
+
+ tmpmade = 1;
+
+ {
+ FILE *tmp = ck_fopen (tmpname, "w+");
+
+ if (cmd1 == 'l' || cmd1 == 'b')
+ lf_copy (left, lenl, tmp);
+ else
+ lf_skip (left, lenl);
+
+ if (cmd1 == 'r' || cmd1 == 'b')
+ lf_copy (right, lenr, tmp);
+ else
+ lf_skip (right, lenr);
+
+ ck_fflush (tmp);
+
+ {
+ int wstatus;
+#if ! HAVE_FORK
+ char *command = xmalloc (strlen (edbin) + strlen (tmpname) + 2);
+ sprintf (command, "%s %s", edbin, tmpname);
+ wstatus = system (command);
+ free (command);
+#else /* HAVE_FORK */
+ pid_t pid;
+
+ ignore_SIGINT = 1;
+ checksigs ();
+
+ pid = vfork ();
+ if (pid == 0)
+ {
+ char const *argv[3];
+ int i = 0;
+
+ argv[i++] = edbin;
+ argv[i++] = tmpname;
+ argv[i++] = 0;
+
+ execvp (edbin, (char **) argv);
+ write (STDERR_FILENO, edbin, strlen (edbin));
+ write (STDERR_FILENO, ": not found\n", 12);
+ _exit (1);
+ }
+
+ if (pid < 0)
+ perror_fatal ("fork failed");
+
+ while (waitpid (pid, &wstatus, 0) < 0)
+ if (errno == EINTR)
+ checksigs ();
+ else
+ perror_fatal ("wait failed");
+
+ ignore_SIGINT = 0;
+#endif /* HAVE_FORK */
+
+ if (wstatus != 0)
+ fatal ("Subsidiary editor failed");
+ }
+
+ if (fseek (tmp, 0L, SEEK_SET) != 0)
+ perror_fatal ("fseek");
+ {
+ /* SDIFF_BUFSIZE is too big for a local var
+ in some compilers, so we allocate it dynamically. */
+ char *buf = xmalloc (SDIFF_BUFSIZE);
+ size_t size;
+
+ while ((size = ck_fread (buf, SDIFF_BUFSIZE, tmp)) != 0)
+ {
+ checksigs ();
+ ck_fwrite (buf, size, outfile);
+ }
+ ck_fclose (tmp);
+
+ free (buf);
+ }
+ return 1;
+ }
+ default:
+ give_help ();
+ break;
+ }
+ }
+}
+
+
+
+/* Alternately reveal bursts of diff output and handle user commands. */
+static int
+interact (diff, left, right, outfile)
+ struct line_filter *diff;
+ struct line_filter *left;
+ struct line_filter *right;
+ FILE *outfile;
+{
+ for (;;)
+ {
+ char diff_help[256];
+ int snarfed = lf_snarf (diff, diff_help, sizeof (diff_help));
+
+ if (snarfed <= 0)
+ return snarfed;
+
+ checksigs ();
+
+ switch (diff_help[0])
+ {
+ case ' ':
+ puts (diff_help + 1);
+ break;
+ case 'i':
+ {
+ int lenl = atoi (diff_help + 1), lenr, lenmax;
+ char *p = strchr (diff_help, ',');
+
+ if (!p)
+ fatal (diff_help);
+ lenr = atoi (p + 1);
+ lenmax = max (lenl, lenr);
+
+ if (suppress_common_flag)
+ lf_skip (diff, lenmax);
+ else
+ lf_copy (diff, lenmax, stdout);
+
+ lf_copy (left, lenl, outfile);
+ lf_skip (right, lenr);
+ break;
+ }
+ case 'c':
+ {
+ int lenl = atoi (diff_help + 1), lenr;
+ char *p = strchr (diff_help, ',');
+
+ if (!p)
+ fatal (diff_help);
+ lenr = atoi (p + 1);
+ lf_copy (diff, max (lenl, lenr), stdout);
+ if (! edit (left, lenl, right, lenr, outfile))
+ return 0;
+ break;
+ }
+ default:
+ fatal (diff_help);
+ break;
+ }
+ }
+}
+
+
+
+/* temporary lossage: this is torn from gnu libc */
+/* Return nonzero if DIR is an existing directory. */
+static int
+diraccess (dir)
+ char const *dir;
+{
+ struct stat buf;
+ return stat (dir, &buf) == 0 && S_ISDIR (buf.st_mode);
+}
+
+#if ! HAVE_TMPNAM
+
+/* Return zero if we know that FILE does not exist. */
+static int
+exists (file)
+ char const *file;
+{
+ struct stat buf;
+ return stat (file, &buf) == 0 || errno != ENOENT;
+}
+
+/* These are the characters used in temporary filenames. */
+static char const letters[] =
+ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+/* Generate a temporary filename and return it (in a newly allocated buffer).
+ Use the prefix "dif" as in tempnam.
+ This goes through a cyclic pattern of all possible
+ filenames consisting of five decimal digits of the current pid and three
+ of the characters in `letters'. Each potential filename is
+ tested for an already-existing file of the same name, and no name of an
+ existing file will be returned. When the cycle reaches its end
+ return 0. */
+static char *
+private_tempnam ()
+{
+ char const *dir = getenv (TMPDIR_ENV);
+ static char const tmpdir[] = PVT_tmpdir;
+ size_t index;
+ char *buf;
+ pid_t pid = getpid ();
+ size_t dlen;
+
+ if (!dir)
+ dir = tmpdir;
+
+ dlen = strlen (dir);
+
+ /* Remove trailing slashes from the directory name. */
+ while (dlen && dir[dlen - 1] == '/')
+ --dlen;
+
+ buf = xmalloc (dlen + 1 + 3 + 5 + 1 + 3 + 1);
+
+ sprintf (buf, "%.*s/.", (int) dlen, dir);
+ if (diraccess (buf))
+ {
+ for (index = 0;
+ index < ((sizeof (letters) - 1) * (sizeof (letters) - 1)
+ * (sizeof (letters) - 1));
+ ++index)
+ {
+ /* Construct a file name and see if it already exists.
+
+ We use a single counter in INDEX to cycle each of three
+ character positions through each of 62 possible letters. */
+
+ sprintf (buf, "%.*s/dif%.5lu.%c%c%c", (int) dlen, dir,
+ (unsigned long) pid % 100000,
+ letters[index % (sizeof (letters) - 1)],
+ letters[(index / (sizeof (letters) - 1))
+ % (sizeof (letters) - 1)],
+ letters[index / ((sizeof (letters) - 1) *
+ (sizeof (letters) - 1))]);
+
+ if (!exists (buf))
+ return buf;
+ }
+ errno = EEXIST;
+ }
+
+ /* Don't free buf; `free' might change errno. We'll exit soon anyway. */
+ return 0;
+}
+
+#endif /* ! HAVE_TMPNAM */
diff --git a/gnu/dist/diffutils/side.c b/gnu/dist/diffutils/side.c
new file mode 100644
index 00000000000..a150b5e705f
--- /dev/null
+++ b/gnu/dist/diffutils/side.c
@@ -0,0 +1,284 @@
+/* sdiff-format output routines for GNU DIFF.
+ Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
+
+This file is part of GNU DIFF.
+
+GNU DIFF is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY. No author or distributor
+accepts responsibility to anyone for the consequences of using it
+or for whether it serves any particular purpose or works at all,
+unless he says so in writing. Refer to the GNU DIFF General Public
+License for full details.
+
+Everyone is granted permission to copy, modify and redistribute
+GNU DIFF, but only under the conditions described in the
+GNU DIFF General Public License. A copy of this license is
+supposed to have been given to you along with GNU DIFF so you
+can know your rights and responsibilities. It should be in a
+file named COPYING. Among other things, the copyright notice
+and this notice must be preserved on all copies. */
+
+
+#include "diff.h"
+
+static unsigned print_half_line PARAMS((char const * const *, unsigned, unsigned));
+static unsigned tab_from_to PARAMS((unsigned, unsigned));
+static void print_1sdiff_line PARAMS((char const * const *, int, char const * const *));
+static void print_sdiff_common_lines PARAMS((int, int));
+static void print_sdiff_hunk PARAMS((struct change *));
+
+/* Next line number to be printed in the two input files. */
+static int next0, next1;
+
+/* Print the edit-script SCRIPT as a sdiff style output. */
+
+void
+print_sdiff_script (script)
+ struct change *script;
+{
+ begin_output ();
+
+ next0 = next1 = - files[0].prefix_lines;
+ print_script (script, find_change, print_sdiff_hunk);
+
+ print_sdiff_common_lines (files[0].valid_lines, files[1].valid_lines);
+}
+
+/* Tab from column FROM to column TO, where FROM <= TO. Yield TO. */
+
+static unsigned
+tab_from_to (from, to)
+ unsigned from, to;
+{
+ FILE *out = outfile;
+ unsigned tab;
+
+ if (! tab_expand_flag)
+ for (tab = from + TAB_WIDTH - from % TAB_WIDTH; tab <= to; tab += TAB_WIDTH)
+ {
+ putc ('\t', out);
+ from = tab;
+ }
+ while (from++ < to)
+ putc (' ', out);
+ return to;
+}
+
+/*
+ * Print the text for half an sdiff line. This means truncate to width
+ * observing tabs, and trim a trailing newline. Returns the last column
+ * written (not the number of chars).
+ */
+static unsigned
+print_half_line (line, indent, out_bound)
+ char const * const *line;
+ unsigned indent, out_bound;
+{
+ FILE *out = outfile;
+ register unsigned in_position = 0, out_position = 0;
+ register char const
+ *text_pointer = line[0],
+ *text_limit = line[1];
+
+ while (text_pointer < text_limit)
+ {
+ register unsigned char c = *text_pointer++;
+
+ switch (c)
+ {
+ case '\t':
+ {
+ unsigned spaces = TAB_WIDTH - in_position % TAB_WIDTH;
+ if (in_position == out_position)
+ {
+ unsigned tabstop = out_position + spaces;
+ if (tab_expand_flag)
+ {
+ if (out_bound < tabstop)
+ tabstop = out_bound;
+ for (; out_position < tabstop; out_position++)
+ putc (' ', out);
+ }
+ else
+ if (tabstop < out_bound)
+ {
+ out_position = tabstop;
+ putc (c, out);
+ }
+ }
+ in_position += spaces;
+ }
+ break;
+
+ case '\r':
+ {
+ putc (c, out);
+ tab_from_to (0, indent);
+ in_position = out_position = 0;
+ }
+ break;
+
+ case '\b':
+ if (in_position != 0 && --in_position < out_bound)
+ if (out_position <= in_position)
+ /* Add spaces to make up for suppressed tab past out_bound. */
+ for (; out_position < in_position; out_position++)
+ putc (' ', out);
+ else
+ {
+ out_position = in_position;
+ putc (c, out);
+ }
+ break;
+
+ case '\f':
+ case '\v':
+ control_char:
+ if (in_position < out_bound)
+ putc (c, out);
+ break;
+
+ default:
+ if (! ISPRINT (c))
+ goto control_char;
+ /* falls through */
+ case ' ':
+ if (in_position++ < out_bound)
+ {
+ out_position = in_position;
+ putc (c, out);
+ }
+ break;
+
+ case '\n':
+ return out_position;
+ }
+ }
+
+ return out_position;
+}
+
+/*
+ * Print side by side lines with a separator in the middle.
+ * 0 parameters are taken to indicate white space text.
+ * Blank lines that can easily be caught are reduced to a single newline.
+ */
+
+static void
+print_1sdiff_line (left, sep, right)
+ char const * const *left;
+ int sep;
+ char const * const *right;
+{
+ FILE *out = outfile;
+ unsigned hw = sdiff_half_width, c2o = sdiff_column2_offset;
+ unsigned col = 0;
+ int put_newline = 0;
+
+ if (left)
+ {
+ if (left[1][-1] == '\n')
+ put_newline = 1;
+ col = print_half_line (left, 0, hw);
+ }
+
+ if (sep != ' ')
+ {
+ col = tab_from_to (col, (hw + c2o - 1) / 2) + 1;
+ if (sep == '|' && put_newline != (right[1][-1] == '\n'))
+ sep = put_newline ? '/' : '\\';
+ putc (sep, out);
+ }
+
+ if (right)
+ {
+ if (right[1][-1] == '\n')
+ put_newline = 1;
+ if (**right != '\n')
+ {
+ col = tab_from_to (col, c2o);
+ print_half_line (right, col, hw);
+ }
+ }
+
+ if (put_newline)
+ putc ('\n', out);
+}
+
+/* Print lines common to both files in side-by-side format. */
+static void
+print_sdiff_common_lines (limit0, limit1)
+ int limit0, limit1;
+{
+ int i0 = next0, i1 = next1;
+
+ if (! sdiff_skip_common_lines && (i0 != limit0 || i1 != limit1))
+ {
+ if (sdiff_help_sdiff)
+ fprintf (outfile, "i%d,%d\n", limit0 - i0, limit1 - i1);
+
+ if (! sdiff_left_only)
+ {
+ while (i0 != limit0 && i1 != limit1)
+ print_1sdiff_line (&files[0].linbuf[i0++], ' ', &files[1].linbuf[i1++]);
+ while (i1 != limit1)
+ print_1sdiff_line (0, ')', &files[1].linbuf[i1++]);
+ }
+ while (i0 != limit0)
+ print_1sdiff_line (&files[0].linbuf[i0++], '(', 0);
+ }
+
+ next0 = limit0;
+ next1 = limit1;
+}
+
+/* Print a hunk of an sdiff diff.
+ This is a contiguous portion of a complete edit script,
+ describing changes in consecutive lines. */
+
+static void
+print_sdiff_hunk (hunk)
+ struct change *hunk;
+{
+ int first0, last0, first1, last1, deletes, inserts;
+ register int i, j;
+
+ /* Determine range of line numbers involved in each file. */
+ analyze_hunk (hunk, &first0, &last0, &first1, &last1, &deletes, &inserts);
+ if (!deletes && !inserts)
+ return;
+
+ /* Print out lines up to this change. */
+ print_sdiff_common_lines (first0, first1);
+
+ if (sdiff_help_sdiff)
+ fprintf (outfile, "c%d,%d\n", last0 - first0 + 1, last1 - first1 + 1);
+
+ /* Print ``xxx | xxx '' lines */
+ if (inserts && deletes)
+ {
+ for (i = first0, j = first1; i <= last0 && j <= last1; ++i, ++j)
+ print_1sdiff_line (&files[0].linbuf[i], '|', &files[1].linbuf[j]);
+ deletes = i <= last0;
+ inserts = j <= last1;
+ next0 = first0 = i;
+ next1 = first1 = j;
+ }
+
+
+ /* Print `` > xxx '' lines */
+ if (inserts)
+ {
+ for (j = first1; j <= last1; ++j)
+ print_1sdiff_line (0, '>', &files[1].linbuf[j]);
+ next1 = j;
+ }
+
+ /* Print ``xxx < '' lines */
+ if (deletes)
+ {
+ for (i = first0; i <= last0; ++i)
+ print_1sdiff_line (&files[0].linbuf[i], '<', 0);
+ next0 = i;
+ }
+}
diff --git a/gnu/dist/diffutils/stamp-h.in b/gnu/dist/diffutils/stamp-h.in
new file mode 100644
index 00000000000..3e01c72e641
--- /dev/null
+++ b/gnu/dist/diffutils/stamp-h.in
@@ -0,0 +1 @@
+Fri Sep 30 22:22:28 PDT 1994
diff --git a/gnu/dist/diffutils/system.h b/gnu/dist/diffutils/system.h
new file mode 100644
index 00000000000..d60af60005f
--- /dev/null
+++ b/gnu/dist/diffutils/system.h
@@ -0,0 +1,267 @@
+/* System dependent declarations.
+ Copyright (C) 1988, 1989, 1992, 1993, 1994 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. */
+
+/* We must define `volatile' and `const' first (the latter inside config.h),
+ so that they're used consistently in all system includes. */
+#if !__STDC__
+#ifndef volatile
+#define volatile
+#endif
+#endif
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#if __STDC__
+#define PARAMS(args) args
+#define VOID void
+#else
+#define PARAMS(args) ()
+#define VOID char
+#endif
+
+#if STAT_MACROS_BROKEN
+#undef S_ISBLK
+#undef S_ISCHR
+#undef S_ISDIR
+#undef S_ISFIFO
+#undef S_ISREG
+#undef S_ISSOCK
+#endif
+#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 !defined(S_ISBLK) && defined(S_IFBLK)
+#define S_ISBLK(mode) (((mode) & S_IFMT) == S_IFBLK)
+#endif
+#if !defined(S_ISCHR) && defined(S_IFCHR)
+#define S_ISCHR(mode) (((mode) & S_IFMT) == S_IFCHR)
+#endif
+#if !defined(S_ISFIFO) && defined(S_IFFIFO)
+#define S_ISFIFO(mode) (((mode) & S_IFMT) == S_IFFIFO)
+#endif
+#if !defined(S_ISSOCK) && defined(S_IFSOCK)
+#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
+#endif
+
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#endif
+#ifndef SEEK_CUR
+#define SEEK_CUR 1
+#endif
+
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+#define STDOUT_FILENO 1
+#endif
+#ifndef STDERR_FILENO
+#define STDERR_FILENO 2
+#endif
+
+#if HAVE_TIME_H
+#include <time.h>
+#else
+#include <sys/time.h>
+#endif
+
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#else
+#if HAVE_SYS_FILE_H
+#include <sys/file.h>
+#endif
+#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
+#include <sys/wait.h>
+#endif
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(stat_val) ((unsigned) (stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+
+#ifndef STAT_BLOCKSIZE
+#if HAVE_ST_BLKSIZE
+#define STAT_BLOCKSIZE(s) (s).st_blksize
+#else
+#define STAT_BLOCKSIZE(s) (8 * 1024)
+#endif
+#endif
+
+#if HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+# define dirent direct
+# define NAMLEN(dirent) ((dirent)->d_namlen)
+# if HAVE_SYS_NDIR_H
+# include <sys/ndir.h>
+# endif
+# if HAVE_SYS_DIR_H
+# include <sys/dir.h>
+# endif
+# if HAVE_NDIR_H
+# include <ndir.h>
+# endif
+#endif
+
+#if HAVE_VFORK_H
+#include <vfork.h>
+#endif
+
+#if HAVE_STDLIB_H
+#include <stdlib.h>
+#else
+VOID *malloc ();
+VOID *realloc ();
+#endif
+#ifndef getenv
+char *getenv ();
+#endif
+
+#if HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifndef INT_MAX
+#define INT_MAX 2147483647
+#endif
+#ifndef CHAR_BIT
+#define CHAR_BIT 8
+#endif
+
+#if STDC_HEADERS || HAVE_STRING_H
+# include <string.h>
+# ifndef bzero
+# define bzero(s, n) memset (s, 0, n)
+# endif
+#else
+# if !HAVE_STRCHR
+# define strchr index
+# define strrchr rindex
+# endif
+char *strchr (), *strrchr ();
+# if !HAVE_MEMCHR
+# define memcmp(s1, s2, n) bcmp (s1, s2, n)
+# define memcpy(d, s, n) bcopy (s, d, n)
+void *memchr ();
+# endif
+#endif
+
+#include <ctype.h>
+/* CTYPE_DOMAIN (C) is nonzero if the unsigned char C can safely be given
+ as an argument to <ctype.h> macros like `isspace'. */
+#if STDC_HEADERS
+#define CTYPE_DOMAIN(c) 1
+#else
+#define CTYPE_DOMAIN(c) ((unsigned) (c) <= 0177)
+#endif
+#ifndef ISPRINT
+#define ISPRINT(c) (CTYPE_DOMAIN (c) && isprint (c))
+#endif
+#ifndef ISSPACE
+#define ISSPACE(c) (CTYPE_DOMAIN (c) && isspace (c))
+#endif
+#ifndef ISUPPER
+#define ISUPPER(c) (CTYPE_DOMAIN (c) && isupper (c))
+#endif
+
+#ifndef ISDIGIT
+#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
+#endif
+
+#include <errno.h>
+#if !STDC_HEADERS
+extern int errno;
+#endif
+
+#ifdef min
+#undef min
+#endif
+#ifdef max
+#undef max
+#endif
+#define min(a,b) ((a) <= (b) ? (a) : (b))
+#define max(a,b) ((a) >= (b) ? (a) : (b))
+
+/* This section contains Posix-compliant defaults for macros
+ that are meant to be overridden by hand in config.h as needed. */
+
+#ifndef filename_cmp
+#define filename_cmp(a, b) strcmp (a, b)
+#endif
+
+#ifndef filename_lastdirchar
+#define filename_lastdirchar(filename) strrchr (filename, '/')
+#endif
+
+#ifndef HAVE_FORK
+#define HAVE_FORK 1
+#endif
+
+#ifndef HAVE_SETMODE
+#define HAVE_SETMODE 0
+#endif
+
+#ifndef initialize_main
+#define initialize_main(argcp, argvp)
+#endif
+
+/* Do struct stat *S, *T describe the same file? Answer -1 if unknown. */
+#ifndef same_file
+#define same_file(s,t) ((s)->st_ino==(t)->st_ino && (s)->st_dev==(t)->st_dev)
+#endif
+
+/* Place into Q a quoted version of A suitable for `popen' or `system',
+ incrementing Q and junking A.
+ Do not increment Q by more than 4 * strlen (A) + 2. */
+#ifndef SYSTEM_QUOTE_ARG
+#define SYSTEM_QUOTE_ARG(q, a) \
+ { \
+ *(q)++ = '\''; \
+ for (; *(a); *(q)++ = *(a)++) \
+ if (*(a) == '\'') \
+ { \
+ *(q)++ = '\''; \
+ *(q)++ = '\\'; \
+ *(q)++ = '\''; \
+ } \
+ *(q)++ = '\''; \
+ }
+#endif
diff --git a/gnu/dist/diffutils/texinfo.tex b/gnu/dist/diffutils/texinfo.tex
new file mode 100644
index 00000000000..58ee9b87fb5
--- /dev/null
+++ b/gnu/dist/diffutils/texinfo.tex
@@ -0,0 +1,4344 @@
+%% TeX macros to handle texinfo files
+
+% Copyright (C) 1985, 86, 88, 90, 91, 92, 93, 1994 Free Software Foundation, Inc.
+
+%This texinfo.tex file 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 texinfo.tex file 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 texinfo.tex file; see the file COPYING. If not, write
+%to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
+%USA.
+
+
+%In other words, you are welcome to use, share and improve this program.
+%You are forbidden to forbid anyone else to use, share and improve
+%what you give them. Help stamp out software-hoarding!
+
+% This automatically updates the version number based on RCS.
+\def\deftexinfoversion$#1: #2 ${\def\texinfoversion{#2}}
+\deftexinfoversion$Revision: 1.1.1.1 $
+\message{Loading texinfo package [Version \texinfoversion]:}
+
+% Print the version number if in a .fmt file.
+\everyjob{\message{[Texinfo version \texinfoversion]}\message{}}
+
+% Save some parts of plain tex whose names we will redefine.
+
+\let\ptextilde=\~
+\let\ptexlbrace=\{
+\let\ptexrbrace=\}
+\let\ptexdots=\dots
+\let\ptexdot=\.
+\let\ptexstar=\*
+\let\ptexend=\end
+\let\ptexbullet=\bullet
+\let\ptexb=\b
+\let\ptexc=\c
+\let\ptexi=\i
+\let\ptext=\t
+\let\ptexl=\l
+\let\ptexL=\L
+
+% Be sure we're in horizontal mode when doing a tie, since we make space
+% equivalent to this in @example-like environments. Otherwise, a space
+% at the beginning of a line will start with \penalty -- and
+% since \penalty is valid in vertical mode, we'd end up putting the
+% penalty on the vertical list instead of in the new paragraph.
+{\catcode`@ = 11
+ \gdef\tie{\leavevmode\penalty\@M\ }
+}
+\let\~ = \tie % And make it available as @~.
+
+\message{Basics,}
+\chardef\other=12
+
+% If this character appears in an error message or help string, it
+% starts a new line in the output.
+\newlinechar = `^^J
+
+% Set up fixed words for English.
+\ifx\putwordChapter\undefined{\gdef\putwordChapter{Chapter}}\fi%
+\def\putwordInfo{Info}%
+\ifx\putwordSee\undefined{\gdef\putwordSee{See}}\fi%
+\ifx\putwordsee\undefined{\gdef\putwordsee{see}}\fi%
+\ifx\putwordfile\undefined{\gdef\putwordfile{file}}\fi%
+\ifx\putwordpage\undefined{\gdef\putwordpage{page}}\fi%
+\ifx\putwordsection\undefined{\gdef\putwordsection{section}}\fi%
+\ifx\putwordSection\undefined{\gdef\putwordSection{Section}}\fi%
+\ifx\putwordTableofContents\undefined{\gdef\putwordTableofContents{Table of Contents}}\fi%
+\ifx\putwordShortContents\undefined{\gdef\putwordShortContents{Short Contents}}\fi%
+\ifx\putwordAppendix\undefined{\gdef\putwordAppendix{Appendix}}\fi%
+
+% Ignore a token.
+%
+\def\gobble#1{}
+
+\hyphenation{ap-pen-dix}
+\hyphenation{mini-buf-fer mini-buf-fers}
+\hyphenation{eshell}
+
+% Margin to add to right of even pages, to left of odd pages.
+\newdimen \bindingoffset \bindingoffset=0pt
+\newdimen \normaloffset \normaloffset=\hoffset
+\newdimen\pagewidth \newdimen\pageheight
+\pagewidth=\hsize \pageheight=\vsize
+
+% Sometimes it is convenient to have everything in the transcript file
+% and nothing on the terminal. We don't just call \tracingall here,
+% since that produces some useless output on the terminal.
+%
+\def\gloggingall{\begingroup \globaldefs = 1 \loggingall \endgroup}%
+\def\loggingall{\tracingcommands2 \tracingstats2
+ \tracingpages1 \tracingoutput1 \tracinglostchars1
+ \tracingmacros2 \tracingparagraphs1 \tracingrestores1
+ \showboxbreadth\maxdimen\showboxdepth\maxdimen
+}%
+
+%---------------------Begin change-----------------------
+%
+%%%% For @cropmarks command.
+% Dimensions to add cropmarks at corners Added by P. A. MacKay, 12 Nov. 1986
+%
+\newdimen\cornerlong \newdimen\cornerthick
+\newdimen \topandbottommargin
+\newdimen \outerhsize \newdimen \outervsize
+\cornerlong=1pc\cornerthick=.3pt % These set size of cropmarks
+\outerhsize=7in
+%\outervsize=9.5in
+% Alternative @smallbook page size is 9.25in
+\outervsize=9.25in
+\topandbottommargin=.75in
+%
+%---------------------End change-----------------------
+
+% \onepageout takes a vbox as an argument. Note that \pagecontents
+% does insertions itself, but you have to call it yourself.
+\chardef\PAGE=255 \output={\onepageout{\pagecontents\PAGE}}
+\def\onepageout#1{\hoffset=\normaloffset
+\ifodd\pageno \advance\hoffset by \bindingoffset
+\else \advance\hoffset by -\bindingoffset\fi
+{\escapechar=`\\\relax % makes sure backslash is used in output files.
+\shipout\vbox{{\let\hsize=\pagewidth \makeheadline} \pagebody{#1}%
+{\let\hsize=\pagewidth \makefootline}}}%
+\advancepageno \ifnum\outputpenalty>-20000 \else\dosupereject\fi}
+
+%%%% For @cropmarks command %%%%
+
+% Here is a modification of the main output routine for Near East Publications
+% This provides right-angle cropmarks at all four corners.
+% The contents of the page are centerlined into the cropmarks,
+% and any desired binding offset is added as an \hskip on either
+% site of the centerlined box. (P. A. MacKay, 12 November, 1986)
+%
+\def\croppageout#1{\hoffset=0pt % make sure this doesn't mess things up
+{\escapechar=`\\\relax % makes sure backslash is used in output files.
+ \shipout
+ \vbox to \outervsize{\hsize=\outerhsize
+ \vbox{\line{\ewtop\hfill\ewtop}}
+ \nointerlineskip
+ \line{\vbox{\moveleft\cornerthick\nstop}
+ \hfill
+ \vbox{\moveright\cornerthick\nstop}}
+ \vskip \topandbottommargin
+ \centerline{\ifodd\pageno\hskip\bindingoffset\fi
+ \vbox{
+ {\let\hsize=\pagewidth \makeheadline}
+ \pagebody{#1}
+ {\let\hsize=\pagewidth \makefootline}}
+ \ifodd\pageno\else\hskip\bindingoffset\fi}
+ \vskip \topandbottommargin plus1fill minus1fill
+ \boxmaxdepth\cornerthick
+ \line{\vbox{\moveleft\cornerthick\nsbot}
+ \hfill
+ \vbox{\moveright\cornerthick\nsbot}}
+ \nointerlineskip
+ \vbox{\line{\ewbot\hfill\ewbot}}
+ }}
+ \advancepageno
+ \ifnum\outputpenalty>-20000 \else\dosupereject\fi}
+%
+% Do @cropmarks to get crop marks
+\def\cropmarks{\let\onepageout=\croppageout }
+
+\def\pagebody#1{\vbox to\pageheight{\boxmaxdepth=\maxdepth #1}}
+{\catcode`\@ =11
+\gdef\pagecontents#1{\ifvoid\topins\else\unvbox\topins\fi
+\dimen@=\dp#1 \unvbox#1
+\ifvoid\footins\else\vskip\skip\footins\footnoterule \unvbox\footins\fi
+\ifr@ggedbottom \kern-\dimen@ \vfil \fi}
+}
+
+%
+% Here are the rules for the cropmarks. Note that they are
+% offset so that the space between them is truly \outerhsize or \outervsize
+% (P. A. MacKay, 12 November, 1986)
+%
+\def\ewtop{\vrule height\cornerthick depth0pt width\cornerlong}
+\def\nstop{\vbox
+ {\hrule height\cornerthick depth\cornerlong width\cornerthick}}
+\def\ewbot{\vrule height0pt depth\cornerthick width\cornerlong}
+\def\nsbot{\vbox
+ {\hrule height\cornerlong depth\cornerthick width\cornerthick}}
+
+% Parse an argument, then pass it to #1. The argument is the rest of
+% the input line (except we remove a trailing comment). #1 should be a
+% macro which expects an ordinary undelimited TeX argument.
+%
+\def\parsearg#1{%
+ \let\next = #1%
+ \begingroup
+ \obeylines
+ \futurelet\temp\parseargx
+}
+
+% If the next token is an obeyed space (from an @example environment or
+% the like), remove it and recurse. Otherwise, we're done.
+\def\parseargx{%
+ % \obeyedspace is defined far below, after the definition of \sepspaces.
+ \ifx\obeyedspace\temp
+ \expandafter\parseargdiscardspace
+ \else
+ \expandafter\parseargline
+ \fi
+}
+
+% Remove a single space (as the delimiter token to the macro call).
+{\obeyspaces %
+ \gdef\parseargdiscardspace {\futurelet\temp\parseargx}}
+
+{\obeylines %
+ \gdef\parseargline#1^^M{%
+ \endgroup % End of the group started in \parsearg.
+ %
+ % First remove any @c comment, then any @comment.
+ % Result of each macro is put in \toks0.
+ \argremovec #1\c\relax %
+ \expandafter\argremovecomment \the\toks0 \comment\relax %
+ %
+ % Call the caller's macro, saved as \next in \parsearg.
+ \expandafter\next\expandafter{\the\toks0}%
+ }%
+}
+
+% Since all \c{,omment} does is throw away the argument, we can let TeX
+% do that for us. The \relax here is matched by the \relax in the call
+% in \parseargline; it could be more or less anything, its purpose is
+% just to delimit the argument to the \c.
+\def\argremovec#1\c#2\relax{\toks0 = {#1}}
+\def\argremovecomment#1\comment#2\relax{\toks0 = {#1}}
+
+% \argremovec{,omment} might leave us with trailing spaces, though; e.g.,
+% @end itemize @c foo
+% will have two active spaces as part of the argument with the
+% `itemize'. Here we remove all active spaces from #1, and assign the
+% result to \toks0.
+%
+% This loses if there are any *other* active characters besides spaces
+% in the argument -- _ ^ +, for example -- since they get expanded.
+% Fortunately, Texinfo does not define any such commands. (If it ever
+% does, the catcode of the characters in questionwill have to be changed
+% here.) But this means we cannot call \removeactivespaces as part of
+% \argremovec{,omment}, since @c uses \parsearg, and thus the argument
+% that \parsearg gets might well have any character at all in it.
+%
+\def\removeactivespaces#1{%
+ \begingroup
+ \ignoreactivespaces
+ \edef\temp{#1}%
+ \global\toks0 = \expandafter{\temp}%
+ \endgroup
+}
+
+% Change the active space to expand to nothing.
+%
+\begingroup
+ \obeyspaces
+ \gdef\ignoreactivespaces{\obeyspaces\let =\empty}
+\endgroup
+
+
+\def\flushcr{\ifx\par\lisppar \def\next##1{}\else \let\next=\relax \fi \next}
+
+%% These are used to keep @begin/@end levels from running away
+%% Call \inENV within environments (after a \begingroup)
+\newif\ifENV \ENVfalse \def\inENV{\ifENV\relax\else\ENVtrue\fi}
+\def\ENVcheck{%
+\ifENV\errmessage{Still within an environment. Type Return to continue.}
+\endgroup\fi} % This is not perfect, but it should reduce lossage
+
+% @begin foo is the same as @foo, for now.
+\newhelp\EMsimple{Type <Return> to continue.}
+
+\outer\def\begin{\parsearg\beginxxx}
+
+\def\beginxxx #1{%
+\expandafter\ifx\csname #1\endcsname\relax
+{\errhelp=\EMsimple \errmessage{Undefined command @begin #1}}\else
+\csname #1\endcsname\fi}
+
+% @end foo executes the definition of \Efoo.
+%
+\def\end{\parsearg\endxxx}
+\def\endxxx #1{%
+ \removeactivespaces{#1}%
+ \edef\endthing{\the\toks0}%
+ %
+ \expandafter\ifx\csname E\endthing\endcsname\relax
+ \expandafter\ifx\csname \endthing\endcsname\relax
+ % There's no \foo, i.e., no ``environment'' foo.
+ \errhelp = \EMsimple
+ \errmessage{Undefined command `@end \endthing'}%
+ \else
+ \unmatchedenderror\endthing
+ \fi
+ \else
+ % Everything's ok; the right environment has been started.
+ \csname E\endthing\endcsname
+ \fi
+}
+
+% There is an environment #1, but it hasn't been started. Give an error.
+%
+\def\unmatchedenderror#1{%
+ \errhelp = \EMsimple
+ \errmessage{This `@end #1' doesn't have a matching `@#1'}%
+}
+
+% Define the control sequence \E#1 to give an unmatched @end error.
+%
+\def\defineunmatchedend#1{%
+ \expandafter\def\csname E#1\endcsname{\unmatchedenderror{#1}}%
+}
+
+
+% Single-spacing is done by various environments (specifically, in
+% \nonfillstart and \quotations).
+\newskip\singlespaceskip \singlespaceskip = 12.5pt
+\def\singlespace{%
+ % Why was this kern here? It messes up equalizing space above and below
+ % environments. --karl, 6may93
+ %{\advance \baselineskip by -\singlespaceskip
+ %\kern \baselineskip}%
+ \setleading \singlespaceskip
+}
+
+%% Simple single-character @ commands
+
+% @@ prints an @
+% Kludge this until the fonts are right (grr).
+\def\@{{\tt \char '100}}
+
+% This is turned off because it was never documented
+% and you can use @w{...} around a quote to suppress ligatures.
+%% Define @` and @' to be the same as ` and '
+%% but suppressing ligatures.
+%\def\`{{`}}
+%\def\'{{'}}
+
+% Used to generate quoted braces.
+
+\def\mylbrace {{\tt \char '173}}
+\def\myrbrace {{\tt \char '175}}
+\let\{=\mylbrace
+\let\}=\myrbrace
+
+% @: forces normal size whitespace following.
+\def\:{\spacefactor=1000 }
+
+% @* forces a line break.
+\def\*{\hfil\break\hbox{}\ignorespaces}
+
+% @. is an end-of-sentence period.
+\def\.{.\spacefactor=3000 }
+
+% @w prevents a word break. Without the \leavevmode, @w at the
+% beginning of a paragraph, when TeX is still in vertical mode, would
+% produce a whole line of output instead of starting the paragraph.
+\def\w#1{\leavevmode\hbox{#1}}
+
+% @group ... @end group forces ... to be all on one page, by enclosing
+% it in a TeX vbox. We use \vtop instead of \vbox to construct the box
+% to keep its height that of a normal line. According to the rules for
+% \topskip (p.114 of the TeXbook), the glue inserted is
+% max (\topskip - \ht (first item), 0). If that height is large,
+% therefore, no glue is inserted, and the space between the headline and
+% the text is small, which looks bad.
+%
+\def\group{\begingroup
+ \ifnum\catcode13=\active \else
+ \errhelp = \groupinvalidhelp
+ \errmessage{@group invalid in context where filling is enabled}%
+ \fi
+ %
+ % The \vtop we start below produces a box with normal height and large
+ % depth; thus, TeX puts \baselineskip glue before it, and (when the
+ % next line of text is done) \lineskip glue after it. (See p.82 of
+ % the TeXbook.) Thus, space below is not quite equal to space
+ % above. But it's pretty close.
+ \def\Egroup{%
+ \egroup % End the \vtop.
+ \endgroup % End the \group.
+ }%
+ %
+ \vtop\bgroup
+ % We have to put a strut on the last line in case the @group is in
+ % the midst of an example, rather than completely enclosing it.
+ % Otherwise, the interline space between the last line of the group
+ % and the first line afterwards is too small. But we can't put the
+ % strut in \Egroup, since there it would be on a line by itself.
+ % Hence this just inserts a strut at the beginning of each line.
+ \everypar = {\strut}%
+ %
+ % Since we have a strut on every line, we don't need any of TeX's
+ % normal interline spacing.
+ \offinterlineskip
+ %
+ % OK, but now we have to do something about blank
+ % lines in the input in @example-like environments, which normally
+ % just turn into \lisppar, which will insert no space now that we've
+ % turned off the interline space. Simplest is to make them be an
+ % empty paragraph.
+ \ifx\par\lisppar
+ \edef\par{\leavevmode \par}%
+ %
+ % Reset ^^M's definition to new definition of \par.
+ \obeylines
+ \fi
+ %
+ % Do @comment since we are called inside an environment such as
+ % @example, where each end-of-line in the input causes an
+ % end-of-line in the output. We don't want the end-of-line after
+ % the `@group' to put extra space in the output. Since @group
+ % should appear on a line by itself (according to the Texinfo
+ % manual), we don't worry about eating any user text.
+ \comment
+}
+%
+% TeX puts in an \escapechar (i.e., `@') at the beginning of the help
+% message, so this ends up printing `@group can only ...'.
+%
+\newhelp\groupinvalidhelp{%
+group can only be used in environments such as @example,^^J%
+where each line of input produces a line of output.}
+
+% @need space-in-mils
+% forces a page break if there is not space-in-mils remaining.
+
+\newdimen\mil \mil=0.001in
+
+\def\need{\parsearg\needx}
+
+% Old definition--didn't work.
+%\def\needx #1{\par %
+%% This method tries to make TeX break the page naturally
+%% if the depth of the box does not fit.
+%{\baselineskip=0pt%
+%\vtop to #1\mil{\vfil}\kern -#1\mil\penalty 10000
+%\prevdepth=-1000pt
+%}}
+
+\def\needx#1{%
+ % Go into vertical mode, so we don't make a big box in the middle of a
+ % paragraph.
+ \par
+ %
+ % Don't add any leading before our big empty box, but allow a page
+ % break, since the best break might be right here.
+ \allowbreak
+ \nointerlineskip
+ \vtop to #1\mil{\vfil}%
+ %
+ % TeX does not even consider page breaks if a penalty added to the
+ % main vertical list is 10000 or more. But in order to see if the
+ % empty box we just added fits on the page, we must make it consider
+ % page breaks. On the other hand, we don't want to actually break the
+ % page after the empty box. So we use a penalty of 9999.
+ %
+ % There is an extremely small chance that TeX will actually break the
+ % page at this \penalty, if there are no other feasible breakpoints in
+ % sight. (If the user is using lots of big @group commands, which
+ % almost-but-not-quite fill up a page, TeX will have a hard time doing
+ % good page breaking, for example.) However, I could not construct an
+ % example where a page broke at this \penalty; if it happens in a real
+ % document, then we can reconsider our strategy.
+ \penalty9999
+ %
+ % Back up by the size of the box, whether we did a page break or not.
+ \kern -#1\mil
+ %
+ % Do not allow a page break right after this kern.
+ \nobreak
+}
+
+% @br forces paragraph break
+
+\let\br = \par
+
+% @dots{} output some dots
+
+\def\dots{$\ldots$}
+
+% @page forces the start of a new page
+
+\def\page{\par\vfill\supereject}
+
+% @exdent text....
+% outputs text on separate line in roman font, starting at standard page margin
+
+% This records the amount of indent in the innermost environment.
+% That's how much \exdent should take out.
+\newskip\exdentamount
+
+% This defn is used inside fill environments such as @defun.
+\def\exdent{\parsearg\exdentyyy}
+\def\exdentyyy #1{{\hfil\break\hbox{\kern -\exdentamount{\rm#1}}\hfil\break}}
+
+% This defn is used inside nofill environments such as @example.
+\def\nofillexdent{\parsearg\nofillexdentyyy}
+\def\nofillexdentyyy #1{{\advance \leftskip by -\exdentamount
+\leftline{\hskip\leftskip{\rm#1}}}}
+
+%\hbox{{\rm#1}}\hfil\break}}
+
+% @include file insert text of that file as input.
+
+\def\include{\parsearg\includezzz}
+%Use \input\thisfile to avoid blank after \input, which may be an active
+%char (in which case the blank would become the \input argument).
+%The grouping keeps the value of \thisfile correct even when @include
+%is nested.
+\def\includezzz #1{\begingroup
+\def\thisfile{#1}\input\thisfile
+\endgroup}
+
+\def\thisfile{}
+
+% @center line outputs that line, centered
+
+\def\center{\parsearg\centerzzz}
+\def\centerzzz #1{{\advance\hsize by -\leftskip
+\advance\hsize by -\rightskip
+\centerline{#1}}}
+
+% @sp n outputs n lines of vertical space
+
+\def\sp{\parsearg\spxxx}
+\def\spxxx #1{\par \vskip #1\baselineskip}
+
+% @comment ...line which is ignored...
+% @c is the same as @comment
+% @ignore ... @end ignore is another way to write a comment
+
+\def\comment{\catcode 64=\other \catcode 123=\other \catcode 125=\other%
+\parsearg \commentxxx}
+
+\def\commentxxx #1{\catcode 64=0 \catcode 123=1 \catcode 125=2 }
+
+\let\c=\comment
+
+% Prevent errors for section commands.
+% Used in @ignore and in failing conditionals.
+\def\ignoresections{%
+\let\chapter=\relax
+\let\unnumbered=\relax
+\let\top=\relax
+\let\unnumberedsec=\relax
+\let\unnumberedsection=\relax
+\let\unnumberedsubsec=\relax
+\let\unnumberedsubsection=\relax
+\let\unnumberedsubsubsec=\relax
+\let\unnumberedsubsubsection=\relax
+\let\section=\relax
+\let\subsec=\relax
+\let\subsubsec=\relax
+\let\subsection=\relax
+\let\subsubsection=\relax
+\let\appendix=\relax
+\let\appendixsec=\relax
+\let\appendixsection=\relax
+\let\appendixsubsec=\relax
+\let\appendixsubsection=\relax
+\let\appendixsubsubsec=\relax
+\let\appendixsubsubsection=\relax
+\let\contents=\relax
+\let\smallbook=\relax
+\let\titlepage=\relax
+}
+
+% Used in nested conditionals, where we have to parse the Texinfo source
+% and so want to turn off most commands, in case they are used
+% incorrectly.
+%
+\def\ignoremorecommands{%
+ \let\defcv = \relax
+ \let\deffn = \relax
+ \let\deffnx = \relax
+ \let\defindex = \relax
+ \let\defivar = \relax
+ \let\defmac = \relax
+ \let\defmethod = \relax
+ \let\defop = \relax
+ \let\defopt = \relax
+ \let\defspec = \relax
+ \let\deftp = \relax
+ \let\deftypefn = \relax
+ \let\deftypefun = \relax
+ \let\deftypevar = \relax
+ \let\deftypevr = \relax
+ \let\defun = \relax
+ \let\defvar = \relax
+ \let\defvr = \relax
+ \let\ref = \relax
+ \let\xref = \relax
+ \let\printindex = \relax
+ \let\pxref = \relax
+ \let\settitle = \relax
+ \let\include = \relax
+ \let\lowersections = \relax
+ \let\down = \relax
+ \let\raisesections = \relax
+ \let\up = \relax
+ \let\set = \relax
+ \let\clear = \relax
+ \let\item = \relax
+ \let\message = \relax
+}
+
+% Ignore @ignore ... @end ignore.
+%
+\def\ignore{\doignore{ignore}}
+
+% Also ignore @ifinfo, @menu, and @direntry text.
+%
+\def\ifinfo{\doignore{ifinfo}}
+\def\menu{\doignore{menu}}
+\def\direntry{\doignore{direntry}}
+
+% Ignore text until a line `@end #1'.
+%
+\def\doignore#1{\begingroup
+ % Don't complain about control sequences we have declared \outer.
+ \ignoresections
+ %
+ % Define a command to swallow text until we reach `@end #1'.
+ \long\def\doignoretext##1\end #1{\enddoignore}%
+ %
+ % Make sure that spaces turn into tokens that match what \doignoretext wants.
+ \catcode32 = 10
+ %
+ % And now expand that command.
+ \doignoretext
+}
+
+% What we do to finish off ignored text.
+%
+\def\enddoignore{\endgroup\ignorespaces}%
+
+\newif\ifwarnedobs\warnedobsfalse
+\def\obstexwarn{%
+ \ifwarnedobs\relax\else
+ % We need to warn folks that they may have trouble with TeX 3.0.
+ % This uses \immediate\write16 rather than \message to get newlines.
+ \immediate\write16{}
+ \immediate\write16{***WARNING*** for users of Unix TeX 3.0!}
+ \immediate\write16{This manual trips a bug in TeX version 3.0 (tex hangs).}
+ \immediate\write16{If you are running another version of TeX, relax.}
+ \immediate\write16{If you are running Unix TeX 3.0, kill this TeX process.}
+ \immediate\write16{ Then upgrade your TeX installation if you can.}
+ \immediate\write16{If you are stuck with version 3.0, run the}
+ \immediate\write16{ script ``tex3patch'' from the Texinfo distribution}
+ \immediate\write16{ to use a workaround.}
+ \immediate\write16{}
+ \warnedobstrue
+ \fi
+}
+
+% **In TeX 3.0, setting text in \nullfont hangs tex. For a
+% workaround (which requires the file ``dummy.tfm'' to be installed),
+% uncomment the following line:
+%%%%%\font\nullfont=dummy\let\obstexwarn=\relax
+
+% Ignore text, except that we keep track of conditional commands for
+% purposes of nesting, up to an `@end #1' command.
+%
+\def\nestedignore#1{%
+ \obstexwarn
+ % We must actually expand the ignored text to look for the @end
+ % command, so that nested ignore constructs work. Thus, we put the
+ % text into a \vbox and then do nothing with the result. To minimize
+ % the change of memory overflow, we follow the approach outlined on
+ % page 401 of the TeXbook: make the current font be a dummy font.
+ %
+ \setbox0 = \vbox\bgroup
+ % Don't complain about control sequences we have declared \outer.
+ \ignoresections
+ %
+ % Define `@end #1' to end the box, which will in turn undefine the
+ % @end command again.
+ \expandafter\def\csname E#1\endcsname{\egroup\ignorespaces}%
+ %
+ % We are going to be parsing Texinfo commands. Most cause no
+ % trouble when they are used incorrectly, but some commands do
+ % complicated argument parsing or otherwise get confused, so we
+ % undefine them.
+ %
+ % We can't do anything about stray @-signs, unfortunately;
+ % they'll produce `undefined control sequence' errors.
+ \ignoremorecommands
+ %
+ % Set the current font to be \nullfont, a TeX primitive, and define
+ % all the font commands to also use \nullfont. We don't use
+ % dummy.tfm, as suggested in the TeXbook, because not all sites
+ % might have that installed. Therefore, math mode will still
+ % produce output, but that should be an extremely small amount of
+ % stuff compared to the main input.
+ %
+ \nullfont
+ \let\tenrm = \nullfont \let\tenit = \nullfont \let\tensl = \nullfont
+ \let\tenbf = \nullfont \let\tentt = \nullfont \let\smallcaps = \nullfont
+ \let\tensf = \nullfont
+ % Similarly for index fonts (mostly for their use in
+ % smallexample)
+ \let\indrm = \nullfont \let\indit = \nullfont \let\indsl = \nullfont
+ \let\indbf = \nullfont \let\indtt = \nullfont \let\indsc = \nullfont
+ \let\indsf = \nullfont
+ %
+ % Don't complain when characters are missing from the fonts.
+ \tracinglostchars = 0
+ %
+ % Don't bother to do space factor calculations.
+ \frenchspacing
+ %
+ % Don't report underfull hboxes.
+ \hbadness = 10000
+ %
+ % Do minimal line-breaking.
+ \pretolerance = 10000
+ %
+ % Do not execute instructions in @tex
+ \def\tex{\doignore{tex}}
+}
+
+% @set VAR sets the variable VAR to an empty value.
+% @set VAR REST-OF-LINE sets VAR to the value REST-OF-LINE.
+%
+% Since we want to separate VAR from REST-OF-LINE (which might be
+% empty), we can't just use \parsearg; we have to insert a space of our
+% own to delimit the rest of the line, and then take it out again if we
+% didn't need it.
+%
+\def\set{\parsearg\setxxx}
+\def\setxxx#1{\setyyy#1 \endsetyyy}
+\def\setyyy#1 #2\endsetyyy{%
+ \def\temp{#2}%
+ \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty
+ \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted.
+ \fi
+}
+\def\setzzz#1#2 \endsetzzz{\expandafter\xdef\csname SET#1\endcsname{#2}}
+
+% @clear VAR clears (i.e., unsets) the variable VAR.
+%
+\def\clear{\parsearg\clearxxx}
+\def\clearxxx#1{\global\expandafter\let\csname SET#1\endcsname=\relax}
+
+% @value{foo} gets the text saved in variable foo.
+%
+\def\value#1{\expandafter
+ \ifx\csname SET#1\endcsname\relax
+ {\{No value for ``#1''\}}
+ \else \csname SET#1\endcsname \fi}
+
+% @ifset VAR ... @end ifset reads the `...' iff VAR has been defined
+% with @set.
+%
+\def\ifset{\parsearg\ifsetxxx}
+\def\ifsetxxx #1{%
+ \expandafter\ifx\csname SET#1\endcsname\relax
+ \expandafter\ifsetfail
+ \else
+ \expandafter\ifsetsucceed
+ \fi
+}
+\def\ifsetsucceed{\conditionalsucceed{ifset}}
+\def\ifsetfail{\nestedignore{ifset}}
+\defineunmatchedend{ifset}
+
+% @ifclear VAR ... @end ifclear reads the `...' iff VAR has never been
+% defined with @set, or has been undefined with @clear.
+%
+\def\ifclear{\parsearg\ifclearxxx}
+\def\ifclearxxx #1{%
+ \expandafter\ifx\csname SET#1\endcsname\relax
+ \expandafter\ifclearsucceed
+ \else
+ \expandafter\ifclearfail
+ \fi
+}
+\def\ifclearsucceed{\conditionalsucceed{ifclear}}
+\def\ifclearfail{\nestedignore{ifclear}}
+\defineunmatchedend{ifclear}
+
+% @iftex always succeeds; we read the text following, through @end
+% iftex). But `@end iftex' should be valid only after an @iftex.
+%
+\def\iftex{\conditionalsucceed{iftex}}
+\defineunmatchedend{iftex}
+
+% We can't just want to start a group at @iftex (for example) and end it
+% at @end iftex, since then @set commands inside the conditional have no
+% effect (they'd get reverted at the end of the group). So we must
+% define \Eiftex to redefine itself to be its previous value. (We can't
+% just define it to fail again with an ``unmatched end'' error, since
+% the @ifset might be nested.)
+%
+\def\conditionalsucceed#1{%
+ \edef\temp{%
+ % Remember the current value of \E#1.
+ \let\nece{prevE#1} = \nece{E#1}%
+ %
+ % At the `@end #1', redefine \E#1 to be its previous value.
+ \def\nece{E#1}{\let\nece{E#1} = \nece{prevE#1}}%
+ }%
+ \temp
+}
+
+% We need to expand lots of \csname's, but we don't want to expand the
+% control sequences after we've constructed them.
+%
+\def\nece#1{\expandafter\noexpand\csname#1\endcsname}
+
+% @asis just yields its argument. Used with @table, for example.
+%
+\def\asis#1{#1}
+
+% @math means output in math mode.
+% We don't use $'s directly in the definition of \math because control
+% sequences like \math are expanded when the toc file is written. Then,
+% we read the toc file back, the $'s will be normal characters (as they
+% should be, according to the definition of Texinfo). So we must use a
+% control sequence to switch into and out of math mode.
+%
+% This isn't quite enough for @math to work properly in indices, but it
+% seems unlikely it will ever be needed there.
+%
+\let\implicitmath = $
+\def\math#1{\implicitmath #1\implicitmath}
+
+% @bullet and @minus need the same treatment as @math, just above.
+\def\bullet{\implicitmath\ptexbullet\implicitmath}
+\def\minus{\implicitmath-\implicitmath}
+
+\def\node{\ENVcheck\parsearg\nodezzz}
+\def\nodezzz#1{\nodexxx [#1,]}
+\def\nodexxx[#1,#2]{\gdef\lastnode{#1}}
+\let\nwnode=\node
+\let\lastnode=\relax
+
+\def\donoderef{\ifx\lastnode\relax\else
+\expandafter\expandafter\expandafter\setref{\lastnode}\fi
+\global\let\lastnode=\relax}
+
+\def\unnumbnoderef{\ifx\lastnode\relax\else
+\expandafter\expandafter\expandafter\unnumbsetref{\lastnode}\fi
+\global\let\lastnode=\relax}
+
+\def\appendixnoderef{\ifx\lastnode\relax\else
+\expandafter\expandafter\expandafter\appendixsetref{\lastnode}\fi
+\global\let\lastnode=\relax}
+
+\let\refill=\relax
+
+% @setfilename is done at the beginning of every texinfo file.
+% So open here the files we need to have open while reading the input.
+% This makes it possible to make a .fmt file for texinfo.
+\def\setfilename{%
+ \readauxfile
+ \opencontents
+ \openindices
+ \fixbackslash % Turn off hack to swallow `\input texinfo'.
+ \global\let\setfilename=\comment % Ignore extra @setfilename cmds.
+ \comment % Ignore the actual filename.
+}
+
+\outer\def\bye{\pagealignmacro\tracingstats=1\ptexend}
+
+\def\inforef #1{\inforefzzz #1,,,,**}
+\def\inforefzzz #1,#2,#3,#4**{\putwordSee{} \putwordInfo{} \putwordfile{} \file{\ignorespaces #3{}},
+ node \samp{\ignorespaces#1{}}}
+
+\message{fonts,}
+
+% Font-change commands.
+
+% Texinfo supports the sans serif font style, which plain TeX does not.
+% So we set up a \sf analogous to plain's \rm, etc.
+\newfam\sffam
+\def\sf{\fam=\sffam \tensf}
+\let\li = \sf % Sometimes we call it \li, not \sf.
+
+%% Try out Computer Modern fonts at \magstephalf
+\let\mainmagstep=\magstephalf
+
+\ifx\bigger\relax
+\let\mainmagstep=\magstep1
+\font\textrm=cmr12
+\font\texttt=cmtt12
+\else
+\font\textrm=cmr10 scaled \mainmagstep
+\font\texttt=cmtt10 scaled \mainmagstep
+\fi
+% Instead of cmb10, you many want to use cmbx10.
+% cmbx10 is a prettier font on its own, but cmb10
+% looks better when embedded in a line with cmr10.
+\font\textbf=cmb10 scaled \mainmagstep
+\font\textit=cmti10 scaled \mainmagstep
+\font\textsl=cmsl10 scaled \mainmagstep
+\font\textsf=cmss10 scaled \mainmagstep
+\font\textsc=cmcsc10 scaled \mainmagstep
+\font\texti=cmmi10 scaled \mainmagstep
+\font\textsy=cmsy10 scaled \mainmagstep
+
+% A few fonts for @defun, etc.
+\font\defbf=cmbx10 scaled \magstep1 %was 1314
+\font\deftt=cmtt10 scaled \magstep1
+\def\df{\let\tentt=\deftt \let\tenbf = \defbf \bf}
+
+% Fonts for indices and small examples.
+% We actually use the slanted font rather than the italic,
+% because texinfo normally uses the slanted fonts for that.
+% Do not make many font distinctions in general in the index, since they
+% aren't very useful.
+\font\ninett=cmtt9
+\font\indrm=cmr9
+\font\indit=cmsl9
+\let\indsl=\indit
+\let\indtt=\ninett
+\let\indsf=\indrm
+\let\indbf=\indrm
+\let\indsc=\indrm
+\font\indi=cmmi9
+\font\indsy=cmsy9
+
+% Fonts for headings
+\font\chaprm=cmbx12 scaled \magstep2
+\font\chapit=cmti12 scaled \magstep2
+\font\chapsl=cmsl12 scaled \magstep2
+\font\chaptt=cmtt12 scaled \magstep2
+\font\chapsf=cmss12 scaled \magstep2
+\let\chapbf=\chaprm
+\font\chapsc=cmcsc10 scaled\magstep3
+\font\chapi=cmmi12 scaled \magstep2
+\font\chapsy=cmsy10 scaled \magstep3
+
+\font\secrm=cmbx12 scaled \magstep1
+\font\secit=cmti12 scaled \magstep1
+\font\secsl=cmsl12 scaled \magstep1
+\font\sectt=cmtt12 scaled \magstep1
+\font\secsf=cmss12 scaled \magstep1
+\font\secbf=cmbx12 scaled \magstep1
+\font\secsc=cmcsc10 scaled\magstep2
+\font\seci=cmmi12 scaled \magstep1
+\font\secsy=cmsy10 scaled \magstep2
+
+% \font\ssecrm=cmbx10 scaled \magstep1 % This size an font looked bad.
+% \font\ssecit=cmti10 scaled \magstep1 % The letters were too crowded.
+% \font\ssecsl=cmsl10 scaled \magstep1
+% \font\ssectt=cmtt10 scaled \magstep1
+% \font\ssecsf=cmss10 scaled \magstep1
+
+%\font\ssecrm=cmb10 scaled 1315 % Note the use of cmb rather than cmbx.
+%\font\ssecit=cmti10 scaled 1315 % Also, the size is a little larger than
+%\font\ssecsl=cmsl10 scaled 1315 % being scaled magstep1.
+%\font\ssectt=cmtt10 scaled 1315
+%\font\ssecsf=cmss10 scaled 1315
+
+%\let\ssecbf=\ssecrm
+
+\font\ssecrm=cmbx12 scaled \magstephalf
+\font\ssecit=cmti12 scaled \magstephalf
+\font\ssecsl=cmsl12 scaled \magstephalf
+\font\ssectt=cmtt12 scaled \magstephalf
+\font\ssecsf=cmss12 scaled \magstephalf
+\font\ssecbf=cmbx12 scaled \magstephalf
+\font\ssecsc=cmcsc10 scaled \magstep1
+\font\sseci=cmmi12 scaled \magstephalf
+\font\ssecsy=cmsy10 scaled \magstep1
+% The smallcaps and symbol fonts should actually be scaled \magstep1.5,
+% but that is not a standard magnification.
+
+% Fonts for title page:
+\font\titlerm = cmbx12 scaled \magstep3
+\let\authorrm = \secrm
+
+% In order for the font changes to affect most math symbols and letters,
+% we have to define the \textfont of the standard families. Since
+% texinfo doesn't allow for producing subscripts and superscripts, we
+% don't bother to reset \scriptfont and \scriptscriptfont (which would
+% also require loading a lot more fonts).
+%
+\def\resetmathfonts{%
+ \textfont0 = \tenrm \textfont1 = \teni \textfont2 = \tensy
+ \textfont\itfam = \tenit \textfont\slfam = \tensl \textfont\bffam = \tenbf
+ \textfont\ttfam = \tentt \textfont\sffam = \tensf
+}
+
+
+% The font-changing commands redefine the meanings of \tenSTYLE, instead
+% of just \STYLE. We do this so that font changes will continue to work
+% in math mode, where it is the current \fam that is relevant in most
+% cases, not the current. Plain TeX does, for example,
+% \def\bf{\fam=\bffam \tenbf} By redefining \tenbf, we obviate the need
+% to redefine \bf itself.
+\def\textfonts{%
+ \let\tenrm=\textrm \let\tenit=\textit \let\tensl=\textsl
+ \let\tenbf=\textbf \let\tentt=\texttt \let\smallcaps=\textsc
+ \let\tensf=\textsf \let\teni=\texti \let\tensy=\textsy
+ \resetmathfonts}
+\def\chapfonts{%
+ \let\tenrm=\chaprm \let\tenit=\chapit \let\tensl=\chapsl
+ \let\tenbf=\chapbf \let\tentt=\chaptt \let\smallcaps=\chapsc
+ \let\tensf=\chapsf \let\teni=\chapi \let\tensy=\chapsy
+ \resetmathfonts}
+\def\secfonts{%
+ \let\tenrm=\secrm \let\tenit=\secit \let\tensl=\secsl
+ \let\tenbf=\secbf \let\tentt=\sectt \let\smallcaps=\secsc
+ \let\tensf=\secsf \let\teni=\seci \let\tensy=\secsy
+ \resetmathfonts}
+\def\subsecfonts{%
+ \let\tenrm=\ssecrm \let\tenit=\ssecit \let\tensl=\ssecsl
+ \let\tenbf=\ssecbf \let\tentt=\ssectt \let\smallcaps=\ssecsc
+ \let\tensf=\ssecsf \let\teni=\sseci \let\tensy=\ssecsy
+ \resetmathfonts}
+\def\indexfonts{%
+ \let\tenrm=\indrm \let\tenit=\indit \let\tensl=\indsl
+ \let\tenbf=\indbf \let\tentt=\indtt \let\smallcaps=\indsc
+ \let\tensf=\indsf \let\teni=\indi \let\tensy=\indsy
+ \resetmathfonts}
+
+% Set up the default fonts, so we can use them for creating boxes.
+%
+\textfonts
+
+% Count depth in font-changes, for error checks
+\newcount\fontdepth \fontdepth=0
+
+% Fonts for short table of contents.
+\font\shortcontrm=cmr12
+\font\shortcontbf=cmbx12
+\font\shortcontsl=cmsl12
+
+%% Add scribe-like font environments, plus @l for inline lisp (usually sans
+%% serif) and @ii for TeX italic
+
+% \smartitalic{ARG} outputs arg in italics, followed by an italic correction
+% unless the following character is such as not to need one.
+\def\smartitalicx{\ifx\next,\else\ifx\next-\else\ifx\next.\else\/\fi\fi\fi}
+\def\smartitalic#1{{\sl #1}\futurelet\next\smartitalicx}
+
+\let\i=\smartitalic
+\let\var=\smartitalic
+\let\dfn=\smartitalic
+\let\emph=\smartitalic
+\let\cite=\smartitalic
+
+\def\b#1{{\bf #1}}
+\let\strong=\b
+
+% We can't just use \exhyphenpenalty, because that only has effect at
+% the end of a paragraph. Restore normal hyphenation at the end of the
+% group within which \nohyphenation is presumably called.
+%
+\def\nohyphenation{\hyphenchar\font = -1 \aftergroup\restorehyphenation}
+\def\restorehyphenation{\hyphenchar\font = `- }
+
+\def\t#1{%
+ {\tt \nohyphenation \rawbackslash \frenchspacing #1}%
+ \null
+}
+\let\ttfont = \t
+%\def\samp #1{`{\tt \rawbackslash \frenchspacing #1}'\null}
+\def\samp #1{`\tclose{#1}'\null}
+\def\key #1{{\tt \nohyphenation \uppercase{#1}}\null}
+\def\ctrl #1{{\tt \rawbackslash \hat}#1}
+
+\let\file=\samp
+
+% @code is a modification of @t,
+% which makes spaces the same size as normal in the surrounding text.
+\def\tclose#1{%
+ {%
+ % Change normal interword space to be same as for the current font.
+ \spaceskip = \fontdimen2\font
+ %
+ % Switch to typewriter.
+ \tt
+ %
+ % But `\ ' produces the large typewriter interword space.
+ \def\ {{\spaceskip = 0pt{} }}%
+ %
+ % Turn off hyphenation.
+ \nohyphenation
+ %
+ \rawbackslash
+ \frenchspacing
+ #1%
+ }%
+ \null
+}
+
+% We *must* turn on hyphenation at `-' and `_' in \code.
+% Otherwise, it is too hard to avoid overful hboxes
+% in the Emacs manual, the Library manual, etc.
+
+% Unfortunately, TeX uses one parameter (\hyphenchar) to control
+% both hyphenation at - and hyphenation within words.
+% We must therefore turn them both off (\tclose does that)
+% and arrange explicitly to hyphenate an a dash.
+% -- rms.
+{
+\catcode`\-=\active
+\catcode`\_=\active
+\global\def\code{\begingroup \catcode`\-=\active \let-\codedash \catcode`\_=\active \let_\codeunder \codex}
+% The following is used by \doprintindex to insure that long function names
+% wrap around. It is necessary for - and _ to be active before the index is
+% read from the file, as \entry parses the arguments long before \code is
+% ever called. -- mycroft
+\global\def\indexbreaks{\catcode`\-=\active \let-\realdash \catcode`\_=\active \let_\realunder}
+}
+\def\realdash{-}
+\def\realunder{_}
+\def\codedash{-\discretionary{}{}{}}
+\def\codeunder{\normalunderscore\discretionary{}{}{}}
+\def\codex #1{\tclose{#1}\endgroup}
+
+%\let\exp=\tclose %Was temporary
+
+% @kbd is like @code, except that if the argument is just one @key command,
+% then @kbd has no effect.
+
+\def\xkey{\key}
+\def\kbdfoo#1#2#3\par{\def\one{#1}\def\three{#3}\def\threex{??}%
+\ifx\one\xkey\ifx\threex\three \key{#2}%
+\else\tclose{\look}\fi
+\else\tclose{\look}\fi}
+
+% Typeset a dimension, e.g., `in' or `pt'. The only reason for the
+% argument is to make the input look right: @dmn{pt} instead of
+% @dmn{}pt.
+%
+\def\dmn#1{\thinspace #1}
+
+\def\kbd#1{\def\look{#1}\expandafter\kbdfoo\look??\par}
+
+\def\l#1{{\li #1}\null} %
+
+\def\r#1{{\rm #1}} % roman font
+% Use of \lowercase was suggested.
+\def\sc#1{{\smallcaps#1}} % smallcaps font
+\def\ii#1{{\it #1}} % italic font
+
+\message{page headings,}
+
+\newskip\titlepagetopglue \titlepagetopglue = 1.5in
+\newskip\titlepagebottomglue \titlepagebottomglue = 2pc
+
+% First the title page. Must do @settitle before @titlepage.
+\def\titlefont#1{{\titlerm #1}}
+
+\newif\ifseenauthor
+\newif\iffinishedtitlepage
+
+\def\shorttitlepage{\parsearg\shorttitlepagezzz}
+\def\shorttitlepagezzz #1{\begingroup\hbox{}\vskip 1.5in \chaprm \centerline{#1}%
+ \endgroup\page\hbox{}\page}
+
+\def\titlepage{\begingroup \parindent=0pt \textfonts
+ \let\subtitlerm=\tenrm
+% I deinstalled the following change because \cmr12 is undefined.
+% This change was not in the ChangeLog anyway. --rms.
+% \let\subtitlerm=\cmr12
+ \def\subtitlefont{\subtitlerm \normalbaselineskip = 13pt \normalbaselines}%
+ %
+ \def\authorfont{\authorrm \normalbaselineskip = 16pt \normalbaselines}%
+ %
+ % Leave some space at the very top of the page.
+ \vglue\titlepagetopglue
+ %
+ % Now you can print the title using @title.
+ \def\title{\parsearg\titlezzz}%
+ \def\titlezzz##1{\leftline{\titlefont{##1}}
+ % print a rule at the page bottom also.
+ \finishedtitlepagefalse
+ \vskip4pt \hrule height 4pt width \hsize \vskip4pt}%
+ % No rule at page bottom unless we print one at the top with @title.
+ \finishedtitlepagetrue
+ %
+ % Now you can put text using @subtitle.
+ \def\subtitle{\parsearg\subtitlezzz}%
+ \def\subtitlezzz##1{{\subtitlefont \rightline{##1}}}%
+ %
+ % @author should come last, but may come many times.
+ \def\author{\parsearg\authorzzz}%
+ \def\authorzzz##1{\ifseenauthor\else\vskip 0pt plus 1filll\seenauthortrue\fi
+ {\authorfont \leftline{##1}}}%
+ %
+ % Most title ``pages'' are actually two pages long, with space
+ % at the top of the second. We don't want the ragged left on the second.
+ \let\oldpage = \page
+ \def\page{%
+ \iffinishedtitlepage\else
+ \finishtitlepage
+ \fi
+ \oldpage
+ \let\page = \oldpage
+ \hbox{}}%
+% \def\page{\oldpage \hbox{}}
+}
+
+\def\Etitlepage{%
+ \iffinishedtitlepage\else
+ \finishtitlepage
+ \fi
+ % It is important to do the page break before ending the group,
+ % because the headline and footline are only empty inside the group.
+ % If we use the new definition of \page, we always get a blank page
+ % after the title page, which we certainly don't want.
+ \oldpage
+ \endgroup
+ \HEADINGSon
+}
+
+\def\finishtitlepage{%
+ \vskip4pt \hrule height 2pt width \hsize
+ \vskip\titlepagebottomglue
+ \finishedtitlepagetrue
+}
+
+%%% Set up page headings and footings.
+
+\let\thispage=\folio
+
+\newtoks \evenheadline % Token sequence for heading line of even pages
+\newtoks \oddheadline % Token sequence for heading line of odd pages
+\newtoks \evenfootline % Token sequence for footing line of even pages
+\newtoks \oddfootline % Token sequence for footing line of odd pages
+
+% Now make Tex use those variables
+\headline={{\textfonts\rm \ifodd\pageno \the\oddheadline
+ \else \the\evenheadline \fi}}
+\footline={{\textfonts\rm \ifodd\pageno \the\oddfootline
+ \else \the\evenfootline \fi}\HEADINGShook}
+\let\HEADINGShook=\relax
+
+% Commands to set those variables.
+% For example, this is what @headings on does
+% @evenheading @thistitle|@thispage|@thischapter
+% @oddheading @thischapter|@thispage|@thistitle
+% @evenfooting @thisfile||
+% @oddfooting ||@thisfile
+
+\def\evenheading{\parsearg\evenheadingxxx}
+\def\oddheading{\parsearg\oddheadingxxx}
+\def\everyheading{\parsearg\everyheadingxxx}
+
+\def\evenfooting{\parsearg\evenfootingxxx}
+\def\oddfooting{\parsearg\oddfootingxxx}
+\def\everyfooting{\parsearg\everyfootingxxx}
+
+{\catcode`\@=0 %
+
+\gdef\evenheadingxxx #1{\evenheadingyyy #1@|@|@|@|\finish}
+\gdef\evenheadingyyy #1@|#2@|#3@|#4\finish{%
+\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\gdef\oddheadingxxx #1{\oddheadingyyy #1@|@|@|@|\finish}
+\gdef\oddheadingyyy #1@|#2@|#3@|#4\finish{%
+\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\gdef\everyheadingxxx #1{\everyheadingyyy #1@|@|@|@|\finish}
+\gdef\everyheadingyyy #1@|#2@|#3@|#4\finish{%
+\global\evenheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}
+\global\oddheadline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\gdef\evenfootingxxx #1{\evenfootingyyy #1@|@|@|@|\finish}
+\gdef\evenfootingyyy #1@|#2@|#3@|#4\finish{%
+\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\gdef\oddfootingxxx #1{\oddfootingyyy #1@|@|@|@|\finish}
+\gdef\oddfootingyyy #1@|#2@|#3@|#4\finish{%
+\global\oddfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+
+\gdef\everyfootingxxx #1{\everyfootingyyy #1@|@|@|@|\finish}
+\gdef\everyfootingyyy #1@|#2@|#3@|#4\finish{%
+\global\evenfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}
+\global\oddfootline={\rlap{\centerline{#2}}\line{#1\hfil#3}}}
+%
+}% unbind the catcode of @.
+
+% @headings double turns headings on for double-sided printing.
+% @headings single turns headings on for single-sided printing.
+% @headings off turns them off.
+% @headings on same as @headings double, retained for compatibility.
+% @headings after turns on double-sided headings after this page.
+% @headings doubleafter turns on double-sided headings after this page.
+% @headings singleafter turns on single-sided headings after this page.
+% By default, they are off.
+
+\def\headings #1 {\csname HEADINGS#1\endcsname}
+
+\def\HEADINGSoff{
+\global\evenheadline={\hfil} \global\evenfootline={\hfil}
+\global\oddheadline={\hfil} \global\oddfootline={\hfil}}
+\HEADINGSoff
+% When we turn headings on, set the page number to 1.
+% For double-sided printing, put current file name in lower left corner,
+% chapter name on inside top of right hand pages, document
+% title on inside top of left hand pages, and page numbers on outside top
+% edge of all pages.
+\def\HEADINGSdouble{
+%\pagealignmacro
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+}
+% For single-sided printing, chapter title goes across top left of page,
+% page number on top right.
+\def\HEADINGSsingle{
+%\pagealignmacro
+\global\pageno=1
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+}
+\def\HEADINGSon{\HEADINGSdouble}
+
+\def\HEADINGSafter{\let\HEADINGShook=\HEADINGSdoublex}
+\let\HEADINGSdoubleafter=\HEADINGSafter
+\def\HEADINGSdoublex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\folio\hfil\thistitle}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+}
+
+\def\HEADINGSsingleafter{\let\HEADINGShook=\HEADINGSsinglex}
+\def\HEADINGSsinglex{%
+\global\evenfootline={\hfil}
+\global\oddfootline={\hfil}
+\global\evenheadline={\line{\thischapter\hfil\folio}}
+\global\oddheadline={\line{\thischapter\hfil\folio}}
+}
+
+% Subroutines used in generating headings
+% Produces Day Month Year style of output.
+\def\today{\number\day\space
+\ifcase\month\or
+January\or February\or March\or April\or May\or June\or
+July\or August\or September\or October\or November\or December\fi
+\space\number\year}
+
+% Use this if you want the Month Day, Year style of output.
+%\def\today{\ifcase\month\or
+%January\or February\or March\or April\or May\or June\or
+%July\or August\or September\or October\or November\or December\fi
+%\space\number\day, \number\year}
+
+% @settitle line... specifies the title of the document, for headings
+% It generates no output of its own
+
+\def\thistitle{No Title}
+\def\settitle{\parsearg\settitlezzz}
+\def\settitlezzz #1{\gdef\thistitle{#1}}
+
+\message{tables,}
+
+% @tabs -- simple alignment
+
+% These don't work. For one thing, \+ is defined as outer.
+% So these macros cannot even be defined.
+
+%\def\tabs{\parsearg\tabszzz}
+%\def\tabszzz #1{\settabs\+#1\cr}
+%\def\tabline{\parsearg\tablinezzz}
+%\def\tablinezzz #1{\+#1\cr}
+%\def\&{&}
+
+% Tables -- @table, @ftable, @vtable, @item(x), @kitem(x), @xitem(x).
+
+% default indentation of table text
+\newdimen\tableindent \tableindent=.8in
+% default indentation of @itemize and @enumerate text
+\newdimen\itemindent \itemindent=.3in
+% margin between end of table item and start of table text.
+\newdimen\itemmargin \itemmargin=.1in
+
+% used internally for \itemindent minus \itemmargin
+\newdimen\itemmax
+
+% Note @table, @vtable, and @vtable define @item, @itemx, etc., with
+% these defs.
+% They also define \itemindex
+% to index the item name in whatever manner is desired (perhaps none).
+
+\newif\ifitemxneedsnegativevskip
+
+\def\itemxpar{\par\ifitemxneedsnegativevskip\vskip-\parskip\nobreak\fi}
+
+\def\internalBitem{\smallbreak \parsearg\itemzzz}
+\def\internalBitemx{\itemxpar \parsearg\itemzzz}
+
+\def\internalBxitem "#1"{\def\xitemsubtopix{#1} \smallbreak \parsearg\xitemzzz}
+\def\internalBxitemx "#1"{\def\xitemsubtopix{#1} \itemxpar \parsearg\xitemzzz}
+
+\def\internalBkitem{\smallbreak \parsearg\kitemzzz}
+\def\internalBkitemx{\itemxpar \parsearg\kitemzzz}
+
+\def\kitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \lastfunction}}%
+ \itemzzz {#1}}
+
+\def\xitemzzz #1{\dosubind {kw}{\code{#1}}{for {\bf \xitemsubtopic}}%
+ \itemzzz {#1}}
+
+\def\itemzzz #1{\begingroup %
+ \advance\hsize by -\rightskip
+ \advance\hsize by -\tableindent
+ \setbox0=\hbox{\itemfont{#1}}%
+ \itemindex{#1}%
+ \nobreak % This prevents a break before @itemx.
+ %
+ % Be sure we are not still in the middle of a paragraph.
+ %{\parskip = 0in
+ %\par
+ %}%
+ %
+ % If the item text does not fit in the space we have, put it on a line
+ % by itself, and do not allow a page break either before or after that
+ % line. We do not start a paragraph here because then if the next
+ % command is, e.g., @kindex, the whatsit would get put into the
+ % horizontal list on a line by itself, resulting in extra blank space.
+ \ifdim \wd0>\itemmax
+ %
+ % Make this a paragraph so we get the \parskip glue and wrapping,
+ % but leave it ragged-right.
+ \begingroup
+ \advance\leftskip by-\tableindent
+ \advance\hsize by\tableindent
+ \advance\rightskip by0pt plus1fil
+ \leavevmode\unhbox0\par
+ \endgroup
+ %
+ % We're going to be starting a paragraph, but we don't want the
+ % \parskip glue -- logically it's part of the @item we just started.
+ \nobreak \vskip-\parskip
+ %
+ % Stop a page break at the \parskip glue coming up. Unfortunately
+ % we can't prevent a possible page break at the following
+ % \baselineskip glue.
+ \nobreak
+ \endgroup
+ \itemxneedsnegativevskipfalse
+ \else
+ % The item text fits into the space. Start a paragraph, so that the
+ % following text (if any) will end up on the same line. Since that
+ % text will be indented by \tableindent, we make the item text be in
+ % a zero-width box.
+ \noindent
+ \rlap{\hskip -\tableindent\box0}\ignorespaces%
+ \endgroup%
+ \itemxneedsnegativevskiptrue%
+ \fi
+}
+
+\def\item{\errmessage{@item while not in a table}}
+\def\itemx{\errmessage{@itemx while not in a table}}
+\def\kitem{\errmessage{@kitem while not in a table}}
+\def\kitemx{\errmessage{@kitemx while not in a table}}
+\def\xitem{\errmessage{@xitem while not in a table}}
+\def\xitemx{\errmessage{@xitemx while not in a table}}
+
+%% Contains a kludge to get @end[description] to work
+\def\description{\tablez{\dontindex}{1}{}{}{}{}}
+
+\def\table{\begingroup\inENV\obeylines\obeyspaces\tablex}
+{\obeylines\obeyspaces%
+\gdef\tablex #1^^M{%
+\tabley\dontindex#1 \endtabley}}
+
+\def\ftable{\begingroup\inENV\obeylines\obeyspaces\ftablex}
+{\obeylines\obeyspaces%
+\gdef\ftablex #1^^M{%
+\tabley\fnitemindex#1 \endtabley
+\def\Eftable{\endgraf\afterenvbreak\endgroup}%
+\let\Etable=\relax}}
+
+\def\vtable{\begingroup\inENV\obeylines\obeyspaces\vtablex}
+{\obeylines\obeyspaces%
+\gdef\vtablex #1^^M{%
+\tabley\vritemindex#1 \endtabley
+\def\Evtable{\endgraf\afterenvbreak\endgroup}%
+\let\Etable=\relax}}
+
+\def\dontindex #1{}
+\def\fnitemindex #1{\doind {fn}{\code{#1}}}%
+\def\vritemindex #1{\doind {vr}{\code{#1}}}%
+
+{\obeyspaces %
+\gdef\tabley#1#2 #3 #4 #5 #6 #7\endtabley{\endgroup%
+\tablez{#1}{#2}{#3}{#4}{#5}{#6}}}
+
+\def\tablez #1#2#3#4#5#6{%
+\aboveenvbreak %
+\begingroup %
+\def\Edescription{\Etable}% Neccessary kludge.
+\let\itemindex=#1%
+\ifnum 0#3>0 \advance \leftskip by #3\mil \fi %
+\ifnum 0#4>0 \tableindent=#4\mil \fi %
+\ifnum 0#5>0 \advance \rightskip by #5\mil \fi %
+\def\itemfont{#2}%
+\itemmax=\tableindent %
+\advance \itemmax by -\itemmargin %
+\advance \leftskip by \tableindent %
+\exdentamount=\tableindent
+\parindent = 0pt
+\parskip = \smallskipamount
+\ifdim \parskip=0pt \parskip=2pt \fi%
+\def\Etable{\endgraf\afterenvbreak\endgroup}%
+\let\item = \internalBitem %
+\let\itemx = \internalBitemx %
+\let\kitem = \internalBkitem %
+\let\kitemx = \internalBkitemx %
+\let\xitem = \internalBxitem %
+\let\xitemx = \internalBxitemx %
+}
+
+% This is the counter used by @enumerate, which is really @itemize
+
+\newcount \itemno
+
+\def\itemize{\parsearg\itemizezzz}
+
+\def\itemizezzz #1{%
+ \begingroup % ended by the @end itemsize
+ \itemizey {#1}{\Eitemize}
+}
+
+\def\itemizey #1#2{%
+\aboveenvbreak %
+\itemmax=\itemindent %
+\advance \itemmax by -\itemmargin %
+\advance \leftskip by \itemindent %
+\exdentamount=\itemindent
+\parindent = 0pt %
+\parskip = \smallskipamount %
+\ifdim \parskip=0pt \parskip=2pt \fi%
+\def#2{\endgraf\afterenvbreak\endgroup}%
+\def\itemcontents{#1}%
+\let\item=\itemizeitem}
+
+% Set sfcode to normal for the chars that usually have another value.
+% These are `.?!:;,'
+\def\frenchspacing{\sfcode46=1000 \sfcode63=1000 \sfcode33=1000
+ \sfcode58=1000 \sfcode59=1000 \sfcode44=1000 }
+
+% \splitoff TOKENS\endmark defines \first to be the first token in
+% TOKENS, and \rest to be the remainder.
+%
+\def\splitoff#1#2\endmark{\def\first{#1}\def\rest{#2}}%
+
+% Allow an optional argument of an uppercase letter, lowercase letter,
+% or number, to specify the first label in the enumerated list. No
+% argument is the same as `1'.
+%
+\def\enumerate{\parsearg\enumeratezzz}
+\def\enumeratezzz #1{\enumeratey #1 \endenumeratey}
+\def\enumeratey #1 #2\endenumeratey{%
+ \begingroup % ended by the @end enumerate
+ %
+ % If we were given no argument, pretend we were given `1'.
+ \def\thearg{#1}%
+ \ifx\thearg\empty \def\thearg{1}\fi
+ %
+ % Detect if the argument is a single token. If so, it might be a
+ % letter. Otherwise, the only valid thing it can be is a number.
+ % (We will always have one token, because of the test we just made.
+ % This is a good thing, since \splitoff doesn't work given nothing at
+ % all -- the first parameter is undelimited.)
+ \expandafter\splitoff\thearg\endmark
+ \ifx\rest\empty
+ % Only one token in the argument. It could still be anything.
+ % A ``lowercase letter'' is one whose \lccode is nonzero.
+ % An ``uppercase letter'' is one whose \lccode is both nonzero, and
+ % not equal to itself.
+ % Otherwise, we assume it's a number.
+ %
+ % We need the \relax at the end of the \ifnum lines to stop TeX from
+ % continuing to look for a <number>.
+ %
+ \ifnum\lccode\expandafter`\thearg=0\relax
+ \numericenumerate % a number (we hope)
+ \else
+ % It's a letter.
+ \ifnum\lccode\expandafter`\thearg=\expandafter`\thearg\relax
+ \lowercaseenumerate % lowercase letter
+ \else
+ \uppercaseenumerate % uppercase letter
+ \fi
+ \fi
+ \else
+ % Multiple tokens in the argument. We hope it's a number.
+ \numericenumerate
+ \fi
+}
+
+% An @enumerate whose labels are integers. The starting integer is
+% given in \thearg.
+%
+\def\numericenumerate{%
+ \itemno = \thearg
+ \startenumeration{\the\itemno}%
+}
+
+% The starting (lowercase) letter is in \thearg.
+\def\lowercaseenumerate{%
+ \itemno = \expandafter`\thearg
+ \startenumeration{%
+ % Be sure we're not beyond the end of the alphabet.
+ \ifnum\itemno=0
+ \errmessage{No more lowercase letters in @enumerate; get a bigger
+ alphabet}%
+ \fi
+ \char\lccode\itemno
+ }%
+}
+
+% The starting (uppercase) letter is in \thearg.
+\def\uppercaseenumerate{%
+ \itemno = \expandafter`\thearg
+ \startenumeration{%
+ % Be sure we're not beyond the end of the alphabet.
+ \ifnum\itemno=0
+ \errmessage{No more uppercase letters in @enumerate; get a bigger
+ alphabet}
+ \fi
+ \char\uccode\itemno
+ }%
+}
+
+% Call itemizey, adding a period to the first argument and supplying the
+% common last two arguments. Also subtract one from the initial value in
+% \itemno, since @item increments \itemno.
+%
+\def\startenumeration#1{%
+ \advance\itemno by -1
+ \itemizey{#1.}\Eenumerate\flushcr
+}
+
+% @alphaenumerate and @capsenumerate are abbreviations for giving an arg
+% to @enumerate.
+%
+\def\alphaenumerate{\enumerate{a}}
+\def\capsenumerate{\enumerate{A}}
+\def\Ealphaenumerate{\Eenumerate}
+\def\Ecapsenumerate{\Eenumerate}
+
+% Definition of @item while inside @itemize.
+
+\def\itemizeitem{%
+\advance\itemno by 1
+{\let\par=\endgraf \smallbreak}%
+\ifhmode \errmessage{\in hmode at itemizeitem}\fi
+{\parskip=0in \hskip 0pt
+\hbox to 0pt{\hss \itemcontents\hskip \itemmargin}%
+\vadjust{\penalty 1200}}%
+\flushcr}
+
+% @multitable macros
+% Amy Hendrickson, 8/18/94
+%
+% @multitable ... @endmultitable will make as many columns as desired.
+% Contents of each column will wrap at width given in preamble. Width
+% can be specified either with sample text given in a template line,
+% or in percent of \hsize, the current width of text on page.
+
+% Table can continue over pages but will only break between lines.
+
+% To make preamble:
+%
+% Either define widths of columns in terms of percent of \hsize:
+% @multitable @percentofhsize .2 .3 .5
+% @item ...
+%
+% Numbers following @percentofhsize are the percent of the total
+% current hsize to be used for each column. You may use as many
+% columns as desired.
+
+% Or use a template:
+% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+% @item ...
+% using the widest term desired in each column.
+
+
+% Each new table line starts with @item, each subsequent new column
+% starts with @tab. Empty columns may be produced by supplying @tab's
+% with nothing between them for as many times as empty columns are needed,
+% ie, @tab@tab@tab will produce two empty columns.
+
+% @item, @tab, @multicolumn or @endmulticolumn do not need to be on their
+% own lines, but it will not hurt if they are.
+
+% Sample multitable:
+
+% @multitable {Column 1 template} {Column 2 template} {Column 3 template}
+% @item first col stuff @tab second col stuff @tab third col
+% @item
+% first col stuff
+% @tab
+% second col stuff
+% @tab
+% third col
+% @item first col stuff @tab second col stuff
+% @tab Many paragraphs of text may be used in any column.
+%
+% They will wrap at the width determined by the template.
+% @item@tab@tab This will be in third column.
+% @endmultitable
+
+% Default dimensions may be reset by user.
+% @intableparskip will set vertical space between paragraphs in table.
+% @intableparindent will set paragraph indent in table.
+% @spacebetweencols will set horizontal space to be left between columns.
+% @spacebetweenlines will set vertical space to be left between lines.
+
+%%%%
+% Dimensions
+
+\newdimen\intableparskip
+\newdimen\intableparindent
+\newdimen\spacebetweencols
+\newdimen\spacebetweenlines
+\intableparskip=0pt
+\intableparindent=6pt
+\spacebetweencols=12pt
+\spacebetweenlines=12pt
+
+%%%%
+% Macros used to set up halign preamble:
+\let\endsetuptable\relax
+\def\xendsetuptable{\endsetuptable}
+\let\percentofhsize\relax
+\def\xpercentofhsize{\percentofhsize}
+\newif\ifsetpercent
+
+\newcount\colcount
+\def\setuptable#1{\def\firstarg{#1}%
+\ifx\firstarg\xendsetuptable\let\go\relax%
+\else
+ \ifx\firstarg\xpercentofhsize\global\setpercenttrue%
+ \else
+ \ifsetpercent
+ \if#1.\else%
+ \global\advance\colcount by1 %
+ \expandafter\xdef\csname col\the\colcount\endcsname{.#1\hsize}%
+ \fi
+ \else
+ \global\advance\colcount by1
+ \setbox0=\hbox{#1}%
+ \expandafter\xdef\csname col\the\colcount\endcsname{\the\wd0}%
+ \fi%
+ \fi%
+ \let\go\setuptable%
+\fi\go}
+%%%%
+% multitable syntax
+\def\tab{&}
+
+%%%%
+% @multitable ... @endmultitable definitions:
+
+\def\multitable#1\item{\bgroup
+\let\item\cr
+\tolerance=9500
+\hbadness=9500
+\parskip=\intableparskip
+\parindent=\intableparindent
+\overfullrule=0pt
+\global\colcount=0\relax%
+\def\Emultitable{\global\setpercentfalse\global\everycr{}\cr\egroup\egroup}%
+ % To parse everything between @multitable and @item :
+\def\one{#1}\expandafter\setuptable\one\endsetuptable
+ % Need to reset this to 0 after \setuptable.
+\global\colcount=0\relax%
+ %
+ % This preamble sets up a generic column definition, which will
+ % be used as many times as user calls for columns.
+ % \vtop will set a single line and will also let text wrap and
+ % continue for many paragraphs if desired.
+\halign\bgroup&\global\advance\colcount by 1\relax%
+\vtop{\hsize=\expandafter\csname col\the\colcount\endcsname
+ % In order to keep entries from bumping into each other
+ % we will add a \leftskip of \spacebetweencols to all columns after
+ % the first one.
+ % If a template has been used, we will add \spacebetweencols
+ % to the width of each template entry.
+ % If user has set preamble in terms of percent of \hsize
+ % we will use that dimension as the width of the column, and
+ % the \leftskip will keep entries from bumping into each other.
+ % Table will start at left margin and final column will justify at
+ % right margin.
+\ifnum\colcount=1
+\else
+ \ifsetpercent
+ \else
+ % If user has <not> set preamble in terms of percent of \hsize
+ % we will advance \hsize by \spacebetweencols
+ \advance\hsize by \spacebetweencols
+ \fi
+ % In either case we will make \leftskip=\spacebetweencols:
+\leftskip=\spacebetweencols
+\fi
+\noindent##}\cr%
+ % \everycr will reset column counter, \colcount, at the end of
+ % each line. Every column entry will cause \colcount to advance by one.
+ % The table preamble
+ % looks at the current \colcount to find the correct column width.
+\global\everycr{\noalign{\nointerlineskip\vskip\spacebetweenlines
+\filbreak%% keeps underfull box messages off when table breaks over pages.
+\global\colcount=0\relax}}}
+
+\message{indexing,}
+% Index generation facilities
+
+% Define \newwrite to be identical to plain tex's \newwrite
+% except not \outer, so it can be used within \newindex.
+{\catcode`\@=11
+\gdef\newwrite{\alloc@7\write\chardef\sixt@@n}}
+
+% \newindex {foo} defines an index named foo.
+% It automatically defines \fooindex such that
+% \fooindex ...rest of line... puts an entry in the index foo.
+% It also defines \fooindfile to be the number of the output channel for
+% the file that accumulates this index. The file's extension is foo.
+% The name of an index should be no more than 2 characters long
+% for the sake of vms.
+
+\def\newindex #1{
+\expandafter\newwrite \csname#1indfile\endcsname% Define number for output file
+\openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex
+\noexpand\doindex {#1}}
+}
+
+% @defindex foo == \newindex{foo}
+
+\def\defindex{\parsearg\newindex}
+
+% Define @defcodeindex, like @defindex except put all entries in @code.
+
+\def\newcodeindex #1{
+\expandafter\newwrite \csname#1indfile\endcsname% Define number for output file
+\openout \csname#1indfile\endcsname \jobname.#1 % Open the file
+\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex
+\noexpand\docodeindex {#1}}
+}
+
+\def\defcodeindex{\parsearg\newcodeindex}
+
+% @synindex foo bar makes index foo feed into index bar.
+% Do this instead of @defindex foo if you don't want it as a separate index.
+\def\synindex #1 #2 {%
+\expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname
+\expandafter\let\csname#1indfile\endcsname=\synindexfoo
+\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex
+\noexpand\doindex {#2}}%
+}
+
+% @syncodeindex foo bar similar, but put all entries made for index foo
+% inside @code.
+\def\syncodeindex #1 #2 {%
+\expandafter\let\expandafter\synindexfoo\expandafter=\csname#2indfile\endcsname
+\expandafter\let\csname#1indfile\endcsname=\synindexfoo
+\expandafter\xdef\csname#1index\endcsname{% % Define \xxxindex
+\noexpand\docodeindex {#2}}%
+}
+
+% Define \doindex, the driver for all \fooindex macros.
+% Argument #1 is generated by the calling \fooindex macro,
+% and it is "foo", the name of the index.
+
+% \doindex just uses \parsearg; it calls \doind for the actual work.
+% This is because \doind is more useful to call from other macros.
+
+% There is also \dosubind {index}{topic}{subtopic}
+% which makes an entry in a two-level index such as the operation index.
+
+\def\doindex#1{\edef\indexname{#1}\parsearg\singleindexer}
+\def\singleindexer #1{\doind{\indexname}{#1}}
+
+% like the previous two, but they put @code around the argument.
+\def\docodeindex#1{\edef\indexname{#1}\parsearg\singlecodeindexer}
+\def\singlecodeindexer #1{\doind{\indexname}{\code{#1}}}
+
+\def\indexdummies{%
+% Take care of the plain tex accent commands.
+\def\"{\realbackslash "}%
+\def\`{\realbackslash `}%
+\def\'{\realbackslash '}%
+\def\^{\realbackslash ^}%
+\def\~{\realbackslash ~}%
+\def\={\realbackslash =}%
+\def\b{\realbackslash b}%
+\def\c{\realbackslash c}%
+\def\d{\realbackslash d}%
+\def\u{\realbackslash u}%
+\def\v{\realbackslash v}%
+\def\H{\realbackslash H}%
+% Take care of the plain tex special European modified letters.
+\def\oe{\realbackslash oe}%
+\def\ae{\realbackslash ae}%
+\def\aa{\realbackslash aa}%
+\def\OE{\realbackslash OE}%
+\def\AE{\realbackslash AE}%
+\def\AA{\realbackslash AA}%
+\def\o{\realbackslash o}%
+\def\O{\realbackslash O}%
+\def\l{\realbackslash l}%
+\def\L{\realbackslash L}%
+\def\ss{\realbackslash ss}%
+% Take care of texinfo commands likely to appear in an index entry.
+\def\_{{\realbackslash _}}%
+\def\w{\realbackslash w }%
+\def\bf{\realbackslash bf }%
+\def\rm{\realbackslash rm }%
+\def\sl{\realbackslash sl }%
+\def\sf{\realbackslash sf}%
+\def\tt{\realbackslash tt}%
+\def\gtr{\realbackslash gtr}%
+\def\less{\realbackslash less}%
+\def\hat{\realbackslash hat}%
+\def\char{\realbackslash char}%
+\def\TeX{\realbackslash TeX}%
+\def\dots{\realbackslash dots }%
+\def\copyright{\realbackslash copyright }%
+\def\tclose##1{\realbackslash tclose {##1}}%
+\def\code##1{\realbackslash code {##1}}%
+\def\samp##1{\realbackslash samp {##1}}%
+\def\t##1{\realbackslash r {##1}}%
+\def\r##1{\realbackslash r {##1}}%
+\def\i##1{\realbackslash i {##1}}%
+\def\b##1{\realbackslash b {##1}}%
+\def\cite##1{\realbackslash cite {##1}}%
+\def\key##1{\realbackslash key {##1}}%
+\def\file##1{\realbackslash file {##1}}%
+\def\var##1{\realbackslash var {##1}}%
+\def\kbd##1{\realbackslash kbd {##1}}%
+\def\dfn##1{\realbackslash dfn {##1}}%
+\def\emph##1{\realbackslash emph {##1}}%
+}
+
+% \indexnofonts no-ops all font-change commands.
+% This is used when outputting the strings to sort the index by.
+\def\indexdummyfont#1{#1}
+\def\indexdummytex{TeX}
+\def\indexdummydots{...}
+
+\def\indexnofonts{%
+% Just ignore accents.
+\let\"=\indexdummyfont
+\let\`=\indexdummyfont
+\let\'=\indexdummyfont
+\let\^=\indexdummyfont
+\let\~=\indexdummyfont
+\let\==\indexdummyfont
+\let\b=\indexdummyfont
+\let\c=\indexdummyfont
+\let\d=\indexdummyfont
+\let\u=\indexdummyfont
+\let\v=\indexdummyfont
+\let\H=\indexdummyfont
+% Take care of the plain tex special European modified letters.
+\def\oe{oe}%
+\def\ae{ae}%
+\def\aa{aa}%
+\def\OE{OE}%
+\def\AE{AE}%
+\def\AA{AA}%
+\def\o{o}%
+\def\O{O}%
+\def\l{l}%
+\def\L{L}%
+\def\ss{ss}%
+\let\w=\indexdummyfont
+\let\t=\indexdummyfont
+\let\r=\indexdummyfont
+\let\i=\indexdummyfont
+\let\b=\indexdummyfont
+\let\emph=\indexdummyfont
+\let\strong=\indexdummyfont
+\let\cite=\indexdummyfont
+\let\sc=\indexdummyfont
+%Don't no-op \tt, since it isn't a user-level command
+% and is used in the definitions of the active chars like <, >, |...
+%\let\tt=\indexdummyfont
+\let\tclose=\indexdummyfont
+\let\code=\indexdummyfont
+\let\file=\indexdummyfont
+\let\samp=\indexdummyfont
+\let\kbd=\indexdummyfont
+\let\key=\indexdummyfont
+\let\var=\indexdummyfont
+\let\TeX=\indexdummytex
+\let\dots=\indexdummydots
+}
+
+% To define \realbackslash, we must make \ not be an escape.
+% We must first make another character (@) an escape
+% so we do not become unable to do a definition.
+
+{\catcode`\@=0 \catcode`\\=\other
+@gdef@realbackslash{\}}
+
+\let\indexbackslash=0 %overridden during \printindex.
+
+\def\doind #1#2{%
+{\count10=\lastpenalty %
+{\indexdummies % Must do this here, since \bf, etc expand at this stage
+\escapechar=`\\%
+{\let\folio=0% Expand all macros now EXCEPT \folio
+\def\rawbackslashxx{\indexbackslash}% \indexbackslash isn't defined now
+% so it will be output as is; and it will print as backslash in the indx.
+%
+% Now process the index-string once, with all font commands turned off,
+% to get the string to sort the index by.
+{\indexnofonts
+\xdef\temp1{#2}%
+}%
+% Now produce the complete index entry. We process the index-string again,
+% this time with font commands expanded, to get what to print in the index.
+\edef\temp{%
+\write \csname#1indfile\endcsname{%
+\realbackslash entry {\temp1}{\folio}{#2}}}%
+\temp }%
+}\penalty\count10}}
+
+\def\dosubind #1#2#3{%
+{\count10=\lastpenalty %
+{\indexdummies % Must do this here, since \bf, etc expand at this stage
+\escapechar=`\\%
+{\let\folio=0%
+\def\rawbackslashxx{\indexbackslash}%
+%
+% Now process the index-string once, with all font commands turned off,
+% to get the string to sort the index by.
+{\indexnofonts
+\xdef\temp1{#2 #3}%
+}%
+% Now produce the complete index entry. We process the index-string again,
+% this time with font commands expanded, to get what to print in the index.
+\edef\temp{%
+\write \csname#1indfile\endcsname{%
+\realbackslash entry {\temp1}{\folio}{#2}{#3}}}%
+\temp }%
+}\penalty\count10}}
+
+% The index entry written in the file actually looks like
+% \entry {sortstring}{page}{topic}
+% or
+% \entry {sortstring}{page}{topic}{subtopic}
+% The texindex program reads in these files and writes files
+% containing these kinds of lines:
+% \initial {c}
+% before the first topic whose initial is c
+% \entry {topic}{pagelist}
+% for a topic that is used without subtopics
+% \primary {topic}
+% for the beginning of a topic that is used with subtopics
+% \secondary {subtopic}{pagelist}
+% for each subtopic.
+
+% Define the user-accessible indexing commands
+% @findex, @vindex, @kindex, @cindex.
+
+\def\findex {\fnindex}
+\def\kindex {\kyindex}
+\def\cindex {\cpindex}
+\def\vindex {\vrindex}
+\def\tindex {\tpindex}
+\def\pindex {\pgindex}
+
+\def\cindexsub {\begingroup\obeylines\cindexsub}
+{\obeylines %
+\gdef\cindexsub "#1" #2^^M{\endgroup %
+\dosubind{cp}{#2}{#1}}}
+
+% Define the macros used in formatting output of the sorted index material.
+
+% This is what you call to cause a particular index to get printed.
+% Write
+% @unnumbered Function Index
+% @printindex fn
+
+\def\printindex{\parsearg\doprintindex}
+
+\def\doprintindex#1{%
+ \tex
+ \dobreak \chapheadingskip {10000}
+ \catcode`\%=\other\catcode`\&=\other\catcode`\#=\other
+ \catcode`\$=\other
+ \catcode`\~=\other
+ \indexbreaks
+ %
+ % The following don't help, since the chars were translated
+ % when the raw index was written, and their fonts were discarded
+ % due to \indexnofonts.
+ %\catcode`\"=\active
+ %\catcode`\^=\active
+ %\catcode`\_=\active
+ %\catcode`\|=\active
+ %\catcode`\<=\active
+ %\catcode`\>=\active
+ % %
+ \def\indexbackslash{\rawbackslashxx}
+ \indexfonts\rm \tolerance=9500 \advance\baselineskip -1pt
+ \begindoublecolumns
+ %
+ % See if the index file exists and is nonempty.
+ \openin 1 \jobname.#1s
+ \ifeof 1
+ % \enddoublecolumns gets confused if there is no text in the index,
+ % and it loses the chapter title and the aux file entries for the
+ % index. The easiest way to prevent this problem is to make sure
+ % there is some text.
+ (Index is nonexistent)
+ \else
+ %
+ % If the index file exists but is empty, then \openin leaves \ifeof
+ % false. We have to make TeX try to read something from the file, so
+ % it can discover if there is anything in it.
+ \read 1 to \temp
+ \ifeof 1
+ (Index is empty)
+ \else
+ \input \jobname.#1s
+ \fi
+ \fi
+ \closein 1
+ \enddoublecolumns
+ \Etex
+}
+
+% These macros are used by the sorted index file itself.
+% Change them to control the appearance of the index.
+
+% Same as \bigskipamount except no shrink.
+% \balancecolumns gets confused if there is any shrink.
+\newskip\initialskipamount \initialskipamount 12pt plus4pt
+
+\def\initial #1{%
+{\let\tentt=\sectt \let\tt=\sectt \let\sf=\sectt
+\ifdim\lastskip<\initialskipamount
+\removelastskip \penalty-200 \vskip \initialskipamount\fi
+\line{\secbf#1\hfill}\kern 2pt\penalty10000}}
+
+% This typesets a paragraph consisting of #1, dot leaders, and then #2
+% flush to the right margin. It is used for index and table of contents
+% entries. The paragraph is indented by \leftskip.
+%
+\def\entry #1#2{\begingroup
+ %
+ % Start a new paragraph if necessary, so our assignments below can't
+ % affect previous text.
+ \par
+ %
+ % Do not fill out the last line with white space.
+ \parfillskip = 0in
+ %
+ % No extra space above this paragraph.
+ \parskip = 0in
+ %
+ % Do not prefer a separate line ending with a hyphen to fewer lines.
+ \finalhyphendemerits = 0
+ %
+ % \hangindent is only relevant when the entry text and page number
+ % don't both fit on one line. In that case, bob suggests starting the
+ % dots pretty far over on the line. Unfortunately, a large
+ % indentation looks wrong when the entry text itself is broken across
+ % lines. So we use a small indentation and put up with long leaders.
+ %
+ % \hangafter is reset to 1 (which is the value we want) at the start
+ % of each paragraph, so we need not do anything with that.
+ \hangindent=2em
+ %
+ % When the entry text needs to be broken, just fill out the first line
+ % with blank space.
+ \rightskip = 0pt plus1fil
+ %
+ % Start a ``paragraph'' for the index entry so the line breaking
+ % parameters we've set above will have an effect.
+ \noindent
+ %
+ % Insert the text of the index entry. TeX will do line-breaking on it.
+ #1%
+ % The following is kluged to not output a line of dots in the index if
+ % there are no page numbers. The next person who breaks this will be
+ % cursed by a Unix daemon.
+ \def\tempa{{\rm }}%
+ \def\tempb{#2}%
+ \edef\tempc{\tempa}%
+ \edef\tempd{\tempb}%
+ \ifx\tempc\tempd\ \else%
+ %
+ % If we must, put the page number on a line of its own, and fill out
+ % this line with blank space. (The \hfil is overwhelmed with the
+ % fill leaders glue in \indexdotfill if the page number does fit.)
+ \hfil\penalty50
+ \null\nobreak\indexdotfill % Have leaders before the page number.
+ %
+ % The `\ ' here is removed by the implicit \unskip that TeX does as
+ % part of (the primitive) \par. Without it, a spurious underfull
+ % \hbox ensues.
+ \ #2% The page number ends the paragraph.
+ \fi%
+ \par
+\endgroup}
+
+% Like \dotfill except takes at least 1 em.
+\def\indexdotfill{\cleaders
+ \hbox{$\mathsurround=0pt \mkern1.5mu ${\it .}$ \mkern1.5mu$}\hskip 1em plus 1fill}
+
+\def\primary #1{\line{#1\hfil}}
+
+\newskip\secondaryindent \secondaryindent=0.5cm
+
+\def\secondary #1#2{
+{\parfillskip=0in \parskip=0in
+\hangindent =1in \hangafter=1
+\noindent\hskip\secondaryindent\hbox{#1}\indexdotfill #2\par
+}}
+
+%% Define two-column mode, which is used in indexes.
+%% Adapted from the TeXbook, page 416.
+\catcode `\@=11
+
+\newbox\partialpage
+
+\newdimen\doublecolumnhsize
+
+\def\begindoublecolumns{\begingroup
+ % Grab any single-column material above us.
+ \output = {\global\setbox\partialpage
+ =\vbox{\unvbox255\kern -\topskip \kern \baselineskip}}%
+ \eject
+ %
+ % Now switch to the double-column output routine.
+ \output={\doublecolumnout}%
+ %
+ % Change the page size parameters. We could do this once outside this
+ % routine, in each of @smallbook, @afourpaper, and the default 8.5x11
+ % format, but then we repeat the same computation. Repeating a couple
+ % of assignments once per index is clearly meaningless for the
+ % execution time, so we may as well do it once.
+ %
+ % First we halve the line length, less a little for the gutter between
+ % the columns. We compute the gutter based on the line length, so it
+ % changes automatically with the paper format. The magic constant
+ % below is chosen so that the gutter has the same value (well, +- <
+ % 1pt) as it did when we hard-coded it.
+ %
+ % We put the result in a separate register, \doublecolumhsize, so we
+ % can restore it in \pagesofar, after \hsize itself has (potentially)
+ % been clobbered.
+ %
+ \doublecolumnhsize = \hsize
+ \advance\doublecolumnhsize by -.04154\hsize
+ \divide\doublecolumnhsize by 2
+ \hsize = \doublecolumnhsize
+ %
+ % Double the \vsize as well. (We don't need a separate register here,
+ % since nobody clobbers \vsize.)
+ \vsize = 2\vsize
+ \doublecolumnpagegoal
+}
+
+\def\enddoublecolumns{\eject \endgroup \pagegoal=\vsize \unvbox\partialpage}
+
+\def\doublecolumnsplit{\splittopskip=\topskip \splitmaxdepth=\maxdepth
+ \global\dimen@=\pageheight \global\advance\dimen@ by-\ht\partialpage
+ \global\setbox1=\vsplit255 to\dimen@ \global\setbox0=\vbox{\unvbox1}
+ \global\setbox3=\vsplit255 to\dimen@ \global\setbox2=\vbox{\unvbox3}
+ \ifdim\ht0>\dimen@ \setbox255=\vbox{\unvbox0\unvbox2} \global\setbox255=\copy5 \fi
+ \ifdim\ht2>\dimen@ \setbox255=\vbox{\unvbox0\unvbox2} \global\setbox255=\copy5 \fi
+}
+\def\doublecolumnpagegoal{%
+ \dimen@=\vsize \advance\dimen@ by-2\ht\partialpage \global\pagegoal=\dimen@
+}
+\def\pagesofar{\unvbox\partialpage %
+ \hsize=\doublecolumnhsize % have to restore this since output routine
+ \wd0=\hsize \wd2=\hsize \hbox to\pagewidth{\box0\hfil\box2}}
+\def\doublecolumnout{%
+ \setbox5=\copy255
+ {\vbadness=10000 \doublecolumnsplit}
+ \ifvbox255
+ \setbox0=\vtop to\dimen@{\unvbox0}
+ \setbox2=\vtop to\dimen@{\unvbox2}
+ \onepageout\pagesofar \unvbox255 \penalty\outputpenalty
+ \else
+ \setbox0=\vbox{\unvbox5}
+ \ifvbox0
+ \dimen@=\ht0 \advance\dimen@ by\topskip \advance\dimen@ by-\baselineskip
+ \divide\dimen@ by2 \splittopskip=\topskip \splitmaxdepth=\maxdepth
+ {\vbadness=10000
+ \loop \global\setbox5=\copy0
+ \setbox1=\vsplit5 to\dimen@
+ \setbox3=\vsplit5 to\dimen@
+ \ifvbox5 \global\advance\dimen@ by1pt \repeat
+ \setbox0=\vbox to\dimen@{\unvbox1}
+ \setbox2=\vbox to\dimen@{\unvbox3}
+ \global\setbox\partialpage=\vbox{\pagesofar}
+ \doublecolumnpagegoal
+ }
+ \fi
+ \fi
+}
+
+\catcode `\@=\other
+\message{sectioning,}
+% Define chapters, sections, etc.
+
+\newcount \chapno
+\newcount \secno \secno=0
+\newcount \subsecno \subsecno=0
+\newcount \subsubsecno \subsubsecno=0
+
+% This counter is funny since it counts through charcodes of letters A, B, ...
+\newcount \appendixno \appendixno = `\@
+\def\appendixletter{\char\the\appendixno}
+
+\newwrite \contentsfile
+% This is called from \setfilename.
+\def\opencontents{\openout \contentsfile = \jobname.toc}
+
+% Each @chapter defines this as the name of the chapter.
+% page headings and footings can use it. @section does likewise
+
+\def\thischapter{} \def\thissection{}
+\def\seccheck#1{\if \pageno<0 %
+\errmessage{@#1 not allowed after generating table of contents}\fi
+%
+}
+
+\def\chapternofonts{%
+\let\rawbackslash=\relax%
+\let\frenchspacing=\relax%
+\def\result{\realbackslash result}
+\def\equiv{\realbackslash equiv}
+\def\expansion{\realbackslash expansion}
+\def\print{\realbackslash print}
+\def\TeX{\realbackslash TeX}
+\def\dots{\realbackslash dots}
+\def\copyright{\realbackslash copyright}
+\def\tt{\realbackslash tt}
+\def\bf{\realbackslash bf }
+\def\w{\realbackslash w}
+\def\less{\realbackslash less}
+\def\gtr{\realbackslash gtr}
+\def\hat{\realbackslash hat}
+\def\char{\realbackslash char}
+\def\tclose##1{\realbackslash tclose {##1}}
+\def\code##1{\realbackslash code {##1}}
+\def\samp##1{\realbackslash samp {##1}}
+\def\r##1{\realbackslash r {##1}}
+\def\b##1{\realbackslash b {##1}}
+\def\key##1{\realbackslash key {##1}}
+\def\file##1{\realbackslash file {##1}}
+\def\kbd##1{\realbackslash kbd {##1}}
+% These are redefined because @smartitalic wouldn't work inside xdef.
+\def\i##1{\realbackslash i {##1}}
+\def\cite##1{\realbackslash cite {##1}}
+\def\var##1{\realbackslash var {##1}}
+\def\emph##1{\realbackslash emph {##1}}
+\def\dfn##1{\realbackslash dfn {##1}}
+}
+
+\newcount\absseclevel % used to calculate proper heading level
+\newcount\secbase\secbase=0 % @raise/lowersections modify this count
+
+% @raisesections: treat @section as chapter, @subsection as section, etc.
+\def\raisesections{\global\advance\secbase by -1}
+\let\up=\raisesections % original BFox name
+
+% @lowersections: treat @chapter as section, @section as subsection, etc.
+\def\lowersections{\global\advance\secbase by 1}
+\let\down=\lowersections % original BFox name
+
+% Choose a numbered-heading macro
+% #1 is heading level if unmodified by @raisesections or @lowersections
+% #2 is text for heading
+\def\numhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
+\ifcase\absseclevel
+ \chapterzzz{#2}
+\or
+ \seczzz{#2}
+\or
+ \numberedsubseczzz{#2}
+\or
+ \numberedsubsubseczzz{#2}
+\else
+ \ifnum \absseclevel<0
+ \chapterzzz{#2}
+ \else
+ \numberedsubsubseczzz{#2}
+ \fi
+\fi
+}
+
+% like \numhead, but chooses appendix heading levels
+\def\apphead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
+\ifcase\absseclevel
+ \appendixzzz{#2}
+\or
+ \appendixsectionzzz{#2}
+\or
+ \appendixsubseczzz{#2}
+\or
+ \appendixsubsubseczzz{#2}
+\else
+ \ifnum \absseclevel<0
+ \appendixzzz{#2}
+ \else
+ \appendixsubsubseczzz{#2}
+ \fi
+\fi
+}
+
+% like \numhead, but chooses numberless heading levels
+\def\unnmhead#1#2{\absseclevel=\secbase\advance\absseclevel by #1
+\ifcase\absseclevel
+ \unnumberedzzz{#2}
+\or
+ \unnumberedseczzz{#2}
+\or
+ \unnumberedsubseczzz{#2}
+\or
+ \unnumberedsubsubseczzz{#2}
+\else
+ \ifnum \absseclevel<0
+ \unnumberedzzz{#2}
+ \else
+ \unnumberedsubsubseczzz{#2}
+ \fi
+\fi
+}
+
+
+\def\thischaptername{No Chapter Title}
+\outer\def\chapter{\parsearg\chapteryyy}
+\def\chapteryyy #1{\numhead0{#1}} % normally numhead0 calls chapterzzz
+\def\chapterzzz #1{\seccheck{chapter}%
+\secno=0 \subsecno=0 \subsubsecno=0
+\global\advance \chapno by 1 \message{Chapter \the\chapno}%
+\chapmacro {#1}{\the\chapno}%
+\gdef\thissection{#1}%
+\gdef\thischaptername{#1}%
+% We don't substitute the actual chapter name into \thischapter
+% because we don't want its macros evaluated now.
+\xdef\thischapter{\putwordChapter{} \the\chapno: \noexpand\thischaptername}%
+{\chapternofonts%
+\edef\temp{{\realbackslash chapentry {#1}{\the\chapno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\donoderef %
+\global\let\section = \numberedsec
+\global\let\subsection = \numberedsubsec
+\global\let\subsubsection = \numberedsubsubsec
+}}
+
+\outer\def\appendix{\parsearg\appendixyyy}
+\def\appendixyyy #1{\apphead0{#1}} % normally apphead0 calls appendixzzz
+\def\appendixzzz #1{\seccheck{appendix}%
+\secno=0 \subsecno=0 \subsubsecno=0
+\global\advance \appendixno by 1 \message{Appendix \appendixletter}%
+\chapmacro {#1}{\putwordAppendix{} \appendixletter}%
+\gdef\thissection{#1}%
+\gdef\thischaptername{#1}%
+\xdef\thischapter{\putwordAppendix{} \appendixletter: \noexpand\thischaptername}%
+{\chapternofonts%
+\edef\temp{{\realbackslash chapentry
+ {#1}{\putwordAppendix{} \appendixletter}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\appendixnoderef %
+\global\let\section = \appendixsec
+\global\let\subsection = \appendixsubsec
+\global\let\subsubsection = \appendixsubsubsec
+}}
+
+\outer\def\top{\parsearg\unnumberedyyy}
+\outer\def\unnumbered{\parsearg\unnumberedyyy}
+\def\unnumberedyyy #1{\unnmhead0{#1}} % normally unnmhead0 calls unnumberedzzz
+\def\unnumberedzzz #1{\seccheck{unnumbered}%
+\secno=0 \subsecno=0 \subsubsecno=0
+%
+% This used to be simply \message{#1}, but TeX fully expands the
+% argument to \message. Therefore, if #1 contained @-commands, TeX
+% expanded them. For example, in `@unnumbered The @cite{Book}', TeX
+% expanded @cite (which turns out to cause errors because \cite is meant
+% to be executed, not expanded).
+%
+% Anyway, we don't want the fully-expanded definition of @cite to appear
+% as a result of the \message, we just want `@cite' itself. We use
+% \the<toks register> to achieve this: TeX expands \the<toks> only once,
+% simply yielding the contents of the <toks register>.
+\toks0 = {#1}\message{(\the\toks0)}%
+%
+\unnumbchapmacro {#1}%
+\gdef\thischapter{#1}\gdef\thissection{#1}%
+{\chapternofonts%
+\edef\temp{{\realbackslash unnumbchapentry {#1}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\unnumbnoderef %
+\global\let\section = \unnumberedsec
+\global\let\subsection = \unnumberedsubsec
+\global\let\subsubsection = \unnumberedsubsubsec
+}}
+
+\outer\def\numberedsec{\parsearg\secyyy}
+\def\secyyy #1{\numhead1{#1}} % normally calls seczzz
+\def\seczzz #1{\seccheck{section}%
+\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 %
+\gdef\thissection{#1}\secheading {#1}{\the\chapno}{\the\secno}%
+{\chapternofonts%
+\edef\temp{{\realbackslash secentry %
+{#1}{\the\chapno}{\the\secno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\donoderef %
+\penalty 10000 %
+}}
+
+\outer\def\appenixsection{\parsearg\appendixsecyyy}
+\outer\def\appendixsec{\parsearg\appendixsecyyy}
+\def\appendixsecyyy #1{\apphead1{#1}} % normally calls appendixsectionzzz
+\def\appendixsectionzzz #1{\seccheck{appendixsection}%
+\subsecno=0 \subsubsecno=0 \global\advance \secno by 1 %
+\gdef\thissection{#1}\secheading {#1}{\appendixletter}{\the\secno}%
+{\chapternofonts%
+\edef\temp{{\realbackslash secentry %
+{#1}{\appendixletter}{\the\secno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\appendixnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\unnumberedsec{\parsearg\unnumberedsecyyy}
+\def\unnumberedsecyyy #1{\unnmhead1{#1}} % normally calls unnumberedseczzz
+\def\unnumberedseczzz #1{\seccheck{unnumberedsec}%
+\plainsecheading {#1}\gdef\thissection{#1}%
+{\chapternofonts%
+\edef\temp{{\realbackslash unnumbsecentry{#1}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\unnumbnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\numberedsubsec{\parsearg\numberedsubsecyyy}
+\def\numberedsubsecyyy #1{\numhead2{#1}} % normally calls numberedsubseczzz
+\def\numberedsubseczzz #1{\seccheck{subsection}%
+\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 %
+\subsecheading {#1}{\the\chapno}{\the\secno}{\the\subsecno}%
+{\chapternofonts%
+\edef\temp{{\realbackslash subsecentry %
+{#1}{\the\chapno}{\the\secno}{\the\subsecno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\donoderef %
+\penalty 10000 %
+}}
+
+\outer\def\appendixsubsec{\parsearg\appendixsubsecyyy}
+\def\appendixsubsecyyy #1{\apphead2{#1}} % normally calls appendixsubseczzz
+\def\appendixsubseczzz #1{\seccheck{appendixsubsec}%
+\gdef\thissection{#1}\subsubsecno=0 \global\advance \subsecno by 1 %
+\subsecheading {#1}{\appendixletter}{\the\secno}{\the\subsecno}%
+{\chapternofonts%
+\edef\temp{{\realbackslash subsecentry %
+{#1}{\appendixletter}{\the\secno}{\the\subsecno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\appendixnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\unnumberedsubsec{\parsearg\unnumberedsubsecyyy}
+\def\unnumberedsubsecyyy #1{\unnmhead2{#1}} %normally calls unnumberedsubseczzz
+\def\unnumberedsubseczzz #1{\seccheck{unnumberedsubsec}%
+\plainsecheading {#1}\gdef\thissection{#1}%
+{\chapternofonts%
+\edef\temp{{\realbackslash unnumbsubsecentry{#1}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\unnumbnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\numberedsubsubsec{\parsearg\numberedsubsubsecyyy}
+\def\numberedsubsubsecyyy #1{\numhead3{#1}} % normally numberedsubsubseczzz
+\def\numberedsubsubseczzz #1{\seccheck{subsubsection}%
+\gdef\thissection{#1}\global\advance \subsubsecno by 1 %
+\subsubsecheading {#1}
+ {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}%
+{\chapternofonts%
+\edef\temp{{\realbackslash subsubsecentry %
+ {#1}
+ {\the\chapno}{\the\secno}{\the\subsecno}{\the\subsubsecno}
+ {\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\donoderef %
+\penalty 10000 %
+}}
+
+\outer\def\appendixsubsubsec{\parsearg\appendixsubsubsecyyy}
+\def\appendixsubsubsecyyy #1{\apphead3{#1}} % normally appendixsubsubseczzz
+\def\appendixsubsubseczzz #1{\seccheck{appendixsubsubsec}%
+\gdef\thissection{#1}\global\advance \subsubsecno by 1 %
+\subsubsecheading {#1}
+ {\appendixletter}{\the\secno}{\the\subsecno}{\the\subsubsecno}%
+{\chapternofonts%
+\edef\temp{{\realbackslash subsubsecentry{#1}%
+ {\appendixletter}
+ {\the\secno}{\the\subsecno}{\the\subsubsecno}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\appendixnoderef %
+\penalty 10000 %
+}}
+
+\outer\def\unnumberedsubsubsec{\parsearg\unnumberedsubsubsecyyy}
+\def\unnumberedsubsubsecyyy #1{\unnmhead3{#1}} %normally unnumberedsubsubseczzz
+\def\unnumberedsubsubseczzz #1{\seccheck{unnumberedsubsubsec}%
+\plainsecheading {#1}\gdef\thissection{#1}%
+{\chapternofonts%
+\edef\temp{{\realbackslash unnumbsubsubsecentry{#1}{\noexpand\folio}}}%
+\escapechar=`\\%
+\write \contentsfile \temp %
+\unnumbnoderef %
+\penalty 10000 %
+}}
+
+% These are variants which are not "outer", so they can appear in @ifinfo.
+% Actually, they should now be obsolete; ordinary section commands should work.
+\def\infotop{\parsearg\unnumberedzzz}
+\def\infounnumbered{\parsearg\unnumberedzzz}
+\def\infounnumberedsec{\parsearg\unnumberedseczzz}
+\def\infounnumberedsubsec{\parsearg\unnumberedsubseczzz}
+\def\infounnumberedsubsubsec{\parsearg\unnumberedsubsubseczzz}
+
+\def\infoappendix{\parsearg\appendixzzz}
+\def\infoappendixsec{\parsearg\appendixseczzz}
+\def\infoappendixsubsec{\parsearg\appendixsubseczzz}
+\def\infoappendixsubsubsec{\parsearg\appendixsubsubseczzz}
+
+\def\infochapter{\parsearg\chapterzzz}
+\def\infosection{\parsearg\sectionzzz}
+\def\infosubsection{\parsearg\subsectionzzz}
+\def\infosubsubsection{\parsearg\subsubsectionzzz}
+
+% These macros control what the section commands do, according
+% to what kind of chapter we are in (ordinary, appendix, or unnumbered).
+% Define them by default for a numbered chapter.
+\global\let\section = \numberedsec
+\global\let\subsection = \numberedsubsec
+\global\let\subsubsection = \numberedsubsubsec
+
+% Define @majorheading, @heading and @subheading
+
+% NOTE on use of \vbox for chapter headings, section headings, and
+% such:
+% 1) We use \vbox rather than the earlier \line to permit
+% overlong headings to fold.
+% 2) \hyphenpenalty is set to 10000 because hyphenation in a
+% heading is obnoxious; this forbids it.
+% 3) Likewise, headings look best if no \parindent is used, and
+% if justification is not attempted. Hence \raggedright.
+
+
+\def\majorheading{\parsearg\majorheadingzzz}
+\def\majorheadingzzz #1{%
+{\advance\chapheadingskip by 10pt \chapbreak }%
+{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}\bigskip \par\penalty 200}
+
+\def\chapheading{\parsearg\chapheadingzzz}
+\def\chapheadingzzz #1{\chapbreak %
+{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}\bigskip \par\penalty 200}
+
+\def\heading{\parsearg\secheadingi}
+
+\def\subheading{\parsearg\subsecheadingi}
+
+\def\subsubheading{\parsearg\subsubsecheadingi}
+
+% These macros generate a chapter, section, etc. heading only
+% (including whitespace, linebreaking, etc. around it),
+% given all the information in convenient, parsed form.
+
+%%% Args are the skip and penalty (usually negative)
+\def\dobreak#1#2{\par\ifdim\lastskip<#1\removelastskip\penalty#2\vskip#1\fi}
+
+\def\setchapterstyle #1 {\csname CHAPF#1\endcsname}
+
+%%% Define plain chapter starts, and page on/off switching for it
+% Parameter controlling skip before chapter headings (if needed)
+
+\newskip \chapheadingskip \chapheadingskip = 30pt plus 8pt minus 4pt
+
+\def\chapbreak{\dobreak \chapheadingskip {-4000}}
+\def\chappager{\par\vfill\supereject}
+\def\chapoddpage{\chappager \ifodd\pageno \else \hbox to 0pt{} \chappager\fi}
+
+\def\setchapternewpage #1 {\csname CHAPPAG#1\endcsname}
+
+\def\CHAPPAGoff{
+\global\let\pchapsepmacro=\chapbreak
+\global\let\pagealignmacro=\chappager}
+
+\def\CHAPPAGon{
+\global\let\pchapsepmacro=\chappager
+\global\let\pagealignmacro=\chappager
+\global\def\HEADINGSon{\HEADINGSsingle}}
+
+\def\CHAPPAGodd{
+\global\let\pchapsepmacro=\chapoddpage
+\global\let\pagealignmacro=\chapoddpage
+\global\def\HEADINGSon{\HEADINGSdouble}}
+
+\CHAPPAGon
+
+\def\CHAPFplain{
+\global\let\chapmacro=\chfplain
+\global\let\unnumbchapmacro=\unnchfplain}
+
+\def\chfplain #1#2{%
+ \pchapsepmacro
+ {%
+ \chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #2\enspace #1}%
+ }%
+ \bigskip
+ \penalty5000
+}
+
+\def\unnchfplain #1{%
+\pchapsepmacro %
+{\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}\bigskip \par\penalty 10000 %
+}
+\CHAPFplain % The default
+
+\def\unnchfopen #1{%
+\chapoddpage {\chapfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}\bigskip \par\penalty 10000 %
+}
+
+\def\chfopen #1#2{\chapoddpage {\chapfonts
+\vbox to 3in{\vfil \hbox to\hsize{\hfil #2} \hbox to\hsize{\hfil #1} \vfil}}%
+\par\penalty 5000 %
+}
+
+\def\CHAPFopen{
+\global\let\chapmacro=\chfopen
+\global\let\unnumbchapmacro=\unnchfopen}
+
+% Parameter controlling skip before section headings.
+
+\newskip \subsecheadingskip \subsecheadingskip = 17pt plus 8pt minus 4pt
+\def\subsecheadingbreak{\dobreak \subsecheadingskip {-500}}
+
+\newskip \secheadingskip \secheadingskip = 21pt plus 8pt minus 4pt
+\def\secheadingbreak{\dobreak \secheadingskip {-1000}}
+
+% @paragraphindent is defined for the Info formatting commands only.
+\let\paragraphindent=\comment
+
+% Section fonts are the base font at magstep2, which produces
+% a size a bit more than 14 points in the default situation.
+
+\def\secheading #1#2#3{\secheadingi {#2.#3\enspace #1}}
+\def\plainsecheading #1{\secheadingi {#1}}
+\def\secheadingi #1{{\advance \secheadingskip by \parskip %
+\secheadingbreak}%
+{\secfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}%
+\ifdim \parskip<10pt \kern 10pt\kern -\parskip\fi \penalty 10000 }
+
+
+% Subsection fonts are the base font at magstep1,
+% which produces a size of 12 points.
+
+\def\subsecheading #1#2#3#4{\subsecheadingi {#2.#3.#4\enspace #1}}
+\def\subsecheadingi #1{{\advance \subsecheadingskip by \parskip %
+\subsecheadingbreak}%
+{\subsecfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}%
+\ifdim \parskip<10pt \kern 10pt\kern -\parskip\fi \penalty 10000 }
+
+\def\subsubsecfonts{\subsecfonts} % Maybe this should change:
+ % Perhaps make sssec fonts scaled
+ % magstep half
+\def\subsubsecheading #1#2#3#4#5{\subsubsecheadingi {#2.#3.#4.#5\enspace #1}}
+\def\subsubsecheadingi #1{{\advance \subsecheadingskip by \parskip %
+\subsecheadingbreak}%
+{\subsubsecfonts \vbox{\hyphenpenalty=10000\tolerance=5000
+ \parindent=0pt\raggedright
+ \rm #1\hfill}}%
+\ifdim \parskip<10pt \kern 10pt\kern -\parskip\fi \penalty 10000}
+
+
+\message{toc printing,}
+
+% Finish up the main text and prepare to read what we've written
+% to \contentsfile.
+
+\newskip\contentsrightmargin \contentsrightmargin=1in
+\def\startcontents#1{%
+ \pagealignmacro
+ \immediate\closeout \contentsfile
+ \ifnum \pageno>0
+ \pageno = -1 % Request roman numbered pages.
+ \fi
+ % Don't need to put `Contents' or `Short Contents' in the headline.
+ % It is abundantly clear what they are.
+ \unnumbchapmacro{#1}\def\thischapter{}%
+ \begingroup % Set up to handle contents files properly.
+ \catcode`\\=0 \catcode`\{=1 \catcode`\}=2 \catcode`\@=11
+ \raggedbottom % Worry more about breakpoints than the bottom.
+ \advance\hsize by -\contentsrightmargin % Don't use the full line length.
+}
+
+
+% Normal (long) toc.
+\outer\def\contents{%
+ \startcontents{\putwordTableofContents}%
+ \input \jobname.toc
+ \endgroup
+ \vfill \eject
+}
+
+% And just the chapters.
+\outer\def\summarycontents{%
+ \startcontents{\putwordShortContents}%
+ %
+ \let\chapentry = \shortchapentry
+ \let\unnumbchapentry = \shortunnumberedentry
+ % We want a true roman here for the page numbers.
+ \secfonts
+ \let\rm=\shortcontrm \let\bf=\shortcontbf \let\sl=\shortcontsl
+ \rm
+ \advance\baselineskip by 1pt % Open it up a little.
+ \def\secentry ##1##2##3##4{}
+ \def\unnumbsecentry ##1##2{}
+ \def\subsecentry ##1##2##3##4##5{}
+ \def\unnumbsubsecentry ##1##2{}
+ \def\subsubsecentry ##1##2##3##4##5##6{}
+ \def\unnumbsubsubsecentry ##1##2{}
+ \input \jobname.toc
+ \endgroup
+ \vfill \eject
+}
+\let\shortcontents = \summarycontents
+
+% These macros generate individual entries in the table of contents.
+% The first argument is the chapter or section name.
+% The last argument is the page number.
+% The arguments in between are the chapter number, section number, ...
+
+% Chapter-level things, for both the long and short contents.
+\def\chapentry#1#2#3{\dochapentry{#2\labelspace#1}{#3}}
+
+% See comments in \dochapentry re vbox and related settings
+\def\shortchapentry#1#2#3{%
+ \tocentry{\shortchaplabel{#2}\labelspace #1}{\doshortpageno{#3}}%
+}
+
+% Typeset the label for a chapter or appendix for the short contents.
+% The arg is, e.g. `Appendix A' for an appendix, or `3' for a chapter.
+% We could simplify the code here by writing out an \appendixentry
+% command in the toc file for appendices, instead of using \chapentry
+% for both, but it doesn't seem worth it.
+\setbox0 = \hbox{\shortcontrm \putwordAppendix }
+\newdimen\shortappendixwidth \shortappendixwidth = \wd0
+
+\def\shortchaplabel#1{%
+ % We typeset #1 in a box of constant width, regardless of the text of
+ % #1, so the chapter titles will come out aligned.
+ \setbox0 = \hbox{#1}%
+ \dimen0 = \ifdim\wd0 > \shortappendixwidth \shortappendixwidth \else 0pt \fi
+ %
+ % This space should be plenty, since a single number is .5em, and the
+ % widest letter (M) is 1em, at least in the Computer Modern fonts.
+ % (This space doesn't include the extra space that gets added after
+ % the label; that gets put in in \shortchapentry above.)
+ \advance\dimen0 by 1.1em
+ \hbox to \dimen0{#1\hfil}%
+}
+
+\def\unnumbchapentry#1#2{\dochapentry{#1}{#2}}
+\def\shortunnumberedentry#1#2{\tocentry{#1}{\doshortpageno{#2}}}
+
+% Sections.
+\def\secentry#1#2#3#4{\dosecentry{#2.#3\labelspace#1}{#4}}
+\def\unnumbsecentry#1#2{\dosecentry{#1}{#2}}
+
+% Subsections.
+\def\subsecentry#1#2#3#4#5{\dosubsecentry{#2.#3.#4\labelspace#1}{#5}}
+\def\unnumbsubsecentry#1#2{\dosubsecentry{#1}{#2}}
+
+% And subsubsections.
+\def\subsubsecentry#1#2#3#4#5#6{%
+ \dosubsubsecentry{#2.#3.#4.#5\labelspace#1}{#6}}
+\def\unnumbsubsubsecentry#1#2{\dosubsubsecentry{#1}{#2}}
+
+
+% This parameter controls the indentation of the various levels.
+\newdimen\tocindent \tocindent = 3pc
+
+% Now for the actual typesetting. In all these, #1 is the text and #2 is the
+% page number.
+%
+% If the toc has to be broken over pages, we would want to be at chapters
+% if at all possible; hence the \penalty.
+\def\dochapentry#1#2{%
+ \penalty-300 \vskip\baselineskip
+ \begingroup
+ \chapentryfonts
+ \tocentry{#1}{\dopageno{#2}}%
+ \endgroup
+ \nobreak\vskip .25\baselineskip
+}
+
+\def\dosecentry#1#2{\begingroup
+ \secentryfonts \leftskip=\tocindent
+ \tocentry{#1}{\dopageno{#2}}%
+\endgroup}
+
+\def\dosubsecentry#1#2{\begingroup
+ \subsecentryfonts \leftskip=2\tocindent
+ \tocentry{#1}{\dopageno{#2}}%
+\endgroup}
+
+\def\dosubsubsecentry#1#2{\begingroup
+ \subsubsecentryfonts \leftskip=3\tocindent
+ \tocentry{#1}{\dopageno{#2}}%
+\endgroup}
+
+% Final typesetting of a toc entry; we use the same \entry macro as for
+% the index entries, but we want to suppress hyphenation here. (We
+% can't do that in the \entry macro, since index entries might consist
+% of hyphenated-identifiers-that-do-not-fit-on-a-line-and-nothing-else.)
+%
+\def\tocentry#1#2{\begingroup
+ \hyphenpenalty = 10000
+ \entry{#1}{#2}%
+\endgroup}
+
+% Space between chapter (or whatever) number and the title.
+\def\labelspace{\hskip1em \relax}
+
+\def\dopageno#1{{\rm #1}}
+\def\doshortpageno#1{{\rm #1}}
+
+\def\chapentryfonts{\secfonts \rm}
+\def\secentryfonts{\textfonts}
+\let\subsecentryfonts = \textfonts
+\let\subsubsecentryfonts = \textfonts
+
+
+\message{environments,}
+
+% Since these characters are used in examples, it should be an even number of
+% \tt widths. Each \tt character is 1en, so two makes it 1em.
+% Furthermore, these definitions must come after we define our fonts.
+\newbox\dblarrowbox \newbox\longdblarrowbox
+\newbox\pushcharbox \newbox\bullbox
+\newbox\equivbox \newbox\errorbox
+
+\let\ptexequiv = \equiv
+
+%{\tentt
+%\global\setbox\dblarrowbox = \hbox to 1em{\hfil$\Rightarrow$\hfil}
+%\global\setbox\longdblarrowbox = \hbox to 1em{\hfil$\mapsto$\hfil}
+%\global\setbox\pushcharbox = \hbox to 1em{\hfil$\dashv$\hfil}
+%\global\setbox\equivbox = \hbox to 1em{\hfil$\ptexequiv$\hfil}
+% Adapted from the manmac format (p.420 of TeXbook)
+%\global\setbox\bullbox = \hbox to 1em{\kern.15em\vrule height .75ex width .85ex
+% depth .1ex\hfil}
+%}
+
+\def\point{$\star$}
+
+\def\result{\leavevmode\raise.15ex\hbox to 1em{\hfil$\Rightarrow$\hfil}}
+\def\expansion{\leavevmode\raise.1ex\hbox to 1em{\hfil$\mapsto$\hfil}}
+\def\print{\leavevmode\lower.1ex\hbox to 1em{\hfil$\dashv$\hfil}}
+
+\def\equiv{\leavevmode\lower.1ex\hbox to 1em{\hfil$\ptexequiv$\hfil}}
+
+% Adapted from the TeXbook's \boxit.
+{\tentt \global\dimen0 = 3em}% Width of the box.
+\dimen2 = .55pt % Thickness of rules
+% The text. (`r' is open on the right, `e' somewhat less so on the left.)
+\setbox0 = \hbox{\kern-.75pt \tensf error\kern-1.5pt}
+
+\global\setbox\errorbox=\hbox to \dimen0{\hfil
+ \hsize = \dimen0 \advance\hsize by -5.8pt % Space to left+right.
+ \advance\hsize by -2\dimen2 % Rules.
+ \vbox{
+ \hrule height\dimen2
+ \hbox{\vrule width\dimen2 \kern3pt % Space to left of text.
+ \vtop{\kern2.4pt \box0 \kern2.4pt}% Space above/below.
+ \kern3pt\vrule width\dimen2}% Space to right.
+ \hrule height\dimen2}
+ \hfil}
+
+% The @error{} command.
+\def\error{\leavevmode\lower.7ex\copy\errorbox}
+
+% @tex ... @end tex escapes into raw Tex temporarily.
+% One exception: @ is still an escape character, so that @end tex works.
+% But \@ or @@ will get a plain tex @ character.
+
+\def\tex{\begingroup
+\catcode `\\=0 \catcode `\{=1 \catcode `\}=2
+\catcode `\$=3 \catcode `\&=4 \catcode `\#=6
+\catcode `\^=7 \catcode `\_=8 \catcode `\~=13 \let~=\tie
+\catcode `\%=14
+\catcode 43=12
+\catcode`\"=12
+\catcode`\==12
+\catcode`\|=12
+\catcode`\<=12
+\catcode`\>=12
+\escapechar=`\\
+%
+\let\~=\ptextilde
+\let\{=\ptexlbrace
+\let\}=\ptexrbrace
+\let\.=\ptexdot
+\let\*=\ptexstar
+\let\dots=\ptexdots
+\def\@{@}%
+\let\bullet=\ptexbullet
+\let\b=\ptexb \let\c=\ptexc \let\i=\ptexi \let\t=\ptext \let\l=\ptexl
+\let\L=\ptexL
+%
+\let\Etex=\endgroup}
+
+% Define @lisp ... @endlisp.
+% @lisp does a \begingroup so it can rebind things,
+% including the definition of @endlisp (which normally is erroneous).
+
+% Amount to narrow the margins by for @lisp.
+\newskip\lispnarrowing \lispnarrowing=0.4in
+
+% This is the definition that ^^M gets inside @lisp, @example, and other
+% such environments. \null is better than a space, since it doesn't
+% have any width.
+\def\lisppar{\null\endgraf}
+
+% Make each space character in the input produce a normal interword
+% space in the output. Don't allow a line break at this space, as this
+% is used only in environments like @example, where each line of input
+% should produce a line of output anyway.
+%
+{\obeyspaces %
+\gdef\sepspaces{\obeyspaces\let =\tie}}
+
+% Define \obeyedspace to be our active space, whatever it is. This is
+% for use in \parsearg.
+{\sepspaces%
+\global\let\obeyedspace= }
+
+% This space is always present above and below environments.
+\newskip\envskipamount \envskipamount = 0pt
+
+% Make spacing and below environment symmetrical. We use \parskip here
+% to help in doing that, since in @example-like environments \parskip
+% is reset to zero; thus the \afterenvbreak inserts no space -- but the
+% start of the next paragraph will insert \parskip
+%
+\def\aboveenvbreak{{\advance\envskipamount by \parskip
+\endgraf \ifdim\lastskip<\envskipamount
+\removelastskip \penalty-50 \vskip\envskipamount \fi}}
+
+\let\afterenvbreak = \aboveenvbreak
+
+% \nonarrowing is a flag. If "set", @lisp etc don't narrow margins.
+\let\nonarrowing=\relax
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \cartouche: draw rectangle w/rounded corners around argument
+\font\circle=lcircle10
+\newdimen\circthick
+\newdimen\cartouter\newdimen\cartinner
+\newskip\normbskip\newskip\normpskip\newskip\normlskip
+\circthick=\fontdimen8\circle
+%
+\def\ctl{{\circle\char'013\hskip -6pt}}% 6pt from pl file: 1/2charwidth
+\def\ctr{{\hskip 6pt\circle\char'010}}
+\def\cbl{{\circle\char'012\hskip -6pt}}
+\def\cbr{{\hskip 6pt\circle\char'011}}
+\def\carttop{\hbox to \cartouter{\hskip\lskip
+ \ctl\leaders\hrule height\circthick\hfil\ctr
+ \hskip\rskip}}
+\def\cartbot{\hbox to \cartouter{\hskip\lskip
+ \cbl\leaders\hrule height\circthick\hfil\cbr
+ \hskip\rskip}}
+%
+\newskip\lskip\newskip\rskip
+
+\long\def\cartouche{%
+\begingroup
+ \lskip=\leftskip \rskip=\rightskip
+ \leftskip=0pt\rightskip=0pt %we want these *outside*.
+ \cartinner=\hsize \advance\cartinner by-\lskip
+ \advance\cartinner by-\rskip
+ \cartouter=\hsize
+ \advance\cartouter by 18pt % allow for 3pt kerns on either
+% side, and for 6pt waste from
+% each corner char
+ \normbskip=\baselineskip \normpskip=\parskip \normlskip=\lineskip
+ % Flag to tell @lisp, etc., not to narrow margin.
+ \let\nonarrowing=\comment
+ \vbox\bgroup
+ \baselineskip=0pt\parskip=0pt\lineskip=0pt
+ \carttop
+ \hbox\bgroup
+ \hskip\lskip
+ \vrule\kern3pt
+ \vbox\bgroup
+ \hsize=\cartinner
+ \kern3pt
+ \begingroup
+ \baselineskip=\normbskip
+ \lineskip=\normlskip
+ \parskip=\normpskip
+ \vskip -\parskip
+\def\Ecartouche{%
+ \endgroup
+ \kern3pt
+ \egroup
+ \kern3pt\vrule
+ \hskip\rskip
+ \egroup
+ \cartbot
+ \egroup
+\endgroup
+}}
+
+
+% This macro is called at the beginning of all the @example variants,
+% inside a group.
+\def\nonfillstart{%
+ \aboveenvbreak
+ \inENV % This group ends at the end of the body
+ \hfuzz = 12pt % Don't be fussy
+ \sepspaces % Make spaces be word-separators rather than space tokens.
+ \singlespace
+ \let\par = \lisppar % don't ignore blank lines
+ \obeylines % each line of input is a line of output
+ \parskip = 0pt
+ \parindent = 0pt
+ \emergencystretch = 0pt % don't try to avoid overfull boxes
+ % @cartouche defines \nonarrowing to inhibit narrowing
+ % at next level down.
+ \ifx\nonarrowing\relax
+ \advance \leftskip by \lispnarrowing
+ \exdentamount=\lispnarrowing
+ \let\exdent=\nofillexdent
+ \let\nonarrowing=\relax
+ \fi
+}
+
+% To ending an @example-like environment, we first end the paragraph
+% (via \afterenvbreak's vertical glue), and then the group. That way we
+% keep the zero \parskip that the environments set -- \parskip glue
+% will be inserted at the beginning of the next paragraph in the
+% document, after the environment.
+%
+\def\nonfillfinish{\afterenvbreak\endgroup}%
+
+% This macro is
+\def\lisp{\begingroup
+ \nonfillstart
+ \let\Elisp = \nonfillfinish
+ \tt
+ \rawbackslash % have \ input char produce \ char from current font
+ \gobble
+}
+
+% Define the \E... control sequence only if we are inside the
+% environment, so the error checking in \end will work.
+%
+% We must call \lisp last in the definition, since it reads the
+% return following the @example (or whatever) command.
+%
+\def\example{\begingroup \def\Eexample{\nonfillfinish\endgroup}\lisp}
+\def\smallexample{\begingroup \def\Esmallexample{\nonfillfinish\endgroup}\lisp}
+\def\smalllisp{\begingroup \def\Esmalllisp{\nonfillfinish\endgroup}\lisp}
+
+% @smallexample and @smalllisp. This is not used unless the @smallbook
+% command is given. Originally contributed by Pavel@xerox.
+%
+\def\smalllispx{\begingroup
+ \nonfillstart
+ \let\Esmalllisp = \nonfillfinish
+ \let\Esmallexample = \nonfillfinish
+ %
+ % Smaller interline space and fonts for small examples.
+ \setleading{10pt}%
+ \indexfonts \tt
+ \rawbackslash % make \ output the \ character from the current font (tt)
+ \gobble
+}
+
+% This is @display; same as @lisp except use roman font.
+%
+\def\display{\begingroup
+ \nonfillstart
+ \let\Edisplay = \nonfillfinish
+ \gobble
+}
+
+% This is @format; same as @display except don't narrow margins.
+%
+\def\format{\begingroup
+ \let\nonarrowing = t
+ \nonfillstart
+ \let\Eformat = \nonfillfinish
+ \gobble
+}
+
+% @flushleft (same as @format) and @flushright.
+%
+\def\flushleft{\begingroup
+ \let\nonarrowing = t
+ \nonfillstart
+ \let\Eflushleft = \nonfillfinish
+ \gobble
+}
+\def\flushright{\begingroup
+ \let\nonarrowing = t
+ \nonfillstart
+ \let\Eflushright = \nonfillfinish
+ \advance\leftskip by 0pt plus 1fill
+ \gobble}
+
+% @quotation does normal linebreaking (hence we can't use \nonfillstart)
+% and narrows the margins.
+%
+\def\quotation{%
+ \begingroup\inENV %This group ends at the end of the @quotation body
+ {\parskip=0pt \aboveenvbreak}% because \aboveenvbreak inserts \parskip
+ \singlespace
+ \parindent=0pt
+ % We have retained a nonzero parskip for the environment, since we're
+ % doing normal filling. So to avoid extra space below the environment...
+ \def\Equotation{\parskip = 0pt \nonfillfinish}%
+ %
+ % @cartouche defines \nonarrowing to inhibit narrowing at next level down.
+ \ifx\nonarrowing\relax
+ \advance\leftskip by \lispnarrowing
+ \advance\rightskip by \lispnarrowing
+ \exdentamount = \lispnarrowing
+ \let\nonarrowing = \relax
+ \fi
+}
+
+\message{defuns,}
+% Define formatter for defuns
+% First, allow user to change definition object font (\df) internally
+\def\setdeffont #1 {\csname DEF#1\endcsname}
+
+\newskip\defbodyindent \defbodyindent=.4in
+\newskip\defargsindent \defargsindent=50pt
+\newskip\deftypemargin \deftypemargin=12pt
+\newskip\deflastargmargin \deflastargmargin=18pt
+
+\newcount\parencount
+% define \functionparens, which makes ( and ) and & do special things.
+% \functionparens affects the group it is contained in.
+\def\activeparens{%
+\catcode`\(=\active \catcode`\)=\active \catcode`\&=\active
+\catcode`\[=\active \catcode`\]=\active}
+
+% Make control sequences which act like normal parenthesis chars.
+\let\lparen = ( \let\rparen = )
+
+{\activeparens % Now, smart parens don't turn on until &foo (see \amprm)
+
+% Be sure that we always have a definition for `(', etc. For example,
+% if the fn name has parens in it, \boldbrax will not be in effect yet,
+% so TeX would otherwise complain about undefined control sequence.
+\global\let(=\lparen \global\let)=\rparen
+\global\let[=\lbrack \global\let]=\rbrack
+
+\gdef\functionparens{\boldbrax\let&=\amprm\parencount=0 }
+\gdef\boldbrax{\let(=\opnr\let)=\clnr\let[=\lbrb\let]=\rbrb}
+
+% Definitions of (, ) and & used in args for functions.
+% This is the definition of ( outside of all parentheses.
+\gdef\oprm#1 {{\rm\char`\(}#1 \bf \let(=\opnested %
+\global\advance\parencount by 1 }
+%
+% This is the definition of ( when already inside a level of parens.
+\gdef\opnested{\char`\(\global\advance\parencount by 1 }
+%
+\gdef\clrm{% Print a paren in roman if it is taking us back to depth of 0.
+% also in that case restore the outer-level definition of (.
+\ifnum \parencount=1 {\rm \char `\)}\sl \let(=\oprm \else \char `\) \fi
+\global\advance \parencount by -1 }
+% If we encounter &foo, then turn on ()-hacking afterwards
+\gdef\amprm#1 {{\rm\&#1}\let(=\oprm \let)=\clrm\ }
+%
+\gdef\normalparens{\boldbrax\let&=\ampnr}
+} % End of definition inside \activeparens
+%% These parens (in \boldbrax) actually are a little bolder than the
+%% contained text. This is especially needed for [ and ]
+\def\opnr{{\sf\char`\(}} \def\clnr{{\sf\char`\)}} \def\ampnr{\&}
+\def\lbrb{{\bf\char`\[}} \def\rbrb{{\bf\char`\]}}
+
+% First, defname, which formats the header line itself.
+% #1 should be the function name.
+% #2 should be the type of definition, such as "Function".
+
+\def\defname #1#2{%
+% Get the values of \leftskip and \rightskip as they were
+% outside the @def...
+\dimen2=\leftskip
+\advance\dimen2 by -\defbodyindent
+\dimen3=\rightskip
+\advance\dimen3 by -\defbodyindent
+\noindent %
+\setbox0=\hbox{\hskip \deflastargmargin{\rm #2}\hskip \deftypemargin}%
+\dimen0=\hsize \advance \dimen0 by -\wd0 % compute size for first line
+\dimen1=\hsize \advance \dimen1 by -\defargsindent %size for continuations
+\parshape 2 0in \dimen0 \defargsindent \dimen1 %
+% Now output arg 2 ("Function" or some such)
+% ending at \deftypemargin from the right margin,
+% but stuck inside a box of width 0 so it does not interfere with linebreaking
+{% Adjust \hsize to exclude the ambient margins,
+% so that \rightline will obey them.
+\advance \hsize by -\dimen2 \advance \hsize by -\dimen3
+\rlap{\rightline{{\rm #2}\hskip \deftypemargin}}}%
+% Make all lines underfull and no complaints:
+\tolerance=10000 \hbadness=10000
+\advance\leftskip by -\defbodyindent
+\exdentamount=\defbodyindent
+{\df #1}\enskip % Generate function name
+}
+
+% Actually process the body of a definition
+% #1 should be the terminating control sequence, such as \Edefun.
+% #2 should be the "another name" control sequence, such as \defunx.
+% #3 should be the control sequence that actually processes the header,
+% such as \defunheader.
+
+\def\defparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody
+\medbreak %
+% Define the end token that this defining construct specifies
+% so that it will exit this group.
+\def#1{\endgraf\endgroup\medbreak}%
+\def#2{\begingroup\obeylines\activeparens\spacesplit#3}%
+\parindent=0in
+\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+\exdentamount=\defbodyindent
+\begingroup %
+\catcode 61=\active % 61 is `='
+\obeylines\activeparens\spacesplit#3}
+
+\def\defmethparsebody #1#2#3#4 {\begingroup\inENV %
+\medbreak %
+% Define the end token that this defining construct specifies
+% so that it will exit this group.
+\def#1{\endgraf\endgroup\medbreak}%
+\def#2##1 {\begingroup\obeylines\activeparens\spacesplit{#3{##1}}}%
+\parindent=0in
+\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+\exdentamount=\defbodyindent
+\begingroup\obeylines\activeparens\spacesplit{#3{#4}}}
+
+\def\defopparsebody #1#2#3#4#5 {\begingroup\inENV %
+\medbreak %
+% Define the end token that this defining construct specifies
+% so that it will exit this group.
+\def#1{\endgraf\endgroup\medbreak}%
+\def#2##1 ##2 {\def#4{##1}%
+\begingroup\obeylines\activeparens\spacesplit{#3{##2}}}%
+\parindent=0in
+\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+\exdentamount=\defbodyindent
+\begingroup\obeylines\activeparens\spacesplit{#3{#5}}}
+
+% These parsing functions are similar to the preceding ones
+% except that they do not make parens into active characters.
+% These are used for "variables" since they have no arguments.
+
+\def\defvarparsebody #1#2#3{\begingroup\inENV% Environment for definitionbody
+\medbreak %
+% Define the end token that this defining construct specifies
+% so that it will exit this group.
+\def#1{\endgraf\endgroup\medbreak}%
+\def#2{\begingroup\obeylines\spacesplit#3}%
+\parindent=0in
+\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+\exdentamount=\defbodyindent
+\begingroup %
+\catcode 61=\active %
+\obeylines\spacesplit#3}
+
+% This is used for \def{tp,vr}parsebody. It could probably be used for
+% some of the others, too, with some judicious conditionals.
+%
+\def\parsebodycommon#1#2#3{%
+ \begingroup\inENV %
+ \medbreak %
+ % Define the end token that this defining construct specifies
+ % so that it will exit this group.
+ \def#1{\endgraf\endgroup\medbreak}%
+ \def#2##1 {\begingroup\obeylines\spacesplit{#3{##1}}}%
+ \parindent=0in
+ \advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+ \exdentamount=\defbodyindent
+ \begingroup\obeylines
+}
+
+\def\defvrparsebody#1#2#3#4 {%
+ \parsebodycommon{#1}{#2}{#3}%
+ \spacesplit{#3{#4}}%
+}
+
+% This loses on `@deftp {Data Type} {struct termios}' -- it thinks the
+% type is just `struct', because we lose the braces in `{struct
+% termios}' when \spacesplit reads its undelimited argument. Sigh.
+% \let\deftpparsebody=\defvrparsebody
+%
+% So, to get around this, we put \empty in with the type name. That
+% way, TeX won't find exactly `{...}' as an undelimited argument, and
+% won't strip off the braces.
+%
+\def\deftpparsebody #1#2#3#4 {%
+ \parsebodycommon{#1}{#2}{#3}%
+ \spacesplit{\parsetpheaderline{#3{#4}}}\empty
+}
+
+% Fine, but then we have to eventually remove the \empty *and* the
+% braces (if any). That's what this does, putting the result in \tptemp.
+%
+\def\removeemptybraces\empty#1\relax{\def\tptemp{#1}}%
+
+% After \spacesplit has done its work, this is called -- #1 is the final
+% thing to call, #2 the type name (which starts with \empty), and #3
+% (which might be empty) the arguments.
+%
+\def\parsetpheaderline#1#2#3{%
+ \removeemptybraces#2\relax
+ #1{\tptemp}{#3}%
+}%
+
+\def\defopvarparsebody #1#2#3#4#5 {\begingroup\inENV %
+\medbreak %
+% Define the end token that this defining construct specifies
+% so that it will exit this group.
+\def#1{\endgraf\endgroup\medbreak}%
+\def#2##1 ##2 {\def#4{##1}%
+\begingroup\obeylines\spacesplit{#3{##2}}}%
+\parindent=0in
+\advance\leftskip by \defbodyindent \advance \rightskip by \defbodyindent
+\exdentamount=\defbodyindent
+\begingroup\obeylines\spacesplit{#3{#5}}}
+
+% Split up #2 at the first space token.
+% call #1 with two arguments:
+% the first is all of #2 before the space token,
+% the second is all of #2 after that space token.
+% If #2 contains no space token, all of it is passed as the first arg
+% and the second is passed as empty.
+
+{\obeylines
+\gdef\spacesplit#1#2^^M{\endgroup\spacesplitfoo{#1}#2 \relax\spacesplitfoo}%
+\long\gdef\spacesplitfoo#1#2 #3#4\spacesplitfoo{%
+\ifx\relax #3%
+#1{#2}{}\else #1{#2}{#3#4}\fi}}
+
+% So much for the things common to all kinds of definitions.
+
+% Define @defun.
+
+% First, define the processing that is wanted for arguments of \defun
+% Use this to expand the args and terminate the paragraph they make up
+
+\def\defunargs #1{\functionparens \sl
+% Expand, preventing hyphenation at `-' chars.
+% Note that groups don't affect changes in \hyphenchar.
+\hyphenchar\tensl=0
+#1%
+\hyphenchar\tensl=45
+\ifnum\parencount=0 \else \errmessage{unbalanced parens in @def arguments}\fi%
+\interlinepenalty=10000
+\advance\rightskip by 0pt plus 1fil
+\endgraf\penalty 10000\vskip -\parskip\penalty 10000%
+}
+
+\def\deftypefunargs #1{%
+% Expand, preventing hyphenation at `-' chars.
+% Note that groups don't affect changes in \hyphenchar.
+\functionparens
+\tclose{#1}% avoid \code because of side effects on active chars
+\interlinepenalty=10000
+\advance\rightskip by 0pt plus 1fil
+\endgraf\penalty 10000\vskip -\parskip\penalty 10000%
+}
+
+% Do complete processing of one @defun or @defunx line already parsed.
+
+% @deffn Command forward-char nchars
+
+\def\deffn{\defmethparsebody\Edeffn\deffnx\deffnheader}
+
+\def\deffnheader #1#2#3{\doind {fn}{\code{#2}}%
+\begingroup\defname {#2}{#1}\defunargs{#3}\endgroup %
+\catcode 61=\other % Turn off change made in \defparsebody
+}
+
+% @defun == @deffn Function
+
+\def\defun{\defparsebody\Edefun\defunx\defunheader}
+
+\def\defunheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index
+\begingroup\defname {#1}{Function}%
+\defunargs {#2}\endgroup %
+\catcode 61=\other % Turn off change made in \defparsebody
+}
+
+% @deftypefun int foobar (int @var{foo}, float @var{bar})
+
+\def\deftypefun{\defparsebody\Edeftypefun\deftypefunx\deftypefunheader}
+
+% #1 is the data type. #2 is the name and args.
+\def\deftypefunheader #1#2{\deftypefunheaderx{#1}#2 \relax}
+% #1 is the data type, #2 the name, #3 the args.
+\def\deftypefunheaderx #1#2 #3\relax{%
+\doind {fn}{\code{#2}}% Make entry in function index
+\begingroup\defname {\defheaderxcond#1\relax$$$#2}{Function}%
+\deftypefunargs {#3}\endgroup %
+\catcode 61=\other % Turn off change made in \defparsebody
+}
+
+% @deftypefn {Library Function} int foobar (int @var{foo}, float @var{bar})
+
+\def\deftypefn{\defmethparsebody\Edeftypefn\deftypefnx\deftypefnheader}
+
+% \defheaderxcond#1\relax$$$
+% puts #1 in @code, followed by a space, but does nothing if #1 is null.
+\def\defheaderxcond#1#2$$${\ifx#1\relax\else\code{#1#2} \fi}
+
+% #1 is the classification. #2 is the data type. #3 is the name and args.
+\def\deftypefnheader #1#2#3{\deftypefnheaderx{#1}{#2}#3 \relax}
+% #1 is the classification, #2 the data type, #3 the name, #4 the args.
+\def\deftypefnheaderx #1#2#3 #4\relax{%
+\doind {fn}{\code{#3}}% Make entry in function index
+\begingroup
+\normalparens % notably, turn off `&' magic, which prevents
+% at least some C++ text from working
+\defname {\defheaderxcond#2\relax$$$#3}{#1}%
+\deftypefunargs {#4}\endgroup %
+\catcode 61=\other % Turn off change made in \defparsebody
+}
+
+% @defmac == @deffn Macro
+
+\def\defmac{\defparsebody\Edefmac\defmacx\defmacheader}
+
+\def\defmacheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index
+\begingroup\defname {#1}{Macro}%
+\defunargs {#2}\endgroup %
+\catcode 61=\other % Turn off change made in \defparsebody
+}
+
+% @defspec == @deffn Special Form
+
+\def\defspec{\defparsebody\Edefspec\defspecx\defspecheader}
+
+\def\defspecheader #1#2{\doind {fn}{\code{#1}}% Make entry in function index
+\begingroup\defname {#1}{Special Form}%
+\defunargs {#2}\endgroup %
+\catcode 61=\other % Turn off change made in \defparsebody
+}
+
+% This definition is run if you use @defunx
+% anywhere other than immediately after a @defun or @defunx.
+
+\def\deffnx #1 {\errmessage{@deffnx in invalid context}}
+\def\defunx #1 {\errmessage{@defunx in invalid context}}
+\def\defmacx #1 {\errmessage{@defmacx in invalid context}}
+\def\defspecx #1 {\errmessage{@defspecx in invalid context}}
+\def\deftypefnx #1 {\errmessage{@deftypefnx in invalid context}}
+\def\deftypeunx #1 {\errmessage{@deftypeunx in invalid context}}
+
+% @defmethod, and so on
+
+% @defop {Funny Method} foo-class frobnicate argument
+
+\def\defop #1 {\def\defoptype{#1}%
+\defopparsebody\Edefop\defopx\defopheader\defoptype}
+
+\def\defopheader #1#2#3{%
+\dosubind {fn}{\code{#2}}{on #1}% Make entry in function index
+\begingroup\defname {#2}{\defoptype{} on #1}%
+\defunargs {#3}\endgroup %
+}
+
+% @defmethod == @defop Method
+
+\def\defmethod{\defmethparsebody\Edefmethod\defmethodx\defmethodheader}
+
+\def\defmethodheader #1#2#3{%
+\dosubind {fn}{\code{#2}}{on #1}% entry in function index
+\begingroup\defname {#2}{Method on #1}%
+\defunargs {#3}\endgroup %
+}
+
+% @defcv {Class Option} foo-class foo-flag
+
+\def\defcv #1 {\def\defcvtype{#1}%
+\defopvarparsebody\Edefcv\defcvx\defcvarheader\defcvtype}
+
+\def\defcvarheader #1#2#3{%
+\dosubind {vr}{\code{#2}}{of #1}% Make entry in var index
+\begingroup\defname {#2}{\defcvtype{} of #1}%
+\defvarargs {#3}\endgroup %
+}
+
+% @defivar == @defcv {Instance Variable}
+
+\def\defivar{\defvrparsebody\Edefivar\defivarx\defivarheader}
+
+\def\defivarheader #1#2#3{%
+\dosubind {vr}{\code{#2}}{of #1}% Make entry in var index
+\begingroup\defname {#2}{Instance Variable of #1}%
+\defvarargs {#3}\endgroup %
+}
+
+% These definitions are run if you use @defmethodx, etc.,
+% anywhere other than immediately after a @defmethod, etc.
+
+\def\defopx #1 {\errmessage{@defopx in invalid context}}
+\def\defmethodx #1 {\errmessage{@defmethodx in invalid context}}
+\def\defcvx #1 {\errmessage{@defcvx in invalid context}}
+\def\defivarx #1 {\errmessage{@defivarx in invalid context}}
+
+% Now @defvar
+
+% First, define the processing that is wanted for arguments of @defvar.
+% This is actually simple: just print them in roman.
+% This must expand the args and terminate the paragraph they make up
+\def\defvarargs #1{\normalparens #1%
+\interlinepenalty=10000
+\endgraf\penalty 10000\vskip -\parskip\penalty 10000}
+
+% @defvr Counter foo-count
+
+\def\defvr{\defvrparsebody\Edefvr\defvrx\defvrheader}
+
+\def\defvrheader #1#2#3{\doind {vr}{\code{#2}}%
+\begingroup\defname {#2}{#1}\defvarargs{#3}\endgroup}
+
+% @defvar == @defvr Variable
+
+\def\defvar{\defvarparsebody\Edefvar\defvarx\defvarheader}
+
+\def\defvarheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index
+\begingroup\defname {#1}{Variable}%
+\defvarargs {#2}\endgroup %
+}
+
+% @defopt == @defvr {User Option}
+
+\def\defopt{\defvarparsebody\Edefopt\defoptx\defoptheader}
+
+\def\defoptheader #1#2{\doind {vr}{\code{#1}}% Make entry in var index
+\begingroup\defname {#1}{User Option}%
+\defvarargs {#2}\endgroup %
+}
+
+% @deftypevar int foobar
+
+\def\deftypevar{\defvarparsebody\Edeftypevar\deftypevarx\deftypevarheader}
+
+% #1 is the data type. #2 is the name.
+\def\deftypevarheader #1#2{%
+\doind {vr}{\code{#2}}% Make entry in variables index
+\begingroup\defname {\defheaderxcond#1\relax$$$#2}{Variable}%
+\interlinepenalty=10000
+\endgraf\penalty 10000\vskip -\parskip\penalty 10000
+\endgroup}
+
+% @deftypevr {Global Flag} int enable
+
+\def\deftypevr{\defvrparsebody\Edeftypevr\deftypevrx\deftypevrheader}
+
+\def\deftypevrheader #1#2#3{\doind {vr}{\code{#3}}%
+\begingroup\defname {\defheaderxcond#2\relax$$$#3}{#1}
+\interlinepenalty=10000
+\endgraf\penalty 10000\vskip -\parskip\penalty 10000
+\endgroup}
+
+% This definition is run if you use @defvarx
+% anywhere other than immediately after a @defvar or @defvarx.
+
+\def\defvrx #1 {\errmessage{@defvrx in invalid context}}
+\def\defvarx #1 {\errmessage{@defvarx in invalid context}}
+\def\defoptx #1 {\errmessage{@defoptx in invalid context}}
+\def\deftypevarx #1 {\errmessage{@deftypevarx in invalid context}}
+\def\deftypevrx #1 {\errmessage{@deftypevrx in invalid context}}
+
+% Now define @deftp
+% Args are printed in bold, a slight difference from @defvar.
+
+\def\deftpargs #1{\bf \defvarargs{#1}}
+
+% @deftp Class window height width ...
+
+\def\deftp{\deftpparsebody\Edeftp\deftpx\deftpheader}
+
+\def\deftpheader #1#2#3{\doind {tp}{\code{#2}}%
+\begingroup\defname {#2}{#1}\deftpargs{#3}\endgroup}
+
+% This definition is run if you use @deftpx, etc
+% anywhere other than immediately after a @deftp, etc.
+
+\def\deftpx #1 {\errmessage{@deftpx in invalid context}}
+
+\message{cross reference,}
+% Define cross-reference macros
+\newwrite \auxfile
+
+\newif\ifhavexrefs % True if xref values are known.
+\newif\ifwarnedxrefs % True if we warned once that they aren't known.
+
+% \setref{foo} defines a cross-reference point named foo.
+
+\def\setref#1{%
+\dosetq{#1-title}{Ytitle}%
+\dosetq{#1-pg}{Ypagenumber}%
+\dosetq{#1-snt}{Ysectionnumberandtype}}
+
+\def\unnumbsetref#1{%
+\dosetq{#1-title}{Ytitle}%
+\dosetq{#1-pg}{Ypagenumber}%
+\dosetq{#1-snt}{Ynothing}}
+
+\def\appendixsetref#1{%
+\dosetq{#1-title}{Ytitle}%
+\dosetq{#1-pg}{Ypagenumber}%
+\dosetq{#1-snt}{Yappendixletterandtype}}
+
+% \xref, \pxref, and \ref generate cross-references to specified points.
+% For \xrefX, #1 is the node name, #2 the name of the Info
+% cross-reference, #3 the printed node name, #4 the name of the Info
+% file, #5 the name of the printed manual. All but the node name can be
+% omitted.
+%
+\def\pxref#1{\putwordsee{} \xrefX[#1,,,,,,,]}
+\def\xref#1{\putwordSee{} \xrefX[#1,,,,,,,]}
+\def\ref#1{\xrefX[#1,,,,,,,]}
+\def\xrefX[#1,#2,#3,#4,#5,#6]{\begingroup
+ \def\printedmanual{\ignorespaces #5}%
+ \def\printednodename{\ignorespaces #3}%
+ \setbox1=\hbox{\printedmanual}%
+ \setbox0=\hbox{\printednodename}%
+ \ifdim \wd0 = 0pt
+ % No printed node name was explicitly given.
+ \ifx\SETxref-automatic-section-title\relax %
+ % Use the actual chapter/section title appear inside
+ % the square brackets. Use the real section title if we have it.
+ \ifdim \wd1>0pt%
+ % It is in another manual, so we don't have it.
+ \def\printednodename{\ignorespaces #1}%
+ \else
+ \ifhavexrefs
+ % We know the real title if we have the xref values.
+ \def\printednodename{\refx{#1-title}}%
+ \else
+ % Otherwise just copy the Info node name.
+ \def\printednodename{\ignorespaces #1}%
+ \fi%
+ \fi
+ \def\printednodename{#1-title}%
+ \else
+ % Use the node name inside the square brackets.
+ \def\printednodename{\ignorespaces #1}%
+ \fi
+ \fi
+ %
+ % If we use \unhbox0 and \unhbox1 to print the node names, TeX does not
+ % insert empty discretionaries after hyphens, which means that it will
+ % not find a line break at a hyphen in a node names. Since some manuals
+ % are best written with fairly long node names, containing hyphens, this
+ % is a loss. Therefore, we give the text of the node name again, so it
+ % is as if TeX is seeing it for the first time.
+ \ifdim \wd1 > 0pt
+ \putwordsection{} ``\printednodename'' in \cite{\printedmanual}%
+ \else
+ % _ (for example) has to be the character _ for the purposes of the
+ % control sequence corresponding to the node, but it has to expand
+ % into the usual \leavevmode...\vrule stuff for purposes of
+ % printing. So we \turnoffactive for the \refx-snt, back on for the
+ % printing, back off for the \refx-pg.
+ {\turnoffactive \refx{#1-snt}{}}%
+ \space [\printednodename],\space
+ \turnoffactive \putwordpage\tie\refx{#1-pg}{}%
+ \fi
+\endgroup}
+
+% \dosetq is the interface for calls from other macros
+
+% Use \turnoffactive so that punctuation chars such as underscore
+% work in node names.
+\def\dosetq #1#2{{\let\folio=0 \turnoffactive%
+\edef\next{\write\auxfile{\internalsetq {#1}{#2}}}%
+\next}}
+
+% \internalsetq {foo}{page} expands into
+% CHARACTERS 'xrdef {foo}{...expansion of \Ypage...}
+% When the aux file is read, ' is the escape character
+
+\def\internalsetq #1#2{'xrdef {#1}{\csname #2\endcsname}}
+
+% Things to be expanded by \internalsetq
+
+\def\Ypagenumber{\folio}
+
+\def\Ytitle{\thissection}
+
+\def\Ynothing{}
+
+\def\Ysectionnumberandtype{%
+\ifnum\secno=0 \putwordChapter\xreftie\the\chapno %
+\else \ifnum \subsecno=0 \putwordSection\xreftie\the\chapno.\the\secno %
+\else \ifnum \subsubsecno=0 %
+\putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno %
+\else %
+\putwordSection\xreftie\the\chapno.\the\secno.\the\subsecno.\the\subsubsecno %
+\fi \fi \fi }
+
+\def\Yappendixletterandtype{%
+\ifnum\secno=0 \putwordAppendix\xreftie'char\the\appendixno{}%
+\else \ifnum \subsecno=0 \putwordSection\xreftie'char\the\appendixno.\the\secno %
+\else \ifnum \subsubsecno=0 %
+\putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno %
+\else %
+\putwordSection\xreftie'char\the\appendixno.\the\secno.\the\subsecno.\the\subsubsecno %
+\fi \fi \fi }
+
+\gdef\xreftie{'tie}
+
+% Use TeX 3.0's \inputlineno to get the line number, for better error
+% messages, but if we're using an old version of TeX, don't do anything.
+%
+\ifx\inputlineno\thisisundefined
+ \let\linenumber = \empty % Non-3.0.
+\else
+ \def\linenumber{\the\inputlineno:\space}
+\fi
+
+% Define \refx{NAME}{SUFFIX} to reference a cross-reference string named NAME.
+% If its value is nonempty, SUFFIX is output afterward.
+
+\def\refx#1#2{%
+ \expandafter\ifx\csname X#1\endcsname\relax
+ % If not defined, say something at least.
+ $\langle$un\-de\-fined$\rangle$%
+ \ifhavexrefs
+ \message{\linenumber Undefined cross reference `#1'.}%
+ \else
+ \ifwarnedxrefs\else
+ \global\warnedxrefstrue
+ \message{Cross reference values unknown; you must run TeX again.}%
+ \fi
+ \fi
+ \else
+ % It's defined, so just use it.
+ \csname X#1\endcsname
+ \fi
+ #2% Output the suffix in any case.
+}
+
+% Read the last existing aux file, if any. No error if none exists.
+
+% This is the macro invoked by entries in the aux file.
+\def\xrdef #1#2{
+{\catcode`\'=\other\expandafter \gdef \csname X#1\endcsname {#2}}}
+
+\def\readauxfile{%
+\begingroup
+\catcode `\^^@=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\^^C=\other
+\catcode `\^^D=\other
+\catcode `\^^E=\other
+\catcode `\^^F=\other
+\catcode `\^^G=\other
+\catcode `\^^H=\other
+\catcode `\ =\other
+\catcode `\^^L=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode `\=\other
+\catcode 26=\other
+\catcode `\^^[=\other
+\catcode `\^^\=\other
+\catcode `\^^]=\other
+\catcode `\^^^=\other
+\catcode `\^^_=\other
+\catcode `\@=\other
+\catcode `\^=\other
+\catcode `\~=\other
+\catcode `\[=\other
+\catcode `\]=\other
+\catcode`\"=\other
+\catcode`\_=\other
+\catcode`\|=\other
+\catcode`\<=\other
+\catcode`\>=\other
+\catcode `\$=\other
+\catcode `\#=\other
+\catcode `\&=\other
+% `\+ does not work, so use 43.
+\catcode 43=\other
+% Make the characters 128-255 be printing characters
+{%
+ \count 1=128
+ \def\loop{%
+ \catcode\count 1=\other
+ \advance\count 1 by 1
+ \ifnum \count 1<256 \loop \fi
+ }%
+}%
+% the aux file uses ' as the escape.
+% Turn off \ as an escape so we do not lose on
+% entries which were dumped with control sequences in their names.
+% For example, 'xrdef {$\leq $-fun}{page ...} made by @defun ^^
+% Reference to such entries still does not work the way one would wish,
+% but at least they do not bomb out when the aux file is read in.
+\catcode `\{=1 \catcode `\}=2
+\catcode `\%=\other
+\catcode `\'=0
+\catcode `\\=\other
+\openin 1 \jobname.aux
+\ifeof 1 \else \closein 1 \input \jobname.aux \global\havexrefstrue
+\global\warnedobstrue
+\fi
+% Open the new aux file. Tex will close it automatically at exit.
+\openout \auxfile=\jobname.aux
+\endgroup}
+
+
+% Footnotes.
+
+\newcount \footnoteno
+
+% The trailing space in the following definition for supereject is
+% vital for proper filling; pages come out unaligned when you do a
+% pagealignmacro call if that space before the closing brace is
+% removed.
+\def\supereject{\par\penalty -20000\footnoteno =0 }
+
+% @footnotestyle is meaningful for info output only..
+\let\footnotestyle=\comment
+
+\let\ptexfootnote=\footnote
+
+{\catcode `\@=11
+%
+% Auto-number footnotes. Otherwise like plain.
+\gdef\footnote{%
+ \global\advance\footnoteno by \@ne
+ \edef\thisfootno{$^{\the\footnoteno}$}%
+ %
+ % In case the footnote comes at the end of a sentence, preserve the
+ % extra spacing after we do the footnote number.
+ \let\@sf\empty
+ \ifhmode\edef\@sf{\spacefactor\the\spacefactor}\/\fi
+ %
+ % Remove inadvertent blank space before typesetting the footnote number.
+ \unskip
+ \thisfootno\@sf
+ \footnotezzz
+}%
+
+% Don't bother with the trickery in plain.tex to not require the
+% footnote text as a parameter. Our footnotes don't need to be so general.
+%
+\long\gdef\footnotezzz#1{\insert\footins{%
+ % We want to typeset this text as a normal paragraph, even if the
+ % footnote reference occurs in (for example) a display environment.
+ % So reset some parameters.
+ \interlinepenalty\interfootnotelinepenalty
+ \splittopskip\ht\strutbox % top baseline for broken footnotes
+ \splitmaxdepth\dp\strutbox
+ \floatingpenalty\@MM
+ \leftskip\z@skip
+ \rightskip\z@skip
+ \spaceskip\z@skip
+ \xspaceskip\z@skip
+ \parindent\defaultparindent
+ %
+ % Hang the footnote text off the number.
+ \hang
+ \textindent{\thisfootno}%
+ %
+ % Don't crash into the line above the footnote text. Since this
+ % expands into a box, it must come within the paragraph, lest it
+ % provide a place where TeX can split the footnote.
+ \footstrut
+ #1\strut}%
+}
+
+}%end \catcode `\@=11
+
+% Set the baselineskip to #1, and the lineskip and strut size
+% correspondingly. There is no deep meaning behind these magic numbers
+% used as factors; they just match (closely enough) what Knuth defined.
+%
+\def\lineskipfactor{.08333}
+\def\strutheightpercent{.70833}
+\def\strutdepthpercent {.29167}
+%
+\def\setleading#1{%
+ \normalbaselineskip = #1\relax
+ \normallineskip = \lineskipfactor\normalbaselineskip
+ \normalbaselines
+ \setbox\strutbox =\hbox{%
+ \vrule width0pt height\strutheightpercent\baselineskip
+ depth \strutdepthpercent \baselineskip
+ }%
+}
+
+% @| inserts a changebar to the left of the current line. It should
+% surround any changed text. This approach does *not* work if the
+% change spans more than two lines of output. To handle that, we would
+% have adopt a much more difficult approach (putting marks into the main
+% vertical list for the beginning and end of each change).
+%
+\def\|{%
+ % \vadjust can only be used in horizontal mode.
+ \leavevmode
+ %
+ % Append this vertical mode material after the current line in the output.
+ \vadjust{%
+ % We want to insert a rule with the height and depth of the current
+ % leading; that is exactly what \strutbox is supposed to record.
+ \vskip-\baselineskip
+ %
+ % \vadjust-items are inserted at the left edge of the type. So
+ % the \llap here moves out into the left-hand margin.
+ \llap{%
+ %
+ % For a thicker or thinner bar, change the `1pt'.
+ \vrule height\baselineskip width1pt
+ %
+ % This is the space between the bar and the text.
+ \hskip 12pt
+ }%
+ }%
+}
+
+% For a final copy, take out the rectangles
+% that mark overfull boxes (in case you have decided
+% that the text looks ok even though it passes the margin).
+%
+\def\finalout{\overfullrule=0pt}
+
+
+% End of control word definitions.
+
+\message{and turning on texinfo input format.}
+
+\def\openindices{%
+ \newindex{cp}%
+ \newcodeindex{fn}%
+ \newcodeindex{vr}%
+ \newcodeindex{tp}%
+ \newcodeindex{ky}%
+ \newcodeindex{pg}%
+}
+
+% Set some numeric style parameters, for 8.5 x 11 format.
+
+%\hsize = 6.5in
+\newdimen\defaultparindent \defaultparindent = 15pt
+\parindent = \defaultparindent
+\parskip 18pt plus 1pt
+\setleading{15pt}
+\advance\topskip by 1.2cm
+
+% Prevent underfull vbox error messages.
+\vbadness=10000
+
+% Following George Bush, just get rid of widows and orphans.
+\widowpenalty=10000
+\clubpenalty=10000
+
+% Use TeX 3.0's \emergencystretch to help line breaking, but if we're
+% using an old version of TeX, don't do anything. We want the amount of
+% stretch added to depend on the line length, hence the dependence on
+% \hsize. This makes it come to about 9pt for the 8.5x11 format.
+%
+\ifx\emergencystretch\thisisundefined
+ % Allow us to assign to \emergencystretch anyway.
+ \def\emergencystretch{\dimen0}%
+\else
+ \emergencystretch = \hsize
+ \divide\emergencystretch by 45
+\fi
+
+% Use @smallbook to reset parameters for 7x9.5 format (or else 7x9.25)
+\def\smallbook{
+
+% These values for secheadingskip and subsecheadingskip are
+% experiments. RJC 7 Aug 1992
+\global\secheadingskip = 17pt plus 6pt minus 3pt
+\global\subsecheadingskip = 14pt plus 6pt minus 3pt
+
+\global\lispnarrowing = 0.3in
+\setleading{12pt}
+\advance\topskip by -1cm
+\global\parskip 3pt plus 1pt
+\global\hsize = 5in
+\global\vsize=7.5in
+\global\tolerance=700
+\global\hfuzz=1pt
+\global\contentsrightmargin=0pt
+\global\deftypemargin=0pt
+\global\defbodyindent=.5cm
+
+\global\pagewidth=\hsize
+\global\pageheight=\vsize
+
+\global\let\smalllisp=\smalllispx
+\global\let\smallexample=\smalllispx
+\global\def\Esmallexample{\Esmalllisp}
+}
+
+% Use @afourpaper to print on European A4 paper.
+\def\afourpaper{
+\global\tolerance=700
+\global\hfuzz=1pt
+\setleading{12pt}
+\global\parskip 15pt plus 1pt
+
+\global\vsize= 53\baselineskip
+\advance\vsize by \topskip
+%\global\hsize= 5.85in % A4 wide 10pt
+\global\hsize= 6.5in
+\global\outerhsize=\hsize
+\global\advance\outerhsize by 0.5in
+\global\outervsize=\vsize
+\global\advance\outervsize by 0.6in
+
+\global\pagewidth=\hsize
+\global\pageheight=\vsize
+}
+
+% Allow control of the text dimensions. Parameters in order: textheight;
+% textwidth; \voffset; \hoffset (!); binding offset. All require a dimension;
+% header is additional; added length extends the bottom of the page.
+
+\def\changepagesizes#1#2#3#4#5
+{\global\vsize= #1
+ \advance\vsize by \topskip
+ \global\voffset= #3
+ \global\hsize= #2
+ \global\outerhsize=\hsize
+ \global\advance\outerhsize by 0.5in
+ \global\outervsize=\vsize
+ \global\advance\outervsize by 0.6in
+ \global\pagewidth=\hsize
+ \global\pageheight=\vsize
+ \global\normaloffset= #4
+ \global\bindingoffset= #5}
+
+% This layout is compatible with Latex on A4 paper.
+
+\def\afourlatex{\changepagesizes{22cm}{15cm}{7mm}{4.6mm}{5mm}}
+
+% Define macros to output various characters with catcode for normal text.
+\catcode`\"=\other
+\catcode`\~=\other
+\catcode`\^=\other
+\catcode`\_=\other
+\catcode`\|=\other
+\catcode`\<=\other
+\catcode`\>=\other
+\catcode`\+=\other
+\def\normaldoublequote{"}
+\def\normaltilde{~}
+\def\normalcaret{^}
+\def\normalunderscore{_}
+\def\normalverticalbar{|}
+\def\normalless{<}
+\def\normalgreater{>}
+\def\normalplus{+}
+
+% This macro is used to make a character print one way in ttfont
+% where it can probably just be output, and another way in other fonts,
+% where something hairier probably needs to be done.
+%
+% #1 is what to print if we are indeed using \tt; #2 is what to print
+% otherwise. Since all the Computer Modern typewriter fonts have zero
+% interword stretch (and shrink), and it is reasonable to expect all
+% typewriter fonts to have this, we can check that font parameter.
+%
+\def\ifusingtt#1#2{\ifdim \fontdimen3\the\font=0pt #1\else #2\fi}
+
+% Turn off all special characters except @
+% (and those which the user can use as if they were ordinary).
+% Most of these we simply print from the \tt font, but for some, we can
+% use math or other variants that look better in normal text.
+
+\catcode`\"=\active
+\def\activedoublequote{{\tt \char '042}}
+\let"=\activedoublequote
+\catcode`\~=\active
+\def~{{\tt \char '176}}
+\chardef\hat=`\^
+\catcode`\^=\active
+\def^{{\tt \hat}}
+
+\catcode`\_=\active
+\def_{\ifusingtt\normalunderscore\_}
+% Subroutine for the previous macro.
+\def\_{\lvvmode \kern.06em \vbox{\hrule width.3em height.1ex}}
+
+% \lvvmode is equivalent in function to \leavevmode.
+% Using \leavevmode runs into trouble when written out to
+% an index file due to the expansion of \leavevmode into ``\unhbox
+% \voidb@x'' ---which looks to TeX like ``\unhbox \voidb\x'' due to our
+% magic tricks with @.
+\def\lvvmode{\vbox to 0pt{}}
+
+\catcode`\|=\active
+\def|{{\tt \char '174}}
+\chardef \less=`\<
+\catcode`\<=\active
+\def<{{\tt \less}}
+\chardef \gtr=`\>
+\catcode`\>=\active
+\def>{{\tt \gtr}}
+\catcode`\+=\active
+\def+{{\tt \char 43}}
+%\catcode 27=\active
+%\def^^[{$\diamondsuit$}
+
+% Set up an active definition for =, but don't enable it most of the time.
+{\catcode`\==\active
+\global\def={{\tt \char 61}}}
+
+\catcode`\@=0
+
+% \rawbackslashxx output one backslash character in current font
+\global\chardef\rawbackslashxx=`\\
+%{\catcode`\\=\other
+%@gdef@rawbackslashxx{\}}
+
+% \rawbackslash redefines \ as input to do \rawbackslashxx.
+{\catcode`\\=\active
+@gdef@rawbackslash{@let\=@rawbackslashxx }}
+
+% \normalbackslash outputs one backslash in fixed width font.
+\def\normalbackslash{{\tt\rawbackslashxx}}
+
+% Say @foo, not \foo, in error messages.
+\escapechar=`\@
+
+% \catcode 17=0 % Define control-q
+\catcode`\\=\active
+
+% Used sometimes to turn off (effectively) the active characters
+% even after parsing them.
+@def@turnoffactive{@let"=@normaldoublequote
+@let\=@realbackslash
+@let~=@normaltilde
+@let^=@normalcaret
+@let_=@normalunderscore
+@let|=@normalverticalbar
+@let<=@normalless
+@let>=@normalgreater
+@let+=@normalplus}
+
+@def@normalturnoffactive{@let"=@normaldoublequote
+@let\=@normalbackslash
+@let~=@normaltilde
+@let^=@normalcaret
+@let_=@normalunderscore
+@let|=@normalverticalbar
+@let<=@normalless
+@let>=@normalgreater
+@let+=@normalplus}
+
+% If a .fmt file is being used, we don't want the `\input texinfo' to show up.
+% That is what \eatinput is for; after that, the `\' should revert to printing
+% a backslash.
+%
+@gdef@eatinput input texinfo{@fixbackslash}
+@global@let\ = @eatinput
+
+% On the other hand, perhaps the file did not have a `\input texinfo'. Then
+% the first `\{ in the file would cause an error. This macro tries to fix
+% that, assuming it is called before the first `\' could plausibly occur.
+%
+@gdef@fixbackslash{@ifx\@eatinput @let\ = @normalbackslash @fi}
+
+%% These look ok in all fonts, so just make them not special. The @rm below
+%% makes sure that the current font starts out as the newly loaded cmr10
+@catcode`@$=@other @catcode`@%=@other @catcode`@&=@other @catcode`@#=@other
+
+@textfonts
+@rm
+
+@c Local variables:
+@c page-delimiter: "^\\\\message"
+@c End:
diff --git a/gnu/dist/diffutils/util.c b/gnu/dist/diffutils/util.c
new file mode 100644
index 00000000000..bbc3bff91a4
--- /dev/null
+++ b/gnu/dist/diffutils/util.c
@@ -0,0 +1,754 @@
+/* Support routines for GNU DIFF.
+ Copyright (C) 1988, 1989, 1992, 1993, 1994 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 "diff.h"
+
+#ifndef PR_PROGRAM
+#define PR_PROGRAM "/bin/pr"
+#endif
+
+/* Queue up one-line messages to be printed at the end,
+ when -l is specified. Each message is recorded with a `struct msg'. */
+
+struct msg
+{
+ struct msg *next;
+ char const *format;
+ char const *arg1;
+ char const *arg2;
+ char const *arg3;
+ char const *arg4;
+};
+
+/* Head of the chain of queues messages. */
+
+static struct msg *msg_chain;
+
+/* Tail of the chain of queues messages. */
+
+static struct msg **msg_chain_end = &msg_chain;
+
+/* Use when a system call returns non-zero status.
+ TEXT should normally be the file name. */
+
+void
+perror_with_name (text)
+ char const *text;
+{
+ int e = errno;
+ fprintf (stderr, "%s: ", program_name);
+ errno = e;
+ perror (text);
+}
+
+/* Use when a system call returns non-zero status and that is fatal. */
+
+void
+pfatal_with_name (text)
+ char const *text;
+{
+ int e = errno;
+ print_message_queue ();
+ fprintf (stderr, "%s: ", program_name);
+ errno = e;
+ perror (text);
+ exit (2);
+}
+
+/* Print an error message from the format-string FORMAT
+ with args ARG1 and ARG2. */
+
+void
+error (format, arg, arg1)
+ char const *format, *arg, *arg1;
+{
+ fprintf (stderr, "%s: ", program_name);
+ fprintf (stderr, format, arg, arg1);
+ fprintf (stderr, "\n");
+}
+
+/* Print an error message containing the string TEXT, then exit. */
+
+void
+fatal (m)
+ char const *m;
+{
+ print_message_queue ();
+ error ("%s", m, 0);
+ exit (2);
+}
+
+/* Like printf, except if -l in effect then save the message and print later.
+ This is used for things like "binary files differ" and "Only in ...". */
+
+void
+message (format, arg1, arg2)
+ char const *format, *arg1, *arg2;
+{
+ message5 (format, arg1, arg2, 0, 0);
+}
+
+void
+message5 (format, arg1, arg2, arg3, arg4)
+ char const *format, *arg1, *arg2, *arg3, *arg4;
+{
+ if (paginate_flag)
+ {
+ struct msg *new = (struct msg *) xmalloc (sizeof (struct msg));
+ new->format = format;
+ new->arg1 = concat (arg1, "", "");
+ new->arg2 = concat (arg2, "", "");
+ new->arg3 = arg3 ? concat (arg3, "", "") : 0;
+ new->arg4 = arg4 ? concat (arg4, "", "") : 0;
+ new->next = 0;
+ *msg_chain_end = new;
+ msg_chain_end = &new->next;
+ }
+ else
+ {
+ if (sdiff_help_sdiff)
+ putchar (' ');
+ printf (format, arg1, arg2, arg3, arg4);
+ }
+}
+
+/* Output all the messages that were saved up by calls to `message'. */
+
+void
+print_message_queue ()
+{
+ struct msg *m;
+
+ for (m = msg_chain; m; m = m->next)
+ printf (m->format, m->arg1, m->arg2, m->arg3, m->arg4);
+}
+
+/* Call before outputting the results of comparing files NAME0 and NAME1
+ to set up OUTFILE, the stdio stream for the output to go to.
+
+ Usually, OUTFILE is just stdout. But when -l was specified
+ we fork off a `pr' and make OUTFILE a pipe to it.
+ `pr' then outputs to our stdout. */
+
+static char const *current_name0;
+static char const *current_name1;
+static int current_depth;
+
+void
+setup_output (name0, name1, depth)
+ char const *name0, *name1;
+ int depth;
+{
+ current_name0 = name0;
+ current_name1 = name1;
+ current_depth = depth;
+ outfile = 0;
+}
+
+#if HAVE_FORK
+static pid_t pr_pid;
+#endif
+
+void
+begin_output ()
+{
+ char *name;
+
+ if (outfile != 0)
+ return;
+
+ /* Construct the header of this piece of diff. */
+ name = xmalloc (strlen (current_name0) + strlen (current_name1)
+ + strlen (switch_string) + 7);
+ /* Posix.2 section 4.17.6.1.1 specifies this format. But there is a
+ bug in the first printing (IEEE Std 1003.2-1992 p 251 l 3304):
+ it says that we must print only the last component of the pathnames.
+ This requirement is silly and does not match historical practice. */
+ sprintf (name, "diff%s %s %s", switch_string, current_name0, current_name1);
+
+ if (paginate_flag)
+ {
+ /* Make OUTFILE a pipe to a subsidiary `pr'. */
+
+#if HAVE_FORK
+ int pipes[2];
+
+ if (pipe (pipes) != 0)
+ pfatal_with_name ("pipe");
+
+ fflush (stdout);
+
+ pr_pid = vfork ();
+ if (pr_pid < 0)
+ pfatal_with_name ("vfork");
+
+ if (pr_pid == 0)
+ {
+ close (pipes[1]);
+ if (pipes[0] != STDIN_FILENO)
+ {
+ if (dup2 (pipes[0], STDIN_FILENO) < 0)
+ pfatal_with_name ("dup2");
+ close (pipes[0]);
+ }
+
+ execl (PR_PROGRAM, PR_PROGRAM, "-f", "-h", name, 0);
+ pfatal_with_name (PR_PROGRAM);
+ }
+ else
+ {
+ close (pipes[0]);
+ outfile = fdopen (pipes[1], "w");
+ if (!outfile)
+ pfatal_with_name ("fdopen");
+ }
+#else /* ! HAVE_FORK */
+ char *command = xmalloc (4 * strlen (name) + strlen (PR_PROGRAM) + 10);
+ char *p;
+ char const *a = name;
+ sprintf (command, "%s -f -h ", PR_PROGRAM);
+ p = command + strlen (command);
+ SYSTEM_QUOTE_ARG (p, a);
+ *p = 0;
+ outfile = popen (command, "w");
+ if (!outfile)
+ pfatal_with_name (command);
+ free (command);
+#endif /* ! HAVE_FORK */
+ }
+ else
+ {
+
+ /* If -l was not specified, output the diff straight to `stdout'. */
+
+ outfile = stdout;
+
+ /* If handling multiple files (because scanning a directory),
+ print which files the following output is about. */
+ if (current_depth > 0)
+ printf ("%s\n", name);
+ }
+
+ free (name);
+
+ /* A special header is needed at the beginning of context output. */
+ switch (output_style)
+ {
+ case OUTPUT_CONTEXT:
+ print_context_header (files, 0);
+ break;
+
+ case OUTPUT_UNIFIED:
+ print_context_header (files, 1);
+ break;
+
+ default:
+ break;
+ }
+}
+
+/* Call after the end of output of diffs for one file.
+ Close OUTFILE and get rid of the `pr' subfork. */
+
+void
+finish_output ()
+{
+ if (outfile != 0 && outfile != stdout)
+ {
+ int wstatus;
+ if (ferror (outfile))
+ fatal ("write error");
+#if ! HAVE_FORK
+ wstatus = pclose (outfile);
+#else /* HAVE_FORK */
+ if (fclose (outfile) != 0)
+ pfatal_with_name ("write error");
+ if (waitpid (pr_pid, &wstatus, 0) < 0)
+ pfatal_with_name ("waitpid");
+#endif /* HAVE_FORK */
+ if (wstatus != 0)
+ fatal ("subsidiary pr failed");
+ }
+
+ outfile = 0;
+}
+
+/* Compare two lines (typically one from each input file)
+ according to the command line options.
+ For efficiency, this is invoked only when the lines do not match exactly
+ but an option like -i might cause us to ignore the difference.
+ Return nonzero if the lines differ. */
+
+int
+line_cmp (s1, s2)
+ char const *s1, *s2;
+{
+ register unsigned char const *t1 = (unsigned char const *) s1;
+ register unsigned char const *t2 = (unsigned char const *) s2;
+
+ while (1)
+ {
+ register unsigned char c1 = *t1++;
+ register unsigned char c2 = *t2++;
+
+ /* Test for exact char equality first, since it's a common case. */
+ if (c1 != c2)
+ {
+ /* Ignore horizontal white space if -b or -w is specified. */
+
+ if (ignore_all_space_flag)
+ {
+ /* For -w, just skip past any white space. */
+ while (ISSPACE (c1) && c1 != '\n') c1 = *t1++;
+ while (ISSPACE (c2) && c2 != '\n') c2 = *t2++;
+ }
+ else if (ignore_space_change_flag)
+ {
+ /* For -b, advance past any sequence of white space in line 1
+ and consider it just one Space, or nothing at all
+ if it is at the end of the line. */
+ if (ISSPACE (c1))
+ {
+ while (c1 != '\n')
+ {
+ c1 = *t1++;
+ if (! ISSPACE (c1))
+ {
+ --t1;
+ c1 = ' ';
+ break;
+ }
+ }
+ }
+
+ /* Likewise for line 2. */
+ if (ISSPACE (c2))
+ {
+ while (c2 != '\n')
+ {
+ c2 = *t2++;
+ if (! ISSPACE (c2))
+ {
+ --t2;
+ c2 = ' ';
+ break;
+ }
+ }
+ }
+
+ if (c1 != c2)
+ {
+ /* If we went too far when doing the simple test
+ for equality, go back to the first non-white-space
+ character in both sides and try again. */
+ if (c2 == ' ' && c1 != '\n'
+ && (unsigned char const *) s1 + 1 < t1
+ && ISSPACE(t1[-2]))
+ {
+ --t1;
+ continue;
+ }
+ if (c1 == ' ' && c2 != '\n'
+ && (unsigned char const *) s2 + 1 < t2
+ && ISSPACE(t2[-2]))
+ {
+ --t2;
+ continue;
+ }
+ }
+ }
+
+ /* Lowercase all letters if -i is specified. */
+
+ if (ignore_case_flag)
+ {
+ if (ISUPPER (c1))
+ c1 = tolower (c1);
+ if (ISUPPER (c2))
+ c2 = tolower (c2);
+ }
+
+ if (c1 != c2)
+ break;
+ }
+ if (c1 == '\n')
+ return 0;
+ }
+
+ return (1);
+}
+
+/* Find the consecutive changes at the start of the script START.
+ Return the last link before the first gap. */
+
+struct change *
+find_change (start)
+ struct change *start;
+{
+ return start;
+}
+
+struct change *
+find_reverse_change (start)
+ struct change *start;
+{
+ return start;
+}
+
+/* Divide SCRIPT into pieces by calling HUNKFUN and
+ print each piece with PRINTFUN.
+ Both functions take one arg, an edit script.
+
+ HUNKFUN is called with the tail of the script
+ and returns the last link that belongs together with the start
+ of the tail.
+
+ PRINTFUN takes a subscript which belongs together (with a null
+ link at the end) and prints it. */
+
+void
+print_script (script, hunkfun, printfun)
+ struct change *script;
+ struct change * (*hunkfun) PARAMS((struct change *));
+ void (*printfun) PARAMS((struct change *));
+{
+ struct change *next = script;
+
+ while (next)
+ {
+ struct change *this, *end;
+
+ /* Find a set of changes that belong together. */
+ this = next;
+ end = (*hunkfun) (next);
+
+ /* Disconnect them from the rest of the changes,
+ making them a hunk, and remember the rest for next iteration. */
+ next = end->link;
+ end->link = 0;
+#ifdef DEBUG
+ debug_script (this);
+#endif
+
+ /* Print this hunk. */
+ (*printfun) (this);
+
+ /* Reconnect the script so it will all be freed properly. */
+ end->link = next;
+ }
+}
+
+/* Print the text of a single line LINE,
+ flagging it with the characters in LINE_FLAG (which say whether
+ the line is inserted, deleted, changed, etc.). */
+
+void
+print_1_line (line_flag, line)
+ char const *line_flag;
+ char const * const *line;
+{
+ char const *text = line[0], *limit = line[1]; /* Help the compiler. */
+ FILE *out = outfile; /* Help the compiler some more. */
+ char const *flag_format = 0;
+
+ /* If -T was specified, use a Tab between the line-flag and the text.
+ Otherwise use a Space (as Unix diff does).
+ Print neither space nor tab if line-flags are empty. */
+
+ if (line_flag && *line_flag)
+ {
+ flag_format = tab_align_flag ? "%s\t" : "%s ";
+ fprintf (out, flag_format, line_flag);
+ }
+
+ output_1_line (text, limit, flag_format, line_flag);
+
+ if ((!line_flag || line_flag[0]) && limit[-1] != '\n')
+ fprintf (out, "\n\\ No newline at end of file\n");
+}
+
+/* Output a line from TEXT up to LIMIT. Without -t, output verbatim.
+ With -t, expand white space characters to spaces, and if FLAG_FORMAT
+ is nonzero, output it with argument LINE_FLAG after every
+ internal carriage return, so that tab stops continue to line up. */
+
+void
+output_1_line (text, limit, flag_format, line_flag)
+ char const *text, *limit, *flag_format, *line_flag;
+{
+ if (!tab_expand_flag)
+ fwrite (text, sizeof (char), limit - text, outfile);
+ else
+ {
+ register FILE *out = outfile;
+ register unsigned char c;
+ register char const *t = text;
+ register unsigned column = 0;
+
+ while (t < limit)
+ switch ((c = *t++))
+ {
+ case '\t':
+ {
+ unsigned spaces = TAB_WIDTH - column % TAB_WIDTH;
+ column += spaces;
+ do
+ putc (' ', out);
+ while (--spaces);
+ }
+ break;
+
+ case '\r':
+ putc (c, out);
+ if (flag_format && t < limit && *t != '\n')
+ fprintf (out, flag_format, line_flag);
+ column = 0;
+ break;
+
+ case '\b':
+ if (column == 0)
+ continue;
+ column--;
+ putc (c, out);
+ break;
+
+ default:
+ if (ISPRINT (c))
+ column++;
+ putc (c, out);
+ break;
+ }
+ }
+}
+
+int
+change_letter (inserts, deletes)
+ int inserts, deletes;
+{
+ if (!inserts)
+ return 'd';
+ else if (!deletes)
+ return 'a';
+ else
+ return 'c';
+}
+
+/* Translate an internal line number (an index into diff's table of lines)
+ into an actual line number in the input file.
+ The internal line number is LNUM. FILE points to the data on the file.
+
+ Internal line numbers count from 0 starting after the prefix.
+ Actual line numbers count from 1 within the entire file. */
+
+int
+translate_line_number (file, lnum)
+ struct file_data const *file;
+ int lnum;
+{
+ return lnum + file->prefix_lines + 1;
+}
+
+void
+translate_range (file, a, b, aptr, bptr)
+ struct file_data const *file;
+ int a, b;
+ int *aptr, *bptr;
+{
+ *aptr = translate_line_number (file, a - 1) + 1;
+ *bptr = translate_line_number (file, b + 1) - 1;
+}
+
+/* Print a pair of line numbers with SEPCHAR, translated for file FILE.
+ If the two numbers are identical, print just one number.
+
+ Args A and B are internal line numbers.
+ We print the translated (real) line numbers. */
+
+void
+print_number_range (sepchar, file, a, b)
+ int sepchar;
+ struct file_data *file;
+ int a, b;
+{
+ int trans_a, trans_b;
+ translate_range (file, a, b, &trans_a, &trans_b);
+
+ /* Note: we can have B < A in the case of a range of no lines.
+ In this case, we should print the line number before the range,
+ which is B. */
+ if (trans_b > trans_a)
+ fprintf (outfile, "%d%c%d", trans_a, sepchar, trans_b);
+ else
+ fprintf (outfile, "%d", trans_b);
+}
+
+/* Look at a hunk of edit script and report the range of lines in each file
+ that it applies to. HUNK is the start of the hunk, which is a chain
+ of `struct change'. The first and last line numbers of file 0 are stored in
+ *FIRST0 and *LAST0, and likewise for file 1 in *FIRST1 and *LAST1.
+ Note that these are internal line numbers that count from 0.
+
+ If no lines from file 0 are deleted, then FIRST0 is LAST0+1.
+
+ Also set *DELETES nonzero if any lines of file 0 are deleted
+ and set *INSERTS nonzero if any lines of file 1 are inserted.
+ If only ignorable lines are inserted or deleted, both are
+ set to 0. */
+
+void
+analyze_hunk (hunk, first0, last0, first1, last1, deletes, inserts)
+ struct change *hunk;
+ int *first0, *last0, *first1, *last1;
+ int *deletes, *inserts;
+{
+ int l0, l1, show_from, show_to;
+ int i;
+ int trivial = ignore_blank_lines_flag || ignore_regexp_list;
+ struct change *next;
+
+ show_from = show_to = 0;
+
+ *first0 = hunk->line0;
+ *first1 = hunk->line1;
+
+ next = hunk;
+ do
+ {
+ l0 = next->line0 + next->deleted - 1;
+ l1 = next->line1 + next->inserted - 1;
+ show_from += next->deleted;
+ show_to += next->inserted;
+
+ for (i = next->line0; i <= l0 && trivial; i++)
+ if (!ignore_blank_lines_flag || files[0].linbuf[i][0] != '\n')
+ {
+ struct regexp_list *r;
+ char const *line = files[0].linbuf[i];
+ int len = files[0].linbuf[i + 1] - line;
+
+ for (r = ignore_regexp_list; r; r = r->next)
+ if (0 <= re_search (&r->buf, line, len, 0, len, 0))
+ break; /* Found a match. Ignore this line. */
+ /* If we got all the way through the regexp list without
+ finding a match, then it's nontrivial. */
+ if (!r)
+ trivial = 0;
+ }
+
+ for (i = next->line1; i <= l1 && trivial; i++)
+ if (!ignore_blank_lines_flag || files[1].linbuf[i][0] != '\n')
+ {
+ struct regexp_list *r;
+ char const *line = files[1].linbuf[i];
+ int len = files[1].linbuf[i + 1] - line;
+
+ for (r = ignore_regexp_list; r; r = r->next)
+ if (0 <= re_search (&r->buf, line, len, 0, len, 0))
+ break; /* Found a match. Ignore this line. */
+ /* If we got all the way through the regexp list without
+ finding a match, then it's nontrivial. */
+ if (!r)
+ trivial = 0;
+ }
+ }
+ while ((next = next->link) != 0);
+
+ *last0 = l0;
+ *last1 = l1;
+
+ /* If all inserted or deleted lines are ignorable,
+ tell the caller to ignore this hunk. */
+
+ if (trivial)
+ show_from = show_to = 0;
+
+ *deletes = show_from;
+ *inserts = show_to;
+}
+
+/* malloc a block of memory, with fatal error message if we can't do it. */
+
+VOID *
+xmalloc (size)
+ size_t size;
+{
+ register VOID *value;
+
+ if (size == 0)
+ size = 1;
+
+ value = (VOID *) malloc (size);
+
+ if (!value)
+ fatal ("memory exhausted");
+ return value;
+}
+
+/* realloc a block of memory, with fatal error message if we can't do it. */
+
+VOID *
+xrealloc (old, size)
+ VOID *old;
+ size_t size;
+{
+ register VOID *value;
+
+ if (size == 0)
+ size = 1;
+
+ value = (VOID *) realloc (old, size);
+
+ if (!value)
+ fatal ("memory exhausted");
+ return value;
+}
+
+/* Concatenate three strings, returning a newly malloc'd string. */
+
+char *
+concat (s1, s2, s3)
+ char const *s1, *s2, *s3;
+{
+ size_t len = strlen (s1) + strlen (s2) + strlen (s3);
+ char *new = xmalloc (len + 1);
+ sprintf (new, "%s%s%s", s1, s2, s3);
+ return new;
+}
+
+/* Yield the newly malloc'd pathname
+ of the file in DIR whose filename is FILE. */
+
+char *
+dir_file_pathname (dir, file)
+ char const *dir, *file;
+{
+ char const *p = filename_lastdirchar (dir);
+ return concat (dir, "/" + (p && !p[1]), file);
+}
+
+void
+debug_script (sp)
+ struct change *sp;
+{
+ fflush (stdout);
+ for (; sp; sp = sp->link)
+ fprintf (stderr, "%3d %3d delete %d insert %d\n",
+ sp->line0, sp->line1, sp->deleted, sp->inserted);
+ fflush (stderr);
+}
diff --git a/gnu/dist/diffutils/version.c b/gnu/dist/diffutils/version.c
new file mode 100644
index 00000000000..02993976351
--- /dev/null
+++ b/gnu/dist/diffutils/version.c
@@ -0,0 +1,5 @@
+/* Version number of GNU diff. */
+
+#include <config.h>
+
+char const version_string[] = "2.7";
diff --git a/gnu/dist/diffutils/waitpid.c b/gnu/dist/diffutils/waitpid.c
new file mode 100644
index 00000000000..98f1b9e34a7
--- /dev/null
+++ b/gnu/dist/diffutils/waitpid.c
@@ -0,0 +1,68 @@
+/* Emulate waitpid on systems that just have wait.
+ Copyright (C) 1994 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 "system.h"
+
+#define WAITPID_CHILDREN 8
+static pid_t waited_pid[WAITPID_CHILDREN];
+static int waited_status[WAITPID_CHILDREN];
+
+pid_t
+waitpid (pid, stat_loc, options)
+ pid_t pid;
+ int *stat_loc;
+ int options;
+{
+ int i;
+ pid_t p;
+
+ if (!options && (0 < pid || pid == -1))
+ {
+ /* If we have already waited for this child, return it immediately. */
+ for (i = 0; i < WAITPID_CHILDREN; i++)
+ {
+ p = waited_pid[i];
+ if (p && (p == pid || pid == -1))
+ {
+ waited_pid[i] = 0;
+ goto success;
+ }
+ }
+
+ /* The child has not returned yet; wait for it, accumulating status. */
+ for (i = 0; i < WAITPID_CHILDREN; i++)
+ if (! waited_pid[i])
+ {
+ p = wait (&waited_status[i]);
+ if (p < 0)
+ return p;
+ if (p == pid || pid == -1)
+ goto success;
+ waited_pid[i] = p;
+ }
+ }
+
+ /* We cannot emulate this wait call, e.g. because of too many children. */
+ abort ();
+
+success:
+ if (stat_loc)
+ *stat_loc = waited_status[i];
+ return p;
+}
diff --git a/gnu/dist/diffutils/xmalloc.c b/gnu/dist/diffutils/xmalloc.c
new file mode 100644
index 00000000000..dc44ba4cf7d
--- /dev/null
+++ b/gnu/dist/diffutils/xmalloc.c
@@ -0,0 +1,81 @@
+/* xmalloc.c -- malloc with out of memory checking
+ Copyright (C) 1990, 1991, 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if __STDC__
+#define VOID void
+#else
+#define VOID char
+#endif
+
+#include <sys/types.h>
+
+#if STDC_HEADERS
+#include <stdlib.h>
+#else
+VOID *malloc ();
+VOID *realloc ();
+void free ();
+#endif
+
+#if __STDC__ && defined (HAVE_VPRINTF)
+void error (int, int, char const *, ...);
+#else
+void error ();
+#endif
+
+/* Allocate N bytes of memory dynamically, with error checking. */
+
+VOID *
+xmalloc (n)
+ size_t n;
+{
+ VOID *p;
+
+ p = malloc (n);
+ if (p == 0)
+ /* Must exit with 2 for `cmp'. */
+ error (2, 0, "memory exhausted");
+ return p;
+}
+
+/* Change the size of an allocated block of memory P to N bytes,
+ with error checking.
+ If P is NULL, run xmalloc.
+ If N is 0, run free and return NULL. */
+
+VOID *
+xrealloc (p, n)
+ VOID *p;
+ size_t n;
+{
+ if (p == 0)
+ return xmalloc (n);
+ if (n == 0)
+ {
+ free (p);
+ return 0;
+ }
+ p = realloc (p, n);
+ if (p == 0)
+ /* Must exit with 2 for `cmp'. */
+ error (2, 0, "memory exhausted");
+ return p;
+}