Use dist layout for diffutils, for easier upgrades and texinfo doc.
This commit is contained in:
parent
d84dcf29f1
commit
f598822c56
339
gnu/dist/diffutils/COPYING
vendored
Normal file
339
gnu/dist/diffutils/COPYING
vendored
Normal file
@ -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.
|
1766
gnu/dist/diffutils/ChangeLog
vendored
Normal file
1766
gnu/dist/diffutils/ChangeLog
vendored
Normal file
File diff suppressed because it is too large
Load Diff
179
gnu/dist/diffutils/INSTALL
vendored
Normal file
179
gnu/dist/diffutils/INSTALL
vendored
Normal file
@ -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.
|
||||
|
198
gnu/dist/diffutils/Makefile.in
vendored
Normal file
198
gnu/dist/diffutils/Makefile.in
vendored
Normal file
@ -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:
|
126
gnu/dist/diffutils/NEWS
vendored
Normal file
126
gnu/dist/diffutils/NEWS
vendored
Normal file
@ -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.
|
9
gnu/dist/diffutils/README
vendored
Normal file
9
gnu/dist/diffutils/README
vendored
Normal file
@ -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
|
492
gnu/dist/diffutils/alloca.c
vendored
Normal file
492
gnu/dist/diffutils/alloca.c
vendored
Normal file
@ -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 */
|
1084
gnu/dist/diffutils/analyze.c
vendored
Normal file
1084
gnu/dist/diffutils/analyze.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
568
gnu/dist/diffutils/cmp.c
vendored
Normal file
568
gnu/dist/diffutils/cmp.c
vendored
Normal file
@ -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];
|
||||
}
|
40
gnu/dist/diffutils/cmpbuf.c
vendored
Normal file
40
gnu/dist/diffutils/cmpbuf.c
vendored
Normal file
@ -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;
|
||||
}
|
20
gnu/dist/diffutils/cmpbuf.h
vendored
Normal file
20
gnu/dist/diffutils/cmpbuf.h
vendored
Normal file
@ -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));
|
117
gnu/dist/diffutils/config.hin
vendored
Normal file
117
gnu/dist/diffutils/config.hin
vendored
Normal file
@ -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
|
2149
gnu/dist/diffutils/configure
vendored
Executable file
2149
gnu/dist/diffutils/configure
vendored
Executable file
File diff suppressed because it is too large
Load Diff
26
gnu/dist/diffutils/configure.in
vendored
Normal file
26
gnu/dist/diffutils/configure.in
vendored
Normal file
@ -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])
|
468
gnu/dist/diffutils/context.c
vendored
Normal file
468
gnu/dist/diffutils/context.c
vendored
Normal file
@ -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;
|
||||
}
|
71
gnu/dist/diffutils/diagmeet.note
vendored
Normal file
71
gnu/dist/diffutils/diagmeet.note
vendored
Normal file
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
1106
gnu/dist/diffutils/diff.c
vendored
Normal file
1106
gnu/dist/diffutils/diff.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
340
gnu/dist/diffutils/diff.h
vendored
Normal file
340
gnu/dist/diffutils/diff.h
vendored
Normal file
@ -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[];
|
128
gnu/dist/diffutils/diff.info
vendored
Normal file
128
gnu/dist/diffutils/diff.info
vendored
Normal file
@ -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
|
1211
gnu/dist/diffutils/diff.info-1
vendored
Normal file
1211
gnu/dist/diffutils/diff.info-1
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1312
gnu/dist/diffutils/diff.info-2
vendored
Normal file
1312
gnu/dist/diffutils/diff.info-2
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1327
gnu/dist/diffutils/diff.info-3
vendored
Normal file
1327
gnu/dist/diffutils/diff.info-3
vendored
Normal file
File diff suppressed because it is too large
Load Diff
152
gnu/dist/diffutils/diff.info-4
vendored
Normal file
152
gnu/dist/diffutils/diff.info-4
vendored
Normal file
@ -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.
|
||||
|
||||
|
3916
gnu/dist/diffutils/diff.texi
vendored
Normal file
3916
gnu/dist/diffutils/diff.texi
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1778
gnu/dist/diffutils/diff3.c
vendored
Normal file
1778
gnu/dist/diffutils/diff3.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
216
gnu/dist/diffutils/dir.c
vendored
Normal file
216
gnu/dist/diffutils/dir.c
vendored
Normal file
@ -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;
|
||||
}
|
200
gnu/dist/diffutils/ed.c
vendored
Normal file
200
gnu/dist/diffutils/ed.c
vendored
Normal file
@ -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]);
|
||||
}
|
||||
}
|
111
gnu/dist/diffutils/error.c
vendored
Normal file
111
gnu/dist/diffutils/error.c
vendored
Normal file
@ -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);
|
||||
}
|
209
gnu/dist/diffutils/fnmatch.c
vendored
Normal file
209
gnu/dist/diffutils/fnmatch.c
vendored
Normal file
@ -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__. */
|
69
gnu/dist/diffutils/fnmatch.h
vendored
Normal file
69
gnu/dist/diffutils/fnmatch.h
vendored
Normal file
@ -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 */
|
748
gnu/dist/diffutils/getopt.c
vendored
Normal file
748
gnu/dist/diffutils/getopt.c
vendored
Normal file
@ -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 */
|
129
gnu/dist/diffutils/getopt.h
vendored
Normal file
129
gnu/dist/diffutils/getopt.h
vendored
Normal file
@ -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 */
|
180
gnu/dist/diffutils/getopt1.c
vendored
Normal file
180
gnu/dist/diffutils/getopt1.c
vendored
Normal file
@ -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 */
|
428
gnu/dist/diffutils/ifdef.c
vendored
Normal file
428
gnu/dist/diffutils/ifdef.c
vendored
Normal file
@ -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;
|
||||
}
|
||||
}
|
238
gnu/dist/diffutils/install-sh
vendored
Normal file
238
gnu/dist/diffutils/install-sh
vendored
Normal file
@ -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
|
714
gnu/dist/diffutils/io.c
vendored
Normal file
714
gnu/dist/diffutils/io.c
vendored
Normal file
@ -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;
|
||||
}
|
19
gnu/dist/diffutils/memchr.c
vendored
Normal file
19
gnu/dist/diffutils/memchr.c
vendored
Normal file
@ -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;
|
||||
}
|
32
gnu/dist/diffutils/mkinstalldirs
vendored
Normal file
32
gnu/dist/diffutils/mkinstalldirs
vendored
Normal file
@ -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
|
71
gnu/dist/diffutils/normal.c
vendored
Normal file
71
gnu/dist/diffutils/normal.c
vendored
Normal file
@ -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]);
|
||||
}
|
5248
gnu/dist/diffutils/regex.c
vendored
Normal file
5248
gnu/dist/diffutils/regex.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
490
gnu/dist/diffutils/regex.h
vendored
Normal file
490
gnu/dist/diffutils/regex.h
vendored
Normal file
@ -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:
|
||||
*/
|
1180
gnu/dist/diffutils/sdiff.c
vendored
Normal file
1180
gnu/dist/diffutils/sdiff.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
284
gnu/dist/diffutils/side.c
vendored
Normal file
284
gnu/dist/diffutils/side.c
vendored
Normal file
@ -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;
|
||||
}
|
||||
}
|
1
gnu/dist/diffutils/stamp-h.in
vendored
Normal file
1
gnu/dist/diffutils/stamp-h.in
vendored
Normal file
@ -0,0 +1 @@
|
||||
Fri Sep 30 22:22:28 PDT 1994
|
267
gnu/dist/diffutils/system.h
vendored
Normal file
267
gnu/dist/diffutils/system.h
vendored
Normal file
@ -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
|
4344
gnu/dist/diffutils/texinfo.tex
vendored
Normal file
4344
gnu/dist/diffutils/texinfo.tex
vendored
Normal file
File diff suppressed because it is too large
Load Diff
754
gnu/dist/diffutils/util.c
vendored
Normal file
754
gnu/dist/diffutils/util.c
vendored
Normal file
@ -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);
|
||||
}
|
5
gnu/dist/diffutils/version.c
vendored
Normal file
5
gnu/dist/diffutils/version.c
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
/* Version number of GNU diff. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
char const version_string[] = "2.7";
|
68
gnu/dist/diffutils/waitpid.c
vendored
Normal file
68
gnu/dist/diffutils/waitpid.c
vendored
Normal file
@ -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;
|
||||
}
|
81
gnu/dist/diffutils/xmalloc.c
vendored
Normal file
81
gnu/dist/diffutils/xmalloc.c
vendored
Normal file
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user