mirror of
https://git.FreeBSD.org/src.git
synced 2026-06-02 11:24:32 +00:00
Retire GNU diff3
We added the option to build BSD diff3 in commit2201f7c49f("Build BSD diff3 if GNU diff3 is disabled.") and made it the default in4d5c434ed1("diff3: use bsd diff3 by default") after resolving deficiencies relative to GNU diff3. Thus, we can now remove the GNU diff3 build infrastructure and source. Reviewed by: bapt, ziaee Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D46878
This commit is contained in:
@@ -1,768 +0,0 @@
|
|||||||
Notes on the Free Translation Project
|
|
||||||
*************************************
|
|
||||||
|
|
||||||
Free software is going international! The Free Translation Project is
|
|
||||||
a way to get maintainers of free software, translators, and users all
|
|
||||||
together, so that will gradually become able to speak many languages.
|
|
||||||
A few packages already provide translations for their messages.
|
|
||||||
|
|
||||||
If you found this `ABOUT-NLS' file inside a distribution, you may
|
|
||||||
assume that the distributed package does use GNU `gettext' internally,
|
|
||||||
itself available at your nearest GNU archive site. But you do _not_
|
|
||||||
need to install GNU `gettext' prior to configuring, installing or using
|
|
||||||
this package with messages translated.
|
|
||||||
|
|
||||||
Installers will find here some useful hints. These notes also
|
|
||||||
explain how users should proceed for getting the programs to use the
|
|
||||||
available translations. They tell how people wanting to contribute and
|
|
||||||
work at translations should contact the appropriate team.
|
|
||||||
|
|
||||||
When reporting bugs in the `intl/' directory or bugs which may be
|
|
||||||
related to internationalization, you should tell about the version of
|
|
||||||
`gettext' which is used. The information can be found in the
|
|
||||||
`intl/VERSION' file, in internationalized packages.
|
|
||||||
|
|
||||||
Quick configuration advice
|
|
||||||
==========================
|
|
||||||
|
|
||||||
If you want to exploit the full power of internationalization, you
|
|
||||||
should configure it using
|
|
||||||
|
|
||||||
./configure --with-included-gettext
|
|
||||||
|
|
||||||
to force usage of internationalizing routines provided within this
|
|
||||||
package, despite the existence of internationalizing capabilities in the
|
|
||||||
operating system where this package is being installed. So far, only
|
|
||||||
the `gettext' implementation in the GNU C library version 2 provides as
|
|
||||||
many features (such as locale alias, message inheritance, automatic
|
|
||||||
charset conversion or plural form handling) as the implementation here.
|
|
||||||
It is also not possible to offer this additional functionality on top
|
|
||||||
of a `catgets' implementation. Future versions of GNU `gettext' will
|
|
||||||
very likely convey even more functionality. So it might be a good idea
|
|
||||||
to change to GNU `gettext' as soon as possible.
|
|
||||||
|
|
||||||
So you need _not_ provide this option if you are using GNU libc 2 or
|
|
||||||
you have installed a recent copy of the GNU gettext package with the
|
|
||||||
included `libintl'.
|
|
||||||
|
|
||||||
INSTALL Matters
|
|
||||||
===============
|
|
||||||
|
|
||||||
Some packages are "localizable" when properly installed; the programs
|
|
||||||
they contain can be made to speak your own native language. Most such
|
|
||||||
packages use GNU `gettext'. Other packages have their own ways to
|
|
||||||
internationalization, predating GNU `gettext'.
|
|
||||||
|
|
||||||
By default, this package will be installed to allow translation of
|
|
||||||
messages. It will automatically detect whether the system already
|
|
||||||
provides the GNU `gettext' functions. If not, the GNU `gettext' own
|
|
||||||
library will be used. This library is wholly contained within this
|
|
||||||
package, usually in the `intl/' subdirectory, so prior installation of
|
|
||||||
the GNU `gettext' package is _not_ required. Installers may use
|
|
||||||
special options at configuration time for changing the default
|
|
||||||
behaviour. The commands:
|
|
||||||
|
|
||||||
./configure --with-included-gettext
|
|
||||||
./configure --disable-nls
|
|
||||||
|
|
||||||
will respectively bypass any pre-existing `gettext' to use the
|
|
||||||
internationalizing routines provided within this package, or else,
|
|
||||||
_totally_ disable translation of messages.
|
|
||||||
|
|
||||||
When you already have GNU `gettext' installed on your system and run
|
|
||||||
configure without an option for your new package, `configure' will
|
|
||||||
probably detect the previously built and installed `libintl.a' file and
|
|
||||||
will decide to use this. This might be not what is desirable. You
|
|
||||||
should use the more recent version of the GNU `gettext' library. I.e.
|
|
||||||
if the file `intl/VERSION' shows that the library which comes with this
|
|
||||||
package is more recent, you should use
|
|
||||||
|
|
||||||
./configure --with-included-gettext
|
|
||||||
|
|
||||||
to prevent auto-detection.
|
|
||||||
|
|
||||||
The configuration process will not test for the `catgets' function
|
|
||||||
and therefore it will not be used. The reason is that even an
|
|
||||||
emulation of `gettext' on top of `catgets' could not provide all the
|
|
||||||
extensions of the GNU `gettext' library.
|
|
||||||
|
|
||||||
Internationalized packages have usually many `po/LL.po' files, where
|
|
||||||
LL gives an ISO 639 two-letter code identifying the language. Unless
|
|
||||||
translations have been forbidden at `configure' time by using the
|
|
||||||
`--disable-nls' switch, all available translations are installed
|
|
||||||
together with the package. However, the environment variable `LINGUAS'
|
|
||||||
may be set, prior to configuration, to limit the installed set.
|
|
||||||
`LINGUAS' should then contain a space separated list of two-letter
|
|
||||||
codes, stating which languages are allowed.
|
|
||||||
|
|
||||||
Using This Package
|
|
||||||
==================
|
|
||||||
|
|
||||||
As a user, if your language has been installed for this package, you
|
|
||||||
only have to set the `LANG' environment variable to the appropriate
|
|
||||||
`LL_CC' combination. Here `LL' is an ISO 639 two-letter language code,
|
|
||||||
and `CC' is an ISO 3166 two-letter country code. For example, let's
|
|
||||||
suppose that you speak German and live in Germany. At the shell
|
|
||||||
prompt, merely execute `setenv LANG de_DE' (in `csh'),
|
|
||||||
`export LANG; LANG=de_DE' (in `sh') or `export LANG=de_DE' (in `bash').
|
|
||||||
This can be done from your `.login' or `.profile' file, once and for
|
|
||||||
all.
|
|
||||||
|
|
||||||
You might think that the country code specification is redundant.
|
|
||||||
But in fact, some languages have dialects in different countries. For
|
|
||||||
example, `de_AT' is used for Austria, and `pt_BR' for Brazil. The
|
|
||||||
country code serves to distinguish the dialects.
|
|
||||||
|
|
||||||
The locale naming convention of `LL_CC', with `LL' denoting the
|
|
||||||
language and `CC' denoting the country, is the one use on systems based
|
|
||||||
on GNU libc. On other systems, some variations of this scheme are
|
|
||||||
used, such as `LL' or `LL_CC.ENCODING'. You can get the list of
|
|
||||||
locales supported by your system for your country by running the command
|
|
||||||
`locale -a | grep '^LL''.
|
|
||||||
|
|
||||||
Not all programs have translations for all languages. By default, an
|
|
||||||
English message is shown in place of a nonexistent translation. If you
|
|
||||||
understand other languages, you can set up a priority list of languages.
|
|
||||||
This is done through a different environment variable, called
|
|
||||||
`LANGUAGE'. GNU `gettext' gives preference to `LANGUAGE' over `LANG'
|
|
||||||
for the purpose of message handling, but you still need to have `LANG'
|
|
||||||
set to the primary language; this is required by other parts of the
|
|
||||||
system libraries. For example, some Swedish users who would rather
|
|
||||||
read translations in German than English for when Swedish is not
|
|
||||||
available, set `LANGUAGE' to `sv:de' while leaving `LANG' to `sv_SE'.
|
|
||||||
|
|
||||||
Special advice for Norwegian users: The language code for Norwegian
|
|
||||||
bokma*l changed from `no' to `nb' recently (in 2003). During the
|
|
||||||
transition period, while some message catalogs for this language are
|
|
||||||
installed under `nb' and some older ones under `no', it's recommended
|
|
||||||
for Norwegian users to set `LANGUAGE' to `nb:no' so that both newer and
|
|
||||||
older translations are used.
|
|
||||||
|
|
||||||
In the `LANGUAGE' environment variable, but not in the `LANG'
|
|
||||||
environment variable, `LL_CC' combinations can be abbreviated as `LL'
|
|
||||||
to denote the language's main dialect. For example, `de' is equivalent
|
|
||||||
to `de_DE' (German as spoken in Germany), and `pt' to `pt_PT'
|
|
||||||
(Portuguese as spoken in Portugal) in this context.
|
|
||||||
|
|
||||||
Translating Teams
|
|
||||||
=================
|
|
||||||
|
|
||||||
For the Free Translation Project to be a success, we need interested
|
|
||||||
people who like their own language and write it well, and who are also
|
|
||||||
able to synergize with other translators speaking the same language.
|
|
||||||
Each translation team has its own mailing list. The up-to-date list of
|
|
||||||
teams can be found at the Free Translation Project's homepage,
|
|
||||||
`http://www.iro.umontreal.ca/contrib/po/HTML/', in the "National teams"
|
|
||||||
area.
|
|
||||||
|
|
||||||
If you'd like to volunteer to _work_ at translating messages, you
|
|
||||||
should become a member of the translating team for your own language.
|
|
||||||
The subscribing address is _not_ the same as the list itself, it has
|
|
||||||
`-request' appended. For example, speakers of Swedish can send a
|
|
||||||
message to `sv-request@li.org', having this message body:
|
|
||||||
|
|
||||||
subscribe
|
|
||||||
|
|
||||||
Keep in mind that team members are expected to participate
|
|
||||||
_actively_ in translations, or at solving translational difficulties,
|
|
||||||
rather than merely lurking around. If your team does not exist yet and
|
|
||||||
you want to start one, or if you are unsure about what to do or how to
|
|
||||||
get started, please write to `translation@iro.umontreal.ca' to reach the
|
|
||||||
coordinator for all translator teams.
|
|
||||||
|
|
||||||
The English team is special. It works at improving and uniformizing
|
|
||||||
the terminology in use. Proven linguistic skill are praised more than
|
|
||||||
programming skill, here.
|
|
||||||
|
|
||||||
Available Packages
|
|
||||||
==================
|
|
||||||
|
|
||||||
Languages are not equally supported in all packages. The following
|
|
||||||
matrix shows the current state of internationalization, as of January
|
|
||||||
2004. The matrix shows, in regard of each package, for which languages
|
|
||||||
PO files have been submitted to translation coordination, with a
|
|
||||||
translation percentage of at least 50%.
|
|
||||||
|
|
||||||
Ready PO files af am ar az be bg bs ca cs da de el en en_GB eo es
|
|
||||||
+----------------------------------------------------+
|
|
||||||
a2ps | [] [] [] [] |
|
|
||||||
aegis | () |
|
|
||||||
ant-phone | () |
|
|
||||||
anubis | |
|
|
||||||
ap-utils | |
|
|
||||||
aspell | [] |
|
|
||||||
bash | [] [] [] [] |
|
|
||||||
batchelor | |
|
|
||||||
bfd | [] [] |
|
|
||||||
binutils | [] [] |
|
|
||||||
bison | [] [] [] |
|
|
||||||
bluez-pin | [] [] [] |
|
|
||||||
clisp | |
|
|
||||||
clisp | [] [] [] |
|
|
||||||
console-tools | [] [] |
|
|
||||||
coreutils | [] [] [] [] |
|
|
||||||
cpio | [] [] [] |
|
|
||||||
darkstat | [] () [] |
|
|
||||||
diffutils | [] [] [] [] [] [] [] |
|
|
||||||
e2fsprogs | [] [] [] |
|
|
||||||
enscript | [] [] [] [] |
|
|
||||||
error | [] [] [] [] [] |
|
|
||||||
fetchmail | [] () [] [] [] [] |
|
|
||||||
fileutils | [] [] [] |
|
|
||||||
findutils | [] [] [] [] [] [] [] |
|
|
||||||
flex | [] [] [] [] |
|
|
||||||
fslint | |
|
|
||||||
gas | [] |
|
|
||||||
gawk | [] [] [] [] |
|
|
||||||
gbiff | [] |
|
|
||||||
gcal | [] |
|
|
||||||
gcc | [] [] |
|
|
||||||
gettext | [] [] [] [] [] |
|
|
||||||
gettext-examples | [] [] [] [] |
|
|
||||||
gettext-runtime | [] [] [] [] [] |
|
|
||||||
gettext-tools | [] [] [] |
|
|
||||||
gimp-print | [] [] [] [] [] |
|
|
||||||
gliv | |
|
|
||||||
glunarclock | [] [] |
|
|
||||||
gnubiff | [] |
|
|
||||||
gnucash | [] () [] [] |
|
|
||||||
gnucash-glossary | [] () [] |
|
|
||||||
gnupg | [] () [] [] [] [] |
|
|
||||||
gpe-aerial | [] |
|
|
||||||
gpe-beam | [] [] |
|
|
||||||
gpe-calendar | [] [] |
|
|
||||||
gpe-clock | [] [] |
|
|
||||||
gpe-conf | [] [] |
|
|
||||||
gpe-contacts | [] [] |
|
|
||||||
gpe-edit | [] |
|
|
||||||
gpe-go | [] |
|
|
||||||
gpe-login | [] [] |
|
|
||||||
gpe-ownerinfo | [] [] |
|
|
||||||
gpe-sketchbook | [] [] |
|
|
||||||
gpe-su | [] [] |
|
|
||||||
gpe-taskmanager | [] [] |
|
|
||||||
gpe-timesheet | [] |
|
|
||||||
gpe-today | [] [] |
|
|
||||||
gpe-todo | [] [] |
|
|
||||||
gphoto2 | [] [] [] [] |
|
|
||||||
gprof | [] [] [] |
|
|
||||||
gpsdrive | () () () |
|
|
||||||
gramadoir | [] |
|
|
||||||
grep | [] [] [] [] [] [] |
|
|
||||||
gretl | [] |
|
|
||||||
gtick | [] () |
|
|
||||||
hello | [] [] [] [] [] [] |
|
|
||||||
id-utils | [] [] |
|
|
||||||
indent | [] [] [] [] |
|
|
||||||
iso_3166 | [] [] [] [] [] [] [] [] [] [] |
|
|
||||||
iso_3166_1 | [] [] [] [] [] [] |
|
|
||||||
iso_3166_2 | |
|
|
||||||
iso_3166_3 | [] |
|
|
||||||
iso_4217 | [] [] [] [] |
|
|
||||||
iso_639 | |
|
|
||||||
jpilot | [] [] [] |
|
|
||||||
jtag | |
|
|
||||||
jwhois | [] |
|
|
||||||
kbd | [] [] [] [] [] |
|
|
||||||
latrine | () |
|
|
||||||
ld | [] [] |
|
|
||||||
libc | [] [] [] [] [] [] |
|
|
||||||
libgpewidget | [] [] |
|
|
||||||
libiconv | [] [] [] [] [] |
|
|
||||||
lifelines | [] () |
|
|
||||||
lilypond | [] |
|
|
||||||
lingoteach | |
|
|
||||||
lingoteach_lessons | () () |
|
|
||||||
lynx | [] [] [] [] |
|
|
||||||
m4 | [] [] [] [] |
|
|
||||||
mailutils | [] [] |
|
|
||||||
make | [] [] [] |
|
|
||||||
man-db | [] () [] [] () |
|
|
||||||
minicom | [] [] [] |
|
|
||||||
mysecretdiary | [] [] [] |
|
|
||||||
nano | [] () [] [] [] |
|
|
||||||
nano_1_0 | [] () [] [] [] |
|
|
||||||
opcodes | [] |
|
|
||||||
parted | [] [] [] [] [] |
|
|
||||||
ptx | [] [] [] [] [] |
|
|
||||||
python | |
|
|
||||||
radius | [] |
|
|
||||||
recode | [] [] [] [] [] [] [] |
|
|
||||||
rpm | [] [] |
|
|
||||||
screem | |
|
|
||||||
scrollkeeper | [] [] [] [] [] [] |
|
|
||||||
sed | [] [] [] [] [] [] |
|
|
||||||
sh-utils | [] [] [] |
|
|
||||||
shared-mime-info | |
|
|
||||||
sharutils | [] [] [] [] [] [] |
|
|
||||||
silky | () |
|
|
||||||
skencil | [] () [] |
|
|
||||||
sketch | [] () [] |
|
|
||||||
soundtracker | [] [] [] |
|
|
||||||
sp | [] |
|
|
||||||
tar | [] [] [] [] |
|
|
||||||
texinfo | [] [] [] |
|
|
||||||
textutils | [] [] [] [] |
|
|
||||||
tin | () () |
|
|
||||||
tp-robot | |
|
|
||||||
tuxpaint | [] [] [] [] [] [] [] |
|
|
||||||
unicode-han-tra... | |
|
|
||||||
unicode-transla... | |
|
|
||||||
util-linux | [] [] [] [] [] |
|
|
||||||
vorbis-tools | [] [] [] [] |
|
|
||||||
wastesedge | () |
|
|
||||||
wdiff | [] [] [] [] |
|
|
||||||
wget | [] [] [] [] [] [] |
|
|
||||||
xchat | [] [] [] [] |
|
|
||||||
xfree86_xkb_xml | [] [] |
|
|
||||||
xpad | [] |
|
|
||||||
+----------------------------------------------------+
|
|
||||||
af am ar az be bg bs ca cs da de el en en_GB eo es
|
|
||||||
4 0 0 1 9 4 1 40 41 60 78 17 1 5 13 68
|
|
||||||
|
|
||||||
et eu fa fi fr ga gl he hr hu id is it ja ko lg
|
|
||||||
+-------------------------------------------------+
|
|
||||||
a2ps | [] [] [] () () |
|
|
||||||
aegis | |
|
|
||||||
ant-phone | [] |
|
|
||||||
anubis | [] |
|
|
||||||
ap-utils | [] |
|
|
||||||
aspell | [] [] |
|
|
||||||
bash | [] [] |
|
|
||||||
batchelor | [] [] |
|
|
||||||
bfd | [] |
|
|
||||||
binutils | [] [] |
|
|
||||||
bison | [] [] [] [] |
|
|
||||||
bluez-pin | [] [] [] [] [] |
|
|
||||||
clisp | |
|
|
||||||
clisp | [] |
|
|
||||||
console-tools | |
|
|
||||||
coreutils | [] [] [] [] [] [] |
|
|
||||||
cpio | [] [] [] [] |
|
|
||||||
darkstat | () [] [] [] |
|
|
||||||
diffutils | [] [] [] [] [] [] [] |
|
|
||||||
e2fsprogs | |
|
|
||||||
enscript | [] [] |
|
|
||||||
error | [] [] [] [] |
|
|
||||||
fetchmail | [] |
|
|
||||||
fileutils | [] [] [] [] [] [] |
|
|
||||||
findutils | [] [] [] [] [] [] [] [] [] [] [] |
|
|
||||||
flex | [] [] [] |
|
|
||||||
fslint | [] |
|
|
||||||
gas | [] |
|
|
||||||
gawk | [] [] [] |
|
|
||||||
gbiff | [] |
|
|
||||||
gcal | [] |
|
|
||||||
gcc | [] |
|
|
||||||
gettext | [] [] [] |
|
|
||||||
gettext-examples | [] [] |
|
|
||||||
gettext-runtime | [] [] [] [] [] |
|
|
||||||
gettext-tools | [] [] [] |
|
|
||||||
gimp-print | [] [] |
|
|
||||||
gliv | () |
|
|
||||||
glunarclock | [] [] [] [] |
|
|
||||||
gnubiff | [] |
|
|
||||||
gnucash | () [] |
|
|
||||||
gnucash-glossary | [] |
|
|
||||||
gnupg | [] [] [] [] [] [] [] |
|
|
||||||
gpe-aerial | [] |
|
|
||||||
gpe-beam | [] |
|
|
||||||
gpe-calendar | [] [] [] |
|
|
||||||
gpe-clock | [] |
|
|
||||||
gpe-conf | [] |
|
|
||||||
gpe-contacts | [] [] |
|
|
||||||
gpe-edit | [] [] |
|
|
||||||
gpe-go | [] |
|
|
||||||
gpe-login | [] [] |
|
|
||||||
gpe-ownerinfo | [] [] [] |
|
|
||||||
gpe-sketchbook | [] |
|
|
||||||
gpe-su | [] |
|
|
||||||
gpe-taskmanager | [] |
|
|
||||||
gpe-timesheet | [] [] [] |
|
|
||||||
gpe-today | [] [] |
|
|
||||||
gpe-todo | [] [] |
|
|
||||||
gphoto2 | [] [] [] |
|
|
||||||
gprof | [] [] |
|
|
||||||
gpsdrive | () () () |
|
|
||||||
gramadoir | [] [] |
|
|
||||||
grep | [] [] [] [] [] [] [] [] [] [] [] |
|
|
||||||
gretl | [] [] |
|
|
||||||
gtick | [] [] [] |
|
|
||||||
hello | [] [] [] [] [] [] [] [] [] [] [] [] [] |
|
|
||||||
id-utils | [] [] [] [] |
|
|
||||||
indent | [] [] [] [] [] [] [] [] [] |
|
|
||||||
iso_3166 | [] [] [] [] [] [] [] |
|
|
||||||
iso_3166_1 | [] [] [] [] [] |
|
|
||||||
iso_3166_2 | |
|
|
||||||
iso_3166_3 | |
|
|
||||||
iso_4217 | [] [] [] [] [] [] |
|
|
||||||
iso_639 | |
|
|
||||||
jpilot | [] () |
|
|
||||||
jtag | [] |
|
|
||||||
jwhois | [] [] [] [] |
|
|
||||||
kbd | [] |
|
|
||||||
latrine | [] |
|
|
||||||
ld | [] |
|
|
||||||
libc | [] [] [] [] [] [] |
|
|
||||||
libgpewidget | [] [] [] [] |
|
|
||||||
libiconv | [] [] [] [] [] [] [] [] [] |
|
|
||||||
lifelines | () |
|
|
||||||
lilypond | [] |
|
|
||||||
lingoteach | [] [] |
|
|
||||||
lingoteach_lessons | |
|
|
||||||
lynx | [] [] [] [] |
|
|
||||||
m4 | [] [] [] [] |
|
|
||||||
mailutils | |
|
|
||||||
make | [] [] [] [] [] [] |
|
|
||||||
man-db | () () |
|
|
||||||
minicom | [] [] [] [] |
|
|
||||||
mysecretdiary | [] [] |
|
|
||||||
nano | [] [] [] [] |
|
|
||||||
nano_1_0 | [] [] [] [] |
|
|
||||||
opcodes | [] |
|
|
||||||
parted | [] [] [] |
|
|
||||||
ptx | [] [] [] [] [] [] [] |
|
|
||||||
python | |
|
|
||||||
radius | [] |
|
|
||||||
recode | [] [] [] [] [] [] |
|
|
||||||
rpm | [] [] |
|
|
||||||
screem | |
|
|
||||||
scrollkeeper | [] |
|
|
||||||
sed | [] [] [] [] [] [] [] [] [] |
|
|
||||||
sh-utils | [] [] [] [] [] [] [] |
|
|
||||||
shared-mime-info | [] [] [] |
|
|
||||||
sharutils | [] [] [] [] [] |
|
|
||||||
silky | () [] () () |
|
|
||||||
skencil | [] |
|
|
||||||
sketch | [] |
|
|
||||||
soundtracker | [] [] |
|
|
||||||
sp | [] () |
|
|
||||||
tar | [] [] [] [] [] [] [] [] [] |
|
|
||||||
texinfo | [] [] [] [] |
|
|
||||||
textutils | [] [] [] [] [] [] |
|
|
||||||
tin | [] () |
|
|
||||||
tp-robot | [] |
|
|
||||||
tuxpaint | [] [] [] [] [] [] [] [] [] |
|
|
||||||
unicode-han-tra... | |
|
|
||||||
unicode-transla... | [] [] |
|
|
||||||
util-linux | [] [] [] [] () [] |
|
|
||||||
vorbis-tools | [] |
|
|
||||||
wastesedge | () |
|
|
||||||
wdiff | [] [] [] [] [] [] |
|
|
||||||
wget | [] [] [] [] [] [] [] |
|
|
||||||
xchat | [] [] [] |
|
|
||||||
xfree86_xkb_xml | [] [] |
|
|
||||||
xpad | [] [] |
|
|
||||||
+-------------------------------------------------+
|
|
||||||
et eu fa fi fr ga gl he hr hu id is it ja ko lg
|
|
||||||
22 2 1 26 106 28 24 8 10 41 33 1 26 33 12 0
|
|
||||||
|
|
||||||
lt lv mk mn ms mt nb nl nn no nso pl pt pt_BR ro ru
|
|
||||||
+-----------------------------------------------------+
|
|
||||||
a2ps | [] [] () () [] [] [] |
|
|
||||||
aegis | () () () |
|
|
||||||
ant-phone | [] [] |
|
|
||||||
anubis | [] [] [] [] [] [] |
|
|
||||||
ap-utils | [] () [] |
|
|
||||||
aspell | [] |
|
|
||||||
bash | [] [] [] |
|
|
||||||
batchelor | [] |
|
|
||||||
bfd | [] |
|
|
||||||
binutils | [] |
|
|
||||||
bison | [] [] [] [] [] |
|
|
||||||
bluez-pin | [] [] [] |
|
|
||||||
clisp | |
|
|
||||||
clisp | [] |
|
|
||||||
console-tools | [] |
|
|
||||||
coreutils | [] [] |
|
|
||||||
cpio | [] [] [] [] [] |
|
|
||||||
darkstat | [] [] [] [] |
|
|
||||||
diffutils | [] [] [] [] [] [] |
|
|
||||||
e2fsprogs | [] |
|
|
||||||
enscript | [] [] [] [] |
|
|
||||||
error | [] [] [] |
|
|
||||||
fetchmail | [] [] () [] |
|
|
||||||
fileutils | [] [] [] |
|
|
||||||
findutils | [] [] [] [] [] |
|
|
||||||
flex | [] [] [] [] |
|
|
||||||
fslint | [] [] |
|
|
||||||
gas | |
|
|
||||||
gawk | [] [] [] |
|
|
||||||
gbiff | [] [] |
|
|
||||||
gcal | |
|
|
||||||
gcc | |
|
|
||||||
gettext | [] [] [] |
|
|
||||||
gettext-examples | [] [] [] |
|
|
||||||
gettext-runtime | [] [] [] [] |
|
|
||||||
gettext-tools | [] [] |
|
|
||||||
gimp-print | [] |
|
|
||||||
gliv | [] [] [] |
|
|
||||||
glunarclock | [] [] [] [] |
|
|
||||||
gnubiff | [] |
|
|
||||||
gnucash | [] [] () [] |
|
|
||||||
gnucash-glossary | [] [] |
|
|
||||||
gnupg | [] |
|
|
||||||
gpe-aerial | [] [] [] [] |
|
|
||||||
gpe-beam | [] [] [] [] |
|
|
||||||
gpe-calendar | [] [] [] [] |
|
|
||||||
gpe-clock | [] [] [] [] |
|
|
||||||
gpe-conf | [] [] [] [] |
|
|
||||||
gpe-contacts | [] [] [] [] |
|
|
||||||
gpe-edit | [] [] [] [] |
|
|
||||||
gpe-go | [] [] [] |
|
|
||||||
gpe-login | [] [] [] [] |
|
|
||||||
gpe-ownerinfo | [] [] [] [] |
|
|
||||||
gpe-sketchbook | [] [] [] [] |
|
|
||||||
gpe-su | [] [] [] [] |
|
|
||||||
gpe-taskmanager | [] [] [] [] |
|
|
||||||
gpe-timesheet | [] [] [] [] |
|
|
||||||
gpe-today | [] [] [] [] |
|
|
||||||
gpe-todo | [] [] [] [] |
|
|
||||||
gphoto2 | [] |
|
|
||||||
gprof | [] [] |
|
|
||||||
gpsdrive | () () [] |
|
|
||||||
gramadoir | () [] |
|
|
||||||
grep | [] [] [] [] [] |
|
|
||||||
gretl | |
|
|
||||||
gtick | [] [] [] |
|
|
||||||
hello | [] [] [] [] [] [] [] [] [] [] |
|
|
||||||
id-utils | [] [] [] [] |
|
|
||||||
indent | [] [] [] [] |
|
|
||||||
iso_3166 | [] [] [] |
|
|
||||||
iso_3166_1 | [] [] |
|
|
||||||
iso_3166_2 | |
|
|
||||||
iso_3166_3 | [] |
|
|
||||||
iso_4217 | [] [] [] [] [] [] [] [] |
|
|
||||||
iso_639 | [] |
|
|
||||||
jpilot | () () |
|
|
||||||
jtag | |
|
|
||||||
jwhois | [] [] [] [] () |
|
|
||||||
kbd | [] [] [] |
|
|
||||||
latrine | [] |
|
|
||||||
ld | |
|
|
||||||
libc | [] [] [] [] |
|
|
||||||
libgpewidget | [] [] [] |
|
|
||||||
libiconv | [] [] [] [] [] |
|
|
||||||
lifelines | |
|
|
||||||
lilypond | |
|
|
||||||
lingoteach | |
|
|
||||||
lingoteach_lessons | |
|
|
||||||
lynx | [] [] [] |
|
|
||||||
m4 | [] [] [] [] [] |
|
|
||||||
mailutils | [] [] [] |
|
|
||||||
make | [] [] [] [] |
|
|
||||||
man-db | [] |
|
|
||||||
minicom | [] [] [] [] |
|
|
||||||
mysecretdiary | [] [] [] |
|
|
||||||
nano | [] [] [] [] [] |
|
|
||||||
nano_1_0 | [] [] [] [] [] [] |
|
|
||||||
opcodes | [] [] |
|
|
||||||
parted | [] [] [] [] |
|
|
||||||
ptx | [] [] [] [] [] [] [] [] |
|
|
||||||
python | |
|
|
||||||
radius | [] [] |
|
|
||||||
recode | [] [] [] [] |
|
|
||||||
rpm | [] [] [] |
|
|
||||||
screem | |
|
|
||||||
scrollkeeper | [] [] [] [] [] |
|
|
||||||
sed | [] [] [] |
|
|
||||||
sh-utils | [] [] |
|
|
||||||
shared-mime-info | [] [] |
|
|
||||||
sharutils | [] [] |
|
|
||||||
silky | () |
|
|
||||||
skencil | [] [] |
|
|
||||||
sketch | [] [] |
|
|
||||||
soundtracker | |
|
|
||||||
sp | |
|
|
||||||
tar | [] [] [] [] [] [] |
|
|
||||||
texinfo | [] [] [] [] |
|
|
||||||
textutils | [] [] |
|
|
||||||
tin | |
|
|
||||||
tp-robot | [] |
|
|
||||||
tuxpaint | [] [] [] [] [] [] [] [] |
|
|
||||||
unicode-han-tra... | |
|
|
||||||
unicode-transla... | |
|
|
||||||
util-linux | [] [] [] |
|
|
||||||
vorbis-tools | [] [] [] |
|
|
||||||
wastesedge | |
|
|
||||||
wdiff | [] [] [] [] [] |
|
|
||||||
wget | [] [] [] |
|
|
||||||
xchat | [] [] [] |
|
|
||||||
xfree86_xkb_xml | [] [] |
|
|
||||||
xpad | [] [] |
|
|
||||||
+-----------------------------------------------------+
|
|
||||||
lt lv mk mn ms mt nb nl nn no nso pl pt pt_BR ro ru
|
|
||||||
1 2 0 3 12 0 10 69 6 7 1 40 26 36 76 63
|
|
||||||
|
|
||||||
sk sl sr sv ta th tr uk ven vi wa xh zh_CN zh_TW zu
|
|
||||||
+-----------------------------------------------------+
|
|
||||||
a2ps | [] [] [] [] | 16
|
|
||||||
aegis | | 0
|
|
||||||
ant-phone | | 3
|
|
||||||
anubis | [] [] | 9
|
|
||||||
ap-utils | () | 3
|
|
||||||
aspell | | 4
|
|
||||||
bash | | 9
|
|
||||||
batchelor | | 3
|
|
||||||
bfd | [] [] | 6
|
|
||||||
binutils | [] [] [] | 8
|
|
||||||
bison | [] [] | 14
|
|
||||||
bluez-pin | [] [] [] | 14
|
|
||||||
clisp | | 0
|
|
||||||
clisp | | 5
|
|
||||||
console-tools | | 3
|
|
||||||
coreutils | [] [] [] [] | 16
|
|
||||||
cpio | [] [] | 14
|
|
||||||
darkstat | [] [] [] () () | 12
|
|
||||||
diffutils | [] [] [] | 23
|
|
||||||
e2fsprogs | [] [] | 6
|
|
||||||
enscript | [] [] | 12
|
|
||||||
error | [] [] [] | 15
|
|
||||||
fetchmail | [] [] | 11
|
|
||||||
fileutils | [] [] [] [] [] | 17
|
|
||||||
findutils | [] [] [] [] [] [] | 29
|
|
||||||
flex | [] [] | 13
|
|
||||||
fslint | | 3
|
|
||||||
gas | [] | 3
|
|
||||||
gawk | [] [] | 12
|
|
||||||
gbiff | | 4
|
|
||||||
gcal | [] [] | 4
|
|
||||||
gcc | [] | 4
|
|
||||||
gettext | [] [] [] [] [] | 16
|
|
||||||
gettext-examples | [] [] [] [] [] | 14
|
|
||||||
gettext-runtime | [] [] [] [] [] [] [] [] | 22
|
|
||||||
gettext-tools | [] [] [] [] [] [] | 14
|
|
||||||
gimp-print | [] [] | 10
|
|
||||||
gliv | | 3
|
|
||||||
glunarclock | [] [] [] | 13
|
|
||||||
gnubiff | | 3
|
|
||||||
gnucash | [] [] | 9
|
|
||||||
gnucash-glossary | [] [] [] | 8
|
|
||||||
gnupg | [] [] [] [] | 17
|
|
||||||
gpe-aerial | [] | 7
|
|
||||||
gpe-beam | [] | 8
|
|
||||||
gpe-calendar | [] [] [] [] | 13
|
|
||||||
gpe-clock | [] [] [] | 10
|
|
||||||
gpe-conf | [] [] | 9
|
|
||||||
gpe-contacts | [] [] [] | 11
|
|
||||||
gpe-edit | [] [] [] [] [] | 12
|
|
||||||
gpe-go | | 5
|
|
||||||
gpe-login | [] [] [] [] [] | 13
|
|
||||||
gpe-ownerinfo | [] [] [] [] | 13
|
|
||||||
gpe-sketchbook | [] [] | 9
|
|
||||||
gpe-su | [] [] [] | 10
|
|
||||||
gpe-taskmanager | [] [] [] | 10
|
|
||||||
gpe-timesheet | [] [] [] [] | 12
|
|
||||||
gpe-today | [] [] [] [] [] | 13
|
|
||||||
gpe-todo | [] [] [] [] | 12
|
|
||||||
gphoto2 | [] [] [] | 11
|
|
||||||
gprof | [] [] | 9
|
|
||||||
gpsdrive | [] [] | 3
|
|
||||||
gramadoir | [] | 5
|
|
||||||
grep | [] [] [] [] | 26
|
|
||||||
gretl | | 3
|
|
||||||
gtick | | 7
|
|
||||||
hello | [] [] [] [] [] | 34
|
|
||||||
id-utils | [] [] | 12
|
|
||||||
indent | [] [] [] [] | 21
|
|
||||||
iso_3166 | [] [] [] [] [] [] [] | 27
|
|
||||||
iso_3166_1 | [] [] [] | 16
|
|
||||||
iso_3166_2 | | 0
|
|
||||||
iso_3166_3 | | 2
|
|
||||||
iso_4217 | [] [] [] [] [] [] | 24
|
|
||||||
iso_639 | | 1
|
|
||||||
jpilot | [] [] [] [] [] | 9
|
|
||||||
jtag | [] | 2
|
|
||||||
jwhois | () [] [] | 11
|
|
||||||
kbd | [] [] | 11
|
|
||||||
latrine | | 2
|
|
||||||
ld | [] [] | 5
|
|
||||||
libc | [] [] [] [] | 20
|
|
||||||
libgpewidget | [] [] [] [] | 13
|
|
||||||
libiconv | [] [] [] [] [] [] [] [] | 27
|
|
||||||
lifelines | [] | 2
|
|
||||||
lilypond | [] | 3
|
|
||||||
lingoteach | | 2
|
|
||||||
lingoteach_lessons | () | 0
|
|
||||||
lynx | [] [] [] | 14
|
|
||||||
m4 | [] [] | 15
|
|
||||||
mailutils | | 5
|
|
||||||
make | [] [] [] | 16
|
|
||||||
man-db | [] | 5
|
|
||||||
minicom | | 11
|
|
||||||
mysecretdiary | [] [] | 10
|
|
||||||
nano | [] [] [] [] | 17
|
|
||||||
nano_1_0 | [] [] [] | 17
|
|
||||||
opcodes | [] [] | 6
|
|
||||||
parted | [] [] [] | 15
|
|
||||||
ptx | [] [] | 22
|
|
||||||
python | | 0
|
|
||||||
radius | | 4
|
|
||||||
recode | [] [] [] | 20
|
|
||||||
rpm | [] [] | 9
|
|
||||||
screem | [] [] | 2
|
|
||||||
scrollkeeper | [] [] [] | 15
|
|
||||||
sed | [] [] [] [] [] [] | 24
|
|
||||||
sh-utils | [] [] | 14
|
|
||||||
shared-mime-info | [] [] | 7
|
|
||||||
sharutils | [] [] [] [] | 17
|
|
||||||
silky | () | 3
|
|
||||||
skencil | [] | 6
|
|
||||||
sketch | [] | 6
|
|
||||||
soundtracker | [] [] | 7
|
|
||||||
sp | [] | 3
|
|
||||||
tar | [] [] [] [] [] | 24
|
|
||||||
texinfo | [] [] [] | 14
|
|
||||||
textutils | [] [] [] [] | 16
|
|
||||||
tin | | 1
|
|
||||||
tp-robot | | 2
|
|
||||||
tuxpaint | [] [] [] [] [] | 29
|
|
||||||
unicode-han-tra... | | 0
|
|
||||||
unicode-transla... | | 2
|
|
||||||
util-linux | [] [] | 15
|
|
||||||
vorbis-tools | | 8
|
|
||||||
wastesedge | | 0
|
|
||||||
wdiff | [] [] [] | 18
|
|
||||||
wget | [] [] [] [] [] [] [] [] | 24
|
|
||||||
xchat | [] [] [] [] [] | 15
|
|
||||||
xfree86_xkb_xml | [] [] [] [] [] | 11
|
|
||||||
xpad | | 5
|
|
||||||
+-----------------------------------------------------+
|
|
||||||
63 teams sk sl sr sv ta th tr uk ven vi wa xh zh_CN zh_TW zu
|
|
||||||
131 domains 47 19 28 83 0 0 59 13 1 1 11 0 22 22 0 1373
|
|
||||||
|
|
||||||
Some counters in the preceding matrix are higher than the number of
|
|
||||||
visible blocks let us expect. This is because a few extra PO files are
|
|
||||||
used for implementing regional variants of languages, or language
|
|
||||||
dialects.
|
|
||||||
|
|
||||||
For a PO file in the matrix above to be effective, the package to
|
|
||||||
which it applies should also have been internationalized and
|
|
||||||
distributed as such by its maintainer. There might be an observable
|
|
||||||
lag between the mere existence a PO file and its wide availability in a
|
|
||||||
distribution.
|
|
||||||
|
|
||||||
If January 2004 seems to be old, you may fetch a more recent copy of
|
|
||||||
this `ABOUT-NLS' file on most GNU archive sites. The most up-to-date
|
|
||||||
matrix with full percentage details can be found at
|
|
||||||
`http://www.iro.umontreal.ca/contrib/po/HTML/matrix.html'.
|
|
||||||
|
|
||||||
Using `gettext' in new packages
|
|
||||||
===============================
|
|
||||||
|
|
||||||
If you are writing a freely available program and want to
|
|
||||||
internationalize it you are welcome to use GNU `gettext' in your
|
|
||||||
package. Of course you have to respect the GNU Library General Public
|
|
||||||
License which covers the use of the GNU `gettext' library. This means
|
|
||||||
in particular that even non-free programs can use `libintl' as a shared
|
|
||||||
library, whereas only free software can use `libintl' as a static
|
|
||||||
library or use modified versions of `libintl'.
|
|
||||||
|
|
||||||
Once the sources are changed appropriately and the setup can handle
|
|
||||||
the use of `gettext' the only thing missing are the translations. The
|
|
||||||
Free Translation Project is also available for packages which are not
|
|
||||||
developed inside the GNU project. Therefore the information given above
|
|
||||||
applies also for every other Free Software Project. Contact
|
|
||||||
`translation@iro.umontreal.ca' to make the `.pot' files available to
|
|
||||||
the translation teams.
|
|
||||||
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
Authors of GNU diffutils.
|
|
||||||
|
|
||||||
Copyright 2001 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GNU diffutils.
|
|
||||||
|
|
||||||
GNU diffutils 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 diffutils 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 diffutils; see the file COPYING. If not, write to
|
|
||||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
||||||
Boston, MA 02111-1307, USA.
|
|
||||||
|
|
||||||
The following contributions warranted legal paper exchanges with the
|
|
||||||
Free Software Foundation. Also see files ChangeLog and THANKS.
|
|
||||||
|
|
||||||
DIFFUTILS Leonard H. Tower Jr. US 1949 1987-03-09
|
|
||||||
Assigns diff (diff.c, initial version).
|
|
||||||
|
|
||||||
DIFFUTILS Torbjorn Granlund Sweden 1961 1988-01-11
|
|
||||||
Assigns cmp.
|
|
||||||
tege@matematik.su.se
|
|
||||||
|
|
||||||
DIFFUTILS Mike Haertel US 1967 1988-09-16
|
|
||||||
Assigns changes to diff.
|
|
||||||
|
|
||||||
DIFFUTILS David S. Hayes US ? 1988-01-12
|
|
||||||
Assigns changes to diff.
|
|
||||||
|
|
||||||
DIFFUTILS Randall Smith US 1964 1988-09-21
|
|
||||||
Assigns diff3.
|
|
||||||
|
|
||||||
DIFFUTILS Richard Stallman US 1953 1988-01-15
|
|
||||||
Assigns changes to GNU Diff.
|
|
||||||
|
|
||||||
DIFFUTILS F. Thomas May US 1965 1989-08-22
|
|
||||||
Assigns changes to diff (for -D).
|
|
||||||
|
|
||||||
DIFFUTILS Optimal Solutions, Inc. 1989-08-14
|
|
||||||
Disclaims changes by Thomas May to diff.
|
|
||||||
|
|
||||||
DIFFUTILS Wayne Davison 1990-09-10
|
|
||||||
Disclaims changes to diff.
|
|
||||||
|
|
||||||
DIFFUTILS Digital Research Inc. 1990-09-13
|
|
||||||
Disclaims changes by Wayne Davison to diff.
|
|
||||||
|
|
||||||
DIFFUTILS Paul Eggert 1990-03-16
|
|
||||||
Disclaims changes to diff.
|
|
||||||
eggert@twinsun.com
|
|
||||||
|
|
||||||
DIFFUTILS Paul Eggert 1990-08-14
|
|
||||||
Disclaims changes to GNU Diff.
|
|
||||||
eggert@twinsun.com
|
|
||||||
|
|
||||||
DIFFUTILS Twin Sun Inc. 1990-03-16
|
|
||||||
Disclaims changes to GNU Diff by Paul Eggert.
|
|
||||||
|
|
||||||
DIFFUTILS Twin Sun Inc. 1990-08-14
|
|
||||||
Disclaims changes to GNU Diff by Paul Eggert.
|
|
||||||
|
|
||||||
DIFFUTILS Chip Rosenthal US 1959 1990-03-06
|
|
||||||
Assigns changes to diff.
|
|
||||||
chip@chinacat.Unicom.COM
|
|
||||||
|
|
||||||
DIFFUTILS Unicom Systems Development 1990-03-06
|
|
||||||
Disclaims changes by Chip Rosenthal to diff.
|
|
||||||
|
|
||||||
GCC DIFFUTILS Paul Eggert and Twin Sun Inc. 1992-03-11
|
|
||||||
Disclaims changes by Paul Eggert to gcc and diff.
|
|
||||||
eggert@twinsun.com
|
|
||||||
|
|
||||||
DIFF Wayne Davison 1993-06-20
|
|
||||||
Disclaims diffcvt.c.
|
|
||||||
|
|
||||||
DIFFUTILS Francois Pinard Canada 1949 1993-01-15
|
|
||||||
Assigns wdiff and future changes submitted to the FSF.
|
|
||||||
pinard@iro.umontreal.ca
|
|
||||||
|
|
||||||
DIFFUTILS Patrick D'Cruze Australia 1971 1994-11-10
|
|
||||||
Assigns changes (makefile.in, analyze.c, cmp.c, error.c, diff.c,
|
|
||||||
diff3.c, getopt.c, getopt1.c, regex.c, sdiff.c, util.c, xmalloc.c;
|
|
||||||
new file: language.++)
|
|
||||||
|
|
||||||
DIFFUTILS Paul R. Eggert US 1954 1997-04-07
|
|
||||||
Assigns past and future changes.
|
|
||||||
eggert@twinsun.com
|
|
||||||
|
|
||||||
DIFFUTILS Paul R. Eggert US 1954 1997-04-07
|
|
||||||
Assigns past and future changes to manual.
|
|
||||||
eggert@twinsun.com
|
|
||||||
|
|
||||||
ANY DIFFUTILS GNATS Cyclic Software 1997-11-11
|
|
||||||
Assigns past and future works (work for hire by Tim Pierce (diffutils) and
|
|
||||||
Abe Feldman (GNATS)).
|
|
||||||
kingdon@cyclic.com
|
|
||||||
|
|
||||||
WEBPAGES Gregory B. Harvey Canada 1976 1998-02-14
|
|
||||||
Assigns web pages describing GNU Diffutils and future changes.
|
|
||||||
|
|
||||||
DIFFUTILS Olga Nikulin Russia 1965 2001-01-11
|
|
||||||
Assigns changes to diff. (diffutils-2.7.2/analyze.c, context.c, diff.[ch],
|
|
||||||
ed.c, ifdef.c, io.c, normal.c, side.c, util.c)
|
|
||||||
onikulin@yahoo.com
|
|
||||||
@@ -1,340 +0,0 @@
|
|||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
Version 2, June 1991
|
|
||||||
|
|
||||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
|
||||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The licenses for most software are designed to take away your
|
|
||||||
freedom to share and change it. By contrast, the GNU General Public
|
|
||||||
License is intended to guarantee your freedom to share and change free
|
|
||||||
software--to make sure the software is free for all its users. This
|
|
||||||
General Public License applies to most of the Free Software
|
|
||||||
Foundation's software and to any other program whose authors commit to
|
|
||||||
using it. (Some other Free Software Foundation software is covered by
|
|
||||||
the GNU Library General Public License instead.) You can apply it to
|
|
||||||
your programs, too.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
this service if you wish), that you receive source code or can get it
|
|
||||||
if you want it, that you can change the software or use pieces of it
|
|
||||||
in new free programs; and that you know you can do these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to make restrictions that forbid
|
|
||||||
anyone to deny you these rights or to ask you to surrender the rights.
|
|
||||||
These restrictions translate to certain responsibilities for you if you
|
|
||||||
distribute copies of the software, or if you modify it.
|
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
|
||||||
gratis or for a fee, you must give the recipients all the rights that
|
|
||||||
you have. You must make sure that they, too, receive or can get the
|
|
||||||
source code. And you must show them these terms so they know their
|
|
||||||
rights.
|
|
||||||
|
|
||||||
We protect your rights with two steps: (1) copyright the software, and
|
|
||||||
(2) offer you this license which gives you legal permission to copy,
|
|
||||||
distribute and/or modify the software.
|
|
||||||
|
|
||||||
Also, for each author's protection and ours, we want to make certain
|
|
||||||
that everyone understands that there is no warranty for this free
|
|
||||||
software. If the software is modified by someone else and passed on, we
|
|
||||||
want its recipients to know that what they have is not the original, so
|
|
||||||
that any problems introduced by others will not reflect on the original
|
|
||||||
authors' reputations.
|
|
||||||
|
|
||||||
Finally, any free program is threatened constantly by software
|
|
||||||
patents. We wish to avoid the danger that redistributors of a free
|
|
||||||
program will individually obtain patent licenses, in effect making the
|
|
||||||
program proprietary. To prevent this, we have made it clear that any
|
|
||||||
patent must be licensed for everyone's free use or not licensed at all.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
|
||||||
|
|
||||||
0. This License applies to any program or other work which contains
|
|
||||||
a notice placed by the copyright holder saying it may be distributed
|
|
||||||
under the terms of this General Public License. The "Program", below,
|
|
||||||
refers to any such program or work, and a "work based on the Program"
|
|
||||||
means either the Program or any derivative work under copyright law:
|
|
||||||
that is to say, a work containing the Program or a portion of it,
|
|
||||||
either verbatim or with modifications and/or translated into another
|
|
||||||
language. (Hereinafter, translation is included without limitation in
|
|
||||||
the term "modification".) Each licensee is addressed as "you".
|
|
||||||
|
|
||||||
Activities other than copying, distribution and modification are not
|
|
||||||
covered by this License; they are outside its scope. The act of
|
|
||||||
running the Program is not restricted, and the output from the Program
|
|
||||||
is covered only if its contents constitute a work based on the
|
|
||||||
Program (independent of having been made by running the Program).
|
|
||||||
Whether that is true depends on what the Program does.
|
|
||||||
|
|
||||||
1. You may copy and distribute verbatim copies of the Program's
|
|
||||||
source code as you receive it, in any medium, provided that you
|
|
||||||
conspicuously and appropriately publish on each copy an appropriate
|
|
||||||
copyright notice and disclaimer of warranty; keep intact all the
|
|
||||||
notices that refer to this License and to the absence of any warranty;
|
|
||||||
and give any other recipients of the Program a copy of this License
|
|
||||||
along with the Program.
|
|
||||||
|
|
||||||
You may charge a fee for the physical act of transferring a copy, and
|
|
||||||
you may at your option offer warranty protection in exchange for a fee.
|
|
||||||
|
|
||||||
2. You may modify your copy or copies of the Program or any portion
|
|
||||||
of it, thus forming a work based on the Program, and copy and
|
|
||||||
distribute such modifications or work under the terms of Section 1
|
|
||||||
above, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) You must cause the modified files to carry prominent notices
|
|
||||||
stating that you changed the files and the date of any change.
|
|
||||||
|
|
||||||
b) You must cause any work that you distribute or publish, that in
|
|
||||||
whole or in part contains or is derived from the Program or any
|
|
||||||
part thereof, to be licensed as a whole at no charge to all third
|
|
||||||
parties under the terms of this License.
|
|
||||||
|
|
||||||
c) If the modified program normally reads commands interactively
|
|
||||||
when run, you must cause it, when started running for such
|
|
||||||
interactive use in the most ordinary way, to print or display an
|
|
||||||
announcement including an appropriate copyright notice and a
|
|
||||||
notice that there is no warranty (or else, saying that you provide
|
|
||||||
a warranty) and that users may redistribute the program under
|
|
||||||
these conditions, and telling the user how to view a copy of this
|
|
||||||
License. (Exception: if the Program itself is interactive but
|
|
||||||
does not normally print such an announcement, your work based on
|
|
||||||
the Program is not required to print an announcement.)
|
|
||||||
|
|
||||||
These requirements apply to the modified work as a whole. If
|
|
||||||
identifiable sections of that work are not derived from the Program,
|
|
||||||
and can be reasonably considered independent and separate works in
|
|
||||||
themselves, then this License, and its terms, do not apply to those
|
|
||||||
sections when you distribute them as separate works. But when you
|
|
||||||
distribute the same sections as part of a whole which is a work based
|
|
||||||
on the Program, the distribution of the whole must be on the terms of
|
|
||||||
this License, whose permissions for other licensees extend to the
|
|
||||||
entire whole, and thus to each and every part regardless of who wrote it.
|
|
||||||
|
|
||||||
Thus, it is not the intent of this section to claim rights or contest
|
|
||||||
your rights to work written entirely by you; rather, the intent is to
|
|
||||||
exercise the right to control the distribution of derivative or
|
|
||||||
collective works based on the Program.
|
|
||||||
|
|
||||||
In addition, mere aggregation of another work not based on the Program
|
|
||||||
with the Program (or with a work based on the Program) on a volume of
|
|
||||||
a storage or distribution medium does not bring the other work under
|
|
||||||
the scope of this License.
|
|
||||||
|
|
||||||
3. You may copy and distribute the Program (or a work based on it,
|
|
||||||
under Section 2) in object code or executable form under the terms of
|
|
||||||
Sections 1 and 2 above provided that you also do one of the following:
|
|
||||||
|
|
||||||
a) Accompany it with the complete corresponding machine-readable
|
|
||||||
source code, which must be distributed under the terms of Sections
|
|
||||||
1 and 2 above on a medium customarily used for software interchange; or,
|
|
||||||
|
|
||||||
b) Accompany it with a written offer, valid for at least three
|
|
||||||
years, to give any third party, for a charge no more than your
|
|
||||||
cost of physically performing source distribution, a complete
|
|
||||||
machine-readable copy of the corresponding source code, to be
|
|
||||||
distributed under the terms of Sections 1 and 2 above on a medium
|
|
||||||
customarily used for software interchange; or,
|
|
||||||
|
|
||||||
c) Accompany it with the information you received as to the offer
|
|
||||||
to distribute corresponding source code. (This alternative is
|
|
||||||
allowed only for noncommercial distribution and only if you
|
|
||||||
received the program in object code or executable form with such
|
|
||||||
an offer, in accord with Subsection b above.)
|
|
||||||
|
|
||||||
The source code for a work means the preferred form of the work for
|
|
||||||
making modifications to it. For an executable work, complete source
|
|
||||||
code means all the source code for all modules it contains, plus any
|
|
||||||
associated interface definition files, plus the scripts used to
|
|
||||||
control compilation and installation of the executable. However, as a
|
|
||||||
special exception, the source code distributed need not include
|
|
||||||
anything that is normally distributed (in either source or binary
|
|
||||||
form) with the major components (compiler, kernel, and so on) of the
|
|
||||||
operating system on which the executable runs, unless that component
|
|
||||||
itself accompanies the executable.
|
|
||||||
|
|
||||||
If distribution of executable or object code is made by offering
|
|
||||||
access to copy from a designated place, then offering equivalent
|
|
||||||
access to copy the source code from the same place counts as
|
|
||||||
distribution of the source code, even though third parties are not
|
|
||||||
compelled to copy the source along with the object code.
|
|
||||||
|
|
||||||
4. You may not copy, modify, sublicense, or distribute the Program
|
|
||||||
except as expressly provided under this License. Any attempt
|
|
||||||
otherwise to copy, modify, sublicense or distribute the Program is
|
|
||||||
void, and will automatically terminate your rights under this License.
|
|
||||||
However, parties who have received copies, or rights, from you under
|
|
||||||
this License will not have their licenses terminated so long as such
|
|
||||||
parties remain in full compliance.
|
|
||||||
|
|
||||||
5. You are not required to accept this License, since you have not
|
|
||||||
signed it. However, nothing else grants you permission to modify or
|
|
||||||
distribute the Program or its derivative works. These actions are
|
|
||||||
prohibited by law if you do not accept this License. Therefore, by
|
|
||||||
modifying or distributing the Program (or any work based on the
|
|
||||||
Program), you indicate your acceptance of this License to do so, and
|
|
||||||
all its terms and conditions for copying, distributing or modifying
|
|
||||||
the Program or works based on it.
|
|
||||||
|
|
||||||
6. Each time you redistribute the Program (or any work based on the
|
|
||||||
Program), the recipient automatically receives a license from the
|
|
||||||
original licensor to copy, distribute or modify the Program subject to
|
|
||||||
these terms and conditions. You may not impose any further
|
|
||||||
restrictions on the recipients' exercise of the rights granted herein.
|
|
||||||
You are not responsible for enforcing compliance by third parties to
|
|
||||||
this License.
|
|
||||||
|
|
||||||
7. If, as a consequence of a court judgment or allegation of patent
|
|
||||||
infringement or for any other reason (not limited to patent issues),
|
|
||||||
conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot
|
|
||||||
distribute so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you
|
|
||||||
may not distribute the Program at all. For example, if a patent
|
|
||||||
license would not permit royalty-free redistribution of the Program by
|
|
||||||
all those who receive copies directly or indirectly through you, then
|
|
||||||
the only way you could satisfy both it and this License would be to
|
|
||||||
refrain entirely from distribution of the Program.
|
|
||||||
|
|
||||||
If any portion of this section is held invalid or unenforceable under
|
|
||||||
any particular circumstance, the balance of the section is intended to
|
|
||||||
apply and the section as a whole is intended to apply in other
|
|
||||||
circumstances.
|
|
||||||
|
|
||||||
It is not the purpose of this section to induce you to infringe any
|
|
||||||
patents or other property right claims or to contest validity of any
|
|
||||||
such claims; this section has the sole purpose of protecting the
|
|
||||||
integrity of the free software distribution system, which is
|
|
||||||
implemented by public license practices. Many people have made
|
|
||||||
generous contributions to the wide range of software distributed
|
|
||||||
through that system in reliance on consistent application of that
|
|
||||||
system; it is up to the author/donor to decide if he or she is willing
|
|
||||||
to distribute software through any other system and a licensee cannot
|
|
||||||
impose that choice.
|
|
||||||
|
|
||||||
This section is intended to make thoroughly clear what is believed to
|
|
||||||
be a consequence of the rest of this License.
|
|
||||||
|
|
||||||
8. If the distribution and/or use of the Program is restricted in
|
|
||||||
certain countries either by patents or by copyrighted interfaces, the
|
|
||||||
original copyright holder who places the Program under this License
|
|
||||||
may add an explicit geographical distribution limitation excluding
|
|
||||||
those countries, so that distribution is permitted only in or among
|
|
||||||
countries not thus excluded. In such case, this License incorporates
|
|
||||||
the limitation as if written in the body of this License.
|
|
||||||
|
|
||||||
9. The Free Software Foundation may publish revised and/or new versions
|
|
||||||
of the General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Program
|
|
||||||
specifies a version number of this License which applies to it and "any
|
|
||||||
later version", you have the option of following the terms and conditions
|
|
||||||
either of that version or of any later version published by the Free
|
|
||||||
Software Foundation. If the Program does not specify a version number of
|
|
||||||
this License, you may choose any version ever published by the Free Software
|
|
||||||
Foundation.
|
|
||||||
|
|
||||||
10. If you wish to incorporate parts of the Program into other free
|
|
||||||
programs whose distribution conditions are different, write to the author
|
|
||||||
to ask for permission. For software which is copyrighted by the Free
|
|
||||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
|
||||||
make exceptions for this. Our decision will be guided by the two goals
|
|
||||||
of preserving the free status of all derivatives of our free software and
|
|
||||||
of promoting the sharing and reuse of software generally.
|
|
||||||
|
|
||||||
NO WARRANTY
|
|
||||||
|
|
||||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
|
||||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
|
||||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
|
||||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
|
||||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
|
||||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
|
||||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
|
||||||
REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
|
||||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
|
||||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
|
||||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
|
||||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
|
||||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
|
||||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
|
||||||
POSSIBILITY OF SUCH DAMAGES.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
convey the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program is interactive, make it output a short notice like this
|
|
||||||
when it starts in an interactive mode:
|
|
||||||
|
|
||||||
Gnomovision version 69, Copyright (C) year 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.
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,59 +0,0 @@
|
|||||||
INSTALL
|
|
||||||
Makefile.am
|
|
||||||
Makefile.in
|
|
||||||
aclocal.m4
|
|
||||||
bootstrap
|
|
||||||
config.hin
|
|
||||||
config/
|
|
||||||
configure
|
|
||||||
configure.ac
|
|
||||||
doc/Makefile.am
|
|
||||||
doc/Makefile.in
|
|
||||||
doc/diagmeet.note
|
|
||||||
exgettext
|
|
||||||
lib/Makefile.am
|
|
||||||
lib/Makefile.in
|
|
||||||
lib/alloca.c
|
|
||||||
lib/alloca_.h
|
|
||||||
lib/dirname.c
|
|
||||||
lib/fnmatch.c
|
|
||||||
lib/fnmatch_.h
|
|
||||||
lib/fnmatch_loop.c
|
|
||||||
lib/getopt.c
|
|
||||||
lib/getopt1.c
|
|
||||||
lib/getopt_int.h
|
|
||||||
lib/gettimeofday.c
|
|
||||||
lib/imaxtostr.c
|
|
||||||
lib/inttostr.c
|
|
||||||
lib/malloc.c
|
|
||||||
lib/mkstemp.c
|
|
||||||
lib/offtostr.c
|
|
||||||
lib/posix/Makefile.in
|
|
||||||
lib/realloc.c
|
|
||||||
lib/regex.c
|
|
||||||
lib/regex.h
|
|
||||||
lib/setmode.c
|
|
||||||
lib/stdbool_.h
|
|
||||||
lib/strcasecmp.c
|
|
||||||
lib/stripslash.c
|
|
||||||
lib/strncasecmp.c
|
|
||||||
lib/strtol.c
|
|
||||||
lib/strtoll.c
|
|
||||||
lib/strtoul.c
|
|
||||||
lib/strtoull.c
|
|
||||||
lib/tempname.c
|
|
||||||
lib/time_r.c
|
|
||||||
lib/time_r.h
|
|
||||||
lib/umaxtostr.c
|
|
||||||
lib/waitpid.c
|
|
||||||
lib/xstrdup.c
|
|
||||||
lib/xstrtol.c
|
|
||||||
lib/xstrtoul.c
|
|
||||||
lib/xstrtoumax.c
|
|
||||||
m4/
|
|
||||||
man/Makefile.am
|
|
||||||
man/Makefile.in
|
|
||||||
ms/
|
|
||||||
po/
|
|
||||||
src/Makefile.am
|
|
||||||
src/Makefile.in
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
Import of GNU diff 2.8.7
|
|
||||||
|
|
||||||
Original source available as ftp://alpha.gnu.org/pub/gnu/diffutils/diffutils-2.8.7.tar.gz
|
|
||||||
|
|
||||||
Removed files are listed in FREEBSD-Xlist.
|
|
||||||
@@ -1,244 +0,0 @@
|
|||||||
Version 2.8.7 contains no user-visible changes.
|
|
||||||
|
|
||||||
User-visible changes in version 2.8.6:
|
|
||||||
|
|
||||||
* New diff3 option --strip-trailing-cr.
|
|
||||||
|
|
||||||
* With -N and -P, inaccessible empty regular files (the kind of files
|
|
||||||
that 'patch' creates to indicate nonexistent backups) are now
|
|
||||||
treated as nonexistent when they are in the 'backup' file position.
|
|
||||||
|
|
||||||
* If multiple SKIP values are given to cmp, e.g., `cmp -i 10 -i 20',
|
|
||||||
cmp now uses the maximal value instead of the last one.
|
|
||||||
|
|
||||||
* diff now omits the ".000000000" on hosts that do not support
|
|
||||||
fractional time stamps.
|
|
||||||
|
|
||||||
Version 2.8.5 was not publicly released.
|
|
||||||
|
|
||||||
User-visible changes in version 2.8.4:
|
|
||||||
|
|
||||||
* Diff now simply prints "Files A and B differ" instead of "Binary
|
|
||||||
files A and B differ". The message is output if either A or B
|
|
||||||
appears to be a binary file, and the old wording was misleading
|
|
||||||
because it implied that both files are binary, which is not
|
|
||||||
necessarily the case.
|
|
||||||
|
|
||||||
User-visible changes in version 2.8.3:
|
|
||||||
|
|
||||||
* New locale: en_US.
|
|
||||||
|
|
||||||
User-visible changes in version 2.8.2:
|
|
||||||
|
|
||||||
* New diff and sdiff option:
|
|
||||||
--tabsize=COLUMNS
|
|
||||||
* If --ignore-space-change or --ignore-all-space is also specified,
|
|
||||||
--ignore-blank-lines now considers lines to be empty if they contain
|
|
||||||
only white space.
|
|
||||||
* More platforms now handle multibyte characters correctly when
|
|
||||||
excluding files by name (diff -x and -X).
|
|
||||||
* New locales: hu, pt_BR.
|
|
||||||
|
|
||||||
User-visible changes in version 2.8.1:
|
|
||||||
|
|
||||||
* Documentation fixes.
|
|
||||||
|
|
||||||
User-visible changes in version 2.8:
|
|
||||||
|
|
||||||
* cmp and diff now conform to POSIX 1003.1-2001 (IEEE Std 1003.1-2001)
|
|
||||||
if the underlying system conforms to POSIX and if the _POSIX2_VERSION
|
|
||||||
environment variable is set to 200112. Conformance removes support
|
|
||||||
for `diff -NUM', where NUM is a number. Use -C NUM or -U NUM instead.
|
|
||||||
* cmp now supports trailing operands SKIP1 and SKIP2, like BSD cmp.
|
|
||||||
* cmp -i or --ignore-initial now accepts SKIP1:SKIP2 option value.
|
|
||||||
* New cmp option: -n or --bytes.
|
|
||||||
* cmp's old -c or --print-chars option has been renamed;
|
|
||||||
use -b or --print-bytes instead.
|
|
||||||
* cmp now outputs "byte" rather than "char" outside the POSIX locale.
|
|
||||||
* cmp -l's index column width now adjusts to fit larger (or smaller) files.
|
|
||||||
* cmp -l -s and cmp -s -l are not allowed. Use cmp -s or cmp -l instead.
|
|
||||||
* diff uses ISO 8601 style time stamps for output times (e.g. "2001-11-23
|
|
||||||
16:44:36.875702460 -0800") unless in the C or POSIX locale and the
|
|
||||||
-c style is specified.
|
|
||||||
* diff's -I and -F options use the regexp syntax of grep, not of Emacs.
|
|
||||||
* diff now accepts multiple context arguments, and uses their maximum value.
|
|
||||||
* New diff and sdiff options:
|
|
||||||
-E --ignore-tab-expansion
|
|
||||||
--strip-trailing-cr
|
|
||||||
* New diff options:
|
|
||||||
--from-file=FILE, --to-file=FILE
|
|
||||||
--ignore-file-name-case
|
|
||||||
--no-ignore-file-name-case
|
|
||||||
* New diff3 and sdiff option:
|
|
||||||
--diff-program=PROGRAM
|
|
||||||
* The following diff options are still accepted, but are no longer documented.
|
|
||||||
They may be withdrawn in future releases.
|
|
||||||
-h (omit; it has no effect)
|
|
||||||
-H (use --speed-large-files instead)
|
|
||||||
-L (use --label instead)
|
|
||||||
-P (use --unidirectional-new-file instead)
|
|
||||||
--inhibit-hunk-merge (omit; it has no effect)
|
|
||||||
* Recursive diffs now sort file names according to the LC_COLLATE locale
|
|
||||||
category if possible, instead of using native byte comparison.
|
|
||||||
* Recursive diffs now detect and report directory loops.
|
|
||||||
* Diff printf specs can now use the "0" and "'" flags.
|
|
||||||
* The new sdiff interactive command `ed' precedes each version with a header.
|
|
||||||
* On 64-bit hosts, files larger than 2 GB can be compared.
|
|
||||||
* Some internationalization support has been added, but multibyte locales
|
|
||||||
are still not completely supported yet.
|
|
||||||
* Some diagnostics have been reworded slightly for consistency.
|
|
||||||
Also, `diff -D FOO' now outputs `/* ! FOO */' instead of `/* not FOO */'.
|
|
||||||
* The `patch' part of the manual now describes `patch' version 2.5.4.
|
|
||||||
* Man pages are now distributed and installed.
|
|
||||||
* There is support for DJGPP; see the 'ms' subdirectory and the files
|
|
||||||
m4/dos.m4 and */setmode.*.
|
|
||||||
|
|
||||||
|
|
||||||
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 1003.2-1992 (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.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Copyright (C) 1993, 1994, 1998, 2001, 2002, 2004 Free Software
|
|
||||||
Foundation, Inc.
|
|
||||||
|
|
||||||
This file is part of GNU Diffutils.
|
|
||||||
|
|
||||||
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 they will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; see the file COPYING. If not, write to
|
|
||||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
||||||
Boston, MA 02111-1307, USA.
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
README for GNU DIFF
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
Please see the file COPYING for copying conditions.
|
|
||||||
|
|
||||||
Please see the file doc/version.texi for version information.
|
|
||||||
|
|
||||||
Please see the file doc/diff.texi (or doc/diff.info) for documentation
|
|
||||||
that can be printed with TeX, or read with the `info' program or with
|
|
||||||
Emacs's `M-x info'. Brief man pages are in man/*, but they are no
|
|
||||||
substitute for the documentation.
|
|
||||||
|
|
||||||
Please see the file ABOUT-NLS for notes about translations.
|
|
||||||
|
|
||||||
Please see the file INSTALL for generic compilation and installation
|
|
||||||
instructions. Briefly, you can run "./configure; make install". The
|
|
||||||
command "./configure --help" lists the supported --enable and --with
|
|
||||||
options.
|
|
||||||
|
|
||||||
If you have a problem with internationalization, you might be able to
|
|
||||||
work around it as described in ABOUT-NLS by invoking `./configure
|
|
||||||
--disable-nls'. Many of the problems arise from dynamic linking
|
|
||||||
issues on non-GNU platforms (e.g. with the iconv library). Such
|
|
||||||
problems tend to be shared by other GNU applications on these
|
|
||||||
platforms, and can usually be fixed by carefully tweaking your non-GNU
|
|
||||||
installation. If you have an older version of libiconv, please
|
|
||||||
upgrade to the latest one; see <ftp://ftp.gnu.org/gnu/libiconv/>. If
|
|
||||||
the problem seems isolated to diffutils, though, please report a bug.
|
|
||||||
|
|
||||||
This program requires a Standard C compiler (C89 or later). If you
|
|
||||||
have a nonstandard compiler, please install GCC first.
|
|
||||||
|
|
||||||
If you make changes to the source code, you may need appropriate
|
|
||||||
versions of GNU build tools to regenerate the intermediate files. The
|
|
||||||
following versions were used to generate the intermediate files in
|
|
||||||
this distribution:
|
|
||||||
|
|
||||||
* Autoconf 2.59 <ftp://ftp.gnu.org/gnu/autoconf/autoconf-2.59.tar.gz>
|
|
||||||
* Automake 1.8.3 <ftp://ftp.gnu.org/gnu/automake/automake-1.8.3.tar.gz>
|
|
||||||
* gettext 0.14.1 <ftp://ftp.gnu.org/gnu/gettext/gettext-0.14.1.tar.gz>
|
|
||||||
* help2man 1.33 <ftp://ftp.gnu.org/gnu/help2man/help2man-1.33.1.tar.gz>
|
|
||||||
* Texinfo 4.7 <ftp://ftp.gnu.org/gnu/texinfo/texinfo-4.7.tar.gz>
|
|
||||||
|
|
||||||
Please report bugs to <bug-gnu-utils@gnu.org>.
|
|
||||||
|
|
||||||
-----
|
|
||||||
|
|
||||||
Copyright (C) 1992, 1998, 2001, 2002, 2004 Free Software Foundation,
|
|
||||||
Inc.
|
|
||||||
|
|
||||||
This file is part of GNU Diffutils.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; see the file COPYING. If not, write to
|
|
||||||
the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
||||||
Boston, MA 02111-1307, USA.
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
Thanks to all the following for their contributions to GNU diffutils:
|
|
||||||
|
|
||||||
Thomas Bushnell <tb@becket.net>
|
|
||||||
Wayne Davison <wayned@users.sourceforge.net>
|
|
||||||
Ulrich Drepper <drepper@redhat.com>
|
|
||||||
Paul Eggert <eggert@twinsun.com>
|
|
||||||
Jay Fenlason <hack@gnu.org>
|
|
||||||
John Gilmore <gnu@cygnus.com>
|
|
||||||
Torbjorn Granlund <tege@swox.com>
|
|
||||||
Mike Haertel <mike@ichips.intel.com>
|
|
||||||
Bruno Haible <haible@ilog.fr>
|
|
||||||
Chris Hanson <cph@gnu.org>
|
|
||||||
Jim Kingdon <kingdon@panix.com>
|
|
||||||
Tom Lord <lord@gnu.org>
|
|
||||||
David J. MacKenzie <djm@gnu.org>
|
|
||||||
Roland McGrath <roland@gnu.org>
|
|
||||||
Jim Meyering <meyering@lucent.com>
|
|
||||||
Eugene W. Myers <gene@cs.arizona.edu>
|
|
||||||
Randy Smith <randy@gnu.org>
|
|
||||||
Richard Stallman <rms@gnu.org>
|
|
||||||
Leonard H. Tower Jr. <tower@ai.mit.edu>
|
|
||||||
Eli Zaretskii <eliz@is.elta.co.il>
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
Add --include option (opposite of --exclude).
|
|
||||||
@@ -1,573 +0,0 @@
|
|||||||
/* config.h. Generated by configure. */
|
|
||||||
/* config.hin. Generated from configure.ac by autoheader. */
|
|
||||||
|
|
||||||
/* $FreeBSD$ */
|
|
||||||
|
|
||||||
/* Define to 1 if the `closedir' function returns void instead of `int'. */
|
|
||||||
/* #undef CLOSEDIR_VOID */
|
|
||||||
|
|
||||||
/* 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 to 1 if using `alloca.c'. */
|
|
||||||
/* #undef C_ALLOCA */
|
|
||||||
|
|
||||||
/* Name of editor program, unless overridden. */
|
|
||||||
#define DEFAULT_EDITOR_PROGRAM "/usr/bin/vi"
|
|
||||||
|
|
||||||
/* Define the default level of POSIX conformance. The value is of the form
|
|
||||||
YYYYMM, specifying the year and month the standard was adopted. If not
|
|
||||||
defined here, it defaults to the value of _POSIX2_VERSION in <unistd.h>.
|
|
||||||
Define to 199209 to default to POSIX 1003.2-1992, which makes standard
|
|
||||||
programs like `head', `tail', and `sort' accept obsolete options like `+10'
|
|
||||||
and `-10'. Define to 200112 to default to POSIX 1003.1-2001, which makes
|
|
||||||
these standard programs treat leading-`+' operands as file names and
|
|
||||||
require modern usages like `-n 10' instead of `-10'. Whether defined here
|
|
||||||
or not, the default can be overridden at run time via the _POSIX2_VERSION
|
|
||||||
environment variable. */
|
|
||||||
/* #undef DEFAULT_POSIX2_VERSION */
|
|
||||||
|
|
||||||
/* Define to 1 if translation of program messages to the user's native
|
|
||||||
language is requested. */
|
|
||||||
#define ENABLE_NLS 0
|
|
||||||
|
|
||||||
/* Define on systems for which file names may have a so-called `drive letter'
|
|
||||||
prefix, define this to compute the length of that prefix, including the
|
|
||||||
colon. */
|
|
||||||
#define FILESYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX 0
|
|
||||||
|
|
||||||
/* Define if the backslash character may also serve as a file name component
|
|
||||||
separator. */
|
|
||||||
#define FILESYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR 0
|
|
||||||
|
|
||||||
#if FILESYSTEM_ACCEPTS_DRIVE_LETTER_PREFIX
|
|
||||||
# define FILESYSTEM_PREFIX_LEN(Filename) \
|
|
||||||
((Filename)[0] && (Filename)[1] == ':' ? 2 : 0)
|
|
||||||
#else
|
|
||||||
# define FILESYSTEM_PREFIX_LEN(Filename) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Define if gettimeofday clobbers localtime's static buffer. */
|
|
||||||
/* #undef GETTIMEOFDAY_CLOBBERS_LOCALTIME_BUFFER */
|
|
||||||
|
|
||||||
/* Define to 1 if you have `alloca', as a function or macro. */
|
|
||||||
#define HAVE_ALLOCA 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
|
|
||||||
*/
|
|
||||||
/* #undef HAVE_ALLOCA_H */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `btowc' function. */
|
|
||||||
#define HAVE_BTOWC 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `clock_gettime' function. */
|
|
||||||
#define HAVE_CLOCK_GETTIME 1
|
|
||||||
|
|
||||||
/* Define to 1 if C supports variable-length arrays. */
|
|
||||||
#define HAVE_C_VARARRAYS 1
|
|
||||||
|
|
||||||
/* Define if the GNU dcgettext() function is already present or preinstalled.
|
|
||||||
*/
|
|
||||||
/* #undef HAVE_DCGETTEXT */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `clearerr_unlocked', and to 0 if
|
|
||||||
you don't. */
|
|
||||||
#define HAVE_DECL_CLEARERR_UNLOCKED 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `feof_unlocked', and to 0 if you
|
|
||||||
don't. */
|
|
||||||
#define HAVE_DECL_FEOF_UNLOCKED 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `ferror_unlocked', and to 0 if
|
|
||||||
you don't. */
|
|
||||||
#define HAVE_DECL_FERROR_UNLOCKED 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `fflush_unlocked', and to 0 if
|
|
||||||
you don't. */
|
|
||||||
#define HAVE_DECL_FFLUSH_UNLOCKED 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `fgets_unlocked', and to 0 if
|
|
||||||
you don't. */
|
|
||||||
#define HAVE_DECL_FGETS_UNLOCKED 0
|
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `fputc_unlocked', and to 0 if
|
|
||||||
you don't. */
|
|
||||||
#define HAVE_DECL_FPUTC_UNLOCKED 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `fputs_unlocked', and to 0 if
|
|
||||||
you don't. */
|
|
||||||
#define HAVE_DECL_FPUTS_UNLOCKED 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `fread_unlocked', and to 0 if
|
|
||||||
you don't. */
|
|
||||||
#define HAVE_DECL_FREAD_UNLOCKED 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `fwrite_unlocked', and to 0 if
|
|
||||||
you don't. */
|
|
||||||
#define HAVE_DECL_FWRITE_UNLOCKED 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `getchar_unlocked', and to 0 if
|
|
||||||
you don't. */
|
|
||||||
#define HAVE_DECL_GETCHAR_UNLOCKED 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `getcontext', and to 0 if you
|
|
||||||
don't. */
|
|
||||||
#define HAVE_DECL_GETCONTEXT 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you
|
|
||||||
don't. */
|
|
||||||
#define HAVE_DECL_GETC_UNLOCKED 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `getenv', and to 0 if you don't.
|
|
||||||
*/
|
|
||||||
#define HAVE_DECL_GETENV 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `putchar_unlocked', and to 0 if
|
|
||||||
you don't. */
|
|
||||||
#define HAVE_DECL_PUTCHAR_UNLOCKED 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `putc_unlocked', and to 0 if you
|
|
||||||
don't. */
|
|
||||||
#define HAVE_DECL_PUTC_UNLOCKED 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `sigaltstack', and to 0 if you
|
|
||||||
don't. */
|
|
||||||
#define HAVE_DECL_SIGALTSTACK 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you
|
|
||||||
don't. */
|
|
||||||
#define HAVE_DECL_STRERROR_R 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `strtoimax', and to 0 if you
|
|
||||||
don't. */
|
|
||||||
#define HAVE_DECL_STRTOIMAX 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `strtoll', and to 0 if you
|
|
||||||
don't. */
|
|
||||||
#define HAVE_DECL_STRTOLL 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `strtoull', and to 0 if you
|
|
||||||
don't. */
|
|
||||||
#define HAVE_DECL_STRTOULL 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the declaration of `strtoumax', and to 0 if you
|
|
||||||
don't. */
|
|
||||||
#define HAVE_DECL_STRTOUMAX 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
|
|
||||||
*/
|
|
||||||
#define HAVE_DIRENT_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `dup2' function. */
|
|
||||||
#define HAVE_DUP2 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
|
||||||
#define HAVE_FCNTL_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `fork' function. */
|
|
||||||
#define HAVE_FORK 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `getcontext' function. */
|
|
||||||
#define HAVE_GETCONTEXT 1
|
|
||||||
|
|
||||||
/* Define if the GNU gettext() function is already present or preinstalled. */
|
|
||||||
/* #undef HAVE_GETTEXT */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `gettimeofday' function. */
|
|
||||||
#define HAVE_GETTIMEOFDAY 1
|
|
||||||
|
|
||||||
/* Define if you have the iconv() function. */
|
|
||||||
/* #undef HAVE_ICONV */
|
|
||||||
|
|
||||||
/* Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>. */
|
|
||||||
#define HAVE_INTMAX_T 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
|
||||||
#define HAVE_INTTYPES_H 1
|
|
||||||
|
|
||||||
/* Define if <inttypes.h> exists, doesn't clash with <sys/types.h>, and
|
|
||||||
declares uintmax_t. */
|
|
||||||
#define HAVE_INTTYPES_H_WITH_UINTMAX 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `isascii' function. */
|
|
||||||
#define HAVE_ISASCII 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <locale.h> header file. */
|
|
||||||
#define HAVE_LOCALE_H 1
|
|
||||||
|
|
||||||
/* Define if you have the 'long long' type. */
|
|
||||||
#define HAVE_LONG_LONG 1
|
|
||||||
|
|
||||||
/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
|
|
||||||
to 0 otherwise. */
|
|
||||||
#define HAVE_MALLOC 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `mblen' function. */
|
|
||||||
#define HAVE_MBLEN 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `mbrlen' function. */
|
|
||||||
#define HAVE_MBRLEN 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `mbsrtowcs' function. */
|
|
||||||
#define HAVE_MBSRTOWCS 1
|
|
||||||
|
|
||||||
/* Define to 1 if <wchar.h> declares mbstate_t. */
|
|
||||||
#define HAVE_MBSTATE_T 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <memory.h> header file. */
|
|
||||||
#define HAVE_MEMORY_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `mempcpy' function. */
|
|
||||||
/* #undef HAVE_MEMPCPY */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `mkstemp' function. */
|
|
||||||
#define HAVE_MKSTEMP 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
|
|
||||||
/* #undef HAVE_NDIR_H */
|
|
||||||
|
|
||||||
/* Define to 1 if your system has a GNU libc compatible `realloc' function,
|
|
||||||
and to 0 otherwise. */
|
|
||||||
#define HAVE_REALLOC 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have run the test for working tzset. */
|
|
||||||
#define HAVE_RUN_TZSET_TEST 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `setlocale' function. */
|
|
||||||
#define HAVE_SETLOCALE 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the DOS-style `setmode' function. */
|
|
||||||
/* #undef HAVE_SETMODE_DOS */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `setrlimit' function. */
|
|
||||||
#define HAVE_SETRLIMIT 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `sigaction' function. */
|
|
||||||
#define HAVE_SIGACTION 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `sigaltstack' function. */
|
|
||||||
#define HAVE_SIGALTSTACK 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `sigprocmask' function. */
|
|
||||||
#define HAVE_SIGPROCMASK 1
|
|
||||||
|
|
||||||
/* Define to 1 if the system has the type `stack_t'. */
|
|
||||||
#define HAVE_STACK_T 1
|
|
||||||
|
|
||||||
/* Define to 1 if stdbool.h conforms to C99. */
|
|
||||||
#define HAVE_STDBOOL_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <stdint.h> header file. */
|
|
||||||
#define HAVE_STDINT_H 1
|
|
||||||
|
|
||||||
/* Define if <stdint.h> exists, doesn't clash with <sys/types.h>, and declares
|
|
||||||
uintmax_t. */
|
|
||||||
#define HAVE_STDINT_H_WITH_UINTMAX 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
|
||||||
#define HAVE_STDLIB_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `strcasecmp' function. */
|
|
||||||
#define HAVE_STRCASECMP 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `strcasecoll' function. */
|
|
||||||
/* #undef HAVE_STRCASECOLL */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `strerror_r' function. */
|
|
||||||
#define HAVE_STRERROR_R 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `strftime' function. */
|
|
||||||
#define HAVE_STRFTIME 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `stricoll' function. */
|
|
||||||
/* #undef HAVE_STRICOLL */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <strings.h> header file. */
|
|
||||||
#define HAVE_STRINGS_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <string.h> header file. */
|
|
||||||
#define HAVE_STRING_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `strncasecmp' function. */
|
|
||||||
#define HAVE_STRNCASECMP 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `strtoimax' function. */
|
|
||||||
#define HAVE_STRTOIMAX 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `strtol' function. */
|
|
||||||
#define HAVE_STRTOL 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `strtoll' function. */
|
|
||||||
#define HAVE_STRTOLL 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `strtoul' function. */
|
|
||||||
#define HAVE_STRTOUL 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `strtoull' function. */
|
|
||||||
#define HAVE_STRTOULL 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `strtoumax' function. */
|
|
||||||
#define HAVE_STRTOUMAX 1
|
|
||||||
|
|
||||||
/* Define to 1 if `sa_sigaction' is member of `struct sigaction'. */
|
|
||||||
#define HAVE_STRUCT_SIGACTION_SA_SIGACTION 1
|
|
||||||
|
|
||||||
/* Define to 1 if `st_blksize' is member of `struct stat'. */
|
|
||||||
#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
|
|
||||||
|
|
||||||
/* Define to 1 if `st_rdev' is member of `struct stat'. */
|
|
||||||
#define HAVE_STRUCT_STAT_ST_RDEV 1
|
|
||||||
|
|
||||||
/* Define to 1 if `tm_zone' is member of `struct tm'. */
|
|
||||||
#define HAVE_STRUCT_TM_TM_ZONE 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
|
|
||||||
*/
|
|
||||||
/* #undef HAVE_SYS_DIR_H */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/file.h> header file. */
|
|
||||||
#define HAVE_SYS_FILE_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
|
|
||||||
*/
|
|
||||||
/* #undef HAVE_SYS_NDIR_H */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/resource.h> header file. */
|
|
||||||
#define HAVE_SYS_RESOURCE_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
|
||||||
#define HAVE_SYS_STAT_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/time.h> header file. */
|
|
||||||
#define HAVE_SYS_TIME_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
|
||||||
#define HAVE_SYS_TYPES_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
|
|
||||||
#define HAVE_SYS_WAIT_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if localtime_r, etc. have the type signatures that POSIX
|
|
||||||
requires. */
|
|
||||||
#define HAVE_TIME_R_POSIX 1
|
|
||||||
|
|
||||||
/* Define if struct tm has the tm_gmtoff member. */
|
|
||||||
#define HAVE_TM_GMTOFF 1
|
|
||||||
|
|
||||||
/* Define to 1 if your `struct tm' has `tm_zone'. Deprecated, use
|
|
||||||
`HAVE_STRUCT_TM_TM_ZONE' instead. */
|
|
||||||
#define HAVE_TM_ZONE 1
|
|
||||||
|
|
||||||
/* Define to 1 if you don't have `tm_zone' but do have the external array
|
|
||||||
`tzname'. */
|
|
||||||
/* #undef HAVE_TZNAME */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `tzset' function. */
|
|
||||||
#define HAVE_TZSET 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <ucontext.h> header file. */
|
|
||||||
#define HAVE_UCONTEXT_H 1
|
|
||||||
|
|
||||||
/* Define if you have the 'uintmax_t' type in <stdint.h> or <inttypes.h>. */
|
|
||||||
#define HAVE_UINTMAX_T 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <unistd.h> header file. */
|
|
||||||
#define HAVE_UNISTD_H 1
|
|
||||||
|
|
||||||
/* Define if you have the 'unsigned long long' type. */
|
|
||||||
#define HAVE_UNSIGNED_LONG_LONG 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `vfork' function. */
|
|
||||||
#define HAVE_VFORK 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <vfork.h> header file. */
|
|
||||||
/* #undef HAVE_VFORK_H */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `waitpid' function. */
|
|
||||||
#define HAVE_WAITPID 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <wchar.h> header file. */
|
|
||||||
#define HAVE_WCHAR_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the <wctype.h> header file. */
|
|
||||||
#define HAVE_WCTYPE_H 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `wmempcpy' function. */
|
|
||||||
/* #undef HAVE_WMEMPCPY */
|
|
||||||
|
|
||||||
/* Define to 1 if `fork' works. */
|
|
||||||
#define HAVE_WORKING_FORK 1
|
|
||||||
|
|
||||||
/* Define to 1 if `vfork' works. */
|
|
||||||
#define HAVE_WORKING_VFORK 1
|
|
||||||
|
|
||||||
/* Define to 1 if extending the stack slightly past the limit causes a
|
|
||||||
SIGSEGV, and an alternate stack can be established with sigaltstack, and
|
|
||||||
the signal handler is passed a context that specifies the run time stack.
|
|
||||||
This behavior is defined by POSIX 1003.1-2001 with the X/Open System
|
|
||||||
Interface (XSI) option and is a standardized way to implement a SEGV-based
|
|
||||||
stack overflow detection heuristic. */
|
|
||||||
/* #undef HAVE_XSI_STACK_OVERFLOW_HEURISTIC */
|
|
||||||
|
|
||||||
/* Define to 1 if the system has the type `_Bool'. */
|
|
||||||
#define HAVE__BOOL 1
|
|
||||||
|
|
||||||
/* Define to 1 if you have the `__secure_getenv' function. */
|
|
||||||
/* #undef HAVE___SECURE_GETENV */
|
|
||||||
|
|
||||||
#if FILESYSTEM_BACKSLASH_IS_FILE_NAME_SEPARATOR
|
|
||||||
# define ISSLASH(C) ((C) == '/' || (C) == '\\')
|
|
||||||
#else
|
|
||||||
# define ISSLASH(C) ((C) == '/')
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Name of package */
|
|
||||||
#define PACKAGE "diffutils"
|
|
||||||
|
|
||||||
/* Define to the address where bug reports for this package should be sent. */
|
|
||||||
#define PACKAGE_BUGREPORT "bug-gnu-utils@gnu.org"
|
|
||||||
|
|
||||||
/* Define to the full name of this package. */
|
|
||||||
#define PACKAGE_NAME "GNU diffutils"
|
|
||||||
|
|
||||||
/* Define to the full name and version of this package. */
|
|
||||||
#define PACKAGE_STRING "GNU diffutils 2.8.7"
|
|
||||||
|
|
||||||
/* Define to the one symbol short name of this package. */
|
|
||||||
#define PACKAGE_TARNAME "diffutils"
|
|
||||||
|
|
||||||
/* Define to the version of this package. */
|
|
||||||
#define PACKAGE_VERSION "2.8.7"
|
|
||||||
|
|
||||||
/* Name of "pr" program. */
|
|
||||||
#define PR_PROGRAM "/usr/bin/pr"
|
|
||||||
|
|
||||||
/* Define to 1 to avoid alloca in the regular-expression implementation. */
|
|
||||||
#define REGEX_MALLOC 1
|
|
||||||
|
|
||||||
/* 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 to 1 if the `S_IS*' macros in <sys/stat.h> do not work properly. */
|
|
||||||
/* #undef STAT_MACROS_BROKEN */
|
|
||||||
|
|
||||||
/* Define to 1 if you have the ANSI C header files. */
|
|
||||||
#define STDC_HEADERS 1
|
|
||||||
|
|
||||||
/* Define to 1 if strerror_r returns char *. */
|
|
||||||
/* #undef STRERROR_R_CHAR_P */
|
|
||||||
|
|
||||||
/* Define to be the nanoseconds member of struct stat's st_mtim, if it exists.
|
|
||||||
*/
|
|
||||||
#define ST_MTIM_NSEC tv_nsec
|
|
||||||
|
|
||||||
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
|
|
||||||
#define TIME_WITH_SYS_TIME 1
|
|
||||||
|
|
||||||
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
|
|
||||||
/* #undef TM_IN_SYS_TIME */
|
|
||||||
|
|
||||||
/* Define if tzset clobbers localtime's static buffer. */
|
|
||||||
/* #undef TZSET_CLOBBERS_LOCALTIME_BUFFER */
|
|
||||||
|
|
||||||
/* Version number of package */
|
|
||||||
#define VERSION "2.8.7"
|
|
||||||
|
|
||||||
/* Define to 1 if on AIX 3.
|
|
||||||
System headers sometimes define this.
|
|
||||||
We just want to avoid a redefinition error message. */
|
|
||||||
#ifndef _ALL_SOURCE
|
|
||||||
/* # undef _ALL_SOURCE */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Number of bits in a file offset, on hosts where this is settable. */
|
|
||||||
/* #undef _FILE_OFFSET_BITS */
|
|
||||||
|
|
||||||
/* Enable GNU extensions on systems that have them. */
|
|
||||||
#ifndef _GNU_SOURCE
|
|
||||||
# define _GNU_SOURCE 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Define for large files, on AIX-style hosts. */
|
|
||||||
/* #undef _LARGE_FILES */
|
|
||||||
|
|
||||||
/* Define to 1 if on MINIX. */
|
|
||||||
/* #undef _MINIX */
|
|
||||||
|
|
||||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
|
||||||
this defined. */
|
|
||||||
/* #undef _POSIX_1_SOURCE */
|
|
||||||
|
|
||||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
|
||||||
/* #undef _POSIX_SOURCE */
|
|
||||||
|
|
||||||
/* Enable extensions on Solaris. */
|
|
||||||
#ifndef __EXTENSIONS__
|
|
||||||
# define __EXTENSIONS__ 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Define to empty if `const' does not conform to ANSI C. */
|
|
||||||
/* #undef const */
|
|
||||||
|
|
||||||
/* Define to a replacement function name for fnmatch(). */
|
|
||||||
/* #undef fnmatch */
|
|
||||||
|
|
||||||
/* Define to rpl_gettimeofday if the replacement function should be used. */
|
|
||||||
/* #undef gettimeofday */
|
|
||||||
|
|
||||||
/* Define to rpl_gmtime if the replacement function should be used. */
|
|
||||||
/* #undef gmtime */
|
|
||||||
|
|
||||||
/* Define to `__inline__' or `__inline' if that's what the C compiler
|
|
||||||
calls it, or to nothing if 'inline' is not supported under any name. */
|
|
||||||
#ifndef __cplusplus
|
|
||||||
/* #undef inline */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Define to long or long long if <inttypes.h> and <stdint.h> don't define. */
|
|
||||||
/* #undef intmax_t */
|
|
||||||
|
|
||||||
/* Define to rpl_localtime if the replacement function should be used. */
|
|
||||||
/* #undef localtime */
|
|
||||||
|
|
||||||
/* Define to rpl_malloc if the replacement function should be used. */
|
|
||||||
/* #undef malloc */
|
|
||||||
|
|
||||||
/* Define to a type if <wchar.h> does not define. */
|
|
||||||
/* #undef mbstate_t */
|
|
||||||
|
|
||||||
/* Define to rpl_mkstemp if the replacement function should be used. */
|
|
||||||
/* #undef mkstemp */
|
|
||||||
|
|
||||||
/* Define to the name of the strftime replacement function. */
|
|
||||||
#define my_strftime nstrftime
|
|
||||||
|
|
||||||
/* Define to `long' if <sys/types.h> does not define. */
|
|
||||||
/* #undef off_t */
|
|
||||||
|
|
||||||
/* Define to `int' if <sys/types.h> does not define. */
|
|
||||||
/* #undef pid_t */
|
|
||||||
|
|
||||||
/* Define to rpl_realloc if the replacement function should be used. */
|
|
||||||
/* #undef realloc */
|
|
||||||
|
|
||||||
/* Define to equivalent of C99 restrict keyword, or to nothing if this is not
|
|
||||||
supported. Do not define if restrict is supported directly. */
|
|
||||||
#define restrict __restrict
|
|
||||||
|
|
||||||
/* Define to rpl_tzset if the wrapper function should be used. */
|
|
||||||
/* #undef tzset */
|
|
||||||
|
|
||||||
/* Define to unsigned long or unsigned long long if <stdint.h> and
|
|
||||||
<inttypes.h> don't define. */
|
|
||||||
/* #undef uintmax_t */
|
|
||||||
|
|
||||||
/* Define as `fork' if `vfork' does not work. */
|
|
||||||
/* #undef vfork */
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,452 +0,0 @@
|
|||||||
|
|
||||||
@node GNU Free Documentation License
|
|
||||||
@appendixsec GNU Free Documentation License
|
|
||||||
|
|
||||||
@cindex FDL, GNU Free Documentation License
|
|
||||||
@center Version 1.2, November 2002
|
|
||||||
|
|
||||||
@display
|
|
||||||
Copyright @copyright{} 2000,2001,2002 Free Software Foundation, Inc.
|
|
||||||
59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
|
||||||
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
@end display
|
|
||||||
|
|
||||||
@enumerate 0
|
|
||||||
@item
|
|
||||||
PREAMBLE
|
|
||||||
|
|
||||||
The purpose of this License is to make a manual, textbook, or other
|
|
||||||
functional and useful document @dfn{free} in the sense of freedom: to
|
|
||||||
assure everyone the effective freedom to copy and redistribute it,
|
|
||||||
with or without modifying it, either commercially or noncommercially.
|
|
||||||
Secondarily, this License preserves for the author and publisher a way
|
|
||||||
to get credit for their work, while not being considered responsible
|
|
||||||
for modifications made by others.
|
|
||||||
|
|
||||||
This License is a kind of ``copyleft'', which means that derivative
|
|
||||||
works of the document must themselves be free in the same sense. It
|
|
||||||
complements the GNU General Public License, which is a copyleft
|
|
||||||
license designed for free software.
|
|
||||||
|
|
||||||
We have designed this License in order to use it for manuals for free
|
|
||||||
software, because free software needs free documentation: a free
|
|
||||||
program should come with manuals providing the same freedoms that the
|
|
||||||
software does. But this License is not limited to software manuals;
|
|
||||||
it can be used for any textual work, regardless of subject matter or
|
|
||||||
whether it is published as a printed book. We recommend this License
|
|
||||||
principally for works whose purpose is instruction or reference.
|
|
||||||
|
|
||||||
@item
|
|
||||||
APPLICABILITY AND DEFINITIONS
|
|
||||||
|
|
||||||
This License applies to any manual or other work, in any medium, that
|
|
||||||
contains a notice placed by the copyright holder saying it can be
|
|
||||||
distributed under the terms of this License. Such a notice grants a
|
|
||||||
world-wide, royalty-free license, unlimited in duration, to use that
|
|
||||||
work under the conditions stated herein. The ``Document'', below,
|
|
||||||
refers to any such manual or work. Any member of the public is a
|
|
||||||
licensee, and is addressed as ``you''. You accept the license if you
|
|
||||||
copy, modify or distribute the work in a way requiring permission
|
|
||||||
under copyright law.
|
|
||||||
|
|
||||||
A ``Modified Version'' of the Document means any work containing the
|
|
||||||
Document or a portion of it, either copied verbatim, or with
|
|
||||||
modifications and/or translated into another language.
|
|
||||||
|
|
||||||
A ``Secondary Section'' is a named appendix or a front-matter section
|
|
||||||
of the Document that deals exclusively with the relationship of the
|
|
||||||
publishers or authors of the Document to the Document's overall
|
|
||||||
subject (or to related matters) and contains nothing that could fall
|
|
||||||
directly within that overall subject. (Thus, if the Document is in
|
|
||||||
part a textbook of mathematics, a Secondary Section may not explain
|
|
||||||
any mathematics.) The relationship could be a matter of historical
|
|
||||||
connection with the subject or with related matters, or of legal,
|
|
||||||
commercial, philosophical, ethical or political position regarding
|
|
||||||
them.
|
|
||||||
|
|
||||||
The ``Invariant Sections'' are certain Secondary Sections whose titles
|
|
||||||
are designated, as being those of Invariant Sections, in the notice
|
|
||||||
that says that the Document is released under this License. If a
|
|
||||||
section does not fit the above definition of Secondary then it is not
|
|
||||||
allowed to be designated as Invariant. The Document may contain zero
|
|
||||||
Invariant Sections. If the Document does not identify any Invariant
|
|
||||||
Sections then there are none.
|
|
||||||
|
|
||||||
The ``Cover Texts'' are certain short passages of text that are listed,
|
|
||||||
as Front-Cover Texts or Back-Cover Texts, in the notice that says that
|
|
||||||
the Document is released under this License. A Front-Cover Text may
|
|
||||||
be at most 5 words, and a Back-Cover Text may be at most 25 words.
|
|
||||||
|
|
||||||
A ``Transparent'' copy of the Document means a machine-readable copy,
|
|
||||||
represented in a format whose specification is available to the
|
|
||||||
general public, that is suitable for revising the document
|
|
||||||
straightforwardly with generic text editors or (for images composed of
|
|
||||||
pixels) generic paint programs or (for drawings) some widely available
|
|
||||||
drawing editor, and that is suitable for input to text formatters or
|
|
||||||
for automatic translation to a variety of formats suitable for input
|
|
||||||
to text formatters. A copy made in an otherwise Transparent file
|
|
||||||
format whose markup, or absence of markup, has been arranged to thwart
|
|
||||||
or discourage subsequent modification by readers is not Transparent.
|
|
||||||
An image format is not Transparent if used for any substantial amount
|
|
||||||
of text. A copy that is not ``Transparent'' is called ``Opaque''.
|
|
||||||
|
|
||||||
Examples of suitable formats for Transparent copies include plain
|
|
||||||
@sc{ascii} without markup, Texinfo input format, La@TeX{} input
|
|
||||||
format, @acronym{SGML} or @acronym{XML} using a publicly available
|
|
||||||
@acronym{DTD}, and standard-conforming simple @acronym{HTML},
|
|
||||||
PostScript or @acronym{PDF} designed for human modification. Examples
|
|
||||||
of transparent image formats include @acronym{PNG}, @acronym{XCF} and
|
|
||||||
@acronym{JPG}. Opaque formats include proprietary formats that can be
|
|
||||||
read and edited only by proprietary word processors, @acronym{SGML} or
|
|
||||||
@acronym{XML} for which the @acronym{DTD} and/or processing tools are
|
|
||||||
not generally available, and the machine-generated @acronym{HTML},
|
|
||||||
PostScript or @acronym{PDF} produced by some word processors for
|
|
||||||
output purposes only.
|
|
||||||
|
|
||||||
The ``Title Page'' means, for a printed book, the title page itself,
|
|
||||||
plus such following pages as are needed to hold, legibly, the material
|
|
||||||
this License requires to appear in the title page. For works in
|
|
||||||
formats which do not have any title page as such, ``Title Page'' means
|
|
||||||
the text near the most prominent appearance of the work's title,
|
|
||||||
preceding the beginning of the body of the text.
|
|
||||||
|
|
||||||
A section ``Entitled XYZ'' means a named subunit of the Document whose
|
|
||||||
title either is precisely XYZ or contains XYZ in parentheses following
|
|
||||||
text that translates XYZ in another language. (Here XYZ stands for a
|
|
||||||
specific section name mentioned below, such as ``Acknowledgements'',
|
|
||||||
``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title''
|
|
||||||
of such a section when you modify the Document means that it remains a
|
|
||||||
section ``Entitled XYZ'' according to this definition.
|
|
||||||
|
|
||||||
The Document may include Warranty Disclaimers next to the notice which
|
|
||||||
states that this License applies to the Document. These Warranty
|
|
||||||
Disclaimers are considered to be included by reference in this
|
|
||||||
License, but only as regards disclaiming warranties: any other
|
|
||||||
implication that these Warranty Disclaimers may have is void and has
|
|
||||||
no effect on the meaning of this License.
|
|
||||||
|
|
||||||
@item
|
|
||||||
VERBATIM COPYING
|
|
||||||
|
|
||||||
You may copy and distribute the Document in any medium, either
|
|
||||||
commercially or noncommercially, provided that this License, the
|
|
||||||
copyright notices, and the license notice saying this License applies
|
|
||||||
to the Document are reproduced in all copies, and that you add no other
|
|
||||||
conditions whatsoever to those of this License. You may not use
|
|
||||||
technical measures to obstruct or control the reading or further
|
|
||||||
copying of the copies you make or distribute. However, you may accept
|
|
||||||
compensation in exchange for copies. If you distribute a large enough
|
|
||||||
number of copies you must also follow the conditions in section 3.
|
|
||||||
|
|
||||||
You may also lend copies, under the same conditions stated above, and
|
|
||||||
you may publicly display copies.
|
|
||||||
|
|
||||||
@item
|
|
||||||
COPYING IN QUANTITY
|
|
||||||
|
|
||||||
If you publish printed copies (or copies in media that commonly have
|
|
||||||
printed covers) of the Document, numbering more than 100, and the
|
|
||||||
Document's license notice requires Cover Texts, you must enclose the
|
|
||||||
copies in covers that carry, clearly and legibly, all these Cover
|
|
||||||
Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
|
|
||||||
the back cover. Both covers must also clearly and legibly identify
|
|
||||||
you as the publisher of these copies. The front cover must present
|
|
||||||
the full title with all words of the title equally prominent and
|
|
||||||
visible. You may add other material on the covers in addition.
|
|
||||||
Copying with changes limited to the covers, as long as they preserve
|
|
||||||
the title of the Document and satisfy these conditions, can be treated
|
|
||||||
as verbatim copying in other respects.
|
|
||||||
|
|
||||||
If the required texts for either cover are too voluminous to fit
|
|
||||||
legibly, you should put the first ones listed (as many as fit
|
|
||||||
reasonably) on the actual cover, and continue the rest onto adjacent
|
|
||||||
pages.
|
|
||||||
|
|
||||||
If you publish or distribute Opaque copies of the Document numbering
|
|
||||||
more than 100, you must either include a machine-readable Transparent
|
|
||||||
copy along with each Opaque copy, or state in or with each Opaque copy
|
|
||||||
a computer-network location from which the general network-using
|
|
||||||
public has access to download using public-standard network protocols
|
|
||||||
a complete Transparent copy of the Document, free of added material.
|
|
||||||
If you use the latter option, you must take reasonably prudent steps,
|
|
||||||
when you begin distribution of Opaque copies in quantity, to ensure
|
|
||||||
that this Transparent copy will remain thus accessible at the stated
|
|
||||||
location until at least one year after the last time you distribute an
|
|
||||||
Opaque copy (directly or through your agents or retailers) of that
|
|
||||||
edition to the public.
|
|
||||||
|
|
||||||
It is requested, but not required, that you contact the authors of the
|
|
||||||
Document well before redistributing any large number of copies, to give
|
|
||||||
them a chance to provide you with an updated version of the Document.
|
|
||||||
|
|
||||||
@item
|
|
||||||
MODIFICATIONS
|
|
||||||
|
|
||||||
You may copy and distribute a Modified Version of the Document under
|
|
||||||
the conditions of sections 2 and 3 above, provided that you release
|
|
||||||
the Modified Version under precisely this License, with the Modified
|
|
||||||
Version filling the role of the Document, thus licensing distribution
|
|
||||||
and modification of the Modified Version to whoever possesses a copy
|
|
||||||
of it. In addition, you must do these things in the Modified Version:
|
|
||||||
|
|
||||||
@enumerate A
|
|
||||||
@item
|
|
||||||
Use in the Title Page (and on the covers, if any) a title distinct
|
|
||||||
from that of the Document, and from those of previous versions
|
|
||||||
(which should, if there were any, be listed in the History section
|
|
||||||
of the Document). You may use the same title as a previous version
|
|
||||||
if the original publisher of that version gives permission.
|
|
||||||
|
|
||||||
@item
|
|
||||||
List on the Title Page, as authors, one or more persons or entities
|
|
||||||
responsible for authorship of the modifications in the Modified
|
|
||||||
Version, together with at least five of the principal authors of the
|
|
||||||
Document (all of its principal authors, if it has fewer than five),
|
|
||||||
unless they release you from this requirement.
|
|
||||||
|
|
||||||
@item
|
|
||||||
State on the Title page the name of the publisher of the
|
|
||||||
Modified Version, as the publisher.
|
|
||||||
|
|
||||||
@item
|
|
||||||
Preserve all the copyright notices of the Document.
|
|
||||||
|
|
||||||
@item
|
|
||||||
Add an appropriate copyright notice for your modifications
|
|
||||||
adjacent to the other copyright notices.
|
|
||||||
|
|
||||||
@item
|
|
||||||
Include, immediately after the copyright notices, a license notice
|
|
||||||
giving the public permission to use the Modified Version under the
|
|
||||||
terms of this License, in the form shown in the Addendum below.
|
|
||||||
|
|
||||||
@item
|
|
||||||
Preserve in that license notice the full lists of Invariant Sections
|
|
||||||
and required Cover Texts given in the Document's license notice.
|
|
||||||
|
|
||||||
@item
|
|
||||||
Include an unaltered copy of this License.
|
|
||||||
|
|
||||||
@item
|
|
||||||
Preserve the section Entitled ``History'', Preserve its Title, and add
|
|
||||||
to it an item stating at least the title, year, new authors, and
|
|
||||||
publisher of the Modified Version as given on the Title Page. If
|
|
||||||
there is no section Entitled ``History'' in the Document, create one
|
|
||||||
stating the title, year, authors, and publisher of the Document as
|
|
||||||
given on its Title Page, then add an item describing the Modified
|
|
||||||
Version as stated in the previous sentence.
|
|
||||||
|
|
||||||
@item
|
|
||||||
Preserve the network location, if any, given in the Document for
|
|
||||||
public access to a Transparent copy of the Document, and likewise
|
|
||||||
the network locations given in the Document for previous versions
|
|
||||||
it was based on. These may be placed in the ``History'' section.
|
|
||||||
You may omit a network location for a work that was published at
|
|
||||||
least four years before the Document itself, or if the original
|
|
||||||
publisher of the version it refers to gives permission.
|
|
||||||
|
|
||||||
@item
|
|
||||||
For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve
|
|
||||||
the Title of the section, and preserve in the section all the
|
|
||||||
substance and tone of each of the contributor acknowledgements and/or
|
|
||||||
dedications given therein.
|
|
||||||
|
|
||||||
@item
|
|
||||||
Preserve all the Invariant Sections of the Document,
|
|
||||||
unaltered in their text and in their titles. Section numbers
|
|
||||||
or the equivalent are not considered part of the section titles.
|
|
||||||
|
|
||||||
@item
|
|
||||||
Delete any section Entitled ``Endorsements''. Such a section
|
|
||||||
may not be included in the Modified Version.
|
|
||||||
|
|
||||||
@item
|
|
||||||
Do not retitle any existing section to be Entitled ``Endorsements'' or
|
|
||||||
to conflict in title with any Invariant Section.
|
|
||||||
|
|
||||||
@item
|
|
||||||
Preserve any Warranty Disclaimers.
|
|
||||||
@end enumerate
|
|
||||||
|
|
||||||
If the Modified Version includes new front-matter sections or
|
|
||||||
appendices that qualify as Secondary Sections and contain no material
|
|
||||||
copied from the Document, you may at your option designate some or all
|
|
||||||
of these sections as invariant. To do this, add their titles to the
|
|
||||||
list of Invariant Sections in the Modified Version's license notice.
|
|
||||||
These titles must be distinct from any other section titles.
|
|
||||||
|
|
||||||
You may add a section Entitled ``Endorsements'', provided it contains
|
|
||||||
nothing but endorsements of your Modified Version by various
|
|
||||||
parties---for example, statements of peer review or that the text has
|
|
||||||
been approved by an organization as the authoritative definition of a
|
|
||||||
standard.
|
|
||||||
|
|
||||||
You may add a passage of up to five words as a Front-Cover Text, and a
|
|
||||||
passage of up to 25 words as a Back-Cover Text, to the end of the list
|
|
||||||
of Cover Texts in the Modified Version. Only one passage of
|
|
||||||
Front-Cover Text and one of Back-Cover Text may be added by (or
|
|
||||||
through arrangements made by) any one entity. If the Document already
|
|
||||||
includes a cover text for the same cover, previously added by you or
|
|
||||||
by arrangement made by the same entity you are acting on behalf of,
|
|
||||||
you may not add another; but you may replace the old one, on explicit
|
|
||||||
permission from the previous publisher that added the old one.
|
|
||||||
|
|
||||||
The author(s) and publisher(s) of the Document do not by this License
|
|
||||||
give permission to use their names for publicity for or to assert or
|
|
||||||
imply endorsement of any Modified Version.
|
|
||||||
|
|
||||||
@item
|
|
||||||
COMBINING DOCUMENTS
|
|
||||||
|
|
||||||
You may combine the Document with other documents released under this
|
|
||||||
License, under the terms defined in section 4 above for modified
|
|
||||||
versions, provided that you include in the combination all of the
|
|
||||||
Invariant Sections of all of the original documents, unmodified, and
|
|
||||||
list them all as Invariant Sections of your combined work in its
|
|
||||||
license notice, and that you preserve all their Warranty Disclaimers.
|
|
||||||
|
|
||||||
The combined work need only contain one copy of this License, and
|
|
||||||
multiple identical Invariant Sections may be replaced with a single
|
|
||||||
copy. If there are multiple Invariant Sections with the same name but
|
|
||||||
different contents, make the title of each such section unique by
|
|
||||||
adding at the end of it, in parentheses, the name of the original
|
|
||||||
author or publisher of that section if known, or else a unique number.
|
|
||||||
Make the same adjustment to the section titles in the list of
|
|
||||||
Invariant Sections in the license notice of the combined work.
|
|
||||||
|
|
||||||
In the combination, you must combine any sections Entitled ``History''
|
|
||||||
in the various original documents, forming one section Entitled
|
|
||||||
``History''; likewise combine any sections Entitled ``Acknowledgements'',
|
|
||||||
and any sections Entitled ``Dedications''. You must delete all
|
|
||||||
sections Entitled ``Endorsements.''
|
|
||||||
|
|
||||||
@item
|
|
||||||
COLLECTIONS OF DOCUMENTS
|
|
||||||
|
|
||||||
You may make a collection consisting of the Document and other documents
|
|
||||||
released under this License, and replace the individual copies of this
|
|
||||||
License in the various documents with a single copy that is included in
|
|
||||||
the collection, provided that you follow the rules of this License for
|
|
||||||
verbatim copying of each of the documents in all other respects.
|
|
||||||
|
|
||||||
You may extract a single document from such a collection, and distribute
|
|
||||||
it individually under this License, provided you insert a copy of this
|
|
||||||
License into the extracted document, and follow this License in all
|
|
||||||
other respects regarding verbatim copying of that document.
|
|
||||||
|
|
||||||
@item
|
|
||||||
AGGREGATION WITH INDEPENDENT WORKS
|
|
||||||
|
|
||||||
A compilation of the Document or its derivatives with other separate
|
|
||||||
and independent documents or works, in or on a volume of a storage or
|
|
||||||
distribution medium, is called an ``aggregate'' if the copyright
|
|
||||||
resulting from the compilation is not used to limit the legal rights
|
|
||||||
of the compilation's users beyond what the individual works permit.
|
|
||||||
When the Document is included in an aggregate, this License does not
|
|
||||||
apply to the other works in the aggregate which are not themselves
|
|
||||||
derivative works of the Document.
|
|
||||||
|
|
||||||
If the Cover Text requirement of section 3 is applicable to these
|
|
||||||
copies of the Document, then if the Document is less than one half of
|
|
||||||
the entire aggregate, the Document's Cover Texts may be placed on
|
|
||||||
covers that bracket the Document within the aggregate, or the
|
|
||||||
electronic equivalent of covers if the Document is in electronic form.
|
|
||||||
Otherwise they must appear on printed covers that bracket the whole
|
|
||||||
aggregate.
|
|
||||||
|
|
||||||
@item
|
|
||||||
TRANSLATION
|
|
||||||
|
|
||||||
Translation is considered a kind of modification, so you may
|
|
||||||
distribute translations of the Document under the terms of section 4.
|
|
||||||
Replacing Invariant Sections with translations requires special
|
|
||||||
permission from their copyright holders, but you may include
|
|
||||||
translations of some or all Invariant Sections in addition to the
|
|
||||||
original versions of these Invariant Sections. You may include a
|
|
||||||
translation of this License, and all the license notices in the
|
|
||||||
Document, and any Warranty Disclaimers, provided that you also include
|
|
||||||
the original English version of this License and the original versions
|
|
||||||
of those notices and disclaimers. In case of a disagreement between
|
|
||||||
the translation and the original version of this License or a notice
|
|
||||||
or disclaimer, the original version will prevail.
|
|
||||||
|
|
||||||
If a section in the Document is Entitled ``Acknowledgements'',
|
|
||||||
``Dedications'', or ``History'', the requirement (section 4) to Preserve
|
|
||||||
its Title (section 1) will typically require changing the actual
|
|
||||||
title.
|
|
||||||
|
|
||||||
@item
|
|
||||||
TERMINATION
|
|
||||||
|
|
||||||
You may not copy, modify, sublicense, or distribute the Document except
|
|
||||||
as expressly provided for under this License. Any other attempt to
|
|
||||||
copy, modify, sublicense or distribute the Document 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.
|
|
||||||
|
|
||||||
@item
|
|
||||||
FUTURE REVISIONS OF THIS LICENSE
|
|
||||||
|
|
||||||
The Free Software Foundation may publish new, revised versions
|
|
||||||
of the GNU Free Documentation 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. See
|
|
||||||
@uref{http://www.gnu.org/copyleft/}.
|
|
||||||
|
|
||||||
Each version of the License is given a distinguishing version number.
|
|
||||||
If the Document specifies that a particular numbered version of this
|
|
||||||
License ``or any later version'' applies to it, you have the option of
|
|
||||||
following the terms and conditions either of that specified version or
|
|
||||||
of any later version that has been published (not as a draft) by the
|
|
||||||
Free Software Foundation. If the Document does not specify a version
|
|
||||||
number of this License, you may choose any version ever published (not
|
|
||||||
as a draft) by the Free Software Foundation.
|
|
||||||
@end enumerate
|
|
||||||
|
|
||||||
@page
|
|
||||||
@appendixsubsec ADDENDUM: How to use this License for your documents
|
|
||||||
|
|
||||||
To use this License in a document you have written, include a copy of
|
|
||||||
the License in the document and put the following copyright and
|
|
||||||
license notices just after the title page:
|
|
||||||
|
|
||||||
@smallexample
|
|
||||||
@group
|
|
||||||
Copyright (C) @var{year} @var{your name}.
|
|
||||||
Permission is granted to copy, distribute and/or modify this document
|
|
||||||
under the terms of the GNU Free Documentation License, Version 1.2
|
|
||||||
or any later version published by the Free Software Foundation;
|
|
||||||
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
|
|
||||||
Texts. A copy of the license is included in the section entitled ``GNU
|
|
||||||
Free Documentation License''.
|
|
||||||
@end group
|
|
||||||
@end smallexample
|
|
||||||
|
|
||||||
If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
|
|
||||||
replace the ``with...Texts.'' line with this:
|
|
||||||
|
|
||||||
@smallexample
|
|
||||||
@group
|
|
||||||
with the Invariant Sections being @var{list their titles}, with
|
|
||||||
the Front-Cover Texts being @var{list}, and with the Back-Cover Texts
|
|
||||||
being @var{list}.
|
|
||||||
@end group
|
|
||||||
@end smallexample
|
|
||||||
|
|
||||||
If you have Invariant Sections without Cover Texts, or some other
|
|
||||||
combination of the three, merge those two alternatives to suit the
|
|
||||||
situation.
|
|
||||||
|
|
||||||
If your document contains nontrivial examples of program code, we
|
|
||||||
recommend releasing these examples in parallel under your choice of
|
|
||||||
free software license, such as the GNU General Public License,
|
|
||||||
to permit their use in free software.
|
|
||||||
|
|
||||||
@c Local Variables:
|
|
||||||
@c ispell-local-pdict: "ispell-dict"
|
|
||||||
@c End:
|
|
||||||
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
@set UPDATED 12 April 2004
|
|
||||||
@set UPDATED-MONTH April 2004
|
|
||||||
@set EDITION 2.8.7
|
|
||||||
@set VERSION 2.8.7
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
@set UPDATED 12 April 2004
|
|
||||||
@set UPDATED-MONTH April 2004
|
|
||||||
@set EDITION 2.8.7
|
|
||||||
@set VERSION 2.8.7
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
/* basename.c -- return the last element in a path
|
|
||||||
|
|
||||||
Copyright (C) 1990, 1998, 1999, 2000, 2001, 2003 Free Software
|
|
||||||
Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "dirname.h"
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* In general, we can't use the builtin `basename' function if available,
|
|
||||||
since it has different meanings in different environments.
|
|
||||||
In some environments the builtin `basename' modifies its argument.
|
|
||||||
|
|
||||||
Return the address of the last file name component of NAME. If
|
|
||||||
NAME has no file name components because it is all slashes, return
|
|
||||||
NAME if it is empty, the address of its last slash otherwise. */
|
|
||||||
|
|
||||||
char *
|
|
||||||
base_name (char const *name)
|
|
||||||
{
|
|
||||||
char const *base = name + FILESYSTEM_PREFIX_LEN (name);
|
|
||||||
char const *p;
|
|
||||||
|
|
||||||
for (p = base; *p; p++)
|
|
||||||
{
|
|
||||||
if (ISSLASH (*p))
|
|
||||||
{
|
|
||||||
/* Treat multiple adjacent slashes like a single slash. */
|
|
||||||
do p++;
|
|
||||||
while (ISSLASH (*p));
|
|
||||||
|
|
||||||
/* If the file name ends in slash, use the trailing slash as
|
|
||||||
the basename if no non-slashes have been found. */
|
|
||||||
if (! *p)
|
|
||||||
{
|
|
||||||
if (ISSLASH (*base))
|
|
||||||
base = p - 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* *P is a non-slash preceded by a slash. */
|
|
||||||
base = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (char *) base;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the length of of the basename NAME. Typically NAME is the
|
|
||||||
value returned by base_name. Act like strlen (NAME), except omit
|
|
||||||
redundant trailing slashes. */
|
|
||||||
|
|
||||||
size_t
|
|
||||||
base_len (char const *name)
|
|
||||||
{
|
|
||||||
size_t len;
|
|
||||||
|
|
||||||
for (len = strlen (name); 1 < len && ISSLASH (name[len - 1]); len--)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
@@ -1,311 +0,0 @@
|
|||||||
/* Stack overflow handling.
|
|
||||||
|
|
||||||
Copyright (C) 2002, 2004 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
/* Written by Paul Eggert. */
|
|
||||||
|
|
||||||
/* NOTES:
|
|
||||||
|
|
||||||
A program that uses alloca, dynamic arrays, or large local
|
|
||||||
variables may extend the stack by more than a page at a time. If
|
|
||||||
so, when the stack overflows the operating system may not detect
|
|
||||||
the overflow until the program uses the array, and this module may
|
|
||||||
incorrectly report a program error instead of a stack overflow.
|
|
||||||
|
|
||||||
To avoid this problem, allocate only small objects on the stack; a
|
|
||||||
program should be OK if it limits single allocations to a page or
|
|
||||||
less. Allocate larger arrays in static storage, or on the heap
|
|
||||||
(e.g., with malloc). Yes, this is a pain, but we don't know of any
|
|
||||||
better solution that is portable.
|
|
||||||
|
|
||||||
No attempt has been made to deal with multithreaded applications. */
|
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef __attribute__
|
|
||||||
# if __GNUC__ < 3 || __STRICT_ANSI__
|
|
||||||
# define __attribute__(x)
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "gettext.h"
|
|
||||||
#define _(msgid) gettext (msgid)
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#ifndef ENOTSUP
|
|
||||||
# define ENOTSUP EINVAL
|
|
||||||
#endif
|
|
||||||
#ifndef EOVERFLOW
|
|
||||||
# define EOVERFLOW EINVAL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <signal.h>
|
|
||||||
#if ! HAVE_STACK_T && ! defined stack_t
|
|
||||||
typedef struct sigaltstack stack_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#if HAVE_SYS_RESOURCE_H
|
|
||||||
/* Include sys/time.h here, because...
|
|
||||||
SunOS-4.1.x <sys/resource.h> fails to include <sys/time.h>.
|
|
||||||
This gives "incomplete type" errors for ru_utime and tu_stime. */
|
|
||||||
# if HAVE_SYS_TIME_H
|
|
||||||
# include <sys/time.h>
|
|
||||||
# endif
|
|
||||||
# include <sys/resource.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_UCONTEXT_H
|
|
||||||
# include <ucontext.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_UNISTD_H
|
|
||||||
# include <unistd.h>
|
|
||||||
#endif
|
|
||||||
#ifndef STDERR_FILENO
|
|
||||||
# define STDERR_FILENO 2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
# include <stdio.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "c-stack.h"
|
|
||||||
#include "exitfail.h"
|
|
||||||
|
|
||||||
#if (HAVE_STRUCT_SIGACTION_SA_SIGACTION && defined SA_NODEFER \
|
|
||||||
&& defined SA_ONSTACK && defined SA_RESETHAND && defined SA_SIGINFO)
|
|
||||||
# define SIGACTION_WORKS 1
|
|
||||||
#else
|
|
||||||
# define SIGACTION_WORKS 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern char *program_name;
|
|
||||||
|
|
||||||
/* The user-specified action to take when a SEGV-related program error
|
|
||||||
or stack overflow occurs. */
|
|
||||||
static void (* volatile segv_action) (int);
|
|
||||||
|
|
||||||
/* Translated messages for program errors and stack overflow. Do not
|
|
||||||
translate them in the signal handler, since gettext is not
|
|
||||||
async-signal-safe. */
|
|
||||||
static char const * volatile program_error_message;
|
|
||||||
static char const * volatile stack_overflow_message;
|
|
||||||
|
|
||||||
/* Output an error message, then exit with status EXIT_FAILURE if it
|
|
||||||
appears to have been a stack overflow, or with a core dump
|
|
||||||
otherwise. This function is async-signal-safe. */
|
|
||||||
|
|
||||||
static void die (int) __attribute__ ((noreturn));
|
|
||||||
static void
|
|
||||||
die (int signo)
|
|
||||||
{
|
|
||||||
char const *message;
|
|
||||||
segv_action (signo);
|
|
||||||
message = signo ? program_error_message : stack_overflow_message;
|
|
||||||
write (STDERR_FILENO, program_name, strlen (program_name));
|
|
||||||
write (STDERR_FILENO, ": ", 2);
|
|
||||||
write (STDERR_FILENO, message, strlen (message));
|
|
||||||
write (STDERR_FILENO, "\n", 1);
|
|
||||||
if (! signo)
|
|
||||||
_exit (exit_failure);
|
|
||||||
kill (getpid (), signo);
|
|
||||||
abort ();
|
|
||||||
}
|
|
||||||
|
|
||||||
#if HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK
|
|
||||||
|
|
||||||
/* Direction of the C runtime stack. This function is
|
|
||||||
async-signal-safe. */
|
|
||||||
|
|
||||||
# if STACK_DIRECTION
|
|
||||||
# define find_stack_direction(ptr) STACK_DIRECTION
|
|
||||||
# else
|
|
||||||
static int
|
|
||||||
find_stack_direction (char const *addr)
|
|
||||||
{
|
|
||||||
char dummy;
|
|
||||||
return ! addr ? find_stack_direction (&dummy) : addr < &dummy ? 1 : -1;
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* Storage for the alternate signal stack. */
|
|
||||||
static union
|
|
||||||
{
|
|
||||||
char buffer[SIGSTKSZ];
|
|
||||||
|
|
||||||
/* These other members are for proper alignment. There's no
|
|
||||||
standard way to guarantee stack alignment, but this seems enough
|
|
||||||
in practice. */
|
|
||||||
long double ld;
|
|
||||||
long l;
|
|
||||||
void *p;
|
|
||||||
} alternate_signal_stack;
|
|
||||||
|
|
||||||
# if SIGACTION_WORKS
|
|
||||||
|
|
||||||
/* Handle a segmentation violation and exit. This function is
|
|
||||||
async-signal-safe. */
|
|
||||||
|
|
||||||
static void segv_handler (int, siginfo_t *, void *) __attribute__((noreturn));
|
|
||||||
static void
|
|
||||||
segv_handler (int signo, siginfo_t *info,
|
|
||||||
void *context __attribute__ ((unused)))
|
|
||||||
{
|
|
||||||
/* Clear SIGNO if it seems to have been a stack overflow. */
|
|
||||||
if (0 < info->si_code)
|
|
||||||
{
|
|
||||||
# if ! HAVE_XSI_STACK_OVERFLOW_HEURISTIC
|
|
||||||
/* We can't easily determine whether it is a stack overflow; so
|
|
||||||
assume that the rest of our program is perfect (!) and that
|
|
||||||
this segmentation violation is a stack overflow. */
|
|
||||||
signo = 0;
|
|
||||||
# else
|
|
||||||
/* If the faulting address is within the stack, or within one
|
|
||||||
page of the stack end, assume that it is a stack
|
|
||||||
overflow. */
|
|
||||||
ucontext_t const *user_context = context;
|
|
||||||
char const *stack_base = user_context->uc_stack.ss_sp;
|
|
||||||
size_t stack_size = user_context->uc_stack.ss_size;
|
|
||||||
char const *faulting_address = info->si_addr;
|
|
||||||
size_t s = faulting_address - stack_base;
|
|
||||||
size_t page_size = sysconf (_SC_PAGESIZE);
|
|
||||||
if (find_stack_direction (0) < 0)
|
|
||||||
s += page_size;
|
|
||||||
if (s < stack_size + page_size)
|
|
||||||
signo = 0;
|
|
||||||
|
|
||||||
# if DEBUG
|
|
||||||
{
|
|
||||||
char buf[1024];
|
|
||||||
sprintf (buf,
|
|
||||||
"segv_handler fault=%p base=%p size=%lx page=%lx signo=%d\n",
|
|
||||||
faulting_address, stack_base, (unsigned long) stack_size,
|
|
||||||
(unsigned long) page_size, signo);
|
|
||||||
write (STDERR_FILENO, buf, strlen (buf));
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
|
|
||||||
die (signo);
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
static void
|
|
||||||
null_action (int signo __attribute__ ((unused)))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set up ACTION so that it is invoked on C stack overflow. Return -1
|
|
||||||
(setting errno) if this cannot be done.
|
|
||||||
|
|
||||||
When ACTION is called, it is passed an argument equal to SIGSEGV
|
|
||||||
for a segmentation violation that does not appear related to stack
|
|
||||||
overflow, and is passed zero otherwise. On many platforms it is
|
|
||||||
hard to tell; when in doubt, zero is passed.
|
|
||||||
|
|
||||||
A null ACTION acts like an action that does nothing.
|
|
||||||
|
|
||||||
ACTION must be async-signal-safe. ACTION together with its callees
|
|
||||||
must not require more than SIGSTKSZ bytes of stack space. */
|
|
||||||
|
|
||||||
int
|
|
||||||
c_stack_action (void (*action) (int))
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
stack_t st;
|
|
||||||
st.ss_flags = 0;
|
|
||||||
st.ss_sp = alternate_signal_stack.buffer;
|
|
||||||
st.ss_size = sizeof alternate_signal_stack.buffer;
|
|
||||||
r = sigaltstack (&st, 0);
|
|
||||||
if (r != 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
segv_action = action ? action : null_action;
|
|
||||||
program_error_message = _("program error");
|
|
||||||
stack_overflow_message = _("stack overflow");
|
|
||||||
|
|
||||||
{
|
|
||||||
# if SIGACTION_WORKS
|
|
||||||
struct sigaction act;
|
|
||||||
sigemptyset (&act.sa_mask);
|
|
||||||
|
|
||||||
/* POSIX 1003.1-2001 says SA_RESETHAND implies SA_NODEFER, but
|
|
||||||
this is not true on Solaris 8 at least. It doesn't hurt to use
|
|
||||||
SA_NODEFER here, so leave it in. */
|
|
||||||
act.sa_flags = SA_NODEFER | SA_ONSTACK | SA_RESETHAND | SA_SIGINFO;
|
|
||||||
|
|
||||||
act.sa_sigaction = segv_handler;
|
|
||||||
|
|
||||||
return sigaction (SIGSEGV, &act, 0);
|
|
||||||
# else
|
|
||||||
return signal (SIGSEGV, die) == SIG_ERR ? -1 : 0;
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* ! (HAVE_SIGALTSTACK && HAVE_DECL_SIGALTSTACK) */
|
|
||||||
|
|
||||||
int
|
|
||||||
c_stack_action (void (*action) (int) __attribute__ ((unused)))
|
|
||||||
{
|
|
||||||
errno = ENOTSUP;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
|
|
||||||
int volatile exit_failure;
|
|
||||||
|
|
||||||
static long
|
|
||||||
recurse (char *p)
|
|
||||||
{
|
|
||||||
char array[500];
|
|
||||||
array[0] = 1;
|
|
||||||
return *p + recurse (array);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *program_name;
|
|
||||||
|
|
||||||
int
|
|
||||||
main (int argc __attribute__ ((unused)), char **argv)
|
|
||||||
{
|
|
||||||
program_name = argv[0];
|
|
||||||
fprintf (stderr,
|
|
||||||
"The last output line should contain \"stack overflow\".\n");
|
|
||||||
if (c_stack_action (0) == 0)
|
|
||||||
return recurse ("\1");
|
|
||||||
perror ("c_stack_action");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* DEBUG */
|
|
||||||
|
|
||||||
/*
|
|
||||||
Local Variables:
|
|
||||||
compile-command: "gcc -DDEBUG -DHAVE_CONFIG_H -I.. -g -O -Wall -W c-stack.c"
|
|
||||||
End:
|
|
||||||
*/
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
/* Stack overflow handling.
|
|
||||||
|
|
||||||
Copyright (C) 2002, 2004 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
int c_stack_action (void (*) (int));
|
|
||||||
@@ -1,147 +0,0 @@
|
|||||||
/* Buffer primitives for comparison operations.
|
|
||||||
|
|
||||||
Copyright (C) 1993, 1995, 1998, 2001, 2002 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; see the file COPYING.
|
|
||||||
If not, write to the Free Software Foundation,
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#include <signal.h>
|
|
||||||
#ifndef SA_RESTART
|
|
||||||
# ifdef SA_INTERRUPT /* e.g. SunOS 4.1.x */
|
|
||||||
# define SA_RESTART SA_INTERRUPT
|
|
||||||
# else
|
|
||||||
# define SA_RESTART 0
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_UNISTD_H
|
|
||||||
# include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_INTTYPES_H
|
|
||||||
# include <inttypes.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include "cmpbuf.h"
|
|
||||||
|
|
||||||
/* Determine whether an integer type is signed, and its bounds.
|
|
||||||
This code assumes two's (or one's!) complement with no holes. */
|
|
||||||
|
|
||||||
/* The extra casts work around common compiler bugs,
|
|
||||||
e.g. Cray C 5.0.3.0 when t == time_t. */
|
|
||||||
#ifndef TYPE_SIGNED
|
|
||||||
# define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
|
|
||||||
#endif
|
|
||||||
#ifndef TYPE_MINIMUM
|
|
||||||
# define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \
|
|
||||||
? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) \
|
|
||||||
: (t) 0))
|
|
||||||
#endif
|
|
||||||
#ifndef TYPE_MAXIMUM
|
|
||||||
# define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PTRDIFF_MAX
|
|
||||||
# define PTRDIFF_MAX TYPE_MAXIMUM (ptrdiff_t)
|
|
||||||
#endif
|
|
||||||
#ifndef SIZE_MAX
|
|
||||||
# define SIZE_MAX TYPE_MAXIMUM (size_t)
|
|
||||||
#endif
|
|
||||||
#ifndef SSIZE_MAX
|
|
||||||
# define SSIZE_MAX TYPE_MAXIMUM (ssize_t)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef MIN
|
|
||||||
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
|
|
||||||
|
|
||||||
/* Read NBYTES bytes from descriptor FD into BUF.
|
|
||||||
NBYTES must not be SIZE_MAX.
|
|
||||||
Return the number of characters successfully read.
|
|
||||||
On error, return SIZE_MAX, setting errno.
|
|
||||||
The number returned is always NBYTES unless end-of-file or error. */
|
|
||||||
|
|
||||||
size_t
|
|
||||||
block_read (int fd, char *buf, size_t nbytes)
|
|
||||||
{
|
|
||||||
char *bp = buf;
|
|
||||||
char const *buflim = buf + nbytes;
|
|
||||||
size_t readlim = SSIZE_MAX;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
size_t bytes_to_read = MIN (buflim - bp, readlim);
|
|
||||||
ssize_t nread = read (fd, bp, bytes_to_read);
|
|
||||||
if (nread <= 0)
|
|
||||||
{
|
|
||||||
if (nread == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Accommodate Tru64 5.1, which can't read more than INT_MAX
|
|
||||||
bytes at a time. They call that a 64-bit OS? */
|
|
||||||
if (errno == EINVAL && INT_MAX < bytes_to_read)
|
|
||||||
{
|
|
||||||
readlim = INT_MAX;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This is needed for programs that have signal handlers on
|
|
||||||
older hosts without SA_RESTART. It also accommodates
|
|
||||||
ancient AIX hosts that set errno to EINTR after uncaught
|
|
||||||
SIGCONT. See <news:1r77ojINN85n@ftp.UU.NET>
|
|
||||||
(1993-04-22). */
|
|
||||||
if (! SA_RESTART && errno == EINTR)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
return SIZE_MAX;
|
|
||||||
}
|
|
||||||
bp += nread;
|
|
||||||
}
|
|
||||||
while (bp < buflim);
|
|
||||||
|
|
||||||
return bp - buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Least common multiple of two buffer sizes A and B. However, if
|
|
||||||
either A or B is zero, or if the multiple is greater than LCM_MAX,
|
|
||||||
return a reasonable buffer size. */
|
|
||||||
|
|
||||||
size_t
|
|
||||||
buffer_lcm (size_t a, size_t b, size_t lcm_max)
|
|
||||||
{
|
|
||||||
size_t lcm, m, n, q, 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;
|
|
||||||
|
|
||||||
/* Yield a if there is an overflow. */
|
|
||||||
q = a / n;
|
|
||||||
lcm = q * b;
|
|
||||||
return lcm <= lcm_max && lcm / b == q ? lcm : a;
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
/* Buffer primitives for comparison operations.
|
|
||||||
|
|
||||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; see the file COPYING.
|
|
||||||
If not, write to the Free Software Foundation,
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
size_t block_read (int, char *, size_t);
|
|
||||||
size_t buffer_lcm (size_t, size_t, size_t);
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
/* Take file names apart into directory and base names.
|
|
||||||
|
|
||||||
Copyright (C) 1998, 2001, 2003 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#ifndef DIRNAME_H_
|
|
||||||
# define DIRNAME_H_ 1
|
|
||||||
|
|
||||||
# include <stddef.h>
|
|
||||||
|
|
||||||
# ifndef DIRECTORY_SEPARATOR
|
|
||||||
# define DIRECTORY_SEPARATOR '/'
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifndef ISSLASH
|
|
||||||
# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifndef FILESYSTEM_PREFIX_LEN
|
|
||||||
# define FILESYSTEM_PREFIX_LEN(Filename) 0
|
|
||||||
# endif
|
|
||||||
|
|
||||||
char *base_name (char const *path);
|
|
||||||
char *dir_name (char const *path);
|
|
||||||
size_t base_len (char const *path);
|
|
||||||
size_t dir_len (char const *path);
|
|
||||||
|
|
||||||
int strip_trailing_slashes (char *path);
|
|
||||||
|
|
||||||
#endif /* not DIRNAME_H_ */
|
|
||||||
@@ -1,310 +0,0 @@
|
|||||||
/* Error handler for noninteractive utilities
|
|
||||||
Copyright (C) 1990-1998, 2000-2002, 2003 Free Software Foundation, Inc.
|
|
||||||
This file is part of the GNU C Library.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
|
||||||
with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
/* Written by David MacKenzie <djm@gnu.ai.mit.edu>. */
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "error.h"
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#ifdef _LIBC
|
|
||||||
# include <libintl.h>
|
|
||||||
#else
|
|
||||||
# include "gettext.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _LIBC
|
|
||||||
# include <wchar.h>
|
|
||||||
# define mbsrtowcs __mbsrtowcs
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !_LIBC
|
|
||||||
# include "unlocked-io.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _
|
|
||||||
# define _(String) String
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* If NULL, error will flush stdout, then print on stderr the program
|
|
||||||
name, a colon and a space. Otherwise, error will call this
|
|
||||||
function without parameters instead. */
|
|
||||||
void (*error_print_progname) (void);
|
|
||||||
|
|
||||||
/* This variable is incremented each time `error' is called. */
|
|
||||||
unsigned int error_message_count;
|
|
||||||
|
|
||||||
#ifdef _LIBC
|
|
||||||
/* In the GNU C library, there is a predefined variable for this. */
|
|
||||||
|
|
||||||
# define program_name program_invocation_name
|
|
||||||
# include <errno.h>
|
|
||||||
# include <libio/libioP.h>
|
|
||||||
|
|
||||||
/* In GNU libc we want do not want to use the common name `error' directly.
|
|
||||||
Instead make it a weak alias. */
|
|
||||||
extern void __error (int status, int errnum, const char *message, ...)
|
|
||||||
__attribute__ ((__format__ (__printf__, 3, 4)));
|
|
||||||
extern void __error_at_line (int status, int errnum, const char *file_name,
|
|
||||||
unsigned int line_number, const char *message,
|
|
||||||
...)
|
|
||||||
__attribute__ ((__format__ (__printf__, 5, 6)));;
|
|
||||||
# define error __error
|
|
||||||
# define error_at_line __error_at_line
|
|
||||||
|
|
||||||
# include <libio/iolibio.h>
|
|
||||||
# define fflush(s) INTUSE(_IO_fflush) (s)
|
|
||||||
# undef putc
|
|
||||||
# define putc(c, fp) INTUSE(_IO_putc) (c, fp)
|
|
||||||
|
|
||||||
# include <bits/libc-lock.h>
|
|
||||||
|
|
||||||
#else /* not _LIBC */
|
|
||||||
|
|
||||||
# if !HAVE_DECL_STRERROR_R && STRERROR_R_CHAR_P
|
|
||||||
# ifndef HAVE_DECL_STRERROR_R
|
|
||||||
"this configure-time declaration test was not run"
|
|
||||||
# endif
|
|
||||||
char *strerror_r ();
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifndef SIZE_MAX
|
|
||||||
# define SIZE_MAX ((size_t) -1)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* The calling program should define program_name and set it to the
|
|
||||||
name of the executing program. */
|
|
||||||
extern char *program_name;
|
|
||||||
|
|
||||||
# if HAVE_STRERROR_R || defined strerror_r
|
|
||||||
# define __strerror_r strerror_r
|
|
||||||
# endif
|
|
||||||
#endif /* not _LIBC */
|
|
||||||
|
|
||||||
static void
|
|
||||||
print_errno_message (int errnum)
|
|
||||||
{
|
|
||||||
char const *s;
|
|
||||||
|
|
||||||
#if defined HAVE_STRERROR_R || _LIBC
|
|
||||||
char errbuf[1024];
|
|
||||||
# if STRERROR_R_CHAR_P || _LIBC
|
|
||||||
s = __strerror_r (errnum, errbuf, sizeof errbuf);
|
|
||||||
# else
|
|
||||||
if (__strerror_r (errnum, errbuf, sizeof errbuf) == 0)
|
|
||||||
s = errbuf;
|
|
||||||
else
|
|
||||||
s = 0;
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
s = strerror (errnum);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !_LIBC
|
|
||||||
if (! s)
|
|
||||||
s = _("Unknown system error");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if _LIBC
|
|
||||||
if (_IO_fwide (stderr, 0) > 0)
|
|
||||||
{
|
|
||||||
__fwprintf (stderr, L": %s", s);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fprintf (stderr, ": %s", s);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
error_tail (int status, int errnum, const char *message, va_list args)
|
|
||||||
{
|
|
||||||
#if _LIBC
|
|
||||||
if (_IO_fwide (stderr, 0) > 0)
|
|
||||||
{
|
|
||||||
# define ALLOCA_LIMIT 2000
|
|
||||||
size_t len = strlen (message) + 1;
|
|
||||||
const wchar_t *wmessage = L"out of memory";
|
|
||||||
wchar_t *wbuf = (len < ALLOCA_LIMIT
|
|
||||||
? alloca (len * sizeof *wbuf)
|
|
||||||
: len <= SIZE_MAX / sizeof *wbuf
|
|
||||||
? malloc (len * sizeof *wbuf)
|
|
||||||
: NULL);
|
|
||||||
|
|
||||||
if (wbuf)
|
|
||||||
{
|
|
||||||
size_t res;
|
|
||||||
mbstate_t st;
|
|
||||||
const char *tmp = message;
|
|
||||||
memset (&st, '\0', sizeof (st));
|
|
||||||
res = mbsrtowcs (wbuf, &tmp, len, &st);
|
|
||||||
wmessage = res == (size_t) -1 ? L"???" : wbuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
__vfwprintf (stderr, wmessage, args);
|
|
||||||
if (! (len < ALLOCA_LIMIT))
|
|
||||||
free (wbuf);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
vfprintf (stderr, message, args);
|
|
||||||
va_end (args);
|
|
||||||
|
|
||||||
++error_message_count;
|
|
||||||
if (errnum)
|
|
||||||
print_errno_message (errnum);
|
|
||||||
#if _LIBC
|
|
||||||
if (_IO_fwide (stderr, 0) > 0)
|
|
||||||
putwc (L'\n', stderr);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
putc ('\n', stderr);
|
|
||||||
fflush (stderr);
|
|
||||||
if (status)
|
|
||||||
exit (status);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* 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. */
|
|
||||||
void
|
|
||||||
error (int status, int errnum, const char *message, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
|
|
||||||
#if defined _LIBC && defined __libc_ptf_call
|
|
||||||
/* We do not want this call to be cut short by a thread
|
|
||||||
cancellation. Therefore disable cancellation for now. */
|
|
||||||
int state = PTHREAD_CANCEL_ENABLE;
|
|
||||||
__libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
|
|
||||||
0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fflush (stdout);
|
|
||||||
#ifdef _LIBC
|
|
||||||
_IO_flockfile (stderr);
|
|
||||||
#endif
|
|
||||||
if (error_print_progname)
|
|
||||||
(*error_print_progname) ();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#if _LIBC
|
|
||||||
if (_IO_fwide (stderr, 0) > 0)
|
|
||||||
__fwprintf (stderr, L"%s: ", program_name);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
fprintf (stderr, "%s: ", program_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
va_start (args, message);
|
|
||||||
error_tail (status, errnum, message, args);
|
|
||||||
|
|
||||||
#ifdef _LIBC
|
|
||||||
_IO_funlockfile (stderr);
|
|
||||||
# ifdef __libc_ptf_call
|
|
||||||
__libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sometimes we want to have at most one error per line. This
|
|
||||||
variable controls whether this mode is selected or not. */
|
|
||||||
int error_one_per_line;
|
|
||||||
|
|
||||||
void
|
|
||||||
error_at_line (int status, int errnum, const char *file_name,
|
|
||||||
unsigned int line_number, const char *message, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
|
|
||||||
if (error_one_per_line)
|
|
||||||
{
|
|
||||||
static const char *old_file_name;
|
|
||||||
static unsigned int old_line_number;
|
|
||||||
|
|
||||||
if (old_line_number == line_number
|
|
||||||
&& (file_name == old_file_name
|
|
||||||
|| strcmp (old_file_name, file_name) == 0))
|
|
||||||
/* Simply return and print nothing. */
|
|
||||||
return;
|
|
||||||
|
|
||||||
old_file_name = file_name;
|
|
||||||
old_line_number = line_number;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined _LIBC && defined __libc_ptf_call
|
|
||||||
/* We do not want this call to be cut short by a thread
|
|
||||||
cancellation. Therefore disable cancellation for now. */
|
|
||||||
int state = PTHREAD_CANCEL_ENABLE;
|
|
||||||
__libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state),
|
|
||||||
0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fflush (stdout);
|
|
||||||
#ifdef _LIBC
|
|
||||||
_IO_flockfile (stderr);
|
|
||||||
#endif
|
|
||||||
if (error_print_progname)
|
|
||||||
(*error_print_progname) ();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#if _LIBC
|
|
||||||
if (_IO_fwide (stderr, 0) > 0)
|
|
||||||
__fwprintf (stderr, L"%s: ", program_name);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
fprintf (stderr, "%s:", program_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file_name != NULL)
|
|
||||||
{
|
|
||||||
#if _LIBC
|
|
||||||
if (_IO_fwide (stderr, 0) > 0)
|
|
||||||
__fwprintf (stderr, L"%s:%d: ", file_name, line_number);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
fprintf (stderr, "%s:%d: ", file_name, line_number);
|
|
||||||
}
|
|
||||||
|
|
||||||
va_start (args, message);
|
|
||||||
error_tail (status, errnum, message, args);
|
|
||||||
|
|
||||||
#ifdef _LIBC
|
|
||||||
_IO_funlockfile (stderr);
|
|
||||||
# ifdef __libc_ptf_call
|
|
||||||
__libc_ptf_call (pthread_setcancelstate, (state, NULL), 0);
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _LIBC
|
|
||||||
/* Make the weak alias. */
|
|
||||||
# undef error
|
|
||||||
# undef error_at_line
|
|
||||||
weak_alias (__error, error)
|
|
||||||
weak_alias (__error_at_line, error_at_line)
|
|
||||||
#endif
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
/* Declaration for error-reporting function
|
|
||||||
Copyright (C) 1995, 1996, 1997, 2003 Free Software Foundation, Inc.
|
|
||||||
This file is part of the GNU C Library.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
|
||||||
with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#ifndef _ERROR_H
|
|
||||||
#define _ERROR_H 1
|
|
||||||
|
|
||||||
#ifndef __attribute__
|
|
||||||
/* This feature is available in gcc versions 2.5 and later. */
|
|
||||||
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
|
|
||||||
# define __attribute__(Spec) /* empty */
|
|
||||||
# endif
|
|
||||||
/* The __-protected variants of `format' and `printf' attributes
|
|
||||||
are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
|
|
||||||
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
|
|
||||||
# define __format__ format
|
|
||||||
# define __printf__ printf
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Print a message with `fprintf (stderr, FORMAT, ...)';
|
|
||||||
if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM).
|
|
||||||
If STATUS is nonzero, terminate the program with `exit (STATUS)'. */
|
|
||||||
|
|
||||||
extern void error (int __status, int __errnum, const char *__format, ...)
|
|
||||||
__attribute__ ((__format__ (__printf__, 3, 4)));
|
|
||||||
|
|
||||||
extern void error_at_line (int __status, int __errnum, const char *__fname,
|
|
||||||
unsigned int __lineno, const char *__format, ...)
|
|
||||||
__attribute__ ((__format__ (__printf__, 5, 6)));
|
|
||||||
|
|
||||||
/* If NULL, error will flush stdout, then print on stderr the program
|
|
||||||
name, a colon and a space. Otherwise, error will call this
|
|
||||||
function without parameters instead. */
|
|
||||||
extern void (*error_print_progname) (void);
|
|
||||||
|
|
||||||
/* This variable is incremented each time `error' is called. */
|
|
||||||
extern unsigned int error_message_count;
|
|
||||||
|
|
||||||
/* Sometimes we want to have at most one error per line. This
|
|
||||||
variable controls whether this mode is selected or not. */
|
|
||||||
extern int error_one_per_line;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* error.h */
|
|
||||||
@@ -1,263 +0,0 @@
|
|||||||
/* exclude.c -- exclude file names
|
|
||||||
|
|
||||||
Copyright (C) 1992, 1993, 1994, 1997, 1999, 2000, 2001, 2002, 2003 Free
|
|
||||||
Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; see the file COPYING.
|
|
||||||
If not, write to the Free Software Foundation,
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
/* Written by Paul Eggert <eggert@twinsun.com> */
|
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#ifndef errno
|
|
||||||
extern int errno;
|
|
||||||
#endif
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "exclude.h"
|
|
||||||
#include "fnmatch.h"
|
|
||||||
#include "unlocked-io.h"
|
|
||||||
#include "xalloc.h"
|
|
||||||
|
|
||||||
#if STDC_HEADERS || (! defined isascii && ! HAVE_ISASCII)
|
|
||||||
# define IN_CTYPE_DOMAIN(c) true
|
|
||||||
#else
|
|
||||||
# define IN_CTYPE_DOMAIN(c) isascii (c)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
is_space (unsigned char c)
|
|
||||||
{
|
|
||||||
return IN_CTYPE_DOMAIN (c) && isspace (c);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Verify a requirement at compile-time (unlike assert, which is runtime). */
|
|
||||||
#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; }
|
|
||||||
|
|
||||||
/* Non-GNU systems lack these options, so we don't need to check them. */
|
|
||||||
#ifndef FNM_CASEFOLD
|
|
||||||
# define FNM_CASEFOLD 0
|
|
||||||
#endif
|
|
||||||
#ifndef FNM_LEADING_DIR
|
|
||||||
# define FNM_LEADING_DIR 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
verify (EXCLUDE_macros_do_not_collide_with_FNM_macros,
|
|
||||||
(((EXCLUDE_ANCHORED | EXCLUDE_INCLUDE | EXCLUDE_WILDCARDS)
|
|
||||||
& (FNM_PATHNAME | FNM_NOESCAPE | FNM_PERIOD | FNM_LEADING_DIR
|
|
||||||
| FNM_CASEFOLD))
|
|
||||||
== 0));
|
|
||||||
|
|
||||||
/* An exclude pattern-options pair. The options are fnmatch options
|
|
||||||
ORed with EXCLUDE_* options. */
|
|
||||||
|
|
||||||
struct patopts
|
|
||||||
{
|
|
||||||
char const *pattern;
|
|
||||||
int options;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* An exclude list, of pattern-options pairs. */
|
|
||||||
|
|
||||||
struct exclude
|
|
||||||
{
|
|
||||||
struct patopts *exclude;
|
|
||||||
size_t exclude_alloc;
|
|
||||||
size_t exclude_count;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Return a newly allocated and empty exclude list. */
|
|
||||||
|
|
||||||
struct exclude *
|
|
||||||
new_exclude (void)
|
|
||||||
{
|
|
||||||
return xzalloc (sizeof *new_exclude ());
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free the storage associated with an exclude list. */
|
|
||||||
|
|
||||||
void
|
|
||||||
free_exclude (struct exclude *ex)
|
|
||||||
{
|
|
||||||
free (ex->exclude);
|
|
||||||
free (ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return zero if PATTERN matches F, obeying OPTIONS, except that
|
|
||||||
(unlike fnmatch) wildcards are disabled in PATTERN. */
|
|
||||||
|
|
||||||
static int
|
|
||||||
fnmatch_no_wildcards (char const *pattern, char const *f, int options)
|
|
||||||
{
|
|
||||||
if (! (options & FNM_LEADING_DIR))
|
|
||||||
return ((options & FNM_CASEFOLD)
|
|
||||||
? strcasecmp (pattern, f)
|
|
||||||
: strcmp (pattern, f));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
size_t patlen = strlen (pattern);
|
|
||||||
int r = ((options & FNM_CASEFOLD)
|
|
||||||
? strncasecmp (pattern, f, patlen)
|
|
||||||
: strncmp (pattern, f, patlen));
|
|
||||||
if (! r)
|
|
||||||
{
|
|
||||||
r = f[patlen];
|
|
||||||
if (r == '/')
|
|
||||||
r = 0;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return true if EX excludes F. */
|
|
||||||
|
|
||||||
bool
|
|
||||||
excluded_filename (struct exclude const *ex, char const *f)
|
|
||||||
{
|
|
||||||
size_t exclude_count = ex->exclude_count;
|
|
||||||
|
|
||||||
/* If no options are given, the default is to include. */
|
|
||||||
if (exclude_count == 0)
|
|
||||||
return false;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
struct patopts const *exclude = ex->exclude;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
/* Otherwise, the default is the opposite of the first option. */
|
|
||||||
bool excluded = !! (exclude[0].options & EXCLUDE_INCLUDE);
|
|
||||||
|
|
||||||
/* Scan through the options, seeing whether they change F from
|
|
||||||
excluded to included or vice versa. */
|
|
||||||
for (i = 0; i < exclude_count; i++)
|
|
||||||
{
|
|
||||||
char const *pattern = exclude[i].pattern;
|
|
||||||
int options = exclude[i].options;
|
|
||||||
if (excluded == !! (options & EXCLUDE_INCLUDE))
|
|
||||||
{
|
|
||||||
int (*matcher) (char const *, char const *, int) =
|
|
||||||
(options & EXCLUDE_WILDCARDS
|
|
||||||
? fnmatch
|
|
||||||
: fnmatch_no_wildcards);
|
|
||||||
bool matched = ((*matcher) (pattern, f, options) == 0);
|
|
||||||
char const *p;
|
|
||||||
|
|
||||||
if (! (options & EXCLUDE_ANCHORED))
|
|
||||||
for (p = f; *p && ! matched; p++)
|
|
||||||
if (*p == '/' && p[1] != '/')
|
|
||||||
matched = ((*matcher) (pattern, p + 1, options) == 0);
|
|
||||||
|
|
||||||
excluded ^= matched;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return excluded;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Append to EX the exclusion PATTERN with OPTIONS. */
|
|
||||||
|
|
||||||
void
|
|
||||||
add_exclude (struct exclude *ex, char const *pattern, int options)
|
|
||||||
{
|
|
||||||
struct patopts *patopts;
|
|
||||||
|
|
||||||
if (ex->exclude_count == ex->exclude_alloc)
|
|
||||||
ex->exclude = x2nrealloc (ex->exclude, &ex->exclude_alloc,
|
|
||||||
sizeof *ex->exclude);
|
|
||||||
|
|
||||||
patopts = &ex->exclude[ex->exclude_count++];
|
|
||||||
patopts->pattern = pattern;
|
|
||||||
patopts->options = options;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Use ADD_FUNC to append to EX the patterns in FILENAME, each with
|
|
||||||
OPTIONS. LINE_END terminates each pattern in the file. If
|
|
||||||
LINE_END is a space character, ignore trailing spaces and empty
|
|
||||||
lines in FILE. Return -1 on failure, 0 on success. */
|
|
||||||
|
|
||||||
int
|
|
||||||
add_exclude_file (void (*add_func) (struct exclude *, char const *, int),
|
|
||||||
struct exclude *ex, char const *filename, int options,
|
|
||||||
char line_end)
|
|
||||||
{
|
|
||||||
bool use_stdin = filename[0] == '-' && !filename[1];
|
|
||||||
FILE *in;
|
|
||||||
char *buf = NULL;
|
|
||||||
char *p;
|
|
||||||
char const *pattern;
|
|
||||||
char const *lim;
|
|
||||||
size_t buf_alloc = 0;
|
|
||||||
size_t buf_count = 0;
|
|
||||||
int c;
|
|
||||||
int e = 0;
|
|
||||||
|
|
||||||
if (use_stdin)
|
|
||||||
in = stdin;
|
|
||||||
else if (! (in = fopen (filename, "r")))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
while ((c = getc (in)) != EOF)
|
|
||||||
{
|
|
||||||
if (buf_count == buf_alloc)
|
|
||||||
buf = x2realloc (buf, &buf_alloc);
|
|
||||||
buf[buf_count++] = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ferror (in))
|
|
||||||
e = errno;
|
|
||||||
|
|
||||||
if (!use_stdin && fclose (in) != 0)
|
|
||||||
e = errno;
|
|
||||||
|
|
||||||
buf = xrealloc (buf, buf_count + 1);
|
|
||||||
buf[buf_count] = line_end;
|
|
||||||
lim = buf + buf_count + ! (buf_count == 0 || buf[buf_count - 1] == line_end);
|
|
||||||
pattern = buf;
|
|
||||||
|
|
||||||
for (p = buf; p < lim; p++)
|
|
||||||
if (*p == line_end)
|
|
||||||
{
|
|
||||||
char *pattern_end = p;
|
|
||||||
|
|
||||||
if (is_space (line_end))
|
|
||||||
{
|
|
||||||
for (; ; pattern_end--)
|
|
||||||
if (pattern_end == pattern)
|
|
||||||
goto next_pattern;
|
|
||||||
else if (! is_space (pattern_end[-1]))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
*pattern_end = '\0';
|
|
||||||
(*add_func) (ex, pattern, options);
|
|
||||||
|
|
||||||
next_pattern:
|
|
||||||
pattern = p + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
errno = e;
|
|
||||||
return e ? -1 : 0;
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
/* exclude.h -- declarations for excluding file names
|
|
||||||
|
|
||||||
Copyright (C) 1992, 1993, 1994, 1997, 1999, 2001, 2002, 2003 Free
|
|
||||||
Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; see the file COPYING.
|
|
||||||
If not, write to the Free Software Foundation,
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
/* Written by Paul Eggert <eggert@twinsun.com> */
|
|
||||||
|
|
||||||
/* Exclude options, which can be ORed with fnmatch options. */
|
|
||||||
|
|
||||||
/* Patterns must match the start of file names, instead of matching
|
|
||||||
anywhere after a '/'. */
|
|
||||||
#define EXCLUDE_ANCHORED (1 << 30)
|
|
||||||
|
|
||||||
/* Include instead of exclude. */
|
|
||||||
#define EXCLUDE_INCLUDE (1 << 29)
|
|
||||||
|
|
||||||
/* '?', '*', '[', and '\\' are special in patterns. Without this
|
|
||||||
option, these characters are ordinary and fnmatch is not used. */
|
|
||||||
#define EXCLUDE_WILDCARDS (1 << 28)
|
|
||||||
|
|
||||||
struct exclude;
|
|
||||||
|
|
||||||
struct exclude *new_exclude (void);
|
|
||||||
void free_exclude (struct exclude *);
|
|
||||||
void add_exclude (struct exclude *, char const *, int);
|
|
||||||
int add_exclude_file (void (*) (struct exclude *, char const *, int),
|
|
||||||
struct exclude *, char const *, int, char);
|
|
||||||
bool excluded_filename (struct exclude const *, char const *);
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
/* exit() function.
|
|
||||||
Copyright (C) 1995, 2001 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#ifndef _EXIT_H
|
|
||||||
#define _EXIT_H
|
|
||||||
|
|
||||||
/* Get exit() declaration. */
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
/* Some systems do not define EXIT_*, even with STDC_HEADERS. */
|
|
||||||
#ifndef EXIT_SUCCESS
|
|
||||||
# define EXIT_SUCCESS 0
|
|
||||||
#endif
|
|
||||||
#ifndef EXIT_FAILURE
|
|
||||||
# define EXIT_FAILURE 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _EXIT_H */
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
/* Failure exit status
|
|
||||||
|
|
||||||
Copyright (C) 2002, 2003 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; see the file COPYING.
|
|
||||||
If not, write to the Free Software Foundation,
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "exitfail.h"
|
|
||||||
#include "exit.h"
|
|
||||||
|
|
||||||
int volatile exit_failure = EXIT_FAILURE;
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
/* Failure exit status
|
|
||||||
|
|
||||||
Copyright (C) 2002 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; see the file COPYING.
|
|
||||||
If not, write to the Free Software Foundation,
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
extern int volatile exit_failure;
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
/* Return a string describing the type of a file.
|
|
||||||
|
|
||||||
Copyright (C) 1993, 1994, 2001, 2002, 2004 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
/* Written by Paul Eggert. */
|
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include "file-type.h"
|
|
||||||
|
|
||||||
#include <gettext.h>
|
|
||||||
#define _(text) gettext (text)
|
|
||||||
|
|
||||||
char const *
|
|
||||||
file_type (struct stat const *st)
|
|
||||||
{
|
|
||||||
/* See POSIX 1003.1-2001 XCU Table 4-8 lines 17093-17107 for some of
|
|
||||||
these formats.
|
|
||||||
|
|
||||||
To keep diagnostics grammatical in English, the returned string
|
|
||||||
must start with a consonant. */
|
|
||||||
|
|
||||||
if (S_ISREG (st->st_mode))
|
|
||||||
return st->st_size == 0 ? _("regular empty file") : _("regular file");
|
|
||||||
|
|
||||||
if (S_ISDIR (st->st_mode))
|
|
||||||
return _("directory");
|
|
||||||
|
|
||||||
if (S_ISBLK (st->st_mode))
|
|
||||||
return _("block special file");
|
|
||||||
|
|
||||||
if (S_ISCHR (st->st_mode))
|
|
||||||
return _("character special file");
|
|
||||||
|
|
||||||
if (S_ISFIFO (st->st_mode))
|
|
||||||
return _("fifo");
|
|
||||||
|
|
||||||
if (S_ISLNK (st->st_mode))
|
|
||||||
return _("symbolic link");
|
|
||||||
|
|
||||||
if (S_ISSOCK (st->st_mode))
|
|
||||||
return _("socket");
|
|
||||||
|
|
||||||
if (S_TYPEISMQ (st))
|
|
||||||
return _("message queue");
|
|
||||||
|
|
||||||
if (S_TYPEISSEM (st))
|
|
||||||
return _("semaphore");
|
|
||||||
|
|
||||||
if (S_TYPEISSHM (st))
|
|
||||||
return _("shared memory object");
|
|
||||||
|
|
||||||
if (S_TYPEISTMO (st))
|
|
||||||
return _("typed memory object");
|
|
||||||
|
|
||||||
return _("weird file");
|
|
||||||
}
|
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
/* Return a string describing the type of a file.
|
|
||||||
|
|
||||||
Copyright (C) 1993, 1994, 2001, 2002, 2004 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
/* Written by Paul Eggert and Jim Meyering. */
|
|
||||||
|
|
||||||
#ifndef FILE_TYPE_H
|
|
||||||
# define FILE_TYPE_H 1
|
|
||||||
|
|
||||||
# if ! defined S_ISREG && ! defined S_IFREG
|
|
||||||
you must include <sys/stat.h> before including this file
|
|
||||||
# endif
|
|
||||||
|
|
||||||
char const *file_type (struct stat const *);
|
|
||||||
|
|
||||||
# ifndef S_IFMT
|
|
||||||
# define S_IFMT 0170000
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# if STAT_MACROS_BROKEN
|
|
||||||
# undef S_ISBLK
|
|
||||||
# undef S_ISCHR
|
|
||||||
# undef S_ISDIR
|
|
||||||
# undef S_ISDOOR
|
|
||||||
# undef S_ISFIFO
|
|
||||||
# undef S_ISLNK
|
|
||||||
# undef S_ISNAM
|
|
||||||
# undef S_ISMPB
|
|
||||||
# undef S_ISMPC
|
|
||||||
# undef S_ISNWK
|
|
||||||
# undef S_ISREG
|
|
||||||
# undef S_ISSOCK
|
|
||||||
# endif
|
|
||||||
|
|
||||||
|
|
||||||
# ifndef S_ISBLK
|
|
||||||
# ifdef S_IFBLK
|
|
||||||
# define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
|
|
||||||
# else
|
|
||||||
# define S_ISBLK(m) 0
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifndef S_ISCHR
|
|
||||||
# ifdef S_IFCHR
|
|
||||||
# define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
|
|
||||||
# else
|
|
||||||
# define S_ISCHR(m) 0
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifndef S_ISDIR
|
|
||||||
# ifdef S_IFDIR
|
|
||||||
# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
|
||||||
# else
|
|
||||||
# define S_ISDIR(m) 0
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifndef S_ISDOOR /* Solaris 2.5 and up */
|
|
||||||
# ifdef S_IFDOOR
|
|
||||||
# define S_ISDOOR(m) (((m) & S_IFMT) == S_IFDOOR)
|
|
||||||
# else
|
|
||||||
# define S_ISDOOR(m) 0
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifndef S_ISFIFO
|
|
||||||
# ifdef S_IFIFO
|
|
||||||
# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
|
|
||||||
# else
|
|
||||||
# define S_ISFIFO(m) 0
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifndef S_ISLNK
|
|
||||||
# ifdef S_IFLNK
|
|
||||||
# define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
|
|
||||||
# else
|
|
||||||
# define S_ISLNK(m) 0
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifndef S_ISMPB /* V7 */
|
|
||||||
# ifdef S_IFMPB
|
|
||||||
# define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
|
|
||||||
# define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
|
|
||||||
# else
|
|
||||||
# define S_ISMPB(m) 0
|
|
||||||
# define S_ISMPC(m) 0
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifndef S_ISNAM /* Xenix */
|
|
||||||
# ifdef S_IFNAM
|
|
||||||
# define S_ISNAM(m) (((m) & S_IFMT) == S_IFNAM)
|
|
||||||
# else
|
|
||||||
# define S_ISNAM(m) 0
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifndef S_ISNWK /* HP/UX */
|
|
||||||
# ifdef S_IFNWK
|
|
||||||
# define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
|
|
||||||
# else
|
|
||||||
# define S_ISNWK(m) 0
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifndef S_ISREG
|
|
||||||
# ifdef S_IFREG
|
|
||||||
# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
|
||||||
# else
|
|
||||||
# define S_ISREG(m) 0
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifndef S_ISSOCK
|
|
||||||
# ifdef S_IFSOCK
|
|
||||||
# define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
|
|
||||||
# else
|
|
||||||
# define S_ISSOCK(m) 0
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
|
|
||||||
# ifndef S_TYPEISMQ
|
|
||||||
# define S_TYPEISMQ(p) 0
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifndef S_TYPEISTMO
|
|
||||||
# define S_TYPEISTMO(p) 0
|
|
||||||
# endif
|
|
||||||
|
|
||||||
|
|
||||||
# ifndef S_TYPEISSEM
|
|
||||||
# ifdef S_INSEM
|
|
||||||
# define S_TYPEISSEM(p) (S_ISNAM ((p)->st_mode) && (p)->st_rdev == S_INSEM)
|
|
||||||
# else
|
|
||||||
# define S_TYPEISSEM(p) 0
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifndef S_TYPEISSHM
|
|
||||||
# ifdef S_INSHD
|
|
||||||
# define S_TYPEISSHM(p) (S_ISNAM ((p)->st_mode) && (p)->st_rdev == S_INSHD)
|
|
||||||
# else
|
|
||||||
# define S_TYPEISSHM(p) 0
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#endif /* FILE_TYPE_H */
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
/* Convenience header for conditional use of GNU <libintl.h>.
|
|
||||||
Copyright (C) 1995-1998, 2000-2002 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
|
||||||
with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#ifndef _LIBGETTEXT_H
|
|
||||||
#define _LIBGETTEXT_H 1
|
|
||||||
|
|
||||||
/* NLS can be disabled through the configure --disable-nls option. */
|
|
||||||
#if ENABLE_NLS
|
|
||||||
|
|
||||||
/* Get declarations of GNU message catalog functions. */
|
|
||||||
# include <libintl.h>
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* Solaris /usr/include/locale.h includes /usr/include/libintl.h, which
|
|
||||||
chokes if dcgettext is defined as a macro. So include it now, to make
|
|
||||||
later inclusions of <locale.h> a NOP. We don't include <libintl.h>
|
|
||||||
as well because people using "gettext.h" will not include <libintl.h>,
|
|
||||||
and also including <libintl.h> would fail on SunOS 4, whereas <locale.h>
|
|
||||||
is OK. */
|
|
||||||
#if defined(__sun)
|
|
||||||
# include <locale.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Disabled NLS.
|
|
||||||
The casts to 'const char *' serve the purpose of producing warnings
|
|
||||||
for invalid uses of the value returned from these functions.
|
|
||||||
On pre-ANSI systems without 'const', the config.h file is supposed to
|
|
||||||
contain "#define const". */
|
|
||||||
# define gettext(Msgid) ((const char *) (Msgid))
|
|
||||||
# define dgettext(Domainname, Msgid) ((const char *) (Msgid))
|
|
||||||
# define dcgettext(Domainname, Msgid, Category) ((const char *) (Msgid))
|
|
||||||
# define ngettext(Msgid1, Msgid2, N) \
|
|
||||||
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
|
||||||
# define dngettext(Domainname, Msgid1, Msgid2, N) \
|
|
||||||
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
|
||||||
# define dcngettext(Domainname, Msgid1, Msgid2, N, Category) \
|
|
||||||
((N) == 1 ? (const char *) (Msgid1) : (const char *) (Msgid2))
|
|
||||||
# define textdomain(Domainname) ((const char *) (Domainname))
|
|
||||||
# define bindtextdomain(Domainname, Dirname) ((const char *) (Dirname))
|
|
||||||
# define bind_textdomain_codeset(Domainname, Codeset) ((const char *) (Codeset))
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* A pseudo function call that serves as a marker for the automated
|
|
||||||
extraction of messages, but does not call gettext(). The run-time
|
|
||||||
translation is done at a different place in the code.
|
|
||||||
The argument, String, should be a literal string. Concatenated strings
|
|
||||||
and other string expressions won't work.
|
|
||||||
The macro's expansion is not parenthesized, so that it is suitable as
|
|
||||||
initializer for static 'char[]' or 'const char[]' variables. */
|
|
||||||
#define gettext_noop(String) String
|
|
||||||
|
|
||||||
#endif /* _LIBGETTEXT_H */
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
# This file is generated automatically by "bootstrap".
|
|
||||||
BUILT_SOURCES += $(ALLOCA_H)
|
|
||||||
EXTRA_DIST += alloca_.h
|
|
||||||
|
|
||||||
# We need the following in order to create an <alloca.h> when the system
|
|
||||||
# doesn't have one that works with the given compiler.
|
|
||||||
all-local $(lib_OBJECTS): $(ALLOCA_H)
|
|
||||||
alloca.h: alloca_.h
|
|
||||||
cp $(srcdir)/alloca_.h $@-t
|
|
||||||
mv $@-t $@
|
|
||||||
MOSTLYCLEANFILES += alloca.h alloca.h-t
|
|
||||||
|
|
||||||
lib_SOURCES += c-stack.h c-stack.c
|
|
||||||
|
|
||||||
lib_SOURCES += dirname.h dirname.c basename.c stripslash.c
|
|
||||||
|
|
||||||
|
|
||||||
lib_SOURCES += exclude.h exclude.c
|
|
||||||
|
|
||||||
lib_SOURCES += exit.h
|
|
||||||
|
|
||||||
lib_SOURCES += exitfail.h exitfail.c
|
|
||||||
|
|
||||||
|
|
||||||
lib_SOURCES += file-type.h file-type.c
|
|
||||||
|
|
||||||
BUILT_SOURCES += $(FNMATCH_H)
|
|
||||||
EXTRA_DIST += fnmatch_.h fnmatch_loop.c
|
|
||||||
|
|
||||||
# We need the following in order to create an <fnmatch.h> when the system
|
|
||||||
# doesn't have one that supports the required API.
|
|
||||||
all-local $(lib_OBJECTS): $(FNMATCH_H)
|
|
||||||
fnmatch.h: fnmatch_.h
|
|
||||||
cp $(srcdir)/fnmatch_.h $@-t
|
|
||||||
mv $@-t $@
|
|
||||||
MOSTLYCLEANFILES += fnmatch.h fnmatch.h-t
|
|
||||||
|
|
||||||
|
|
||||||
lib_SOURCES += getopt.h getopt.c getopt1.c getopt_int.h
|
|
||||||
|
|
||||||
lib_SOURCES += gettext.h
|
|
||||||
|
|
||||||
|
|
||||||
lib_SOURCES += hard-locale.h hard-locale.c
|
|
||||||
|
|
||||||
EXTRA_DIST += inttostr.c
|
|
||||||
lib_SOURCES += imaxtostr.c inttostr.h offtostr.c umaxtostr.c
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
lib_SOURCES += posixver.h posixver.c
|
|
||||||
|
|
||||||
|
|
||||||
lib_SOURCES += regex.h
|
|
||||||
|
|
||||||
|
|
||||||
BUILT_SOURCES += $(STDBOOL_H)
|
|
||||||
EXTRA_DIST += stdbool_.h
|
|
||||||
|
|
||||||
# We need the following in order to create an <stdbool.h> when the system
|
|
||||||
# doesn't have one that works.
|
|
||||||
all-local $(lib_OBJECTS): $(STDBOOL_H)
|
|
||||||
stdbool.h: stdbool_.h
|
|
||||||
sed -e 's/@''HAVE__BOOL''@/$(HAVE__BOOL)/g' < $(srcdir)/stdbool_.h > $@-t
|
|
||||||
mv $@-t $@
|
|
||||||
MOSTLYCLEANFILES += stdbool.h stdbool.h-t
|
|
||||||
|
|
||||||
lib_SOURCES += strcase.h
|
|
||||||
|
|
||||||
lib_SOURCES += strftime.c
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
lib_SOURCES += time_r.h
|
|
||||||
|
|
||||||
|
|
||||||
lib_SOURCES += unlocked-io.h
|
|
||||||
|
|
||||||
lib_SOURCES += version-etc.h version-etc.c
|
|
||||||
|
|
||||||
lib_SOURCES += xalloc.h xmalloc.c xstrdup.c
|
|
||||||
|
|
||||||
lib_SOURCES += xstrtol.h xstrtol.c xstrtoul.c
|
|
||||||
|
|
||||||
lib_SOURCES += xstrtoumax.c
|
|
||||||
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
/* hard-locale.c -- Determine whether a locale is hard.
|
|
||||||
|
|
||||||
Copyright (C) 1997, 1998, 1999, 2002, 2003 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "hard-locale.h"
|
|
||||||
|
|
||||||
#if HAVE_LOCALE_H
|
|
||||||
# include <locale.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
/* Return nonzero if the current CATEGORY locale is hard, i.e. if you
|
|
||||||
can't get away with assuming traditional C or POSIX behavior. */
|
|
||||||
int
|
|
||||||
hard_locale (int category)
|
|
||||||
{
|
|
||||||
#if ! HAVE_SETLOCALE
|
|
||||||
return 0;
|
|
||||||
#else
|
|
||||||
|
|
||||||
int hard = 1;
|
|
||||||
char const *p = setlocale (category, 0);
|
|
||||||
|
|
||||||
if (p)
|
|
||||||
{
|
|
||||||
# if defined __GLIBC__ && 2 <= __GLIBC__
|
|
||||||
if (strcmp (p, "C") == 0 || strcmp (p, "POSIX") == 0)
|
|
||||||
hard = 0;
|
|
||||||
# else
|
|
||||||
char *locale = malloc (strlen (p) + 1);
|
|
||||||
if (locale)
|
|
||||||
{
|
|
||||||
strcpy (locale, p);
|
|
||||||
|
|
||||||
/* Temporarily set the locale to the "C" and "POSIX" locales
|
|
||||||
to find their names, so that we can determine whether one
|
|
||||||
or the other is the caller's locale. */
|
|
||||||
if (((p = setlocale (category, "C"))
|
|
||||||
&& strcmp (p, locale) == 0)
|
|
||||||
|| ((p = setlocale (category, "POSIX"))
|
|
||||||
&& strcmp (p, locale) == 0))
|
|
||||||
hard = 0;
|
|
||||||
|
|
||||||
/* Restore the caller's locale. */
|
|
||||||
setlocale (category, locale);
|
|
||||||
free (locale);
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
|
|
||||||
return hard;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
/* Determine whether a locale is hard.
|
|
||||||
|
|
||||||
Copyright (C) 1999, 2003 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#ifndef HARD_LOCALE_H_
|
|
||||||
# define HARD_LOCALE_H_ 1
|
|
||||||
|
|
||||||
int hard_locale (int);
|
|
||||||
|
|
||||||
#endif /* HARD_LOCALE_H_ */
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
/* inttostr.h -- convert integers to printable strings
|
|
||||||
|
|
||||||
Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
/* Written by Paul Eggert */
|
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_INTTYPES_H
|
|
||||||
# include <inttypes.h>
|
|
||||||
#endif
|
|
||||||
#if HAVE_STDINT_H
|
|
||||||
# include <stdint.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#if HAVE_SYS_TYPES_H
|
|
||||||
# include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Upper bound on the string length of an integer converted to string.
|
|
||||||
302 / 1000 is ceil (log10 (2.0)). Subtract 1 for the sign bit;
|
|
||||||
add 1 for integer division truncation; add 1 more for a minus sign. */
|
|
||||||
#define INT_STRLEN_BOUND(t) ((sizeof (t) * CHAR_BIT - 1) * 302 / 1000 + 2)
|
|
||||||
|
|
||||||
#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1)
|
|
||||||
|
|
||||||
char *offtostr (off_t, char *);
|
|
||||||
char *imaxtostr (intmax_t, char *);
|
|
||||||
char *umaxtostr (uintmax_t, char *);
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
/* Which POSIX version to conform to, for utilities.
|
|
||||||
|
|
||||||
Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
|
||||||
with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
/* Written by Paul Eggert. */
|
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "posixver.h"
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#if HAVE_UNISTD_H
|
|
||||||
# include <unistd.h>
|
|
||||||
#endif
|
|
||||||
#ifndef _POSIX2_VERSION
|
|
||||||
# define _POSIX2_VERSION 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef DEFAULT_POSIX2_VERSION
|
|
||||||
# define DEFAULT_POSIX2_VERSION _POSIX2_VERSION
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The POSIX version that utilities should conform to. The default is
|
|
||||||
specified by the system. */
|
|
||||||
|
|
||||||
int
|
|
||||||
posix2_version (void)
|
|
||||||
{
|
|
||||||
long int v = DEFAULT_POSIX2_VERSION;
|
|
||||||
char const *s = getenv ("_POSIX2_VERSION");
|
|
||||||
|
|
||||||
if (s && *s)
|
|
||||||
{
|
|
||||||
char *e;
|
|
||||||
long int i = strtol (s, &e, 10);
|
|
||||||
if (! *e)
|
|
||||||
v = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
return v < INT_MIN ? INT_MIN : v < INT_MAX ? v : INT_MAX;
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
int posix2_version (void);
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
/* Parse arguments from a string and prepend them to an argv.
|
|
||||||
|
|
||||||
Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
||||||
02111-1307, USA. */
|
|
||||||
|
|
||||||
/* Written by Paul Eggert <eggert@twinsun.com>. */
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
#include "prepargs.h"
|
|
||||||
#include <string.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <xalloc.h>
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
/* IN_CTYPE_DOMAIN (C) is nonzero if the unsigned char C can safely be given
|
|
||||||
as an argument to <ctype.h> macros like "isspace". */
|
|
||||||
#ifdef STDC_HEADERS
|
|
||||||
# define IN_CTYPE_DOMAIN(c) 1
|
|
||||||
#else
|
|
||||||
# define IN_CTYPE_DOMAIN(c) ((c) <= 0177)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ISSPACE(c) (IN_CTYPE_DOMAIN (c) && isspace (c))
|
|
||||||
|
|
||||||
/* Find the white-space-separated options specified by OPTIONS, and
|
|
||||||
using BUF to store copies of these options, set ARGV[0], ARGV[1],
|
|
||||||
etc. to the option copies. Return the number N of options found.
|
|
||||||
Do not set ARGV[N]. If ARGV is zero, do not store ARGV[0] etc.
|
|
||||||
Backslash can be used to escape whitespace (and backslashes). */
|
|
||||||
static int
|
|
||||||
prepend_args (char const *options, char *buf, char **argv)
|
|
||||||
{
|
|
||||||
char const *o = options;
|
|
||||||
char *b = buf;
|
|
||||||
int n = 0;
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
while (ISSPACE ((unsigned char) *o))
|
|
||||||
o++;
|
|
||||||
if (!*o)
|
|
||||||
return n;
|
|
||||||
if (argv)
|
|
||||||
argv[n] = b;
|
|
||||||
n++;
|
|
||||||
|
|
||||||
do
|
|
||||||
if ((*b++ = *o++) == '\\' && *o)
|
|
||||||
b[-1] = *o++;
|
|
||||||
while (*o && ! ISSPACE ((unsigned char) *o));
|
|
||||||
|
|
||||||
*b++ = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Prepend the whitespace-separated options in OPTIONS to the argument
|
|
||||||
vector of a main program with argument count *PARGC and argument
|
|
||||||
vector *PARGV. */
|
|
||||||
void
|
|
||||||
prepend_default_options (char const *options, int *pargc, char ***pargv)
|
|
||||||
{
|
|
||||||
if (options)
|
|
||||||
{
|
|
||||||
char *buf = xmalloc (strlen (options) + 1);
|
|
||||||
int prepended = prepend_args (options, buf, (char **) 0);
|
|
||||||
int argc = *pargc;
|
|
||||||
char * const *argv = *pargv;
|
|
||||||
char **pp = (char **) xmalloc ((prepended + argc + 1) * sizeof *pp);
|
|
||||||
*pargc = prepended + argc;
|
|
||||||
*pargv = pp;
|
|
||||||
*pp++ = *argv++;
|
|
||||||
pp += prepend_args (options, buf, pp);
|
|
||||||
while ((*pp++ = *argv++))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
/* Parse arguments from a string and prepend them to an argv. */
|
|
||||||
|
|
||||||
void prepend_default_options (char const *, int *, char ***);
|
|
||||||
@@ -1,125 +0,0 @@
|
|||||||
/* Shell command argument quoting.
|
|
||||||
Copyright (C) 1994, 1995, 1997 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; see the file COPYING.
|
|
||||||
If not, write to the Free Software Foundation,
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
/* Written by Paul Eggert <eggert@twinsun.com> */
|
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <quotesys.h>
|
|
||||||
|
|
||||||
/* Place into QUOTED a quoted version of ARG suitable for `system'.
|
|
||||||
Return the length of the resulting string (which is not null-terminated).
|
|
||||||
If QUOTED is null, return the length without any side effects. */
|
|
||||||
|
|
||||||
size_t
|
|
||||||
quote_system_arg (quoted, arg)
|
|
||||||
char *quoted;
|
|
||||||
char const *arg;
|
|
||||||
{
|
|
||||||
char const *a;
|
|
||||||
size_t len = 0;
|
|
||||||
|
|
||||||
/* Scan ARG, copying it to QUOTED if QUOTED is not null,
|
|
||||||
looking for shell metacharacters. */
|
|
||||||
|
|
||||||
for (a = arg; ; a++)
|
|
||||||
{
|
|
||||||
char c = *a;
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
/* ARG has no shell metacharacters. */
|
|
||||||
return len;
|
|
||||||
|
|
||||||
case '=':
|
|
||||||
if (*arg == '-')
|
|
||||||
break;
|
|
||||||
/* Fall through. */
|
|
||||||
case '\t': case '\n': case ' ':
|
|
||||||
case '!': case '"': case '#': case '$': case '%': case '&': case '\'':
|
|
||||||
case '(': case ')': case '*': case ';':
|
|
||||||
case '<': case '>': case '?': case '[': case '\\':
|
|
||||||
case '^': case '`': case '|': case '~':
|
|
||||||
{
|
|
||||||
/* ARG has a shell metacharacter.
|
|
||||||
Start over, quoting it this time. */
|
|
||||||
|
|
||||||
len = 0;
|
|
||||||
c = *arg++;
|
|
||||||
|
|
||||||
/* If ARG is an option, quote just its argument.
|
|
||||||
This is not necessary, but it looks nicer. */
|
|
||||||
if (c == '-' && arg < a)
|
|
||||||
{
|
|
||||||
c = *arg++;
|
|
||||||
|
|
||||||
if (quoted)
|
|
||||||
{
|
|
||||||
quoted[len] = '-';
|
|
||||||
quoted[len + 1] = c;
|
|
||||||
}
|
|
||||||
len += 2;
|
|
||||||
|
|
||||||
if (c == '-')
|
|
||||||
while (arg < a)
|
|
||||||
{
|
|
||||||
c = *arg++;
|
|
||||||
if (quoted)
|
|
||||||
quoted[len] = c;
|
|
||||||
len++;
|
|
||||||
if (c == '=')
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
c = *arg++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (quoted)
|
|
||||||
quoted[len] = '\'';
|
|
||||||
len++;
|
|
||||||
|
|
||||||
for (; c; c = *arg++)
|
|
||||||
{
|
|
||||||
if (c == '\'')
|
|
||||||
{
|
|
||||||
if (quoted)
|
|
||||||
{
|
|
||||||
quoted[len] = '\'';
|
|
||||||
quoted[len + 1] = '\\';
|
|
||||||
quoted[len + 2] = '\'';
|
|
||||||
}
|
|
||||||
len += 3;
|
|
||||||
}
|
|
||||||
if (quoted)
|
|
||||||
quoted[len] = c;
|
|
||||||
len++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (quoted)
|
|
||||||
quoted[len] = '\'';
|
|
||||||
return len + 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (quoted)
|
|
||||||
quoted[len] = c;
|
|
||||||
len++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
/* quotesys.h -- declarations for quoting system arguments */
|
|
||||||
|
|
||||||
#if defined __STDC__ || __GNUC__
|
|
||||||
# define __QUOTESYS_P(args) args
|
|
||||||
#else
|
|
||||||
# define __QUOTESYS_P(args) ()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
size_t quote_system_arg __QUOTESYS_P ((char *, char const *));
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
/* Set a file descriptor's mode to binary or to text.
|
|
||||||
|
|
||||||
Copyright (C) 2001, 2004 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; see the file COPYING.
|
|
||||||
If not, write to the Free Software Foundation,
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
/* Written by Paul Eggert <eggert@twinsun.com> */
|
|
||||||
|
|
||||||
#ifndef set_binary_mode
|
|
||||||
bool set_binary_mode (int, bool);
|
|
||||||
# if ! HAVE_SETMODE_DOS
|
|
||||||
# define set_binary_mode(fd, mode) true
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
/* Case-insensitive string comparison functions.
|
|
||||||
Copyright (C) 1995-1996, 2001, 2003 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#ifndef _STRCASE_H
|
|
||||||
#define _STRCASE_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
/* Compare strings S1 and S2, ignoring case, returning less than, equal to or
|
|
||||||
greater than zero if S1 is lexicographically less than, equal to or greater
|
|
||||||
than S2.
|
|
||||||
Note: This function does not work correctly in multibyte locales. */
|
|
||||||
extern int strcasecmp (const char *s1, const char *s2);
|
|
||||||
|
|
||||||
/* Compare no more than N characters of strings S1 and S2, ignoring case,
|
|
||||||
returning less than, equal to or greater than zero if S1 is
|
|
||||||
lexicographically less than, equal to or greater than S2.
|
|
||||||
Note: This function can not work correctly in multibyte locales. */
|
|
||||||
extern int strncasecmp (const char *s1, const char *s2, size_t n);
|
|
||||||
|
|
||||||
#endif /* _STRCASE_H */
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,80 +0,0 @@
|
|||||||
/* Convert string representation of a number into an intmax_t value.
|
|
||||||
Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
/* Written by Paul Eggert. */
|
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_INTTYPES_H
|
|
||||||
# include <inttypes.h>
|
|
||||||
#elif HAVE_STDINT_H
|
|
||||||
# include <stdint.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
/* Verify a requirement at compile-time (unlike assert, which is runtime). */
|
|
||||||
#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; }
|
|
||||||
|
|
||||||
#ifdef UNSIGNED
|
|
||||||
# ifndef HAVE_DECL_STRTOULL
|
|
||||||
"this configure-time declaration test was not run"
|
|
||||||
# endif
|
|
||||||
# if !HAVE_DECL_STRTOULL && HAVE_UNSIGNED_LONG_LONG
|
|
||||||
unsigned long long strtoull (char const *, char **, int);
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
# ifndef HAVE_DECL_STRTOLL
|
|
||||||
"this configure-time declaration test was not run"
|
|
||||||
# endif
|
|
||||||
# if !HAVE_DECL_STRTOLL && HAVE_UNSIGNED_LONG_LONG
|
|
||||||
long long strtoll (char const *, char **, int);
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNSIGNED
|
|
||||||
# undef HAVE_LONG_LONG
|
|
||||||
# define HAVE_LONG_LONG HAVE_UNSIGNED_LONG_LONG
|
|
||||||
# define INT uintmax_t
|
|
||||||
# define strtoimax strtoumax
|
|
||||||
# define strtol strtoul
|
|
||||||
# define strtoll strtoull
|
|
||||||
#else
|
|
||||||
# define INT intmax_t
|
|
||||||
#endif
|
|
||||||
|
|
||||||
INT
|
|
||||||
strtoimax (char const *ptr, char **endptr, int base)
|
|
||||||
{
|
|
||||||
#if HAVE_LONG_LONG
|
|
||||||
verify (size_is_that_of_long_or_long_long,
|
|
||||||
(sizeof (INT) == sizeof (long)
|
|
||||||
|| sizeof (INT) == sizeof (long long)));
|
|
||||||
|
|
||||||
if (sizeof (INT) != sizeof (long))
|
|
||||||
return strtoll (ptr, endptr, base);
|
|
||||||
#else
|
|
||||||
verify (size_is_that_of_long,
|
|
||||||
sizeof (INT) == sizeof (long));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return strtol (ptr, endptr, base);
|
|
||||||
}
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
#define UNSIGNED 1
|
|
||||||
#include "strtoimax.c"
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
/* Prefer faster, non-thread-safe stdio functions if available.
|
|
||||||
|
|
||||||
Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License along
|
|
||||||
with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
/* Written by Jim Meyering. */
|
|
||||||
|
|
||||||
#ifndef UNLOCKED_IO_H
|
|
||||||
# define UNLOCKED_IO_H 1
|
|
||||||
|
|
||||||
# ifndef USE_UNLOCKED_IO
|
|
||||||
# define USE_UNLOCKED_IO 1
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# if USE_UNLOCKED_IO
|
|
||||||
|
|
||||||
/* These are wrappers for functions/macros from the GNU C library, and
|
|
||||||
from other C libraries supporting POSIX's optional thread-safe functions.
|
|
||||||
|
|
||||||
The standard I/O functions are thread-safe. These *_unlocked ones are
|
|
||||||
more efficient but not thread-safe. That they're not thread-safe is
|
|
||||||
fine since all of the applications in this package are single threaded.
|
|
||||||
|
|
||||||
Also, some code that is shared with the GNU C library may invoke
|
|
||||||
the *_unlocked functions directly. On hosts that lack those
|
|
||||||
functions, invoke the non-thread-safe versions instead. */
|
|
||||||
|
|
||||||
# include <stdio.h>
|
|
||||||
|
|
||||||
# if HAVE_DECL_CLEARERR_UNLOCKED
|
|
||||||
# undef clearerr
|
|
||||||
# define clearerr(x) clearerr_unlocked (x)
|
|
||||||
# else
|
|
||||||
# define clearerr_unlocked(x) clearerr (x)
|
|
||||||
# endif
|
|
||||||
# if HAVE_DECL_FEOF_UNLOCKED
|
|
||||||
# undef feof
|
|
||||||
# define feof(x) feof_unlocked (x)
|
|
||||||
# else
|
|
||||||
# define feof_unlocked(x) feof (x)
|
|
||||||
# endif
|
|
||||||
# if HAVE_DECL_FERROR_UNLOCKED
|
|
||||||
# undef ferror
|
|
||||||
# define ferror(x) ferror_unlocked (x)
|
|
||||||
# else
|
|
||||||
# define ferror_unlocked(x) ferror (x)
|
|
||||||
# endif
|
|
||||||
# if HAVE_DECL_FFLUSH_UNLOCKED
|
|
||||||
# undef fflush
|
|
||||||
# define fflush(x) fflush_unlocked (x)
|
|
||||||
# else
|
|
||||||
# define fflush_unlocked(x) fflush (x)
|
|
||||||
# endif
|
|
||||||
# if HAVE_DECL_FGETS_UNLOCKED
|
|
||||||
# undef fgets
|
|
||||||
# define fgets(x,y,z) fgets_unlocked (x,y,z)
|
|
||||||
# else
|
|
||||||
# define fgets_unlocked(x,y,z) fgets (x,y,z)
|
|
||||||
# endif
|
|
||||||
# if HAVE_DECL_FPUTC_UNLOCKED
|
|
||||||
# undef fputc
|
|
||||||
# define fputc(x,y) fputc_unlocked (x,y)
|
|
||||||
# else
|
|
||||||
# define fputc_unlocked(x,y) fputc (x,y)
|
|
||||||
# endif
|
|
||||||
# if HAVE_DECL_FPUTS_UNLOCKED
|
|
||||||
# undef fputs
|
|
||||||
# define fputs(x,y) fputs_unlocked (x,y)
|
|
||||||
# else
|
|
||||||
# define fputs_unlocked(x,y) fputs (x,y)
|
|
||||||
# endif
|
|
||||||
# if HAVE_DECL_FREAD_UNLOCKED
|
|
||||||
# undef fread
|
|
||||||
# define fread(w,x,y,z) fread_unlocked (w,x,y,z)
|
|
||||||
# else
|
|
||||||
# define fread_unlocked(w,x,y,z) fread (w,x,y,z)
|
|
||||||
# endif
|
|
||||||
# if HAVE_DECL_FWRITE_UNLOCKED
|
|
||||||
# undef fwrite
|
|
||||||
# define fwrite(w,x,y,z) fwrite_unlocked (w,x,y,z)
|
|
||||||
# else
|
|
||||||
# define fwrite_unlocked(w,x,y,z) fwrite (w,x,y,z)
|
|
||||||
# endif
|
|
||||||
# if HAVE_DECL_GETC_UNLOCKED
|
|
||||||
# undef getc
|
|
||||||
# define getc(x) getc_unlocked (x)
|
|
||||||
# else
|
|
||||||
# define getc_unlocked(x) getc (x)
|
|
||||||
# endif
|
|
||||||
# if HAVE_DECL_GETCHAR_UNLOCKED
|
|
||||||
# undef getchar
|
|
||||||
# define getchar() getchar_unlocked ()
|
|
||||||
# else
|
|
||||||
# define getchar_unlocked() getchar ()
|
|
||||||
# endif
|
|
||||||
# if HAVE_DECL_PUTC_UNLOCKED
|
|
||||||
# undef putc
|
|
||||||
# define putc(x,y) putc_unlocked (x,y)
|
|
||||||
# else
|
|
||||||
# define putc_unlocked(x,y) putc (x,y)
|
|
||||||
# endif
|
|
||||||
# if HAVE_DECL_PUTCHAR_UNLOCKED
|
|
||||||
# undef putchar
|
|
||||||
# define putchar(x) putchar_unlocked (x)
|
|
||||||
# else
|
|
||||||
# define putchar_unlocked(x) putchar (x)
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# undef flockfile
|
|
||||||
# define flockfile(x) ((void) 0)
|
|
||||||
|
|
||||||
# undef ftrylockfile
|
|
||||||
# define ftrylockfile(x) 0
|
|
||||||
|
|
||||||
# undef funlockfile
|
|
||||||
# define funlockfile(x) ((void) 0)
|
|
||||||
|
|
||||||
# endif /* USE_UNLOCKED_IO */
|
|
||||||
#endif /* UNLOCKED_IO_H */
|
|
||||||
@@ -1,176 +0,0 @@
|
|||||||
/* Utility to help print --version output in a consistent format.
|
|
||||||
Copyright (C) 1999-2004 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
/* Written by Jim Meyering. */
|
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Specification. */
|
|
||||||
#include "version-etc.h"
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "unlocked-io.h"
|
|
||||||
|
|
||||||
#include "gettext.h"
|
|
||||||
#define _(msgid) gettext (msgid)
|
|
||||||
|
|
||||||
/* Default copyright goes to the FSF. */
|
|
||||||
|
|
||||||
const char* version_etc_copyright =
|
|
||||||
/* Do *not* mark this string for translation. */
|
|
||||||
"Copyright (C) 2004 Free Software Foundation, Inc.";
|
|
||||||
|
|
||||||
|
|
||||||
/* Like version_etc, below, but with the NULL-terminated author list
|
|
||||||
provided via a variable of type va_list. */
|
|
||||||
void
|
|
||||||
version_etc_va (FILE *stream,
|
|
||||||
const char *command_name, const char *package,
|
|
||||||
const char *version, va_list authors)
|
|
||||||
{
|
|
||||||
unsigned int n_authors;
|
|
||||||
|
|
||||||
/* Count the number of authors. */
|
|
||||||
{
|
|
||||||
va_list tmp_authors;
|
|
||||||
|
|
||||||
#ifdef __va_copy
|
|
||||||
__va_copy (tmp_authors, authors);
|
|
||||||
#else
|
|
||||||
tmp_authors = authors;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
n_authors = 0;
|
|
||||||
while (va_arg (tmp_authors, const char *) != NULL)
|
|
||||||
++n_authors;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (command_name)
|
|
||||||
fprintf (stream, "%s (%s) %s\n", command_name, package, version);
|
|
||||||
else
|
|
||||||
fprintf (stream, "%s %s\n", package, version);
|
|
||||||
|
|
||||||
switch (n_authors)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
/* The caller must provide at least one author name. */
|
|
||||||
abort ();
|
|
||||||
case 1:
|
|
||||||
/* TRANSLATORS: %s denotes an author name. */
|
|
||||||
vfprintf (stream, _("Written by %s.\n"), authors);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
/* TRANSLATORS: Each %s denotes an author name. */
|
|
||||||
vfprintf (stream, _("Written by %s and %s.\n"), authors);
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
/* TRANSLATORS: Each %s denotes an author name. */
|
|
||||||
vfprintf (stream, _("Written by %s, %s, and %s.\n"), authors);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
/* TRANSLATORS: Each %s denotes an author name.
|
|
||||||
You can use line breaks, estimating that each author name occupies
|
|
||||||
ca. 16 screen columns and that a screen line has ca. 80 columns. */
|
|
||||||
vfprintf (stream, _("Written by %s, %s, %s,\nand %s.\n"), authors);
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
/* TRANSLATORS: Each %s denotes an author name.
|
|
||||||
You can use line breaks, estimating that each author name occupies
|
|
||||||
ca. 16 screen columns and that a screen line has ca. 80 columns. */
|
|
||||||
vfprintf (stream, _("Written by %s, %s, %s,\n%s, and %s.\n"), authors);
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
/* TRANSLATORS: Each %s denotes an author name.
|
|
||||||
You can use line breaks, estimating that each author name occupies
|
|
||||||
ca. 16 screen columns and that a screen line has ca. 80 columns. */
|
|
||||||
vfprintf (stream, _("Written by %s, %s, %s,\n%s, %s, and %s.\n"),
|
|
||||||
authors);
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
/* TRANSLATORS: Each %s denotes an author name.
|
|
||||||
You can use line breaks, estimating that each author name occupies
|
|
||||||
ca. 16 screen columns and that a screen line has ca. 80 columns. */
|
|
||||||
vfprintf (stream, _("Written by %s, %s, %s,\n%s, %s, %s, and %s.\n"),
|
|
||||||
authors);
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
/* TRANSLATORS: Each %s denotes an author name.
|
|
||||||
You can use line breaks, estimating that each author name occupies
|
|
||||||
ca. 16 screen columns and that a screen line has ca. 80 columns. */
|
|
||||||
vfprintf (stream, _("\
|
|
||||||
Written by %s, %s, %s,\n%s, %s, %s, %s,\nand %s.\n"),
|
|
||||||
authors);
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
/* TRANSLATORS: Each %s denotes an author name.
|
|
||||||
You can use line breaks, estimating that each author name occupies
|
|
||||||
ca. 16 screen columns and that a screen line has ca. 80 columns. */
|
|
||||||
vfprintf (stream, _("\
|
|
||||||
Written by %s, %s, %s,\n%s, %s, %s, %s,\n%s, and %s.\n"),
|
|
||||||
authors);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* 10 or more authors. Use an abbreviation, since the human reader
|
|
||||||
will probably not want to read the entire list anyway. */
|
|
||||||
/* TRANSLATORS: Each %s denotes an author name.
|
|
||||||
You can use line breaks, estimating that each author name occupies
|
|
||||||
ca. 16 screen columns and that a screen line has ca. 80 columns. */
|
|
||||||
vfprintf (stream, _("\
|
|
||||||
Written by %s, %s, %s,\n%s, %s, %s, %s,\n%s, %s, and others.\n"),
|
|
||||||
authors);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
va_end (authors);
|
|
||||||
putc ('\n', stream);
|
|
||||||
|
|
||||||
fputs (version_etc_copyright, stream);
|
|
||||||
putc ('\n', stream);
|
|
||||||
|
|
||||||
fputs (_("\
|
|
||||||
This is free software; see the source for copying conditions. There is NO\n\
|
|
||||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"),
|
|
||||||
stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Display the --version information the standard way.
|
|
||||||
|
|
||||||
If COMMAND_NAME is NULL, the PACKAGE is asumed to be the name of
|
|
||||||
the program. The formats are therefore:
|
|
||||||
|
|
||||||
PACKAGE VERSION
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
COMMAND_NAME (PACKAGE) VERSION.
|
|
||||||
|
|
||||||
The author names are passed as separate arguments, with an additional
|
|
||||||
NULL argument at the end. */
|
|
||||||
void
|
|
||||||
version_etc (FILE *stream,
|
|
||||||
const char *command_name, const char *package,
|
|
||||||
const char *version, /* const char *author1, ...*/ ...)
|
|
||||||
{
|
|
||||||
va_list authors;
|
|
||||||
|
|
||||||
va_start (authors, version);
|
|
||||||
version_etc_va (stream, command_name, package, version, authors);
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
/* Utility to help print --version output in a consistent format.
|
|
||||||
Copyright (C) 1999, 2003 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
/* Written by Jim Meyering. */
|
|
||||||
|
|
||||||
#ifndef VERSION_ETC_H
|
|
||||||
# define VERSION_ETC_H 1
|
|
||||||
|
|
||||||
# include <stdarg.h>
|
|
||||||
# include <stdio.h>
|
|
||||||
|
|
||||||
extern const char *version_etc_copyright;
|
|
||||||
|
|
||||||
extern void version_etc_va (FILE *stream,
|
|
||||||
const char *command_name, const char *package,
|
|
||||||
const char *version, va_list authors);
|
|
||||||
|
|
||||||
extern void version_etc (FILE *stream,
|
|
||||||
const char *command_name, const char *package,
|
|
||||||
const char *version,
|
|
||||||
/* const char *author1, ...*/ ...);
|
|
||||||
|
|
||||||
#endif /* VERSION_ETC_H */
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
/* xalloc.h -- malloc with out-of-memory checking
|
|
||||||
|
|
||||||
Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
|
|
||||||
1999, 2000, 2003 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#ifndef XALLOC_H_
|
|
||||||
# define XALLOC_H_
|
|
||||||
|
|
||||||
# include <stddef.h>
|
|
||||||
|
|
||||||
# ifndef __attribute__
|
|
||||||
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
|
|
||||||
# define __attribute__(x)
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifndef ATTRIBUTE_NORETURN
|
|
||||||
# define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* If this pointer is non-zero, run the specified function upon each
|
|
||||||
allocation failure. It is initialized to zero. */
|
|
||||||
extern void (*xalloc_fail_func) (void);
|
|
||||||
|
|
||||||
/* If XALLOC_FAIL_FUNC is undefined or a function that returns, this
|
|
||||||
message is output. It is translated via gettext.
|
|
||||||
Its value is "memory exhausted". */
|
|
||||||
extern char const xalloc_msg_memory_exhausted[];
|
|
||||||
|
|
||||||
/* This function is always triggered when memory is exhausted. It is
|
|
||||||
in charge of honoring the two previous items. It exits with status
|
|
||||||
exit_failure (defined in exitfail.h). This is the
|
|
||||||
function to call when one wants the program to die because of a
|
|
||||||
memory allocation failure. */
|
|
||||||
extern void xalloc_die (void) ATTRIBUTE_NORETURN;
|
|
||||||
|
|
||||||
void *xmalloc (size_t s);
|
|
||||||
void *xnmalloc (size_t n, size_t s);
|
|
||||||
void *xzalloc (size_t s);
|
|
||||||
void *xcalloc (size_t n, size_t s);
|
|
||||||
void *xrealloc (void *p, size_t s);
|
|
||||||
void *xnrealloc (void *p, size_t n, size_t s);
|
|
||||||
void *x2realloc (void *p, size_t *pn);
|
|
||||||
void *x2nrealloc (void *p, size_t *pn, size_t s);
|
|
||||||
void *xclone (void const *p, size_t s);
|
|
||||||
char *xstrdup (const char *str);
|
|
||||||
|
|
||||||
/* Return 1 if an array of N objects, each of size S, cannot exist due
|
|
||||||
to size arithmetic overflow. S must be positive and N must be
|
|
||||||
nonnegative. This is a macro, not an inline function, so that it
|
|
||||||
works correctly even when SIZE_MAX < N.
|
|
||||||
|
|
||||||
By gnulib convention, SIZE_MAX represents overflow in size
|
|
||||||
calculations, so the conservative dividend to use here is
|
|
||||||
SIZE_MAX - 1, since SIZE_MAX might represent an overflowed value.
|
|
||||||
However, malloc (SIZE_MAX) fails on all known hosts where
|
|
||||||
sizeof (ptrdiff_t) <= sizeof (size_t), so do not bother to test for
|
|
||||||
exactly-SIZE_MAX allocations on such hosts; this avoids a test and
|
|
||||||
branch when S is known to be 1. */
|
|
||||||
# define xalloc_oversized(n, s) \
|
|
||||||
((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n))
|
|
||||||
|
|
||||||
/* These macros are deprecated; they will go away soon, and are retained
|
|
||||||
temporarily only to ease conversion to the functions described above. */
|
|
||||||
# define CCLONE(p, n) xclone (p, (n) * sizeof *(p))
|
|
||||||
# define CLONE(p) xclone (p, sizeof *(p))
|
|
||||||
# define NEW(type, var) type *var = xmalloc (sizeof (type))
|
|
||||||
# define XCALLOC(type, n) xcalloc (n, sizeof (type))
|
|
||||||
# define XMALLOC(type, n) xnmalloc (n, sizeof (type))
|
|
||||||
# define XREALLOC(p, type, n) xnrealloc (p, n, sizeof (type))
|
|
||||||
# define XFREE(p) free (p)
|
|
||||||
|
|
||||||
#endif /* !XALLOC_H_ */
|
|
||||||
@@ -1,255 +0,0 @@
|
|||||||
/* xmalloc.c -- malloc with out of memory checking
|
|
||||||
|
|
||||||
Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2003,
|
|
||||||
1999, 2000, 2002, 2003 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#if HAVE_CONFIG_H
|
|
||||||
# include <config.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "xalloc.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "gettext.h"
|
|
||||||
#define _(msgid) gettext (msgid)
|
|
||||||
#define N_(msgid) msgid
|
|
||||||
|
|
||||||
#include "error.h"
|
|
||||||
#include "exitfail.h"
|
|
||||||
|
|
||||||
#ifndef SIZE_MAX
|
|
||||||
# define SIZE_MAX ((size_t) -1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef HAVE_MALLOC
|
|
||||||
"you must run the autoconf test for a GNU libc compatible malloc"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef HAVE_REALLOC
|
|
||||||
"you must run the autoconf test for a GNU libc compatible realloc"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* If non NULL, call this function when memory is exhausted. */
|
|
||||||
void (*xalloc_fail_func) (void) = 0;
|
|
||||||
|
|
||||||
/* If XALLOC_FAIL_FUNC is NULL, or does return, display this message
|
|
||||||
before exiting when memory is exhausted. Goes through gettext. */
|
|
||||||
char const xalloc_msg_memory_exhausted[] = N_("memory exhausted");
|
|
||||||
|
|
||||||
void
|
|
||||||
xalloc_die (void)
|
|
||||||
{
|
|
||||||
if (xalloc_fail_func)
|
|
||||||
(*xalloc_fail_func) ();
|
|
||||||
error (exit_failure, 0, "%s", _(xalloc_msg_memory_exhausted));
|
|
||||||
/* The `noreturn' cannot be given to error, since it may return if
|
|
||||||
its first argument is 0. To help compilers understand the
|
|
||||||
xalloc_die does terminate, call abort. */
|
|
||||||
abort ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate an array of N objects, each with S bytes of memory,
|
|
||||||
dynamically, with error checking. S must be nonzero. */
|
|
||||||
|
|
||||||
static inline void *
|
|
||||||
xnmalloc_inline (size_t n, size_t s)
|
|
||||||
{
|
|
||||||
void *p;
|
|
||||||
if (xalloc_oversized (n, s) || ! (p = malloc (n * s)))
|
|
||||||
xalloc_die ();
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
xnmalloc (size_t n, size_t s)
|
|
||||||
{
|
|
||||||
return xnmalloc_inline (n, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate N bytes of memory dynamically, with error checking. */
|
|
||||||
|
|
||||||
void *
|
|
||||||
xmalloc (size_t n)
|
|
||||||
{
|
|
||||||
return xnmalloc_inline (n, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Change the size of an allocated block of memory P to an array of N
|
|
||||||
objects each of S bytes, with error checking. S must be nonzero. */
|
|
||||||
|
|
||||||
static inline void *
|
|
||||||
xnrealloc_inline (void *p, size_t n, size_t s)
|
|
||||||
{
|
|
||||||
if (xalloc_oversized (n, s) || ! (p = realloc (p, n * s)))
|
|
||||||
xalloc_die ();
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
xnrealloc (void *p, size_t n, size_t s)
|
|
||||||
{
|
|
||||||
return xnrealloc_inline (p, n, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Change the size of an allocated block of memory P to N bytes,
|
|
||||||
with error checking. */
|
|
||||||
|
|
||||||
void *
|
|
||||||
xrealloc (void *p, size_t n)
|
|
||||||
{
|
|
||||||
return xnrealloc_inline (p, n, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* If P is null, allocate a block of at least *PN such objects;
|
|
||||||
otherwise, reallocate P so that it contains more than *PN objects
|
|
||||||
each of S bytes. *PN must be nonzero unless P is null, and S must
|
|
||||||
be nonzero. Set *PN to the new number of objects, and return the
|
|
||||||
pointer to the new block. *PN is never set to zero, and the
|
|
||||||
returned pointer is never null.
|
|
||||||
|
|
||||||
Repeated reallocations are guaranteed to make progress, either by
|
|
||||||
allocating an initial block with a nonzero size, or by allocating a
|
|
||||||
larger block.
|
|
||||||
|
|
||||||
In the following implementation, nonzero sizes are doubled so that
|
|
||||||
repeated reallocations have O(N log N) overall cost rather than
|
|
||||||
O(N**2) cost, but the specification for this function does not
|
|
||||||
guarantee that sizes are doubled.
|
|
||||||
|
|
||||||
Here is an example of use:
|
|
||||||
|
|
||||||
int *p = NULL;
|
|
||||||
size_t used = 0;
|
|
||||||
size_t allocated = 0;
|
|
||||||
|
|
||||||
void
|
|
||||||
append_int (int value)
|
|
||||||
{
|
|
||||||
if (used == allocated)
|
|
||||||
p = x2nrealloc (p, &allocated, sizeof *p);
|
|
||||||
p[used++] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
This causes x2nrealloc to allocate a block of some nonzero size the
|
|
||||||
first time it is called.
|
|
||||||
|
|
||||||
To have finer-grained control over the initial size, set *PN to a
|
|
||||||
nonzero value before calling this function with P == NULL. For
|
|
||||||
example:
|
|
||||||
|
|
||||||
int *p = NULL;
|
|
||||||
size_t used = 0;
|
|
||||||
size_t allocated = 0;
|
|
||||||
size_t allocated1 = 1000;
|
|
||||||
|
|
||||||
void
|
|
||||||
append_int (int value)
|
|
||||||
{
|
|
||||||
if (used == allocated)
|
|
||||||
{
|
|
||||||
p = x2nrealloc (p, &allocated1, sizeof *p);
|
|
||||||
allocated = allocated1;
|
|
||||||
}
|
|
||||||
p[used++] = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
static inline void *
|
|
||||||
x2nrealloc_inline (void *p, size_t *pn, size_t s)
|
|
||||||
{
|
|
||||||
size_t n = *pn;
|
|
||||||
|
|
||||||
if (! p)
|
|
||||||
{
|
|
||||||
if (! n)
|
|
||||||
{
|
|
||||||
/* The approximate size to use for initial small allocation
|
|
||||||
requests, when the invoking code specifies an old size of
|
|
||||||
zero. 64 bytes is the largest "small" request for the
|
|
||||||
GNU C library malloc. */
|
|
||||||
enum { DEFAULT_MXFAST = 64 };
|
|
||||||
|
|
||||||
n = DEFAULT_MXFAST / s;
|
|
||||||
n += !n;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (SIZE_MAX / 2 / s < n)
|
|
||||||
xalloc_die ();
|
|
||||||
n *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
*pn = n;
|
|
||||||
return xrealloc (p, n * s);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
x2nrealloc (void *p, size_t *pn, size_t s)
|
|
||||||
{
|
|
||||||
return x2nrealloc_inline (p, pn, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If P is null, allocate a block of at least *PN bytes; otherwise,
|
|
||||||
reallocate P so that it contains more than *PN bytes. *PN must be
|
|
||||||
nonzero unless P is null. Set *PN to the new block's size, and
|
|
||||||
return the pointer to the new block. *PN is never set to zero, and
|
|
||||||
the returned pointer is never null. */
|
|
||||||
|
|
||||||
void *
|
|
||||||
x2realloc (void *p, size_t *pn)
|
|
||||||
{
|
|
||||||
return x2nrealloc_inline (p, pn, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate S bytes of zeroed memory dynamically, with error checking.
|
|
||||||
There's no need for xnzalloc (N, S), since it would be equivalent
|
|
||||||
to xcalloc (N, S). */
|
|
||||||
|
|
||||||
void *
|
|
||||||
xzalloc (size_t s)
|
|
||||||
{
|
|
||||||
return memset (xmalloc (s), 0, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate zeroed memory for N elements of S bytes, with error
|
|
||||||
checking. S must be nonzero. */
|
|
||||||
|
|
||||||
void *
|
|
||||||
xcalloc (size_t n, size_t s)
|
|
||||||
{
|
|
||||||
void *p;
|
|
||||||
/* Test for overflow, since some calloc implementations don't have
|
|
||||||
proper overflow checks. */
|
|
||||||
if (xalloc_oversized (n, s) || ! (p = calloc (n, s)))
|
|
||||||
xalloc_die ();
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clone an object P of size S, with error checking. There's no need
|
|
||||||
for xnclone (P, N, S), since xclone (P, N * S) works without any
|
|
||||||
need for an arithmetic overflow check. */
|
|
||||||
|
|
||||||
void *
|
|
||||||
xclone (void const *p, size_t s)
|
|
||||||
{
|
|
||||||
return memcpy (xmalloc (s), p, s);
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
/* A more useful interface to strtol.
|
|
||||||
|
|
||||||
Copyright (C) 1995, 1996, 1998, 1999, 2001, 2002, 2003, 2004 Free
|
|
||||||
Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
|
||||||
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#ifndef XSTRTOL_H_
|
|
||||||
# define XSTRTOL_H_ 1
|
|
||||||
|
|
||||||
# include "exitfail.h"
|
|
||||||
|
|
||||||
/* Get uintmax_t. */
|
|
||||||
# if HAVE_INTTYPES_H
|
|
||||||
# include <inttypes.h>
|
|
||||||
# else
|
|
||||||
# if HAVE_STDINT_H
|
|
||||||
# include <stdint.h>
|
|
||||||
# endif
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifndef _STRTOL_ERROR
|
|
||||||
enum strtol_error
|
|
||||||
{
|
|
||||||
LONGINT_OK = 0,
|
|
||||||
|
|
||||||
/* These two values can be ORed together, to indicate that both
|
|
||||||
errors occurred. */
|
|
||||||
LONGINT_OVERFLOW = 1,
|
|
||||||
LONGINT_INVALID_SUFFIX_CHAR = 2,
|
|
||||||
|
|
||||||
LONGINT_INVALID_SUFFIX_CHAR_WITH_OVERFLOW = (LONGINT_INVALID_SUFFIX_CHAR
|
|
||||||
| LONGINT_OVERFLOW),
|
|
||||||
LONGINT_INVALID = 4
|
|
||||||
};
|
|
||||||
typedef enum strtol_error strtol_error;
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# define _DECLARE_XSTRTOL(name, type) \
|
|
||||||
strtol_error name (const char *, char **, int, type *, const char *);
|
|
||||||
_DECLARE_XSTRTOL (xstrtol, long int)
|
|
||||||
_DECLARE_XSTRTOL (xstrtoul, unsigned long int)
|
|
||||||
_DECLARE_XSTRTOL (xstrtoimax, intmax_t)
|
|
||||||
_DECLARE_XSTRTOL (xstrtoumax, uintmax_t)
|
|
||||||
|
|
||||||
# define _STRTOL_ERROR(Exit_code, Str, Argument_type_string, Err) \
|
|
||||||
do \
|
|
||||||
{ \
|
|
||||||
switch ((Err)) \
|
|
||||||
{ \
|
|
||||||
default: \
|
|
||||||
abort (); \
|
|
||||||
\
|
|
||||||
case LONGINT_INVALID: \
|
|
||||||
error ((Exit_code), 0, "invalid %s `%s'", \
|
|
||||||
(Argument_type_string), (Str)); \
|
|
||||||
break; \
|
|
||||||
\
|
|
||||||
case LONGINT_INVALID_SUFFIX_CHAR: \
|
|
||||||
case LONGINT_INVALID_SUFFIX_CHAR | LONGINT_OVERFLOW: \
|
|
||||||
error ((Exit_code), 0, "invalid character following %s in `%s'", \
|
|
||||||
(Argument_type_string), (Str)); \
|
|
||||||
break; \
|
|
||||||
\
|
|
||||||
case LONGINT_OVERFLOW: \
|
|
||||||
error ((Exit_code), 0, "%s `%s' too large", \
|
|
||||||
(Argument_type_string), (Str)); \
|
|
||||||
break; \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
|
|
||||||
# define STRTOL_FATAL_ERROR(Str, Argument_type_string, Err) \
|
|
||||||
_STRTOL_ERROR (exit_failure, Str, Argument_type_string, Err)
|
|
||||||
|
|
||||||
# define STRTOL_FAIL_WARN(Str, Argument_type_string, Err) \
|
|
||||||
_STRTOL_ERROR (0, Str, Argument_type_string, Err)
|
|
||||||
|
|
||||||
#endif /* not XSTRTOL_H_ */
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.33.
|
|
||||||
.TH CMP "1" "April 2004" "diffutils 2.8.7" "User Commands"
|
|
||||||
.SH NAME
|
|
||||||
cmp \- compare two files byte by byte
|
|
||||||
.SH SYNOPSIS
|
|
||||||
.B cmp
|
|
||||||
[\fIOPTION\fR]... \fIFILE1 \fR[\fIFILE2 \fR[\fISKIP1 \fR[\fISKIP2\fR]]]
|
|
||||||
.SH DESCRIPTION
|
|
||||||
Compare two files byte by byte.
|
|
||||||
.TP
|
|
||||||
\fB\-b\fR \fB\-\-print\-bytes\fR
|
|
||||||
Print differing bytes.
|
|
||||||
.TP
|
|
||||||
\fB\-i\fR SKIP \fB\-\-ignore\-initial\fR=\fISKIP\fR
|
|
||||||
Skip the first SKIP bytes of input.
|
|
||||||
.HP
|
|
||||||
\fB\-i\fR SKIP1:SKIP2 \fB\-\-ignore\-initial\fR=\fISKIP1\fR:SKIP2
|
|
||||||
.IP
|
|
||||||
Skip the first SKIP1 bytes of FILE1 and the first SKIP2 bytes of FILE2.
|
|
||||||
.TP
|
|
||||||
\fB\-l\fR \fB\-\-verbose\fR
|
|
||||||
Output byte numbers and values of all differing bytes.
|
|
||||||
.TP
|
|
||||||
\fB\-n\fR LIMIT \fB\-\-bytes\fR=\fILIMIT\fR
|
|
||||||
Compare at most LIMIT bytes.
|
|
||||||
.TP
|
|
||||||
\fB\-s\fR \fB\-\-quiet\fR \fB\-\-silent\fR
|
|
||||||
Output nothing; yield exit status only.
|
|
||||||
.TP
|
|
||||||
\fB\-v\fR \fB\-\-version\fR
|
|
||||||
Output version info.
|
|
||||||
.TP
|
|
||||||
\fB\-\-help\fR
|
|
||||||
Output this help.
|
|
||||||
.PP
|
|
||||||
SKIP1 and SKIP2 are the number of bytes to skip in each file.
|
|
||||||
SKIP values may be followed by the following multiplicative suffixes:
|
|
||||||
kB 1000, K 1024, MB 1,000,000, M 1,048,576,
|
|
||||||
GB 1,000,000,000, G 1,073,741,824, and so on for T, P, E, Z, Y.
|
|
||||||
.PP
|
|
||||||
If a FILE is `-' or missing, read standard input.
|
|
||||||
Exit status is 0 if inputs are the same, 1 if different, 2 if trouble.
|
|
||||||
.SH AUTHOR
|
|
||||||
Written by Torbjorn Granlund and David MacKenzie.
|
|
||||||
.SH "REPORTING BUGS"
|
|
||||||
Report bugs to <bug-gnu-utils@gnu.org>.
|
|
||||||
.SH COPYRIGHT
|
|
||||||
Copyright \(co 2004 Free Software Foundation, Inc.
|
|
||||||
.br
|
|
||||||
This is free software; see the source for copying conditions. There is NO
|
|
||||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
.SH "SEE ALSO"
|
|
||||||
The full documentation for
|
|
||||||
.B cmp
|
|
||||||
is maintained as a Texinfo manual. If the
|
|
||||||
.B info
|
|
||||||
and
|
|
||||||
.B cmp
|
|
||||||
programs are properly installed at your site, the command
|
|
||||||
.IP
|
|
||||||
.B info diff
|
|
||||||
.PP
|
|
||||||
should give you access to the complete manual.
|
|
||||||
@@ -1,227 +0,0 @@
|
|||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.33.
|
|
||||||
.TH DIFF "1" "April 2004" "diffutils 2.8.7" "User Commands"
|
|
||||||
.SH NAME
|
|
||||||
diff \- compare files line by line
|
|
||||||
.SH SYNOPSIS
|
|
||||||
.B diff
|
|
||||||
[\fIOPTION\fR]... \fIFILES\fR
|
|
||||||
.SH DESCRIPTION
|
|
||||||
Compare files line by line.
|
|
||||||
.TP
|
|
||||||
\fB\-i\fR \fB\-\-ignore\-case\fR
|
|
||||||
Ignore case differences in file contents.
|
|
||||||
.TP
|
|
||||||
\fB\-\-ignore\-file\-name\-case\fR
|
|
||||||
Ignore case when comparing file names.
|
|
||||||
.TP
|
|
||||||
\fB\-\-no\-ignore\-file\-name\-case\fR
|
|
||||||
Consider case when comparing file names.
|
|
||||||
.TP
|
|
||||||
\fB\-E\fR \fB\-\-ignore\-tab\-expansion\fR
|
|
||||||
Ignore changes due to tab expansion.
|
|
||||||
.TP
|
|
||||||
\fB\-b\fR \fB\-\-ignore\-space\-change\fR
|
|
||||||
Ignore changes in the amount of white space.
|
|
||||||
.TP
|
|
||||||
\fB\-w\fR \fB\-\-ignore\-all\-space\fR
|
|
||||||
Ignore all white space.
|
|
||||||
.TP
|
|
||||||
\fB\-B\fR \fB\-\-ignore\-blank\-lines\fR
|
|
||||||
Ignore changes whose lines are all blank.
|
|
||||||
.TP
|
|
||||||
\fB\-I\fR RE \fB\-\-ignore\-matching\-lines\fR=\fIRE\fR
|
|
||||||
Ignore changes whose lines all match RE.
|
|
||||||
.TP
|
|
||||||
\fB\-\-strip\-trailing\-cr\fR
|
|
||||||
Strip trailing carriage return on input.
|
|
||||||
.TP
|
|
||||||
\fB\-a\fR \fB\-\-text\fR
|
|
||||||
Treat all files as text.
|
|
||||||
.TP
|
|
||||||
\fB\-c\fR \fB\-C\fR NUM \fB\-\-context\fR[=\fINUM\fR]
|
|
||||||
Output NUM (default 3) lines of copied context.
|
|
||||||
.TP
|
|
||||||
\fB\-u\fR \fB\-U\fR NUM \fB\-\-unified\fR[=\fINUM\fR]
|
|
||||||
Output NUM (default 3) lines of unified context.
|
|
||||||
.TP
|
|
||||||
\fB\-\-label\fR LABEL
|
|
||||||
Use LABEL instead of file name.
|
|
||||||
.TP
|
|
||||||
\fB\-p\fR \fB\-\-show\-c\-function\fR
|
|
||||||
Show which C function each change is in.
|
|
||||||
.TP
|
|
||||||
\fB\-F\fR RE \fB\-\-show\-function\-line\fR=\fIRE\fR
|
|
||||||
Show the most recent line matching RE.
|
|
||||||
.TP
|
|
||||||
\fB\-q\fR \fB\-\-brief\fR
|
|
||||||
Output only whether files differ.
|
|
||||||
.TP
|
|
||||||
\fB\-e\fR \fB\-\-ed\fR
|
|
||||||
Output an ed script.
|
|
||||||
.TP
|
|
||||||
\fB\-\-normal\fR
|
|
||||||
Output a normal diff.
|
|
||||||
.TP
|
|
||||||
\fB\-n\fR \fB\-\-rcs\fR
|
|
||||||
Output an RCS format diff.
|
|
||||||
.TP
|
|
||||||
\fB\-y\fR \fB\-\-side\-by\-side\fR
|
|
||||||
Output in two columns.
|
|
||||||
.TP
|
|
||||||
\fB\-W\fR NUM \fB\-\-width\fR=\fINUM\fR
|
|
||||||
Output at most NUM (default 130) print columns.
|
|
||||||
.TP
|
|
||||||
\fB\-\-left\-column\fR
|
|
||||||
Output only the left column of common lines.
|
|
||||||
.TP
|
|
||||||
\fB\-\-suppress\-common\-lines\fR
|
|
||||||
Do not output common lines.
|
|
||||||
.TP
|
|
||||||
\fB\-D\fR NAME \fB\-\-ifdef\fR=\fINAME\fR
|
|
||||||
Output merged file to show `#ifdef NAME' diffs.
|
|
||||||
.TP
|
|
||||||
\fB\-\-GTYPE\-group\-format\fR=\fIGFMT\fR
|
|
||||||
Similar, but format GTYPE input groups with GFMT.
|
|
||||||
.TP
|
|
||||||
\fB\-\-line\-format\fR=\fILFMT\fR
|
|
||||||
Similar, but format all input lines with LFMT.
|
|
||||||
.TP
|
|
||||||
\fB\-\-LTYPE\-line\-format\fR=\fILFMT\fR
|
|
||||||
Similar, but format LTYPE input lines with LFMT.
|
|
||||||
.TP
|
|
||||||
LTYPE is `old', `new', or `unchanged'.
|
|
||||||
GTYPE is LTYPE or `changed'.
|
|
||||||
.IP
|
|
||||||
GFMT may contain:
|
|
||||||
.TP
|
|
||||||
%<
|
|
||||||
lines from FILE1
|
|
||||||
.TP
|
|
||||||
%>
|
|
||||||
lines from FILE2
|
|
||||||
.TP
|
|
||||||
%=
|
|
||||||
lines common to FILE1 and FILE2
|
|
||||||
.TP
|
|
||||||
%[-][WIDTH][.[PREC]]{doxX}LETTER
|
|
||||||
printf-style spec for LETTER
|
|
||||||
.IP
|
|
||||||
LETTERs are as follows for new group, lower case for old group:
|
|
||||||
.TP
|
|
||||||
F
|
|
||||||
first line number
|
|
||||||
.TP
|
|
||||||
L
|
|
||||||
last line number
|
|
||||||
.TP
|
|
||||||
N
|
|
||||||
number of lines = L-F+1
|
|
||||||
.TP
|
|
||||||
E
|
|
||||||
F-1
|
|
||||||
.TP
|
|
||||||
M
|
|
||||||
L+1
|
|
||||||
.IP
|
|
||||||
LFMT may contain:
|
|
||||||
.TP
|
|
||||||
%L
|
|
||||||
contents of line
|
|
||||||
.TP
|
|
||||||
%l
|
|
||||||
contents of line, excluding any trailing newline
|
|
||||||
.TP
|
|
||||||
%[-][WIDTH][.[PREC]]{doxX}n
|
|
||||||
printf-style spec for input line number
|
|
||||||
.IP
|
|
||||||
Either GFMT or LFMT may contain:
|
|
||||||
.TP
|
|
||||||
%%
|
|
||||||
%
|
|
||||||
.TP
|
|
||||||
%c'C'
|
|
||||||
the single character C
|
|
||||||
.TP
|
|
||||||
%c'\eOOO'
|
|
||||||
the character with octal code OOO
|
|
||||||
.TP
|
|
||||||
\fB\-l\fR \fB\-\-paginate\fR
|
|
||||||
Pass the output through `pr' to paginate it.
|
|
||||||
.TP
|
|
||||||
\fB\-t\fR \fB\-\-expand\-tabs\fR
|
|
||||||
Expand tabs to spaces in output.
|
|
||||||
.TP
|
|
||||||
\fB\-T\fR \fB\-\-initial\-tab\fR
|
|
||||||
Make tabs line up by prepending a tab.
|
|
||||||
.TP
|
|
||||||
\fB\-\-tabsize\fR=\fINUM\fR
|
|
||||||
Tab stops are every NUM (default 8) print columns.
|
|
||||||
.TP
|
|
||||||
\fB\-r\fR \fB\-\-recursive\fR
|
|
||||||
Recursively compare any subdirectories found.
|
|
||||||
.TP
|
|
||||||
\fB\-N\fR \fB\-\-new\-file\fR
|
|
||||||
Treat absent files as empty.
|
|
||||||
.TP
|
|
||||||
\fB\-\-unidirectional\-new\-file\fR
|
|
||||||
Treat absent first files as empty.
|
|
||||||
.TP
|
|
||||||
\fB\-s\fR \fB\-\-report\-identical\-files\fR
|
|
||||||
Report when two files are the same.
|
|
||||||
.TP
|
|
||||||
\fB\-x\fR PAT \fB\-\-exclude\fR=\fIPAT\fR
|
|
||||||
Exclude files that match PAT.
|
|
||||||
.TP
|
|
||||||
\fB\-X\fR FILE \fB\-\-exclude\-from\fR=\fIFILE\fR
|
|
||||||
Exclude files that match any pattern in FILE.
|
|
||||||
.TP
|
|
||||||
\fB\-S\fR FILE \fB\-\-starting\-file\fR=\fIFILE\fR
|
|
||||||
Start with FILE when comparing directories.
|
|
||||||
.TP
|
|
||||||
\fB\-\-from\-file\fR=\fIFILE1\fR
|
|
||||||
Compare FILE1 to all operands. FILE1 can be a directory.
|
|
||||||
.TP
|
|
||||||
\fB\-\-to\-file\fR=\fIFILE2\fR
|
|
||||||
Compare all operands to FILE2. FILE2 can be a directory.
|
|
||||||
.TP
|
|
||||||
\fB\-\-horizon\-lines\fR=\fINUM\fR
|
|
||||||
Keep NUM lines of the common prefix and suffix.
|
|
||||||
.TP
|
|
||||||
\fB\-d\fR \fB\-\-minimal\fR
|
|
||||||
Try hard to find a smaller set of changes.
|
|
||||||
.TP
|
|
||||||
\fB\-\-speed\-large\-files\fR
|
|
||||||
Assume large files and many scattered small changes.
|
|
||||||
.TP
|
|
||||||
\fB\-v\fR \fB\-\-version\fR
|
|
||||||
Output version info.
|
|
||||||
.TP
|
|
||||||
\fB\-\-help\fR
|
|
||||||
Output this help.
|
|
||||||
.PP
|
|
||||||
FILES are `FILE1 FILE2' or `DIR1 DIR2' or `DIR FILE...' or `FILE... DIR'.
|
|
||||||
If \fB\-\-from\-file\fR or \fB\-\-to\-file\fR is given, there are no restrictions on FILES.
|
|
||||||
If a FILE is `-', read standard input.
|
|
||||||
Exit status is 0 if inputs are the same, 1 if different, 2 if trouble.
|
|
||||||
.SH AUTHOR
|
|
||||||
Written by Paul Eggert, Mike Haertel, David Hayes,
|
|
||||||
Richard Stallman, and Len Tower.
|
|
||||||
.SH "REPORTING BUGS"
|
|
||||||
Report bugs to <bug-gnu-utils@gnu.org>.
|
|
||||||
.SH COPYRIGHT
|
|
||||||
Copyright \(co 2004 Free Software Foundation, Inc.
|
|
||||||
.br
|
|
||||||
This is free software; see the source for copying conditions. There is NO
|
|
||||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
.SH "SEE ALSO"
|
|
||||||
The full documentation for
|
|
||||||
.B diff
|
|
||||||
is maintained as a Texinfo manual. If the
|
|
||||||
.B info
|
|
||||||
and
|
|
||||||
.B diff
|
|
||||||
programs are properly installed at your site, the command
|
|
||||||
.IP
|
|
||||||
.B info diff
|
|
||||||
.PP
|
|
||||||
should give you access to the complete manual.
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.33.
|
|
||||||
.TH DIFF3 "1" "April 2004" "diffutils 2.8.7" "User Commands"
|
|
||||||
.SH NAME
|
|
||||||
diff3 \- compare three files line by line
|
|
||||||
.SH SYNOPSIS
|
|
||||||
.B diff3
|
|
||||||
[\fIOPTION\fR]... \fIMYFILE OLDFILE YOURFILE\fR
|
|
||||||
.SH DESCRIPTION
|
|
||||||
Compare three files line by line.
|
|
||||||
.TP
|
|
||||||
\fB\-e\fR \fB\-\-ed\fR
|
|
||||||
Output unmerged changes from OLDFILE to YOURFILE into MYFILE.
|
|
||||||
.TP
|
|
||||||
\fB\-E\fR \fB\-\-show\-overlap\fR
|
|
||||||
Output unmerged changes, bracketing conflicts.
|
|
||||||
.TP
|
|
||||||
\fB\-A\fR \fB\-\-show\-all\fR
|
|
||||||
Output all changes, bracketing conflicts.
|
|
||||||
.TP
|
|
||||||
\fB\-x\fR \fB\-\-overlap\-only\fR
|
|
||||||
Output overlapping changes.
|
|
||||||
.TP
|
|
||||||
\fB\-X\fR
|
|
||||||
Output overlapping changes, bracketing them.
|
|
||||||
.TP
|
|
||||||
\fB\-3\fR \fB\-\-easy\-only\fR
|
|
||||||
Output unmerged nonoverlapping changes.
|
|
||||||
.TP
|
|
||||||
\fB\-m\fR \fB\-\-merge\fR
|
|
||||||
Output merged file instead of ed script (default \fB\-A\fR).
|
|
||||||
.TP
|
|
||||||
\fB\-L\fR LABEL \fB\-\-label\fR=\fILABEL\fR
|
|
||||||
Use LABEL instead of file name.
|
|
||||||
.TP
|
|
||||||
\fB\-i\fR
|
|
||||||
Append `w' and `q' commands to ed scripts.
|
|
||||||
.TP
|
|
||||||
\fB\-a\fR \fB\-\-text\fR
|
|
||||||
Treat all files as text.
|
|
||||||
.TP
|
|
||||||
\fB\-\-strip\-trailing\-cr\fR
|
|
||||||
Strip trailing carriage return on input.
|
|
||||||
.TP
|
|
||||||
\fB\-T\fR \fB\-\-initial\-tab\fR
|
|
||||||
Make tabs line up by prepending a tab.
|
|
||||||
.TP
|
|
||||||
\fB\-\-diff\-program\fR=\fIPROGRAM\fR
|
|
||||||
Use PROGRAM to compare files.
|
|
||||||
.TP
|
|
||||||
\fB\-v\fR \fB\-\-version\fR
|
|
||||||
Output version info.
|
|
||||||
.TP
|
|
||||||
\fB\-\-help\fR
|
|
||||||
Output this help.
|
|
||||||
.PP
|
|
||||||
If a FILE is `-', read standard input.
|
|
||||||
Exit status is 0 if successful, 1 if conflicts, 2 if trouble.
|
|
||||||
.SH AUTHOR
|
|
||||||
Written by Randy Smith.
|
|
||||||
.SH "REPORTING BUGS"
|
|
||||||
Report bugs to <bug-gnu-utils@gnu.org>.
|
|
||||||
.SH COPYRIGHT
|
|
||||||
Copyright \(co 2004 Free Software Foundation, Inc.
|
|
||||||
.br
|
|
||||||
This is free software; see the source for copying conditions. There is NO
|
|
||||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
.SH "SEE ALSO"
|
|
||||||
The full documentation for
|
|
||||||
.B diff3
|
|
||||||
is maintained as a Texinfo manual. If the
|
|
||||||
.B info
|
|
||||||
and
|
|
||||||
.B diff3
|
|
||||||
programs are properly installed at your site, the command
|
|
||||||
.IP
|
|
||||||
.B info diff3
|
|
||||||
.PP
|
|
||||||
should give you access to the complete manual.
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.33.
|
|
||||||
.TH SDIFF "1" "April 2004" "diffutils 2.8.7" "User Commands"
|
|
||||||
.SH NAME
|
|
||||||
sdiff \- side-by-side merge of file differences
|
|
||||||
.SH SYNOPSIS
|
|
||||||
.B sdiff
|
|
||||||
[\fIOPTION\fR]... \fIFILE1 FILE2\fR
|
|
||||||
.SH DESCRIPTION
|
|
||||||
Side-by-side merge of file differences.
|
|
||||||
.TP
|
|
||||||
\fB\-o\fR FILE \fB\-\-output\fR=\fIFILE\fR
|
|
||||||
Operate interactively, sending output to FILE.
|
|
||||||
.TP
|
|
||||||
\fB\-i\fR \fB\-\-ignore\-case\fR
|
|
||||||
Consider upper- and lower-case to be the same.
|
|
||||||
.TP
|
|
||||||
\fB\-E\fR \fB\-\-ignore\-tab\-expansion\fR
|
|
||||||
Ignore changes due to tab expansion.
|
|
||||||
.TP
|
|
||||||
\fB\-b\fR \fB\-\-ignore\-space\-change\fR
|
|
||||||
Ignore changes in the amount of white space.
|
|
||||||
.TP
|
|
||||||
\fB\-W\fR \fB\-\-ignore\-all\-space\fR
|
|
||||||
Ignore all white space.
|
|
||||||
.TP
|
|
||||||
\fB\-B\fR \fB\-\-ignore\-blank\-lines\fR
|
|
||||||
Ignore changes whose lines are all blank.
|
|
||||||
.TP
|
|
||||||
\fB\-I\fR RE \fB\-\-ignore\-matching\-lines\fR=\fIRE\fR
|
|
||||||
Ignore changes whose lines all match RE.
|
|
||||||
.TP
|
|
||||||
\fB\-\-strip\-trailing\-cr\fR
|
|
||||||
Strip trailing carriage return on input.
|
|
||||||
.TP
|
|
||||||
\fB\-a\fR \fB\-\-text\fR
|
|
||||||
Treat all files as text.
|
|
||||||
.TP
|
|
||||||
\fB\-w\fR NUM \fB\-\-width\fR=\fINUM\fR
|
|
||||||
Output at most NUM (default 130) print columns.
|
|
||||||
.TP
|
|
||||||
\fB\-l\fR \fB\-\-left\-column\fR
|
|
||||||
Output only the left column of common lines.
|
|
||||||
.TP
|
|
||||||
\fB\-s\fR \fB\-\-suppress\-common\-lines\fR
|
|
||||||
Do not output common lines.
|
|
||||||
.TP
|
|
||||||
\fB\-t\fR \fB\-\-expand\-tabs\fR
|
|
||||||
Expand tabs to spaces in output.
|
|
||||||
.TP
|
|
||||||
\fB\-\-tabsize\fR=\fINUM\fR
|
|
||||||
Tab stops are every NUM (default 8) print columns.
|
|
||||||
.TP
|
|
||||||
\fB\-d\fR \fB\-\-minimal\fR
|
|
||||||
Try hard to find a smaller set of changes.
|
|
||||||
.TP
|
|
||||||
\fB\-H\fR \fB\-\-speed\-large\-files\fR
|
|
||||||
Assume large files and many scattered small changes.
|
|
||||||
.TP
|
|
||||||
\fB\-\-diff\-program\fR=\fIPROGRAM\fR
|
|
||||||
Use PROGRAM to compare files.
|
|
||||||
.TP
|
|
||||||
\fB\-v\fR \fB\-\-version\fR
|
|
||||||
Output version info.
|
|
||||||
.TP
|
|
||||||
\fB\-\-help\fR
|
|
||||||
Output this help.
|
|
||||||
.PP
|
|
||||||
If a FILE is `-', read standard input.
|
|
||||||
Exit status is 0 if inputs are the same, 1 if different, 2 if trouble.
|
|
||||||
.SH AUTHOR
|
|
||||||
Written by Thomas Lord.
|
|
||||||
.SH "REPORTING BUGS"
|
|
||||||
Report bugs to <bug-gnu-utils@gnu.org>.
|
|
||||||
.SH COPYRIGHT
|
|
||||||
Copyright \(co 2004 Free Software Foundation, Inc.
|
|
||||||
.br
|
|
||||||
This is free software; see the source for copying conditions. There is NO
|
|
||||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
.SH "SEE ALSO"
|
|
||||||
The full documentation for
|
|
||||||
.B sdiff
|
|
||||||
is maintained as a Texinfo manual. If the
|
|
||||||
.B info
|
|
||||||
and
|
|
||||||
.B sdiff
|
|
||||||
programs are properly installed at your site, the command
|
|
||||||
.IP
|
|
||||||
.B info diff
|
|
||||||
.PP
|
|
||||||
should give you access to the complete manual.
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,677 +0,0 @@
|
|||||||
/* cmp - compare two files byte by byte
|
|
||||||
|
|
||||||
Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2001,
|
|
||||||
2002, 2004 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
|
||||||
any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
See the GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; see the file COPYING.
|
|
||||||
If not, write to the Free Software Foundation,
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#include "system.h"
|
|
||||||
#include "paths.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include <c-stack.h>
|
|
||||||
#include <cmpbuf.h>
|
|
||||||
#include <error.h>
|
|
||||||
#include <exit.h>
|
|
||||||
#include <exitfail.h>
|
|
||||||
#include <file-type.h>
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <hard-locale.h>
|
|
||||||
#include <inttostr.h>
|
|
||||||
#include <setmode.h>
|
|
||||||
#include <unlocked-io.h>
|
|
||||||
#include <version-etc.h>
|
|
||||||
#include <xalloc.h>
|
|
||||||
#include <xstrtol.h>
|
|
||||||
|
|
||||||
#if defined LC_MESSAGES && ENABLE_NLS
|
|
||||||
# define hard_locale_LC_MESSAGES hard_locale (LC_MESSAGES)
|
|
||||||
#else
|
|
||||||
# define hard_locale_LC_MESSAGES 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int cmp (void);
|
|
||||||
static off_t file_position (int);
|
|
||||||
static size_t block_compare (word const *, word const *);
|
|
||||||
static size_t block_compare_and_count (word const *, word const *, off_t *);
|
|
||||||
static void sprintc (char *, unsigned char);
|
|
||||||
|
|
||||||
/* Name under which this program was invoked. */
|
|
||||||
char *program_name;
|
|
||||||
|
|
||||||
/* Filenames of the compared files. */
|
|
||||||
static char const *file[2];
|
|
||||||
|
|
||||||
/* File descriptors of the files. */
|
|
||||||
static int file_desc[2];
|
|
||||||
|
|
||||||
/* Status of the files. */
|
|
||||||
static struct stat stat_buf[2];
|
|
||||||
|
|
||||||
/* Read buffers for the files. */
|
|
||||||
static word *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[2];
|
|
||||||
|
|
||||||
/* Number of bytes to compare. */
|
|
||||||
static uintmax_t bytes = UINTMAX_MAX;
|
|
||||||
|
|
||||||
/* Output format. */
|
|
||||||
static enum comparison_type
|
|
||||||
{
|
|
||||||
type_first_diff, /* Print the first difference. */
|
|
||||||
type_all_diffs, /* Print all differences. */
|
|
||||||
type_status /* Exit status only. */
|
|
||||||
} comparison_type;
|
|
||||||
|
|
||||||
/* If nonzero, print values of bytes quoted like cat -t does. */
|
|
||||||
static bool opt_print_bytes;
|
|
||||||
|
|
||||||
/* Values for long options that do not have single-letter equivalents. */
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
HELP_OPTION = CHAR_MAX + 1
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct option const long_options[] =
|
|
||||||
{
|
|
||||||
{"print-bytes", 0, 0, 'b'},
|
|
||||||
{"print-chars", 0, 0, 'c'}, /* obsolescent as of diffutils 2.7.3 */
|
|
||||||
{"ignore-initial", 1, 0, 'i'},
|
|
||||||
{"verbose", 0, 0, 'l'},
|
|
||||||
{"bytes", 1, 0, 'n'},
|
|
||||||
{"silent", 0, 0, 's'},
|
|
||||||
{"quiet", 0, 0, 's'},
|
|
||||||
{"version", 0, 0, 'v'},
|
|
||||||
{"help", 0, 0, HELP_OPTION},
|
|
||||||
{0, 0, 0, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
static void try_help (char const *, char const *) __attribute__((noreturn));
|
|
||||||
static void
|
|
||||||
try_help (char const *reason_msgid, char const *operand)
|
|
||||||
{
|
|
||||||
if (reason_msgid)
|
|
||||||
error (0, 0, _(reason_msgid), operand);
|
|
||||||
error (EXIT_TROUBLE, 0,
|
|
||||||
_("Try `%s --help' for more information."), program_name);
|
|
||||||
abort ();
|
|
||||||
}
|
|
||||||
|
|
||||||
static char const valid_suffixes[] = "kKMGTPEZY0";
|
|
||||||
|
|
||||||
/* Update ignore_initial[F] according to the result of parsing an
|
|
||||||
*operand ARGPTR of --ignore-initial, updating *ARGPTR to point
|
|
||||||
*after the operand. If DELIMITER is nonzero, the operand may be
|
|
||||||
*followed by DELIMITER; otherwise it must be null-terminated. */
|
|
||||||
static void
|
|
||||||
specify_ignore_initial (int f, char **argptr, char delimiter)
|
|
||||||
{
|
|
||||||
uintmax_t val;
|
|
||||||
off_t o;
|
|
||||||
char const *arg = *argptr;
|
|
||||||
strtol_error e = xstrtoumax (arg, argptr, 0, &val, valid_suffixes);
|
|
||||||
if (! (e == LONGINT_OK
|
|
||||||
|| (e == LONGINT_INVALID_SUFFIX_CHAR && **argptr == delimiter))
|
|
||||||
|| (o = val) < 0 || o != val || val == UINTMAX_MAX)
|
|
||||||
try_help ("invalid --ignore-initial value `%s'", arg);
|
|
||||||
if (ignore_initial[f] < o)
|
|
||||||
ignore_initial[f] = o;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Specify the output format. */
|
|
||||||
static void
|
|
||||||
specify_comparison_type (enum comparison_type t)
|
|
||||||
{
|
|
||||||
if (comparison_type && comparison_type != t)
|
|
||||||
try_help ("options -l and -s are incompatible", 0);
|
|
||||||
comparison_type = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
check_stdout (void)
|
|
||||||
{
|
|
||||||
if (ferror (stdout))
|
|
||||||
error (EXIT_TROUBLE, 0, "%s", _("write failed"));
|
|
||||||
else if (fclose (stdout) != 0)
|
|
||||||
error (EXIT_TROUBLE, errno, "%s", _("standard output"));
|
|
||||||
}
|
|
||||||
|
|
||||||
static char const * const option_help_msgid[] = {
|
|
||||||
N_("-b --print-bytes Print differing bytes."),
|
|
||||||
N_("-i SKIP --ignore-initial=SKIP Skip the first SKIP bytes of input."),
|
|
||||||
N_("-i SKIP1:SKIP2 --ignore-initial=SKIP1:SKIP2"),
|
|
||||||
N_(" Skip the first SKIP1 bytes of FILE1 and the first SKIP2 bytes of FILE2."),
|
|
||||||
N_("-l --verbose Output byte numbers and values of all differing bytes."),
|
|
||||||
N_("-n LIMIT --bytes=LIMIT Compare at most LIMIT bytes."),
|
|
||||||
N_("-s --quiet --silent Output nothing; yield exit status only."),
|
|
||||||
N_("-v --version Output version info."),
|
|
||||||
N_("--help Output this help."),
|
|
||||||
0
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
usage (void)
|
|
||||||
{
|
|
||||||
char const * const *p;
|
|
||||||
|
|
||||||
printf (_("Usage: %s [OPTION]... FILE1 [FILE2 [SKIP1 [SKIP2]]]\n"),
|
|
||||||
program_name);
|
|
||||||
printf ("%s\n\n", _("Compare two files byte by byte."));
|
|
||||||
for (p = option_help_msgid; *p; p++)
|
|
||||||
printf (" %s\n", _(*p));
|
|
||||||
printf ("\n%s\n%s\n\n%s\n%s\n\n%s\n",
|
|
||||||
_("SKIP1 and SKIP2 are the number of bytes to skip in each file."),
|
|
||||||
_("SKIP values may be followed by the following multiplicative suffixes:\n\
|
|
||||||
kB 1000, K 1024, MB 1,000,000, M 1,048,576,\n\
|
|
||||||
GB 1,000,000,000, G 1,073,741,824, and so on for T, P, E, Z, Y."),
|
|
||||||
_("If a FILE is `-' or missing, read standard input."),
|
|
||||||
_("Exit status is 0 if inputs are the same, 1 if different, 2 if trouble."),
|
|
||||||
_("Report bugs to <bug-gnu-utils@gnu.org>."));
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
main (int argc, char **argv)
|
|
||||||
{
|
|
||||||
int c, f, exit_status;
|
|
||||||
size_t words_per_buffer;
|
|
||||||
|
|
||||||
exit_failure = EXIT_TROUBLE;
|
|
||||||
initialize_main (&argc, &argv);
|
|
||||||
program_name = argv[0];
|
|
||||||
setlocale (LC_ALL, "");
|
|
||||||
bindtextdomain (PACKAGE, LOCALEDIR);
|
|
||||||
textdomain (PACKAGE);
|
|
||||||
c_stack_action (0);
|
|
||||||
|
|
||||||
/* Parse command line options. */
|
|
||||||
|
|
||||||
while ((c = getopt_long (argc, argv, "bci:ln:sv", long_options, 0))
|
|
||||||
!= -1)
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case 'b':
|
|
||||||
case 'c': /* 'c' is obsolescent as of diffutils 2.7.3 */
|
|
||||||
opt_print_bytes = true;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'i':
|
|
||||||
specify_ignore_initial (0, &optarg, ':');
|
|
||||||
if (*optarg++ == ':')
|
|
||||||
specify_ignore_initial (1, &optarg, 0);
|
|
||||||
else if (ignore_initial[1] < ignore_initial[0])
|
|
||||||
ignore_initial[1] = ignore_initial[0];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'l':
|
|
||||||
specify_comparison_type (type_all_diffs);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'n':
|
|
||||||
{
|
|
||||||
uintmax_t n;
|
|
||||||
if (xstrtoumax (optarg, 0, 0, &n, valid_suffixes) != LONGINT_OK)
|
|
||||||
try_help ("invalid --bytes value `%s'", optarg);
|
|
||||||
if (n < bytes)
|
|
||||||
bytes = n;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 's':
|
|
||||||
specify_comparison_type (type_status);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'v':
|
|
||||||
/* TRANSLATORS: Please translate the second "o" in "Torbjorn
|
|
||||||
Granlund" to an o-with-umlaut (U+00F6, LATIN SMALL LETTER O
|
|
||||||
WITH DIAERESIS) if possible. */
|
|
||||||
version_etc (stdout, "cmp", PACKAGE_NAME, PACKAGE_VERSION,
|
|
||||||
_("Torbjorn Granlund"), "David MacKenzie", (char *) 0);
|
|
||||||
check_stdout ();
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
|
|
||||||
case HELP_OPTION:
|
|
||||||
usage ();
|
|
||||||
check_stdout ();
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
|
|
||||||
default:
|
|
||||||
try_help (0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (optind == argc)
|
|
||||||
try_help ("missing operand after `%s'", argv[argc - 1]);
|
|
||||||
|
|
||||||
file[0] = argv[optind++];
|
|
||||||
file[1] = optind < argc ? argv[optind++] : "-";
|
|
||||||
|
|
||||||
for (f = 0; f < 2 && optind < argc; f++)
|
|
||||||
{
|
|
||||||
char *arg = argv[optind++];
|
|
||||||
specify_ignore_initial (f, &arg, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (optind < argc)
|
|
||||||
try_help ("extra operand `%s'", argv[optind]);
|
|
||||||
|
|
||||||
for (f = 0; f < 2; f++)
|
|
||||||
{
|
|
||||||
/* If file[1] is "-", treat it first; this avoids a misdiagnostic if
|
|
||||||
stdin is closed and opening file[0] yields file descriptor 0. */
|
|
||||||
int f1 = f ^ (strcmp (file[1], "-") == 0);
|
|
||||||
|
|
||||||
/* Two files with the same name and offset are identical.
|
|
||||||
But wait until we open the file once, for proper diagnostics. */
|
|
||||||
if (f && ignore_initial[0] == ignore_initial[1]
|
|
||||||
&& file_name_cmp (file[0], file[1]) == 0)
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
|
|
||||||
file_desc[f1] = (strcmp (file[f1], "-") == 0
|
|
||||||
? STDIN_FILENO
|
|
||||||
: open (file[f1], O_RDONLY, 0));
|
|
||||||
if (file_desc[f1] < 0 || fstat (file_desc[f1], stat_buf + f1) != 0)
|
|
||||||
{
|
|
||||||
if (file_desc[f1] < 0 && comparison_type == type_status)
|
|
||||||
exit (EXIT_TROUBLE);
|
|
||||||
else
|
|
||||||
error (EXIT_TROUBLE, errno, "%s", file[f1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
set_binary_mode (file_desc[f1], true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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])
|
|
||||||
&& same_file_attributes (&stat_buf[0], &stat_buf[1])
|
|
||||||
&& file_position (0) == file_position (1))
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
|
|
||||||
/* 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
|
|
||||||
and if more bytes will be compared than are in the smaller file. */
|
|
||||||
|
|
||||||
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 (s0 < 0)
|
|
||||||
s0 = 0;
|
|
||||||
if (s1 < 0)
|
|
||||||
s1 = 0;
|
|
||||||
if (s0 != s1 && MIN (s0, s1) < bytes)
|
|
||||||
exit (EXIT_FAILURE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the optimal block size of the files. */
|
|
||||||
|
|
||||||
buf_size = buffer_lcm (STAT_BLOCKSIZE (stat_buf[0]),
|
|
||||||
STAT_BLOCKSIZE (stat_buf[1]),
|
|
||||||
PTRDIFF_MAX - sizeof (word));
|
|
||||||
|
|
||||||
/* Allocate word-aligned buffers, with space for sentinels at the end. */
|
|
||||||
|
|
||||||
words_per_buffer = (buf_size + 2 * sizeof (word) - 1) / sizeof (word);
|
|
||||||
buffer[0] = xmalloc (2 * sizeof (word) * words_per_buffer);
|
|
||||||
buffer[1] = buffer[0] + words_per_buffer;
|
|
||||||
|
|
||||||
exit_status = cmp ();
|
|
||||||
|
|
||||||
for (f = 0; f < 2; f++)
|
|
||||||
if (close (file_desc[f]) != 0)
|
|
||||||
error (EXIT_TROUBLE, errno, "%s", file[f]);
|
|
||||||
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 EXIT_SUCCESS if identical, EXIT_FAILURE if different,
|
|
||||||
>1 if error. */
|
|
||||||
|
|
||||||
static int
|
|
||||||
cmp (void)
|
|
||||||
{
|
|
||||||
off_t line_number = 1; /* Line number (1...) of difference. */
|
|
||||||
off_t byte_number = 1; /* Byte number (1...) of difference. */
|
|
||||||
uintmax_t remaining = bytes; /* Remaining number of bytes to compare. */
|
|
||||||
size_t read0, read1; /* Number of bytes read from each file. */
|
|
||||||
size_t first_diff; /* Offset (0...) in buffers of 1st diff. */
|
|
||||||
size_t smaller; /* The lesser of `read0' and `read1'. */
|
|
||||||
word *buffer0 = buffer[0];
|
|
||||||
word *buffer1 = buffer[1];
|
|
||||||
char *buf0 = (char *) buffer0;
|
|
||||||
char *buf1 = (char *) buffer1;
|
|
||||||
int ret = EXIT_SUCCESS;
|
|
||||||
int f;
|
|
||||||
int offset_width;
|
|
||||||
|
|
||||||
if (comparison_type == type_all_diffs)
|
|
||||||
{
|
|
||||||
off_t byte_number_max = MIN (bytes, TYPE_MAXIMUM (off_t));
|
|
||||||
|
|
||||||
for (f = 0; f < 2; f++)
|
|
||||||
if (S_ISREG (stat_buf[f].st_mode))
|
|
||||||
{
|
|
||||||
off_t file_bytes = stat_buf[f].st_size - file_position (f);
|
|
||||||
if (file_bytes < byte_number_max)
|
|
||||||
byte_number_max = file_bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (offset_width = 1; (byte_number_max /= 10) != 0; offset_width++)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (f = 0; f < 2; f++)
|
|
||||||
{
|
|
||||||
off_t ig = ignore_initial[f];
|
|
||||||
if (ig && file_position (f) == -1)
|
|
||||||
{
|
|
||||||
/* lseek failed; read and discard the ignored initial prefix. */
|
|
||||||
do
|
|
||||||
{
|
|
||||||
size_t bytes_to_read = MIN (ig, buf_size);
|
|
||||||
size_t r = block_read (file_desc[f], buf0, bytes_to_read);
|
|
||||||
if (r != bytes_to_read)
|
|
||||||
{
|
|
||||||
if (r == SIZE_MAX)
|
|
||||||
error (EXIT_TROUBLE, errno, "%s", file[f]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ig -= r;
|
|
||||||
}
|
|
||||||
while (ig);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
size_t bytes_to_read = buf_size;
|
|
||||||
|
|
||||||
if (remaining != UINTMAX_MAX)
|
|
||||||
{
|
|
||||||
if (remaining < bytes_to_read)
|
|
||||||
bytes_to_read = remaining;
|
|
||||||
remaining -= bytes_to_read;
|
|
||||||
}
|
|
||||||
|
|
||||||
read0 = block_read (file_desc[0], buf0, bytes_to_read);
|
|
||||||
if (read0 == SIZE_MAX)
|
|
||||||
error (EXIT_TROUBLE, errno, "%s", file[0]);
|
|
||||||
read1 = block_read (file_desc[1], buf1, bytes_to_read);
|
|
||||||
if (read1 == SIZE_MAX)
|
|
||||||
error (EXIT_TROUBLE, 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 (buffer0, buffer1, &line_number)
|
|
||||||
: block_compare (buffer0, buffer1));
|
|
||||||
|
|
||||||
byte_number += first_diff;
|
|
||||||
smaller = MIN (read0, read1);
|
|
||||||
|
|
||||||
if (first_diff < smaller)
|
|
||||||
{
|
|
||||||
switch (comparison_type)
|
|
||||||
{
|
|
||||||
case type_first_diff:
|
|
||||||
{
|
|
||||||
char byte_buf[INT_BUFSIZE_BOUND (off_t)];
|
|
||||||
char line_buf[INT_BUFSIZE_BOUND (off_t)];
|
|
||||||
char const *byte_num = offtostr (byte_number, byte_buf);
|
|
||||||
char const *line_num = offtostr (line_number, line_buf);
|
|
||||||
if (!opt_print_bytes)
|
|
||||||
{
|
|
||||||
/* See POSIX 1003.1-2001 for this format. This
|
|
||||||
message is used only in the POSIX locale, so it
|
|
||||||
need not be translated. */
|
|
||||||
static char const char_message[] =
|
|
||||||
"%s %s differ: char %s, line %s\n";
|
|
||||||
|
|
||||||
/* The POSIX rationale recommends using the word
|
|
||||||
"byte" outside the POSIX locale. Some gettext
|
|
||||||
implementations translate even in the POSIX
|
|
||||||
locale if certain other environment variables
|
|
||||||
are set, so use "byte" if a translation is
|
|
||||||
available, or if outside the POSIX locale. */
|
|
||||||
static char const byte_msgid[] =
|
|
||||||
N_("%s %s differ: byte %s, line %s\n");
|
|
||||||
char const *byte_message = _(byte_msgid);
|
|
||||||
bool use_byte_message = (byte_message != byte_msgid
|
|
||||||
|| hard_locale_LC_MESSAGES);
|
|
||||||
|
|
||||||
printf (use_byte_message ? byte_message : char_message,
|
|
||||||
file[0], file[1], byte_num, line_num);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned char c0 = buf0[first_diff];
|
|
||||||
unsigned char c1 = buf1[first_diff];
|
|
||||||
char s0[5];
|
|
||||||
char s1[5];
|
|
||||||
sprintc (s0, c0);
|
|
||||||
sprintc (s1, c1);
|
|
||||||
printf (_("%s %s differ: byte %s, line %s is %3o %s %3o %s\n"),
|
|
||||||
file[0], file[1], byte_num, line_num,
|
|
||||||
c0, s0, c1, s1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Fall through. */
|
|
||||||
case type_status:
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
|
|
||||||
case type_all_diffs:
|
|
||||||
do
|
|
||||||
{
|
|
||||||
unsigned char c0 = buf0[first_diff];
|
|
||||||
unsigned char c1 = buf1[first_diff];
|
|
||||||
if (c0 != c1)
|
|
||||||
{
|
|
||||||
char byte_buf[INT_BUFSIZE_BOUND (off_t)];
|
|
||||||
char const *byte_num = offtostr (byte_number, byte_buf);
|
|
||||||
if (!opt_print_bytes)
|
|
||||||
{
|
|
||||||
/* See POSIX 1003.1-2001 for this format. */
|
|
||||||
printf ("%*s %3o %3o\n",
|
|
||||||
offset_width, byte_num, c0, c1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char s0[5];
|
|
||||||
char s1[5];
|
|
||||||
sprintc (s0, c0);
|
|
||||||
sprintc (s1, c1);
|
|
||||||
printf ("%*s %3o %-4s %3o %s\n",
|
|
||||||
offset_width, byte_num, c0, s0, c1, s1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
byte_number++;
|
|
||||||
first_diff++;
|
|
||||||
}
|
|
||||||
while (first_diff < smaller);
|
|
||||||
ret = EXIT_FAILURE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (read0 != read1)
|
|
||||||
{
|
|
||||||
if (comparison_type != type_status)
|
|
||||||
{
|
|
||||||
/* See POSIX 1003.1-2001 for this format. */
|
|
||||||
fprintf (stderr, _("cmp: EOF on %s\n"), file[read1 < read0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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.
|
|
||||||
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 (word const *p0, word const *p1, off_t *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. */
|
|
||||||
size_t cnt = 0; /* Number of '\n' occurrences. */
|
|
||||||
word nnnn; /* Newline, sizeof (word) times. */
|
|
||||||
int i;
|
|
||||||
|
|
||||||
nnnn = 0;
|
|
||||||
for (i = 0; i < sizeof nnnn; i++)
|
|
||||||
nnnn = (nnnn << CHAR_BIT) | '\n';
|
|
||||||
|
|
||||||
/* Find the rough position of the first difference by reading words,
|
|
||||||
not bytes. */
|
|
||||||
|
|
||||||
for (l0 = p0, l1 = p1; (l = *l0) == *l1; l0++, l1++)
|
|
||||||
{
|
|
||||||
l ^= nnnn;
|
|
||||||
for (i = 0; i < sizeof l; i++)
|
|
||||||
{
|
|
||||||
unsigned char uc = l;
|
|
||||||
cnt += ! uc;
|
|
||||||
l >>= CHAR_BIT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the exact differing position (endianness independent). */
|
|
||||||
|
|
||||||
for (c0 = (char const *) l0, c1 = (char const *) l1;
|
|
||||||
*c0 == *c1;
|
|
||||||
c0++, c1++)
|
|
||||||
cnt += *c0 == '\n';
|
|
||||||
|
|
||||||
*count += cnt;
|
|
||||||
return c0 - (char const *) p0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compare two blocks of memory P0 and P1 until they differ.
|
|
||||||
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 (word const *p0, word const *p1)
|
|
||||||
{
|
|
||||||
word const *l0, *l1;
|
|
||||||
char const *c0, *c1;
|
|
||||||
|
|
||||||
/* Find the rough position of the first difference by reading words,
|
|
||||||
not bytes. */
|
|
||||||
|
|
||||||
for (l0 = p0, l1 = p1; *l0 == *l1; l0++, l1++)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Find the exact differing position (endianness independent). */
|
|
||||||
|
|
||||||
for (c0 = (char const *) l0, c1 = (char const *) l1;
|
|
||||||
*c0 == *c1;
|
|
||||||
c0++, c1++)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
return c0 - (char const *) p0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Put into BUF the unsigned char C, making unprintable bytes
|
|
||||||
visible by quoting like cat -t does. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
sprintc (char *buf, unsigned char c)
|
|
||||||
{
|
|
||||||
if (! isprint (c))
|
|
||||||
{
|
|
||||||
if (c >= 128)
|
|
||||||
{
|
|
||||||
*buf++ = 'M';
|
|
||||||
*buf++ = '-';
|
|
||||||
c -= 128;
|
|
||||||
}
|
|
||||||
if (c < 32)
|
|
||||||
{
|
|
||||||
*buf++ = '^';
|
|
||||||
c += 64;
|
|
||||||
}
|
|
||||||
else if (c == 127)
|
|
||||||
{
|
|
||||||
*buf++ = '^';
|
|
||||||
c = '?';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*buf++ = c;
|
|
||||||
*buf = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Position file F to ignore_initial[F] bytes from its initial position,
|
|
||||||
and yield its new position. Don't try more than once. */
|
|
||||||
|
|
||||||
static off_t
|
|
||||||
file_position (int f)
|
|
||||||
{
|
|
||||||
static bool positioned[2];
|
|
||||||
static off_t position[2];
|
|
||||||
|
|
||||||
if (! positioned[f])
|
|
||||||
{
|
|
||||||
positioned[f] = true;
|
|
||||||
position[f] = lseek (file_desc[f], ignore_initial[f], SEEK_CUR);
|
|
||||||
}
|
|
||||||
return position[f];
|
|
||||||
}
|
|
||||||
@@ -1,478 +0,0 @@
|
|||||||
/* Context-format output routines for GNU DIFF.
|
|
||||||
|
|
||||||
Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1998, 2001,
|
|
||||||
2002, 2004 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 this program; see the file COPYING.
|
|
||||||
If not, write to the Free Software Foundation,
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#include "diff.h"
|
|
||||||
#include <inttostr.h>
|
|
||||||
|
|
||||||
#ifdef ST_MTIM_NSEC
|
|
||||||
# define TIMESPEC_NS(timespec) ((timespec).ST_MTIM_NSEC)
|
|
||||||
#else
|
|
||||||
# define TIMESPEC_NS(timespec) 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
size_t nstrftime (char *, size_t, char const *, struct tm const *, int, long);
|
|
||||||
|
|
||||||
static char const *find_function (char const * const *, lin);
|
|
||||||
static struct change *find_hunk (struct change *);
|
|
||||||
static void mark_ignorable (struct change *);
|
|
||||||
static void pr_context_hunk (struct change *);
|
|
||||||
static void pr_unidiff_hunk (struct change *);
|
|
||||||
|
|
||||||
/* Last place find_function started searching from. */
|
|
||||||
static lin find_function_last_search;
|
|
||||||
|
|
||||||
/* The value find_function returned when it started searching there. */
|
|
||||||
static lin 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 (char const *mark,
|
|
||||||
struct file_data *inf,
|
|
||||||
char const *label)
|
|
||||||
{
|
|
||||||
if (label)
|
|
||||||
fprintf (outfile, "%s %s\n", mark, label);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char buf[MAX (INT_STRLEN_BOUND (int) + 32,
|
|
||||||
INT_STRLEN_BOUND (time_t) + 11)];
|
|
||||||
struct tm const *tm = localtime (&inf->stat.st_mtime);
|
|
||||||
long nsec = TIMESPEC_NS (inf->stat.st_mtim);
|
|
||||||
if (! (tm && nstrftime (buf, sizeof buf, time_format, tm, 0, nsec)))
|
|
||||||
{
|
|
||||||
time_t sec = inf->stat.st_mtime;
|
|
||||||
verify (info_preserved, sizeof inf->stat.st_mtime <= sizeof sec);
|
|
||||||
sprintf (buf, "%jd.%.9ld", (intmax_t)sec, nsec);
|
|
||||||
}
|
|
||||||
fprintf (outfile, "%s %s\t%s\n", mark, inf->name, buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print a header for a context diff, with the file names and dates. */
|
|
||||||
|
|
||||||
void
|
|
||||||
print_context_header (struct file_data inf[], bool unidiff)
|
|
||||||
{
|
|
||||||
if (unidiff)
|
|
||||||
{
|
|
||||||
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 (struct change *script, bool unidiff)
|
|
||||||
{
|
|
||||||
if (ignore_blank_lines || ignore_regexp.fastmap)
|
|
||||||
mark_ignorable (script);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
struct change *e;
|
|
||||||
for (e = script; e; e = e->link)
|
|
||||||
e->ignore = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
find_function_last_search = - files[0].prefix_lines;
|
|
||||||
find_function_last_match = LIN_MAX;
|
|
||||||
|
|
||||||
if (unidiff)
|
|
||||||
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 (struct file_data const *file, lin a, lin b)
|
|
||||||
{
|
|
||||||
long int trans_a, trans_b;
|
|
||||||
translate_range (file, a, b, &trans_a, &trans_b);
|
|
||||||
|
|
||||||
/* 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.
|
|
||||||
|
|
||||||
POSIX 1003.1-2001 requires two line numbers separated by a comma
|
|
||||||
even if the line numbers are the same. However, this does not
|
|
||||||
match existing practice and is surely an error in the
|
|
||||||
specification. */
|
|
||||||
|
|
||||||
if (trans_b <= trans_a)
|
|
||||||
fprintf (outfile, "%ld", trans_b);
|
|
||||||
else
|
|
||||||
fprintf (outfile, "%ld,%ld", trans_a, trans_b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print FUNCTION in a context header. */
|
|
||||||
static void
|
|
||||||
print_context_function (FILE *out, char const *function)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
putc (' ', out);
|
|
||||||
for (i = 0; i < 40 && function[i] != '\n'; i++)
|
|
||||||
continue;
|
|
||||||
fwrite (function, sizeof (char), i, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 (struct change *hunk)
|
|
||||||
{
|
|
||||||
lin first0, last0, first1, last1, i;
|
|
||||||
char const *prefix;
|
|
||||||
char const *function;
|
|
||||||
FILE *out;
|
|
||||||
|
|
||||||
/* Determine range of line numbers involved in each file. */
|
|
||||||
|
|
||||||
enum changes changes = analyze_hunk (hunk, &first0, &last0, &first1, &last1);
|
|
||||||
if (! changes)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Include a context's width before and after. */
|
|
||||||
|
|
||||||
i = - files[0].prefix_lines;
|
|
||||||
first0 = MAX (first0 - context, i);
|
|
||||||
first1 = MAX (first1 - context, i);
|
|
||||||
if (last0 < files[0].valid_lines - context)
|
|
||||||
last0 += context;
|
|
||||||
else
|
|
||||||
last0 = files[0].valid_lines - 1;
|
|
||||||
if (last1 < files[1].valid_lines - context)
|
|
||||||
last1 += context;
|
|
||||||
else
|
|
||||||
last1 = files[1].valid_lines - 1;
|
|
||||||
|
|
||||||
/* If desired, find the preceding function definition line in file 0. */
|
|
||||||
function = 0;
|
|
||||||
if (function_regexp.fastmap)
|
|
||||||
function = find_function (files[0].linbuf, first0);
|
|
||||||
|
|
||||||
begin_output ();
|
|
||||||
out = outfile;
|
|
||||||
|
|
||||||
fprintf (out, "***************");
|
|
||||||
|
|
||||||
if (function)
|
|
||||||
print_context_function (out, function);
|
|
||||||
|
|
||||||
fprintf (out, "\n*** ");
|
|
||||||
print_context_number_range (&files[0], first0, last0);
|
|
||||||
fprintf (out, " ****\n");
|
|
||||||
|
|
||||||
if (changes & OLD)
|
|
||||||
{
|
|
||||||
struct change *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 (changes & NEW)
|
|
||||||
{
|
|
||||||
struct change *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 (struct file_data const *file, lin a, lin b)
|
|
||||||
{
|
|
||||||
long int trans_a, trans_b;
|
|
||||||
translate_range (file, a, b, &trans_a, &trans_b);
|
|
||||||
|
|
||||||
/* We can have B < A in the case of a range of no lines.
|
|
||||||
In this case, we print the line number before the range,
|
|
||||||
which is B. It would be more logical to print A, but
|
|
||||||
'patch' expects B in order to detect diffs against empty files. */
|
|
||||||
if (trans_b <= trans_a)
|
|
||||||
fprintf (outfile, trans_b < trans_a ? "%ld,0" : "%ld", trans_b);
|
|
||||||
else
|
|
||||||
fprintf (outfile, "%ld,%ld", 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 (struct change *hunk)
|
|
||||||
{
|
|
||||||
lin first0, last0, first1, last1;
|
|
||||||
lin i, j, k;
|
|
||||||
struct change *next;
|
|
||||||
char const *function;
|
|
||||||
FILE *out;
|
|
||||||
|
|
||||||
/* Determine range of line numbers involved in each file. */
|
|
||||||
|
|
||||||
if (! analyze_hunk (hunk, &first0, &last0, &first1, &last1))
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Include a context's width before and after. */
|
|
||||||
|
|
||||||
i = - files[0].prefix_lines;
|
|
||||||
first0 = MAX (first0 - context, i);
|
|
||||||
first1 = MAX (first1 - context, i);
|
|
||||||
if (last0 < files[0].valid_lines - context)
|
|
||||||
last0 += context;
|
|
||||||
else
|
|
||||||
last0 = files[0].valid_lines - 1;
|
|
||||||
if (last1 < files[1].valid_lines - context)
|
|
||||||
last1 += context;
|
|
||||||
else
|
|
||||||
last1 = files[1].valid_lines - 1;
|
|
||||||
|
|
||||||
/* If desired, find the preceding function definition line in file 0. */
|
|
||||||
function = 0;
|
|
||||||
if (function_regexp.fastmap)
|
|
||||||
function = find_function (files[0].linbuf, first0);
|
|
||||||
|
|
||||||
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 (function)
|
|
||||||
print_context_function (out, function);
|
|
||||||
|
|
||||||
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 (initial_tab ? '\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 (initial_tab)
|
|
||||||
putc ('\t', out);
|
|
||||||
print_1_line (0, &files[0].linbuf[i++]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Then output the inserted part. */
|
|
||||||
|
|
||||||
k = next->inserted;
|
|
||||||
while (k--)
|
|
||||||
{
|
|
||||||
putc ('+', out);
|
|
||||||
if (initial_tab)
|
|
||||||
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 (struct change *start)
|
|
||||||
{
|
|
||||||
struct change *prev;
|
|
||||||
lin top0, top1;
|
|
||||||
lin thresh;
|
|
||||||
|
|
||||||
/* Threshold distance is 2 * CONTEXT + 1 between two non-ignorable
|
|
||||||
changes, but only CONTEXT if one is ignorable. Watch out for
|
|
||||||
integer overflow, though. */
|
|
||||||
lin non_ignorable_threshold =
|
|
||||||
(LIN_MAX - 1) / 2 < context ? LIN_MAX : 2 * context + 1;
|
|
||||||
lin ignorable_threshold = context;
|
|
||||||
|
|
||||||
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;
|
|
||||||
thresh = (prev->ignore || (start && start->ignore)
|
|
||||||
? ignorable_threshold
|
|
||||||
: non_ignorable_threshold);
|
|
||||||
/* 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 (struct change *script)
|
|
||||||
{
|
|
||||||
while (script)
|
|
||||||
{
|
|
||||||
struct change *next = script->link;
|
|
||||||
lin first0, last0, first1, last1;
|
|
||||||
|
|
||||||
/* Turn this change into a hunk: detach it from the others. */
|
|
||||||
script->link = 0;
|
|
||||||
|
|
||||||
/* Determine whether this change is ignorable. */
|
|
||||||
script->ignore = ! analyze_hunk (script,
|
|
||||||
&first0, &last0, &first1, &last1);
|
|
||||||
|
|
||||||
/* Reconnect the chain as before. */
|
|
||||||
script->link = next;
|
|
||||||
|
|
||||||
/* Advance to the following change. */
|
|
||||||
script = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the last function-header line in LINBUF prior to line number LINENUM.
|
|
||||||
This is a line containing a match for the regexp in `function_regexp'.
|
|
||||||
Return the address of the text, or 0 if no function-header is found. */
|
|
||||||
|
|
||||||
static char const *
|
|
||||||
find_function (char const * const *linbuf, lin linenum)
|
|
||||||
{
|
|
||||||
lin i = linenum;
|
|
||||||
lin last = find_function_last_search;
|
|
||||||
find_function_last_search = i;
|
|
||||||
|
|
||||||
while (last <= --i)
|
|
||||||
{
|
|
||||||
/* See if this line is what we want. */
|
|
||||||
char const *line = linbuf[i];
|
|
||||||
size_t linelen = linbuf[i + 1] - line - 1;
|
|
||||||
|
|
||||||
/* FIXME: re_search's size args should be size_t, not int. */
|
|
||||||
int len = MIN (linelen, INT_MAX);
|
|
||||||
|
|
||||||
if (0 <= re_search (&function_regexp, line, len, 0, len, 0))
|
|
||||||
{
|
|
||||||
find_function_last_match = i;
|
|
||||||
return line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* If we search back to where we started searching the previous time,
|
|
||||||
find the line we found last time. */
|
|
||||||
if (find_function_last_match != LIN_MAX)
|
|
||||||
return linbuf[find_function_last_match];
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,375 +0,0 @@
|
|||||||
/* Shared definitions for GNU DIFF
|
|
||||||
|
|
||||||
Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1998, 2001,
|
|
||||||
2002, 2004 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 this program; see the file COPYING.
|
|
||||||
If not, write to the Free Software Foundation,
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#include "system.h"
|
|
||||||
#include <regex.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <unlocked-io.h>
|
|
||||||
|
|
||||||
/* What kind of changes a hunk contains. */
|
|
||||||
enum changes
|
|
||||||
{
|
|
||||||
/* No changes: lines common to both files. */
|
|
||||||
UNCHANGED,
|
|
||||||
|
|
||||||
/* Deletes only: lines taken from just the first file. */
|
|
||||||
OLD,
|
|
||||||
|
|
||||||
/* Inserts only: lines taken from just the second file. */
|
|
||||||
NEW,
|
|
||||||
|
|
||||||
/* Both deletes and inserts: a hunk containing both old and new lines. */
|
|
||||||
CHANGED
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Variables for command line options */
|
|
||||||
|
|
||||||
#ifndef GDIFF_MAIN
|
|
||||||
# define XTERN extern
|
|
||||||
#else
|
|
||||||
# define XTERN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum output_style
|
|
||||||
{
|
|
||||||
/* No output style specified. */
|
|
||||||
OUTPUT_UNSPECIFIED,
|
|
||||||
|
|
||||||
/* 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)
|
|
||||||
|
|
||||||
XTERN enum output_style output_style;
|
|
||||||
|
|
||||||
/* Nonzero if output cannot be generated for identical files. */
|
|
||||||
XTERN bool 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. */
|
|
||||||
XTERN lin context;
|
|
||||||
|
|
||||||
/* Consider all files as text files (-a).
|
|
||||||
Don't interpret codes over 0177 as implying a "binary file". */
|
|
||||||
XTERN bool text;
|
|
||||||
|
|
||||||
/* Number of lines to keep in identical prefix and suffix. */
|
|
||||||
XTERN lin horizon_lines;
|
|
||||||
|
|
||||||
/* The significance of white space during comparisons. */
|
|
||||||
XTERN enum
|
|
||||||
{
|
|
||||||
/* All white space is significant (the default). */
|
|
||||||
IGNORE_NO_WHITE_SPACE,
|
|
||||||
|
|
||||||
/* Ignore changes due to tab expansion (-E). */
|
|
||||||
IGNORE_TAB_EXPANSION,
|
|
||||||
|
|
||||||
/* Ignore changes in horizontal white space (-b). */
|
|
||||||
IGNORE_SPACE_CHANGE,
|
|
||||||
|
|
||||||
/* Ignore all horizontal white space (-w). */
|
|
||||||
IGNORE_ALL_SPACE
|
|
||||||
} ignore_white_space;
|
|
||||||
|
|
||||||
/* Ignore changes that affect only blank lines (-B). */
|
|
||||||
XTERN bool ignore_blank_lines;
|
|
||||||
|
|
||||||
/* Files can be compared byte-by-byte, as if they were binary.
|
|
||||||
This depends on various options. */
|
|
||||||
XTERN bool files_can_be_treated_as_binary;
|
|
||||||
|
|
||||||
/* Ignore differences in case of letters (-i). */
|
|
||||||
XTERN bool ignore_case;
|
|
||||||
|
|
||||||
/* Ignore differences in case of letters in file names. */
|
|
||||||
XTERN bool ignore_file_name_case;
|
|
||||||
|
|
||||||
/* File labels for `-c' output headers (--label). */
|
|
||||||
XTERN char *file_label[2];
|
|
||||||
|
|
||||||
/* Regexp to identify function-header lines (-F). */
|
|
||||||
XTERN struct re_pattern_buffer function_regexp;
|
|
||||||
|
|
||||||
/* Ignore changes that affect only lines matching this regexp (-I). */
|
|
||||||
XTERN struct re_pattern_buffer ignore_regexp;
|
|
||||||
|
|
||||||
/* Say only whether files differ, not how (-q). */
|
|
||||||
XTERN bool brief;
|
|
||||||
|
|
||||||
/* Expand tabs in the output so the text lines up properly
|
|
||||||
despite the characters added to the front of each line (-t). */
|
|
||||||
XTERN bool expand_tabs;
|
|
||||||
|
|
||||||
/* Number of columns between tab stops. */
|
|
||||||
XTERN size_t tabsize;
|
|
||||||
|
|
||||||
/* Use a tab in the output, rather than a space, before the text of an
|
|
||||||
input line, so as to keep the proper alignment in the input line
|
|
||||||
without changing the characters in it (-T). */
|
|
||||||
XTERN bool initial_tab;
|
|
||||||
|
|
||||||
/* Remove trailing carriage returns from input. */
|
|
||||||
XTERN bool strip_trailing_cr;
|
|
||||||
|
|
||||||
/* In directory comparison, specify file to start with (-S).
|
|
||||||
This is used for resuming an aborted comparison.
|
|
||||||
All file names less than this name are ignored. */
|
|
||||||
XTERN char const *starting_file;
|
|
||||||
|
|
||||||
/* Pipe each file's output through pr (-l). */
|
|
||||||
XTERN bool paginate;
|
|
||||||
|
|
||||||
/* Line group formats for unchanged, old, new, and changed groups. */
|
|
||||||
XTERN char const *group_format[CHANGED + 1];
|
|
||||||
|
|
||||||
/* Line formats for unchanged, old, and new lines. */
|
|
||||||
XTERN char const *line_format[NEW + 1];
|
|
||||||
|
|
||||||
/* If using OUTPUT_SDIFF print extra information to help the sdiff filter. */
|
|
||||||
XTERN bool sdiff_merge_assist;
|
|
||||||
|
|
||||||
/* Tell OUTPUT_SDIFF to show only the left version of common lines. */
|
|
||||||
XTERN bool left_column;
|
|
||||||
|
|
||||||
/* Tell OUTPUT_SDIFF to not show common lines. */
|
|
||||||
XTERN bool suppress_common_lines;
|
|
||||||
|
|
||||||
/* The half line width and column 2 offset for OUTPUT_SDIFF. */
|
|
||||||
XTERN size_t sdiff_half_width;
|
|
||||||
XTERN size_t 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. */
|
|
||||||
XTERN char *switch_string;
|
|
||||||
|
|
||||||
/* Use heuristics for better speed with large files with a small
|
|
||||||
density of changes. */
|
|
||||||
XTERN bool speed_large_files;
|
|
||||||
|
|
||||||
/* Patterns that match file names to be excluded. */
|
|
||||||
XTERN struct exclude *excluded;
|
|
||||||
|
|
||||||
/* Don't discard lines. This makes things slower (sometimes much
|
|
||||||
slower) but will find a guaranteed minimal set of changes. */
|
|
||||||
XTERN bool minimal;
|
|
||||||
|
|
||||||
/* Name of program the user invoked (for error messages). */
|
|
||||||
XTERN char *program_name;
|
|
||||||
|
|
||||||
/* The strftime format to use for time strings. */
|
|
||||||
XTERN char const *time_format;
|
|
||||||
|
|
||||||
/* 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 */
|
|
||||||
lin inserted; /* # lines of file 1 changed here. */
|
|
||||||
lin deleted; /* # lines of file 0 changed here. */
|
|
||||||
lin line0; /* Line number of 1st deleted line. */
|
|
||||||
lin line1; /* Line number of 1st inserted line. */
|
|
||||||
bool 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 */
|
|
||||||
|
|
||||||
/* Buffer in which text of file is read. */
|
|
||||||
word *buffer;
|
|
||||||
|
|
||||||
/* Allocated size of buffer, in bytes. Always a multiple of
|
|
||||||
sizeof *buffer. */
|
|
||||||
size_t bufsize;
|
|
||||||
|
|
||||||
/* Number of valid bytes now in the buffer. */
|
|
||||||
size_t buffered;
|
|
||||||
|
|
||||||
/* 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. */
|
|
||||||
lin 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]. */
|
|
||||||
lin 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. */
|
|
||||||
lin *equivs;
|
|
||||||
|
|
||||||
/* Vector, like the previous one except that
|
|
||||||
the elements for discarded lines have been squeezed out. */
|
|
||||||
lin *undiscarded;
|
|
||||||
|
|
||||||
/* Vector mapping virtual line numbers (not counting discarded lines)
|
|
||||||
to real ones (counting those lines). Both are origin-0. */
|
|
||||||
lin *realindexes;
|
|
||||||
|
|
||||||
/* Total number of nondiscarded lines. */
|
|
||||||
lin 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;
|
|
||||||
|
|
||||||
/* 1 if file ends in a line with no final newline. */
|
|
||||||
bool missing_newline;
|
|
||||||
|
|
||||||
/* 1 if at end of file. */
|
|
||||||
bool eof;
|
|
||||||
|
|
||||||
/* 1 more than the maximum equivalence value used for this or its
|
|
||||||
sibling file. */
|
|
||||||
lin equiv_max;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The file buffer, considered as an array of bytes rather than
|
|
||||||
as an array of words. */
|
|
||||||
#define FILE_BUFFER(f) ((char *) (f)->buffer)
|
|
||||||
|
|
||||||
/* Data on two input files being compared. */
|
|
||||||
|
|
||||||
struct comparison
|
|
||||||
{
|
|
||||||
struct file_data file[2];
|
|
||||||
struct comparison const *parent; /* parent, if a recursive comparison */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Describe the two files currently being compared. */
|
|
||||||
|
|
||||||
XTERN struct file_data files[2];
|
|
||||||
|
|
||||||
/* Stdio stream to output diffs to. */
|
|
||||||
|
|
||||||
XTERN FILE *outfile;
|
|
||||||
|
|
||||||
/* Declare various functions. */
|
|
||||||
|
|
||||||
/* analyze.c */
|
|
||||||
int diff_2_files (struct comparison *);
|
|
||||||
|
|
||||||
/* context.c */
|
|
||||||
void print_context_header (struct file_data[], bool);
|
|
||||||
void print_context_script (struct change *, bool);
|
|
||||||
|
|
||||||
/* dir.c */
|
|
||||||
int diff_dirs (struct comparison const *, int (*) (struct comparison const *, char const *, char const *));
|
|
||||||
|
|
||||||
/* ed.c */
|
|
||||||
void print_ed_script (struct change *);
|
|
||||||
void pr_forward_ed_script (struct change *);
|
|
||||||
|
|
||||||
/* ifdef.c */
|
|
||||||
void print_ifdef_script (struct change *);
|
|
||||||
|
|
||||||
/* io.c */
|
|
||||||
void file_block_read (struct file_data *, size_t);
|
|
||||||
bool read_files (struct file_data[], bool);
|
|
||||||
|
|
||||||
/* normal.c */
|
|
||||||
void print_normal_script (struct change *);
|
|
||||||
|
|
||||||
/* rcs.c */
|
|
||||||
void print_rcs_script (struct change *);
|
|
||||||
|
|
||||||
/* side.c */
|
|
||||||
void print_sdiff_script (struct change *);
|
|
||||||
|
|
||||||
/* util.c */
|
|
||||||
extern char const change_letter[4];
|
|
||||||
extern char const pr_program[];
|
|
||||||
char *concat (char const *, char const *, char const *);
|
|
||||||
char *dir_file_pathname (char const *, char const *);
|
|
||||||
bool lines_differ (char const *, char const *);
|
|
||||||
lin translate_line_number (struct file_data const *, lin);
|
|
||||||
struct change *find_change (struct change *);
|
|
||||||
struct change *find_reverse_change (struct change *);
|
|
||||||
void *zalloc (size_t);
|
|
||||||
enum changes analyze_hunk (struct change *, lin *, lin *, lin *, lin *);
|
|
||||||
void begin_output (void);
|
|
||||||
void debug_script (struct change *);
|
|
||||||
void fatal (char const *) __attribute__((noreturn));
|
|
||||||
void finish_output (void);
|
|
||||||
void message (char const *, char const *, char const *);
|
|
||||||
void message5 (char const *, char const *, char const *, char const *, char const *);
|
|
||||||
void output_1_line (char const *, char const *, char const *, char const *);
|
|
||||||
void perror_with_name (char const *);
|
|
||||||
void pfatal_with_name (char const *) __attribute__((noreturn));
|
|
||||||
void print_1_line (char const *, char const * const *);
|
|
||||||
void print_message_queue (void);
|
|
||||||
void print_number_range (char, struct file_data *, lin, lin);
|
|
||||||
void print_script (struct change *, struct change * (*) (struct change *), void (*) (struct change *));
|
|
||||||
void setup_output (char const *, char const *, bool);
|
|
||||||
void translate_range (struct file_data const *, lin, lin, long int *, long int *);
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,288 +0,0 @@
|
|||||||
/* Read, sort and compare two directories. Used for GNU DIFF.
|
|
||||||
|
|
||||||
Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1998, 2001, 2002,
|
|
||||||
2004 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 this program; see the file COPYING.
|
|
||||||
If not, write to the Free Software Foundation,
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#include "diff.h"
|
|
||||||
#include <error.h>
|
|
||||||
#include <exclude.h>
|
|
||||||
#include <setjmp.h>
|
|
||||||
#include <strcase.h>
|
|
||||||
#include <xalloc.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
|
|
||||||
{
|
|
||||||
size_t nnames; /* Number of names. */
|
|
||||||
char const **names; /* Sorted names of files in dir, followed by 0. */
|
|
||||||
char *data; /* Allocated storage for file names. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Whether file names in directories should be compared with
|
|
||||||
locale-specific sorting. */
|
|
||||||
static bool locale_specific_sorting;
|
|
||||||
|
|
||||||
/* Where to go if locale-specific sorting fails. */
|
|
||||||
static jmp_buf failed_locale_specific_sorting;
|
|
||||||
|
|
||||||
static bool dir_loop (struct comparison const *, int);
|
|
||||||
static int compare_names_for_qsort (void const *, void const *);
|
|
||||||
|
|
||||||
|
|
||||||
/* Read a directory and get its vector of names. */
|
|
||||||
|
|
||||||
static bool
|
|
||||||
dir_read (struct file_data const *dir, struct dirdata *dirdata)
|
|
||||||
{
|
|
||||||
register struct dirent *next;
|
|
||||||
register size_t 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 false;
|
|
||||||
|
|
||||||
/* Initialize the table of filenames. */
|
|
||||||
|
|
||||||
data_alloc = 512;
|
|
||||||
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 "." and "..". */
|
|
||||||
if (d_name[0] == '.'
|
|
||||||
&& (d_name[1] == 0 || (d_name[1] == '.' && d_name[2] == 0)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (excluded_filename (excluded, d_name))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
while (data_alloc < data_used + d_size)
|
|
||||||
{
|
|
||||||
if (PTRDIFF_MAX / 2 <= data_alloc)
|
|
||||||
xalloc_die ();
|
|
||||||
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 false;
|
|
||||||
}
|
|
||||||
#if CLOSEDIR_VOID
|
|
||||||
closedir (reading);
|
|
||||||
#else
|
|
||||||
if (closedir (reading) != 0)
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Create the `names' table from the `data' table. */
|
|
||||||
if (PTRDIFF_MAX / sizeof *names - 1 <= nnames)
|
|
||||||
xalloc_die ();
|
|
||||||
dirdata->names = names = xmalloc ((nnames + 1) * sizeof *names);
|
|
||||||
dirdata->nnames = nnames;
|
|
||||||
for (i = 0; i < nnames; i++)
|
|
||||||
{
|
|
||||||
names[i] = data;
|
|
||||||
data += strlen (data) + 1;
|
|
||||||
}
|
|
||||||
names[nnames] = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compare file names, returning a value compatible with strcmp. */
|
|
||||||
|
|
||||||
static int
|
|
||||||
compare_names (char const *name1, char const *name2)
|
|
||||||
{
|
|
||||||
if (locale_specific_sorting)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
errno = 0;
|
|
||||||
if (ignore_file_name_case)
|
|
||||||
r = strcasecoll (name1, name2);
|
|
||||||
else
|
|
||||||
r = strcoll (name1, name2);
|
|
||||||
if (errno)
|
|
||||||
{
|
|
||||||
error (0, errno, _("cannot compare file names `%s' and `%s'"),
|
|
||||||
name1, name2);
|
|
||||||
longjmp (failed_locale_specific_sorting, 1);
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (ignore_file_name_case
|
|
||||||
? strcasecmp (name1, name2)
|
|
||||||
: file_name_cmp (name1, name2));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* A wrapper for compare_names suitable as an argument for qsort. */
|
|
||||||
|
|
||||||
static int
|
|
||||||
compare_names_for_qsort (void const *file1, void const *file2)
|
|
||||||
{
|
|
||||||
char const *const *f1 = file1;
|
|
||||||
char const *const *f2 = file2;
|
|
||||||
return compare_names (*f1, *f2);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Compare the contents of two directories named in CMP.
|
|
||||||
This is a top-level routine; it does everything necessary for diff
|
|
||||||
on two directories.
|
|
||||||
|
|
||||||
CMP->file[0].desc == -1 says directory CMP->file[0] doesn't exist,
|
|
||||||
but pretend it is empty. Likewise for CMP->file[1].
|
|
||||||
|
|
||||||
HANDLE_FILE is a caller-provided subroutine called to handle each file.
|
|
||||||
It gets three operands: CMP, name of file in dir 0, name of file in dir 1.
|
|
||||||
These names are relative to the original working directory.
|
|
||||||
|
|
||||||
For a file that appears in only one of the dirs, one of the name-args
|
|
||||||
to HANDLE_FILE is zero.
|
|
||||||
|
|
||||||
Returns the maximum of all the values returned by HANDLE_FILE,
|
|
||||||
or EXIT_TROUBLE if trouble is encountered in opening files. */
|
|
||||||
|
|
||||||
int
|
|
||||||
diff_dirs (struct comparison const *cmp,
|
|
||||||
int (*handle_file) (struct comparison const *,
|
|
||||||
char const *, char const *))
|
|
||||||
{
|
|
||||||
struct dirdata dirdata[2];
|
|
||||||
int volatile val = EXIT_SUCCESS;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if ((cmp->file[0].desc == -1 || dir_loop (cmp, 0))
|
|
||||||
&& (cmp->file[1].desc == -1 || dir_loop (cmp, 1)))
|
|
||||||
{
|
|
||||||
error (0, 0, "%s: recursive directory loop",
|
|
||||||
cmp->file[cmp->file[0].desc == -1].name);
|
|
||||||
return EXIT_TROUBLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get contents of both dirs. */
|
|
||||||
for (i = 0; i < 2; i++)
|
|
||||||
if (! dir_read (&cmp->file[i], &dirdata[i]))
|
|
||||||
{
|
|
||||||
perror_with_name (cmp->file[i].name);
|
|
||||||
val = EXIT_TROUBLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (val == EXIT_SUCCESS)
|
|
||||||
{
|
|
||||||
char const **volatile names[2];
|
|
||||||
names[0] = dirdata[0].names;
|
|
||||||
names[1] = dirdata[1].names;
|
|
||||||
|
|
||||||
/* Use locale-specific sorting if possible, else native byte order. */
|
|
||||||
locale_specific_sorting = true;
|
|
||||||
if (setjmp (failed_locale_specific_sorting))
|
|
||||||
locale_specific_sorting = false;
|
|
||||||
|
|
||||||
/* Sort the directories. */
|
|
||||||
for (i = 0; i < 2; i++)
|
|
||||||
qsort (names[i], dirdata[i].nnames, sizeof *dirdata[i].names,
|
|
||||||
compare_names_for_qsort);
|
|
||||||
|
|
||||||
/* If `-S name' was given, and this is the topmost level of comparison,
|
|
||||||
ignore all file names less than the specified starting name. */
|
|
||||||
|
|
||||||
if (starting_file && ! cmp->parent)
|
|
||||||
{
|
|
||||||
while (*names[0] && compare_names (*names[0], starting_file) < 0)
|
|
||||||
names[0]++;
|
|
||||||
while (*names[1] && compare_names (*names[1], starting_file) < 0)
|
|
||||||
names[1]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Loop while files remain in one or both dirs. */
|
|
||||||
while (*names[0] || *names[1])
|
|
||||||
{
|
|
||||||
/* 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 = (!*names[0] ? 1 : !*names[1] ? -1
|
|
||||||
: compare_names (*names[0], *names[1]));
|
|
||||||
int v1 = (*handle_file) (cmp,
|
|
||||||
0 < nameorder ? 0 : *names[0]++,
|
|
||||||
nameorder < 0 ? 0 : *names[1]++);
|
|
||||||
if (val < v1)
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return nonzero if CMP is looping recursively in argument I. */
|
|
||||||
|
|
||||||
static bool
|
|
||||||
dir_loop (struct comparison const *cmp, int i)
|
|
||||||
{
|
|
||||||
struct comparison const *p = cmp;
|
|
||||||
while ((p = p->parent))
|
|
||||||
if (0 < same_file (&p->file[i].stat, &cmp->file[i].stat))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
@@ -1,169 +0,0 @@
|
|||||||
/* Output routines for ed-script format.
|
|
||||||
|
|
||||||
Copyright (C) 1988, 1989, 1991, 1992, 1993, 1995, 1998, 2001, 2004
|
|
||||||
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 this program; see the file COPYING.
|
|
||||||
If not, write to the Free Software Foundation,
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#include "diff.h"
|
|
||||||
|
|
||||||
static void print_ed_hunk (struct change *);
|
|
||||||
static void print_rcs_hunk (struct change *);
|
|
||||||
static void pr_forward_ed_hunk (struct change *);
|
|
||||||
|
|
||||||
/* Print our script as ed commands. */
|
|
||||||
|
|
||||||
void
|
|
||||||
print_ed_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 (struct change *hunk)
|
|
||||||
{
|
|
||||||
lin f0, l0, f1, l1;
|
|
||||||
enum changes changes;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
debug_script (hunk);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Determine range of line numbers involved in each file. */
|
|
||||||
changes = analyze_hunk (hunk, &f0, &l0, &f1, &l1);
|
|
||||||
if (!changes)
|
|
||||||
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[changes]);
|
|
||||||
|
|
||||||
/* Print new/changed lines from second file, if needed */
|
|
||||||
if (changes != OLD)
|
|
||||||
{
|
|
||||||
lin i;
|
|
||||||
for (i = f1; i <= l1; i++)
|
|
||||||
{
|
|
||||||
if (files[1].linbuf[i][0] == '.' && files[1].linbuf[i][1] == '\n')
|
|
||||||
{
|
|
||||||
/* The file's line is just a dot, and it would exit
|
|
||||||
insert mode. Precede the dot with another dot, exit
|
|
||||||
insert mode, remove the extra dot, and then resume
|
|
||||||
insert mode. */
|
|
||||||
fprintf (outfile, "..\n.\ns/.//\na\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
print_1_line ("", &files[1].linbuf[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
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 (struct change *script)
|
|
||||||
{
|
|
||||||
print_script (script, find_change, pr_forward_ed_hunk);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
pr_forward_ed_hunk (struct change *hunk)
|
|
||||||
{
|
|
||||||
lin i, f0, l0, f1, l1;
|
|
||||||
|
|
||||||
/* Determine range of line numbers involved in each file. */
|
|
||||||
enum changes changes = analyze_hunk (hunk, &f0, &l0, &f1, &l1);
|
|
||||||
if (!changes)
|
|
||||||
return;
|
|
||||||
|
|
||||||
begin_output ();
|
|
||||||
|
|
||||||
fprintf (outfile, "%c", change_letter[changes]);
|
|
||||||
print_number_range (' ', files, f0, l0);
|
|
||||||
fprintf (outfile, "\n");
|
|
||||||
|
|
||||||
/* If deletion only, print just the number range. */
|
|
||||||
|
|
||||||
if (changes == OLD)
|
|
||||||
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 (struct change *script)
|
|
||||||
{
|
|
||||||
print_script (script, find_change, print_rcs_hunk);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print a hunk of an RCS diff */
|
|
||||||
|
|
||||||
static void
|
|
||||||
print_rcs_hunk (struct change *hunk)
|
|
||||||
{
|
|
||||||
lin i, f0, l0, f1, l1;
|
|
||||||
long int tf0, tl0, tf1, tl1;
|
|
||||||
|
|
||||||
/* Determine range of line numbers involved in each file. */
|
|
||||||
enum changes changes = analyze_hunk (hunk, &f0, &l0, &f1, &l1);
|
|
||||||
if (!changes)
|
|
||||||
return;
|
|
||||||
|
|
||||||
begin_output ();
|
|
||||||
|
|
||||||
translate_range (&files[0], f0, l0, &tf0, &tl0);
|
|
||||||
|
|
||||||
if (changes & OLD)
|
|
||||||
{
|
|
||||||
fprintf (outfile, "d");
|
|
||||||
/* For deletion, print just the starting line number from file 0
|
|
||||||
and the number of lines deleted. */
|
|
||||||
fprintf (outfile, "%ld %ld\n", tf0, tf0 <= tl0 ? tl0 - tf0 + 1 : 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (changes & NEW)
|
|
||||||
{
|
|
||||||
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, "%ld %ld\n", tl0, tf1 <= tl1 ? tl1 - tf1 + 1 : 1);
|
|
||||||
|
|
||||||
/* Print the inserted lines. */
|
|
||||||
for (i = f1; i <= l1; i++)
|
|
||||||
print_1_line ("", &files[1].linbuf[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,430 +0,0 @@
|
|||||||
/* #ifdef-format output routines for GNU DIFF.
|
|
||||||
|
|
||||||
Copyright (C) 1989, 1991, 1992, 1993, 1994, 2001, 2002, 2004 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"
|
|
||||||
|
|
||||||
#include <xalloc.h>
|
|
||||||
|
|
||||||
struct group
|
|
||||||
{
|
|
||||||
struct file_data const *file;
|
|
||||||
lin from, upto; /* start and limit lines for this group of lines */
|
|
||||||
};
|
|
||||||
|
|
||||||
static char const *format_group (FILE *, char const *, char,
|
|
||||||
struct group const *);
|
|
||||||
static char const *do_printf_spec (FILE *, char const *,
|
|
||||||
struct file_data const *, lin,
|
|
||||||
struct group const *);
|
|
||||||
static char const *scan_char_literal (char const *, char *);
|
|
||||||
static lin groups_letter_value (struct group const *, char);
|
|
||||||
static void format_ifdef (char const *, lin, lin, lin, lin);
|
|
||||||
static void print_ifdef_hunk (struct change *);
|
|
||||||
static void print_ifdef_lines (FILE *, char const *, struct group const *);
|
|
||||||
|
|
||||||
static lin next_line0;
|
|
||||||
static lin next_line1;
|
|
||||||
|
|
||||||
/* Print the edit-script SCRIPT as a merged #ifdef file. */
|
|
||||||
|
|
||||||
void
|
|
||||||
print_ifdef_script (struct change *script)
|
|
||||||
{
|
|
||||||
next_line0 = next_line1 = - files[0].prefix_lines;
|
|
||||||
print_script (script, find_change, print_ifdef_hunk);
|
|
||||||
if (next_line0 < files[0].valid_lines
|
|
||||||
|| next_line1 < files[1].valid_lines)
|
|
||||||
{
|
|
||||||
begin_output ();
|
|
||||||
format_ifdef (group_format[UNCHANGED],
|
|
||||||
next_line0, files[0].valid_lines,
|
|
||||||
next_line1, 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 (struct change *hunk)
|
|
||||||
{
|
|
||||||
lin first0, last0, first1, last1;
|
|
||||||
|
|
||||||
/* Determine range of line numbers involved in each file. */
|
|
||||||
enum changes changes = analyze_hunk (hunk, &first0, &last0, &first1, &last1);
|
|
||||||
if (!changes)
|
|
||||||
return;
|
|
||||||
|
|
||||||
begin_output ();
|
|
||||||
|
|
||||||
/* Print lines up to this change. */
|
|
||||||
if (next_line0 < first0 || next_line1 < first1)
|
|
||||||
format_ifdef (group_format[UNCHANGED],
|
|
||||||
next_line0, first0,
|
|
||||||
next_line1, first1);
|
|
||||||
|
|
||||||
/* Print this change. */
|
|
||||||
next_line0 = last0 + 1;
|
|
||||||
next_line1 = last1 + 1;
|
|
||||||
format_ifdef (group_format[changes],
|
|
||||||
first0, next_line0,
|
|
||||||
first1, next_line1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 (char const *format, lin beg0, lin end0, lin beg1, lin 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 const *
|
|
||||||
format_group (register FILE *out, char const *format, char endchar,
|
|
||||||
struct group const *groups)
|
|
||||||
{
|
|
||||||
register char c;
|
|
||||||
register char const *f = format;
|
|
||||||
|
|
||||||
while ((c = *f) != endchar && c != 0)
|
|
||||||
{
|
|
||||||
char const *f1 = ++f;
|
|
||||||
if (c == '%')
|
|
||||||
switch ((c = *f++))
|
|
||||||
{
|
|
||||||
case '%':
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '(':
|
|
||||||
/* Print if-then-else format e.g. `%(n=1?thenpart:elsepart)'. */
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
uintmax_t value[2];
|
|
||||||
FILE *thenout, *elseout;
|
|
||||||
|
|
||||||
for (i = 0; i < 2; i++)
|
|
||||||
{
|
|
||||||
if (ISDIGIT (*f))
|
|
||||||
{
|
|
||||||
char *fend;
|
|
||||||
errno = 0;
|
|
||||||
value[i] = strtoumax (f, &fend, 10);
|
|
||||||
if (errno)
|
|
||||||
goto bad_format;
|
|
||||||
f = fend;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
value[i] = groups_letter_value (groups, *f);
|
|
||||||
if (value[i] == -1)
|
|
||||||
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:
|
|
||||||
f = do_printf_spec (out, f - 2, 0, 0, groups);
|
|
||||||
if (f)
|
|
||||||
continue;
|
|
||||||
/* Fall through. */
|
|
||||||
bad_format:
|
|
||||||
c = '%';
|
|
||||||
f = f1;
|
|
||||||
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 lin
|
|
||||||
groups_letter_value (struct group const *g, char letter)
|
|
||||||
{
|
|
||||||
switch (letter)
|
|
||||||
{
|
|
||||||
case 'E': letter = 'e'; g++; break;
|
|
||||||
case 'F': letter = 'f'; g++; break;
|
|
||||||
case 'L': letter = 'l'; g++; break;
|
|
||||||
case 'M': letter = 'm'; g++; break;
|
|
||||||
case 'N': letter = 'n'; g++; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 (register FILE *out, char const *format,
|
|
||||||
struct group const *group)
|
|
||||||
{
|
|
||||||
struct file_data const *file = group->file;
|
|
||||||
char const * const *linbuf = file->linbuf;
|
|
||||||
lin from = group->from, upto = group->upto;
|
|
||||||
|
|
||||||
if (!out)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* If possible, use a single fwrite; it's faster. */
|
|
||||||
if (!expand_tabs && format[0] == '%')
|
|
||||||
{
|
|
||||||
if (format[1] == 'l' && format[2] == '\n' && !format[3] && from < upto)
|
|
||||||
{
|
|
||||||
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 const *f = format;
|
|
||||||
|
|
||||||
while ((c = *f++) != 0)
|
|
||||||
{
|
|
||||||
char const *f1 = f;
|
|
||||||
if (c == '%')
|
|
||||||
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:
|
|
||||||
f = do_printf_spec (out, f - 2, file, from, 0);
|
|
||||||
if (f)
|
|
||||||
continue;
|
|
||||||
c = '%';
|
|
||||||
f = f1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
putc (c, out);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static char const *
|
|
||||||
do_printf_spec (FILE *out, char const *spec,
|
|
||||||
struct file_data const *file, lin n,
|
|
||||||
struct group const *groups)
|
|
||||||
{
|
|
||||||
char const *f = spec;
|
|
||||||
char c;
|
|
||||||
char c1;
|
|
||||||
|
|
||||||
/* Scan printf-style SPEC of the form %[-'0]*[0-9]*(.[0-9]*)?[cdoxX]. */
|
|
||||||
/* assert (*f == '%'); */
|
|
||||||
f++;
|
|
||||||
while ((c = *f++) == '-' || c == '\'' || c == '0')
|
|
||||||
continue;
|
|
||||||
while (ISDIGIT (c))
|
|
||||||
c = *f++;
|
|
||||||
if (c == '.')
|
|
||||||
while (ISDIGIT (c = *f++))
|
|
||||||
continue;
|
|
||||||
c1 = *f++;
|
|
||||||
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case 'c':
|
|
||||||
if (c1 != '\'')
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char value;
|
|
||||||
f = scan_char_literal (f, &value);
|
|
||||||
if (!f)
|
|
||||||
return 0;
|
|
||||||
if (out)
|
|
||||||
putc (value, out);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'd': case 'o': case 'x': case 'X':
|
|
||||||
{
|
|
||||||
lin value;
|
|
||||||
|
|
||||||
if (file)
|
|
||||||
{
|
|
||||||
if (c1 != 'n')
|
|
||||||
return 0;
|
|
||||||
value = translate_line_number (file, n);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
value = groups_letter_value (groups, c1);
|
|
||||||
if (value < 0)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (out)
|
|
||||||
{
|
|
||||||
/* For example, if the spec is "%3xn", use the printf
|
|
||||||
format spec "%3lx". Here the spec prefix is "%3". */
|
|
||||||
long int long_value = value;
|
|
||||||
size_t spec_prefix_len = f - spec - 2;
|
|
||||||
#if HAVE_C_VARARRAYS
|
|
||||||
char format[spec_prefix_len + 3];
|
|
||||||
#else
|
|
||||||
char *format = xmalloc (spec_prefix_len + 3);
|
|
||||||
#endif
|
|
||||||
char *p = format + spec_prefix_len;
|
|
||||||
memcpy (format, spec, spec_prefix_len);
|
|
||||||
*p++ = 'l';
|
|
||||||
*p++ = c;
|
|
||||||
*p = '\0';
|
|
||||||
fprintf (out, format, long_value);
|
|
||||||
#if ! HAVE_C_VARARRAYS
|
|
||||||
free (format);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Scan the character literal represented in the string LIT; LIT points just
|
|
||||||
after the initial apostrophe. Put the literal's value into *VALPTR.
|
|
||||||
Yield the address of the first character after the closing apostrophe,
|
|
||||||
or zero if the literal is ill-formed. */
|
|
||||||
static char const *
|
|
||||||
scan_char_literal (char const *lit, char *valptr)
|
|
||||||
{
|
|
||||||
register char const *p = lit;
|
|
||||||
char value;
|
|
||||||
ptrdiff_t digits;
|
|
||||||
char c = *p++;
|
|
||||||
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
case '\'':
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case '\\':
|
|
||||||
value = 0;
|
|
||||||
while ((c = *p++) != '\'')
|
|
||||||
{
|
|
||||||
unsigned int 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
*valptr = value;
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
@@ -1,859 +0,0 @@
|
|||||||
/* File I/O for GNU DIFF.
|
|
||||||
|
|
||||||
Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1998, 2001, 2002,
|
|
||||||
2004 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 this program; see the file COPYING.
|
|
||||||
If not, write to the Free Software Foundation,
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#include "diff.h"
|
|
||||||
#include <cmpbuf.h>
|
|
||||||
#include <file-type.h>
|
|
||||||
#include <setmode.h>
|
|
||||||
#include <xalloc.h>
|
|
||||||
|
|
||||||
/* Rotate an unsigned value to the left. */
|
|
||||||
#define ROL(v, n) ((v) << (n) | (v) >> (sizeof (v) * CHAR_BIT - (n)))
|
|
||||||
|
|
||||||
/* Given a hash value and a new character, return a new hash value. */
|
|
||||||
#define HASH(h, c) ((c) + ROL (h, 7))
|
|
||||||
|
|
||||||
/* The type of a hash value. */
|
|
||||||
typedef size_t hash_value;
|
|
||||||
verify (hash_value_is_unsigned, ! TYPE_SIGNED (hash_value));
|
|
||||||
|
|
||||||
/* Lines are put into equivalence classes of lines that match in lines_differ.
|
|
||||||
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
|
|
||||||
{
|
|
||||||
lin next; /* Next item in this bucket. */
|
|
||||||
hash_value 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 lin *buckets;
|
|
||||||
|
|
||||||
/* Number of buckets in the hash table array, not counting buckets[-1]. */
|
|
||||||
static size_t 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 lin equivs_index;
|
|
||||||
|
|
||||||
/* Number of elements allocated in the array `equivs'. */
|
|
||||||
static lin equivs_alloc;
|
|
||||||
|
|
||||||
/* Read a block of data into a file buffer, checking for EOF and error. */
|
|
||||||
|
|
||||||
void
|
|
||||||
file_block_read (struct file_data *current, size_t size)
|
|
||||||
{
|
|
||||||
if (size && ! current->eof)
|
|
||||||
{
|
|
||||||
size_t s = block_read (current->desc,
|
|
||||||
FILE_BUFFER (current) + current->buffered, size);
|
|
||||||
if (s == SIZE_MAX)
|
|
||||||
pfatal_with_name (current->name);
|
|
||||||
current->buffered += s;
|
|
||||||
current->eof = s < size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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. */
|
|
||||||
|
|
||||||
static bool
|
|
||||||
sip (struct file_data *current, bool 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 = buffer_lcm (sizeof (word),
|
|
||||||
STAT_BLOCKSIZE (current->stat),
|
|
||||||
PTRDIFF_MAX - 2 * sizeof (word));
|
|
||||||
current->buffer = xmalloc (current->bufsize);
|
|
||||||
|
|
||||||
if (! skip_test)
|
|
||||||
{
|
|
||||||
/* Check first part of file to see if it's a binary file. */
|
|
||||||
|
|
||||||
bool was_binary = set_binary_mode (current->desc, true);
|
|
||||||
off_t buffered;
|
|
||||||
file_block_read (current, current->bufsize);
|
|
||||||
buffered = current->buffered;
|
|
||||||
|
|
||||||
if (! was_binary)
|
|
||||||
{
|
|
||||||
/* Revert to text mode and seek back to the beginning to
|
|
||||||
reread the file. Use relative seek, since file
|
|
||||||
descriptors like stdin might not start at offset
|
|
||||||
zero. */
|
|
||||||
|
|
||||||
if (lseek (current->desc, - buffered, SEEK_CUR) == -1)
|
|
||||||
pfatal_with_name (current->name);
|
|
||||||
set_binary_mode (current->desc, false);
|
|
||||||
current->buffered = 0;
|
|
||||||
current->eof = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return binary_file_p (current->buffer, buffered);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
current->buffered = 0;
|
|
||||||
current->eof = false;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Slurp the rest of the current file completely into memory. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
slurp (struct file_data *current)
|
|
||||||
{
|
|
||||||
size_t cc;
|
|
||||||
|
|
||||||
if (current->desc < 0)
|
|
||||||
{
|
|
||||||
/* The file is nonexistent. */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 just enough room for appended newline plus word sentinel,
|
|
||||||
plus word-alignment since we want the buffer word-aligned. */
|
|
||||||
size_t file_size = current->stat.st_size;
|
|
||||||
cc = file_size + 2 * sizeof (word) - file_size % sizeof (word);
|
|
||||||
if (file_size != current->stat.st_size || cc < file_size
|
|
||||||
|| PTRDIFF_MAX <= cc)
|
|
||||||
xalloc_die ();
|
|
||||||
|
|
||||||
if (current->bufsize < cc)
|
|
||||||
{
|
|
||||||
current->bufsize = cc;
|
|
||||||
current->buffer = xrealloc (current->buffer, cc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Try to read at least 1 more byte than the size indicates, to
|
|
||||||
detect whether the file is growing. This is a nicety for
|
|
||||||
users who run 'diff' on files while they are changing. */
|
|
||||||
|
|
||||||
if (current->buffered <= file_size)
|
|
||||||
{
|
|
||||||
file_block_read (current, file_size + 1 - current->buffered);
|
|
||||||
if (current->buffered <= file_size)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* It's not a regular file, or it's a growing regular file; read it,
|
|
||||||
growing the buffer as needed. */
|
|
||||||
|
|
||||||
file_block_read (current, current->bufsize - current->buffered);
|
|
||||||
|
|
||||||
if (current->buffered)
|
|
||||||
{
|
|
||||||
while (current->buffered == current->bufsize)
|
|
||||||
{
|
|
||||||
if (PTRDIFF_MAX / 2 - sizeof (word) < current->bufsize)
|
|
||||||
xalloc_die ();
|
|
||||||
current->bufsize *= 2;
|
|
||||||
current->buffer = xrealloc (current->buffer, current->bufsize);
|
|
||||||
file_block_read (current, current->bufsize - current->buffered);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate just enough room for appended newline plus word
|
|
||||||
sentinel, plus word-alignment. */
|
|
||||||
cc = current->buffered + 2 * sizeof (word);
|
|
||||||
current->bufsize = cc - cc % 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 (struct file_data *current)
|
|
||||||
{
|
|
||||||
hash_value h;
|
|
||||||
char const *p = current->prefix_end;
|
|
||||||
unsigned char c;
|
|
||||||
lin i, *bucket;
|
|
||||||
size_t length;
|
|
||||||
|
|
||||||
/* Cache often-used quantities in local variables to help the compiler. */
|
|
||||||
char const **linbuf = current->linbuf;
|
|
||||||
lin alloc_lines = current->alloc_lines;
|
|
||||||
lin line = 0;
|
|
||||||
lin linbuf_base = current->linbuf_base;
|
|
||||||
lin *cureqs = xmalloc (alloc_lines * sizeof *cureqs);
|
|
||||||
struct equivclass *eqs = equivs;
|
|
||||||
lin eqs_index = equivs_index;
|
|
||||||
lin eqs_alloc = equivs_alloc;
|
|
||||||
char const *suffix_begin = current->suffix_begin;
|
|
||||||
char const *bufend = FILE_BUFFER (current) + current->buffered;
|
|
||||||
bool diff_length_compare_anyway =
|
|
||||||
ignore_white_space != IGNORE_NO_WHITE_SPACE;
|
|
||||||
bool same_length_diff_contents_compare_anyway =
|
|
||||||
diff_length_compare_anyway | ignore_case;
|
|
||||||
|
|
||||||
while (p < suffix_begin)
|
|
||||||
{
|
|
||||||
char const *ip = p;
|
|
||||||
|
|
||||||
h = 0;
|
|
||||||
|
|
||||||
/* Hash this line until we find a newline. */
|
|
||||||
if (ignore_case)
|
|
||||||
switch (ignore_white_space)
|
|
||||||
{
|
|
||||||
case IGNORE_ALL_SPACE:
|
|
||||||
while ((c = *p++) != '\n')
|
|
||||||
if (! isspace (c))
|
|
||||||
h = HASH (h, tolower (c));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IGNORE_SPACE_CHANGE:
|
|
||||||
while ((c = *p++) != '\n')
|
|
||||||
{
|
|
||||||
if (isspace (c))
|
|
||||||
{
|
|
||||||
do
|
|
||||||
if ((c = *p++) == '\n')
|
|
||||||
goto hashing_done;
|
|
||||||
while (isspace (c));
|
|
||||||
|
|
||||||
h = HASH (h, ' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
/* C is now the first non-space. */
|
|
||||||
h = HASH (h, tolower (c));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IGNORE_TAB_EXPANSION:
|
|
||||||
{
|
|
||||||
size_t column = 0;
|
|
||||||
while ((c = *p++) != '\n')
|
|
||||||
{
|
|
||||||
size_t repetitions = 1;
|
|
||||||
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case '\b':
|
|
||||||
column -= 0 < column;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '\t':
|
|
||||||
c = ' ';
|
|
||||||
repetitions = tabsize - column % tabsize;
|
|
||||||
column = (column + repetitions < column
|
|
||||||
? 0
|
|
||||||
: column + repetitions);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '\r':
|
|
||||||
column = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
c = tolower (c);
|
|
||||||
column++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
do
|
|
||||||
h = HASH (h, c);
|
|
||||||
while (--repetitions != 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
while ((c = *p++) != '\n')
|
|
||||||
h = HASH (h, tolower (c));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
switch (ignore_white_space)
|
|
||||||
{
|
|
||||||
case IGNORE_ALL_SPACE:
|
|
||||||
while ((c = *p++) != '\n')
|
|
||||||
if (! isspace (c))
|
|
||||||
h = HASH (h, c);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IGNORE_SPACE_CHANGE:
|
|
||||||
while ((c = *p++) != '\n')
|
|
||||||
{
|
|
||||||
if (isspace (c))
|
|
||||||
{
|
|
||||||
do
|
|
||||||
if ((c = *p++) == '\n')
|
|
||||||
goto hashing_done;
|
|
||||||
while (isspace (c));
|
|
||||||
|
|
||||||
h = HASH (h, ' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
/* C is now the first non-space. */
|
|
||||||
h = HASH (h, c);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IGNORE_TAB_EXPANSION:
|
|
||||||
{
|
|
||||||
size_t column = 0;
|
|
||||||
while ((c = *p++) != '\n')
|
|
||||||
{
|
|
||||||
size_t repetitions = 1;
|
|
||||||
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case '\b':
|
|
||||||
column -= 0 < column;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '\t':
|
|
||||||
c = ' ';
|
|
||||||
repetitions = tabsize - column % tabsize;
|
|
||||||
column = (column + repetitions < column
|
|
||||||
? 0
|
|
||||||
: column + repetitions);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '\r':
|
|
||||||
column = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
column++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
do
|
|
||||||
h = HASH (h, c);
|
|
||||||
while (--repetitions != 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
while ((c = *p++) != '\n')
|
|
||||||
h = HASH (h, c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
hashing_done:;
|
|
||||||
|
|
||||||
bucket = &buckets[h % nbuckets];
|
|
||||||
length = p - ip - 1;
|
|
||||||
|
|
||||||
if (p == bufend
|
|
||||||
&& current->missing_newline
|
|
||||||
&& ROBUST_OUTPUT_STYLE (output_style))
|
|
||||||
{
|
|
||||||
/* This line is incomplete. If this is significant,
|
|
||||||
put the line into buckets[-1]. */
|
|
||||||
if (ignore_white_space < IGNORE_SPACE_CHANGE)
|
|
||||||
bucket = &buckets[-1];
|
|
||||||
|
|
||||||
/* Omit the inserted newline when computing linbuf later. */
|
|
||||||
p--;
|
|
||||||
bufend = suffix_begin = 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)
|
|
||||||
{
|
|
||||||
if (PTRDIFF_MAX / (2 * sizeof *eqs) <= eqs_alloc)
|
|
||||||
xalloc_die ();
|
|
||||||
eqs_alloc *= 2;
|
|
||||||
eqs = xrealloc (eqs, eqs_alloc * 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 class if lines_differ reports the lines
|
|
||||||
equal. */
|
|
||||||
if (eqs[i].length == length)
|
|
||||||
{
|
|
||||||
/* Reuse existing equivalence class if the lines are identical.
|
|
||||||
This detects the common case of exact identity
|
|
||||||
faster than lines_differ would. */
|
|
||||||
if (memcmp (eqline, ip, length) == 0)
|
|
||||||
break;
|
|
||||||
if (!same_length_diff_contents_compare_anyway)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else if (!diff_length_compare_anyway)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (! lines_differ (eqline, ip))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Maybe increase the size of the line table. */
|
|
||||||
if (line == alloc_lines)
|
|
||||||
{
|
|
||||||
/* Double (alloc_lines - linbuf_base) by adding to alloc_lines. */
|
|
||||||
if (PTRDIFF_MAX / 3 <= alloc_lines
|
|
||||||
|| PTRDIFF_MAX / sizeof *cureqs <= 2 * alloc_lines - linbuf_base
|
|
||||||
|| PTRDIFF_MAX / sizeof *linbuf <= alloc_lines - linbuf_base)
|
|
||||||
xalloc_die ();
|
|
||||||
alloc_lines = 2 * alloc_lines - linbuf_base;
|
|
||||||
cureqs = xrealloc (cureqs, alloc_lines * sizeof *cureqs);
|
|
||||||
linbuf += linbuf_base;
|
|
||||||
linbuf = xrealloc (linbuf,
|
|
||||||
(alloc_lines - linbuf_base) * sizeof *linbuf);
|
|
||||||
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. */
|
|
||||||
if (PTRDIFF_MAX / 3 <= alloc_lines
|
|
||||||
|| PTRDIFF_MAX / sizeof *cureqs <= 2 * alloc_lines - linbuf_base
|
|
||||||
|| PTRDIFF_MAX / sizeof *linbuf <= alloc_lines - linbuf_base)
|
|
||||||
xalloc_die ();
|
|
||||||
alloc_lines = 2 * alloc_lines - linbuf_base;
|
|
||||||
linbuf += linbuf_base;
|
|
||||||
linbuf = xrealloc (linbuf,
|
|
||||||
(alloc_lines - linbuf_base) * sizeof *linbuf);
|
|
||||||
linbuf -= linbuf_base;
|
|
||||||
}
|
|
||||||
linbuf[line] = p;
|
|
||||||
|
|
||||||
if (p == bufend)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (context <= i && no_diff_means_no_output)
|
|
||||||
break;
|
|
||||||
|
|
||||||
line++;
|
|
||||||
|
|
||||||
while (*p++ != '\n')
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 text. Make sure the text end is initialized.
|
|
||||||
Make sure text ends in a newline,
|
|
||||||
but remember that we had to add one.
|
|
||||||
Strip trailing CRs, if that was requested. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
prepare_text (struct file_data *current)
|
|
||||||
{
|
|
||||||
size_t buffered = current->buffered;
|
|
||||||
char *p = FILE_BUFFER (current);
|
|
||||||
char *dst;
|
|
||||||
|
|
||||||
if (buffered == 0 || p[buffered - 1] == '\n')
|
|
||||||
current->missing_newline = false;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
p[buffered++] = '\n';
|
|
||||||
current->missing_newline = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!p)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Don't use uninitialized storage when planting or using sentinels. */
|
|
||||||
memset (p + buffered, 0, sizeof (word));
|
|
||||||
|
|
||||||
if (strip_trailing_cr && (dst = memchr (p, '\r', buffered)))
|
|
||||||
{
|
|
||||||
char const *src = dst;
|
|
||||||
char const *srclim = p + buffered;
|
|
||||||
|
|
||||||
do
|
|
||||||
dst += ! ((*dst = *src++) == '\r' && *src == '\n');
|
|
||||||
while (src < srclim);
|
|
||||||
|
|
||||||
buffered -= src - dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
current->buffered = buffered;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* We have found N lines in a buffer of size S; guess the
|
|
||||||
proportionate number of lines that will be found in a buffer of
|
|
||||||
size T. However, do not guess a number of lines so large that the
|
|
||||||
resulting line table might cause overflow in size calculations. */
|
|
||||||
static lin
|
|
||||||
guess_lines (lin n, size_t s, size_t t)
|
|
||||||
{
|
|
||||||
size_t guessed_bytes_per_line = n < 10 ? 32 : s / (n - 1);
|
|
||||||
lin guessed_lines = MAX (1, t / guessed_bytes_per_line);
|
|
||||||
return MIN (guessed_lines, PTRDIFF_MAX / (2 * sizeof (char *) + 1) - 5) + 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Given a vector of two file_data objects, find the identical
|
|
||||||
prefixes and suffixes of each object. */
|
|
||||||
|
|
||||||
static void
|
|
||||||
find_identical_ends (struct file_data filevec[])
|
|
||||||
{
|
|
||||||
word *w0, *w1;
|
|
||||||
char *p0, *p1, *buffer0, *buffer1;
|
|
||||||
char const *end0, *beg0;
|
|
||||||
char const **linbuf0, **linbuf1;
|
|
||||||
lin i, lines;
|
|
||||||
size_t n0, n1;
|
|
||||||
lin alloc_lines0, alloc_lines1;
|
|
||||||
lin buffered_prefix, prefix_count, prefix_mask;
|
|
||||||
lin middle_guess, suffix_guess;
|
|
||||||
|
|
||||||
slurp (&filevec[0]);
|
|
||||||
prepare_text (&filevec[0]);
|
|
||||||
if (filevec[0].desc != filevec[1].desc)
|
|
||||||
{
|
|
||||||
slurp (&filevec[1]);
|
|
||||||
prepare_text (&filevec[1]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
filevec[1].buffer = filevec[0].buffer;
|
|
||||||
filevec[1].bufsize = filevec[0].bufsize;
|
|
||||||
filevec[1].buffered = filevec[0].buffered;
|
|
||||||
filevec[1].missing_newline = filevec[0].missing_newline;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find identical prefix. */
|
|
||||||
|
|
||||||
w0 = filevec[0].buffer;
|
|
||||||
w1 = filevec[1].buffer;
|
|
||||||
p0 = buffer0 = (char *) w0;
|
|
||||||
p1 = buffer1 = (char *) w1;
|
|
||||||
n0 = filevec[0].buffered;
|
|
||||||
n1 = filevec[1].buffered;
|
|
||||||
|
|
||||||
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. */
|
|
||||||
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. */
|
|
||||||
for (; p0 != beg0; p0--, p1--)
|
|
||||||
if (*p0 != *p1)
|
|
||||||
{
|
|
||||||
/* Point at the first char of the matching suffix. */
|
|
||||||
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')
|
|
||||||
continue;
|
|
||||||
|
|
||||||
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 for options like -D that output the whole file,
|
|
||||||
or for enormous contexts (to avoid worrying about arithmetic overflow).
|
|
||||||
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.fastmap
|
|
||||||
&& context < LIN_MAX / 4 && context < n0)
|
|
||||||
{
|
|
||||||
middle_guess = guess_lines (0, 0, p0 - filevec[0].prefix_end);
|
|
||||||
suffix_guess = guess_lines (0, 0, buffer0 + n0 - p0);
|
|
||||||
for (prefix_count = 1; prefix_count <= context; prefix_count *= 2)
|
|
||||||
continue;
|
|
||||||
alloc_lines0 = (prefix_count + middle_guess
|
|
||||||
+ MIN (context, suffix_guess));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
prefix_count = 0;
|
|
||||||
alloc_lines0 = guess_lines (0, 0, n0);
|
|
||||||
}
|
|
||||||
|
|
||||||
prefix_mask = prefix_count - 1;
|
|
||||||
lines = 0;
|
|
||||||
linbuf0 = xmalloc (alloc_lines0 * sizeof *linbuf0);
|
|
||||||
p0 = buffer0;
|
|
||||||
|
|
||||||
/* 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))
|
|
||||||
{
|
|
||||||
end0 = filevec[0].prefix_end;
|
|
||||||
while (p0 != end0)
|
|
||||||
{
|
|
||||||
lin l = lines++ & prefix_mask;
|
|
||||||
if (l == alloc_lines0)
|
|
||||||
{
|
|
||||||
if (PTRDIFF_MAX / (2 * sizeof *linbuf0) <= alloc_lines0)
|
|
||||||
xalloc_die ();
|
|
||||||
alloc_lines0 *= 2;
|
|
||||||
linbuf0 = xrealloc (linbuf0, alloc_lines0 * sizeof *linbuf0);
|
|
||||||
}
|
|
||||||
linbuf0[l] = p0;
|
|
||||||
while (*p0++ != '\n')
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buffered_prefix = prefix_count && context < lines ? context : lines;
|
|
||||||
|
|
||||||
/* Allocate line buffer 1. */
|
|
||||||
|
|
||||||
middle_guess = guess_lines (lines, p0 - buffer0, p1 - filevec[1].prefix_end);
|
|
||||||
suffix_guess = guess_lines (lines, p0 - buffer0, buffer1 + n1 - p1);
|
|
||||||
alloc_lines1 = buffered_prefix + middle_guess + MIN (context, suffix_guess);
|
|
||||||
if (alloc_lines1 < buffered_prefix
|
|
||||||
|| PTRDIFF_MAX / sizeof *linbuf1 <= alloc_lines1)
|
|
||||||
xalloc_die ();
|
|
||||||
linbuf1 = 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If 1 < k, then (2**k - prime_offset[k]) is the largest prime less
|
|
||||||
than 2**k. This table is derived from Chris K. Caldwell's list
|
|
||||||
<http://www.utm.edu/research/primes/lists/2small/>. */
|
|
||||||
|
|
||||||
static unsigned char const prime_offset[] =
|
|
||||||
{
|
|
||||||
0, 0, 1, 1, 3, 1, 3, 1, 5, 3, 3, 9, 3, 1, 3, 19, 15, 1, 5, 1, 3, 9, 3,
|
|
||||||
15, 3, 39, 5, 39, 57, 3, 35, 1, 5, 9, 41, 31, 5, 25, 45, 7, 87, 21,
|
|
||||||
11, 57, 17, 55, 21, 115, 59, 81, 27, 129, 47, 111, 33, 55, 5, 13, 27,
|
|
||||||
55, 93, 1, 57, 25
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Verify that this host's size_t is not too wide for the above table. */
|
|
||||||
|
|
||||||
verify (enough_prime_offsets,
|
|
||||||
sizeof (size_t) * CHAR_BIT <= sizeof prime_offset);
|
|
||||||
|
|
||||||
/* Given a vector of two file_data objects, read the file associated
|
|
||||||
with each one, and build the table of equivalence classes.
|
|
||||||
Return nonzero if either file appears to be a binary file.
|
|
||||||
If PRETEND_BINARY is nonzero, pretend they are binary regardless. */
|
|
||||||
|
|
||||||
bool
|
|
||||||
read_files (struct file_data filevec[], bool pretend_binary)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
bool skip_test = text | pretend_binary;
|
|
||||||
bool 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 = filevec[0].buffered;
|
|
||||||
}
|
|
||||||
if (appears_binary)
|
|
||||||
{
|
|
||||||
set_binary_mode (filevec[0].desc, true);
|
|
||||||
set_binary_mode (filevec[1].desc, true);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
find_identical_ends (filevec);
|
|
||||||
|
|
||||||
equivs_alloc = filevec[0].alloc_lines + filevec[1].alloc_lines + 1;
|
|
||||||
if (PTRDIFF_MAX / sizeof *equivs <= equivs_alloc)
|
|
||||||
xalloc_die ();
|
|
||||||
equivs = xmalloc (equivs_alloc * sizeof *equivs);
|
|
||||||
/* Equivalence class 0 is permanently safe for lines that were not
|
|
||||||
hashed. Real equivalence classes start at 1. */
|
|
||||||
equivs_index = 1;
|
|
||||||
|
|
||||||
/* Allocate (one plus) a prime number of hash buckets. Use a prime
|
|
||||||
number between 1/3 and 2/3 of the value of equiv_allocs,
|
|
||||||
approximately. */
|
|
||||||
for (i = 9; (size_t) 1 << i < equivs_alloc / 3; i++)
|
|
||||||
continue;
|
|
||||||
nbuckets = ((size_t) 1 << i) - prime_offset[i];
|
|
||||||
if (PTRDIFF_MAX / sizeof *buckets <= nbuckets)
|
|
||||||
xalloc_die ();
|
|
||||||
buckets = zalloc ((nbuckets + 1) * sizeof *buckets);
|
|
||||||
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 false;
|
|
||||||
}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
/* Normal-format output routines for GNU DIFF.
|
|
||||||
|
|
||||||
Copyright (C) 1988, 1989, 1993, 1995, 1998, 2001 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 this program; see the file COPYING.
|
|
||||||
If not, write to the Free Software Foundation,
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#include "diff.h"
|
|
||||||
|
|
||||||
static void print_normal_hunk (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 (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 (struct change *hunk)
|
|
||||||
{
|
|
||||||
lin first0, last0, first1, last1;
|
|
||||||
register lin i;
|
|
||||||
|
|
||||||
/* Determine range of line numbers involved in each file. */
|
|
||||||
enum changes changes = analyze_hunk (hunk, &first0, &last0, &first1, &last1);
|
|
||||||
if (!changes)
|
|
||||||
return;
|
|
||||||
|
|
||||||
begin_output ();
|
|
||||||
|
|
||||||
/* Print out the line number header for this hunk */
|
|
||||||
print_number_range (',', &files[0], first0, last0);
|
|
||||||
fprintf (outfile, "%c", change_letter[changes]);
|
|
||||||
print_number_range (',', &files[1], first1, last1);
|
|
||||||
fprintf (outfile, "\n");
|
|
||||||
|
|
||||||
/* Print the lines that the first file has. */
|
|
||||||
if (changes & OLD)
|
|
||||||
for (i = first0; i <= last0; i++)
|
|
||||||
print_1_line ("<", &files[0].linbuf[i]);
|
|
||||||
|
|
||||||
if (changes == CHANGED)
|
|
||||||
fprintf (outfile, "---\n");
|
|
||||||
|
|
||||||
/* Print the lines that the second file has. */
|
|
||||||
if (changes & NEW)
|
|
||||||
for (i = first1; i <= last1; i++)
|
|
||||||
print_1_line (">", &files[1].linbuf[i]);
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,281 +0,0 @@
|
|||||||
/* sdiff-format output routines for GNU DIFF.
|
|
||||||
|
|
||||||
Copyright (C) 1991, 1992, 1993, 1998, 2001, 2002, 2004 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 void print_sdiff_common_lines (lin, lin);
|
|
||||||
static void print_sdiff_hunk (struct change *);
|
|
||||||
|
|
||||||
/* Next line number to be printed in the two input files. */
|
|
||||||
static lin next0, next1;
|
|
||||||
|
|
||||||
/* Print the edit-script SCRIPT as a sdiff style output. */
|
|
||||||
|
|
||||||
void
|
|
||||||
print_sdiff_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 size_t
|
|
||||||
tab_from_to (size_t from, size_t to)
|
|
||||||
{
|
|
||||||
FILE *out = outfile;
|
|
||||||
size_t tab;
|
|
||||||
size_t tab_size = tabsize;
|
|
||||||
|
|
||||||
if (!expand_tabs)
|
|
||||||
for (tab = from + tab_size - from % tab_size; tab <= to; tab += tab_size)
|
|
||||||
{
|
|
||||||
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. Return the
|
|
||||||
last column written (not the number of chars). */
|
|
||||||
|
|
||||||
static size_t
|
|
||||||
print_half_line (char const *const *line, size_t indent, size_t out_bound)
|
|
||||||
{
|
|
||||||
FILE *out = outfile;
|
|
||||||
register size_t in_position = 0;
|
|
||||||
register size_t out_position = 0;
|
|
||||||
register char const *text_pointer = line[0];
|
|
||||||
register char const *text_limit = line[1];
|
|
||||||
|
|
||||||
while (text_pointer < text_limit)
|
|
||||||
{
|
|
||||||
register unsigned char c = *text_pointer++;
|
|
||||||
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case '\t':
|
|
||||||
{
|
|
||||||
size_t spaces = tabsize - in_position % tabsize;
|
|
||||||
if (in_position == out_position)
|
|
||||||
{
|
|
||||||
size_t tabstop = out_position + spaces;
|
|
||||||
if (expand_tabs)
|
|
||||||
{
|
|
||||||
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 (char const *const *left, char sep,
|
|
||||||
char const *const *right)
|
|
||||||
{
|
|
||||||
FILE *out = outfile;
|
|
||||||
size_t hw = sdiff_half_width;
|
|
||||||
size_t c2o = sdiff_column2_offset;
|
|
||||||
size_t col = 0;
|
|
||||||
bool put_newline = false;
|
|
||||||
|
|
||||||
if (left)
|
|
||||||
{
|
|
||||||
put_newline |= left[1][-1] == '\n';
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
put_newline |= right[1][-1] == '\n';
|
|
||||||
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 (lin limit0, lin limit1)
|
|
||||||
{
|
|
||||||
lin i0 = next0, i1 = next1;
|
|
||||||
|
|
||||||
if (!suppress_common_lines && (i0 != limit0 || i1 != limit1))
|
|
||||||
{
|
|
||||||
if (sdiff_merge_assist)
|
|
||||||
{
|
|
||||||
long int len0 = limit0 - i0;
|
|
||||||
long int len1 = limit1 - i1;
|
|
||||||
fprintf (outfile, "i%ld,%ld\n", len0, len1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!left_column)
|
|
||||||
{
|
|
||||||
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 (struct change *hunk)
|
|
||||||
{
|
|
||||||
lin first0, last0, first1, last1;
|
|
||||||
register lin i, j;
|
|
||||||
|
|
||||||
/* Determine range of line numbers involved in each file. */
|
|
||||||
enum changes changes =
|
|
||||||
analyze_hunk (hunk, &first0, &last0, &first1, &last1);
|
|
||||||
if (!changes)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Print out lines up to this change. */
|
|
||||||
print_sdiff_common_lines (first0, first1);
|
|
||||||
|
|
||||||
if (sdiff_merge_assist)
|
|
||||||
{
|
|
||||||
long int len0 = last0 - first0 + 1;
|
|
||||||
long int len1 = last1 - first1 + 1;
|
|
||||||
fprintf (outfile, "c%ld,%ld\n", len0, len1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print ``xxx | xxx '' lines */
|
|
||||||
if (changes == CHANGED)
|
|
||||||
{
|
|
||||||
for (i = first0, j = first1; i <= last0 && j <= last1; i++, j++)
|
|
||||||
print_1sdiff_line (&files[0].linbuf[i], '|', &files[1].linbuf[j]);
|
|
||||||
changes = (i <= last0 ? OLD : 0) + (j <= last1 ? NEW : 0);
|
|
||||||
next0 = first0 = i;
|
|
||||||
next1 = first1 = j;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print `` > xxx '' lines */
|
|
||||||
if (changes & NEW)
|
|
||||||
{
|
|
||||||
for (j = first1; j <= last1; ++j)
|
|
||||||
print_1sdiff_line (0, '>', &files[1].linbuf[j]);
|
|
||||||
next1 = j;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print ``xxx < '' lines */
|
|
||||||
if (changes & OLD)
|
|
||||||
{
|
|
||||||
for (i = first0; i <= last0; ++i)
|
|
||||||
print_1sdiff_line (&files[0].linbuf[i], '<', 0);
|
|
||||||
next0 = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,326 +0,0 @@
|
|||||||
/* System dependent declarations.
|
|
||||||
|
|
||||||
Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1998, 2001, 2002,
|
|
||||||
2004 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 this program; see the file COPYING.
|
|
||||||
If not, write to the Free Software Foundation,
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
|
|
||||||
/* Don't bother to support K&R C compilers any more; it's not worth
|
|
||||||
the trouble. These macros prevent some library modules from being
|
|
||||||
compiled in K&R C mode. */
|
|
||||||
#define PARAMS(Args) Args
|
|
||||||
#define PROTOTYPES 1
|
|
||||||
|
|
||||||
/* Define `__attribute__' and `volatile' first
|
|
||||||
so that they're used consistently in all system includes. */
|
|
||||||
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6) || __STRICT_ANSI__
|
|
||||||
# define __attribute__(x)
|
|
||||||
#endif
|
|
||||||
#if defined const && !defined volatile
|
|
||||||
# define volatile
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Verify a requirement at compile-time (unlike assert, which is runtime). */
|
|
||||||
#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; }
|
|
||||||
|
|
||||||
|
|
||||||
/* Determine whether an integer type is signed, and its bounds.
|
|
||||||
This code assumes two's (or one's!) complement with no holes. */
|
|
||||||
|
|
||||||
/* The extra casts work around common compiler bugs,
|
|
||||||
e.g. Cray C 5.0.3.0 when t == time_t. */
|
|
||||||
#ifndef TYPE_SIGNED
|
|
||||||
# define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
|
|
||||||
#endif
|
|
||||||
#ifndef TYPE_MINIMUM
|
|
||||||
# define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \
|
|
||||||
? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) \
|
|
||||||
: (t) 0))
|
|
||||||
#endif
|
|
||||||
#ifndef TYPE_MAXIMUM
|
|
||||||
# define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#ifndef S_IRWXU
|
|
||||||
# define S_IRWXU 0700
|
|
||||||
#endif
|
|
||||||
#ifndef S_IRWXG
|
|
||||||
# define S_IRWXG 0070
|
|
||||||
#endif
|
|
||||||
#ifndef S_IRWXO
|
|
||||||
# define S_IRWXO 0007
|
|
||||||
#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
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#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
|
|
||||||
#ifndef O_RDWR
|
|
||||||
# define O_RDWR 2
|
|
||||||
#endif
|
|
||||||
#ifndef S_IRUSR
|
|
||||||
# define S_IRUSR 0400
|
|
||||||
#endif
|
|
||||||
#ifndef S_IWUSR
|
|
||||||
# define S_IWUSR 0200
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_SYS_WAIT_H
|
|
||||||
# include <sys/wait.h>
|
|
||||||
#endif
|
|
||||||
#ifndef WEXITSTATUS
|
|
||||||
# define WEXITSTATUS(stat_val) ((unsigned int) (stat_val) >> 8)
|
|
||||||
#endif
|
|
||||||
#ifndef WIFEXITED
|
|
||||||
# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef STAT_BLOCKSIZE
|
|
||||||
# if HAVE_STRUCT_STAT_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
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#define EXIT_TROUBLE 2
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
|
|
||||||
#if HAVE_INTTYPES_H
|
|
||||||
# include <inttypes.h>
|
|
||||||
#endif
|
|
||||||
#ifndef PTRDIFF_MAX
|
|
||||||
# define PTRDIFF_MAX TYPE_MAXIMUM (ptrdiff_t)
|
|
||||||
#endif
|
|
||||||
#ifndef SIZE_MAX
|
|
||||||
# define SIZE_MAX TYPE_MAXIMUM (size_t)
|
|
||||||
#endif
|
|
||||||
#ifndef UINTMAX_MAX
|
|
||||||
# define UINTMAX_MAX TYPE_MAXIMUM (uintmax_t)
|
|
||||||
#endif
|
|
||||||
#if ! HAVE_STRTOUMAX && ! defined strtoumax
|
|
||||||
uintmax_t strtoumax (char const *, char **, int);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#if ! HAVE_STRCASECOLL
|
|
||||||
# if HAVE_STRICOLL || defined stricoll
|
|
||||||
# define strcasecoll(a, b) stricoll (a, b)
|
|
||||||
# else
|
|
||||||
# define strcasecoll(a, b) strcasecmp (a, b) /* best we can do */
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#if ! (HAVE_STRCASECMP || defined strcasecmp)
|
|
||||||
int strcasecmp (char const *, char const *);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAVE_LOCALE_H
|
|
||||||
# include <locale.h>
|
|
||||||
#else
|
|
||||||
# define setlocale(category, locale)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <gettext.h>
|
|
||||||
|
|
||||||
#define _(msgid) gettext (msgid)
|
|
||||||
#define N_(msgid) msgid
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
/* ISDIGIT differs from isdigit, as follows:
|
|
||||||
- Its arg may be any int or unsigned int; it need not be an unsigned char.
|
|
||||||
- It's guaranteed to evaluate its argument exactly once.
|
|
||||||
- It's typically faster.
|
|
||||||
POSIX 1003.1-2001 says that only '0' through '9' are digits.
|
|
||||||
Prefer ISDIGIT to isdigit unless it's important to use the locale's
|
|
||||||
definition of `digit' even when the host does not conform to POSIX. */
|
|
||||||
#define ISDIGIT(c) ((unsigned int) (c) - '0' <= 9)
|
|
||||||
|
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include <signal.h>
|
|
||||||
#ifndef SA_RESTART
|
|
||||||
# ifdef SA_INTERRUPT /* e.g. SunOS 4.1.x */
|
|
||||||
# define SA_RESTART SA_INTERRUPT
|
|
||||||
# else
|
|
||||||
# define SA_RESTART 0
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#if !defined SIGCHLD && defined SIGCLD
|
|
||||||
# define SIGCHLD SIGCLD
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef MIN
|
|
||||||
#undef MAX
|
|
||||||
#define MIN(a, b) ((a) <= (b) ? (a) : (b))
|
|
||||||
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
#if HAVE_VFORK_H
|
|
||||||
# include <vfork.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ! HAVE_WORKING_VFORK
|
|
||||||
# define vfork fork
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Type used for fast comparison of several bytes at a time. */
|
|
||||||
|
|
||||||
#ifndef word
|
|
||||||
# define word uintmax_t
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The integer type of a line number. Since files are read into main
|
|
||||||
memory, ptrdiff_t should be wide enough. */
|
|
||||||
|
|
||||||
typedef ptrdiff_t lin;
|
|
||||||
#define LIN_MAX PTRDIFF_MAX
|
|
||||||
verify (lin_is_signed, TYPE_SIGNED (lin));
|
|
||||||
verify (lin_is_wide_enough, sizeof (ptrdiff_t) <= sizeof (lin));
|
|
||||||
verify (lin_is_printable_as_long_int, sizeof (lin) <= sizeof (long int));
|
|
||||||
|
|
||||||
/* This section contains POSIX-compliant defaults for macros
|
|
||||||
that are meant to be overridden by hand in config.h as needed. */
|
|
||||||
|
|
||||||
#ifndef file_name_cmp
|
|
||||||
# define file_name_cmp strcmp
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef initialize_main
|
|
||||||
# define initialize_main(argcp, argvp)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NULL_DEVICE
|
|
||||||
# define NULL_DEVICE "/dev/null"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Do struct stat *S, *T describe the same special file? */
|
|
||||||
#ifndef same_special_file
|
|
||||||
# if HAVE_ST_RDEV && defined S_ISBLK && defined S_ISCHR
|
|
||||||
# define same_special_file(s, t) \
|
|
||||||
(((S_ISBLK ((s)->st_mode) && S_ISBLK ((t)->st_mode)) \
|
|
||||||
|| (S_ISCHR ((s)->st_mode) && S_ISCHR ((t)->st_mode))) \
|
|
||||||
&& (s)->st_rdev == (t)->st_rdev)
|
|
||||||
# else
|
|
||||||
# define same_special_file(s, t) 0
|
|
||||||
# endif
|
|
||||||
#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)) \
|
|
||||||
|| same_special_file (s, t))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Do struct stat *S, *T have the same file attributes?
|
|
||||||
|
|
||||||
POSIX says that two files are identical if st_ino and st_dev are
|
|
||||||
the same, but many filesystems incorrectly assign the same (device,
|
|
||||||
inode) pair to two distinct files, including:
|
|
||||||
|
|
||||||
- GNU/Linux NFS servers that export all local filesystems as a
|
|
||||||
single NFS filesystem, if a local device number (st_dev) exceeds
|
|
||||||
255, or if a local inode number (st_ino) exceeds 16777215.
|
|
||||||
|
|
||||||
- Network Appliance NFS servers in snapshot directories; see
|
|
||||||
Network Appliance bug #195.
|
|
||||||
|
|
||||||
- ClearCase MVFS; see bug id ATRia04618.
|
|
||||||
|
|
||||||
Check whether two files that purport to be the same have the same
|
|
||||||
attributes, to work around instances of this common bug. Do not
|
|
||||||
inspect all attributes, only attributes useful in checking for this
|
|
||||||
bug.
|
|
||||||
|
|
||||||
It's possible for two distinct files on a buggy filesystem to have
|
|
||||||
the same attributes, but it's not worth slowing down all
|
|
||||||
implementations (or complicating the configuration) to cater to
|
|
||||||
these rare cases in buggy implementations. */
|
|
||||||
|
|
||||||
#ifndef same_file_attributes
|
|
||||||
# define same_file_attributes(s, t) \
|
|
||||||
((s)->st_mode == (t)->st_mode \
|
|
||||||
&& (s)->st_nlink == (t)->st_nlink \
|
|
||||||
&& (s)->st_uid == (t)->st_uid \
|
|
||||||
&& (s)->st_gid == (t)->st_gid \
|
|
||||||
&& (s)->st_size == (t)->st_size \
|
|
||||||
&& (s)->st_mtime == (t)->st_mtime \
|
|
||||||
&& (s)->st_ctime == (t)->st_ctime)
|
|
||||||
#endif
|
|
||||||
@@ -1,775 +0,0 @@
|
|||||||
/* Support routines for GNU DIFF.
|
|
||||||
|
|
||||||
Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1998, 2001, 2002,
|
|
||||||
2004 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 this program; see the file COPYING.
|
|
||||||
If not, write to the Free Software Foundation,
|
|
||||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|
||||||
|
|
||||||
#include "diff.h"
|
|
||||||
#include <dirname.h>
|
|
||||||
#include <error.h>
|
|
||||||
#include <quotesys.h>
|
|
||||||
#include <xalloc.h>
|
|
||||||
|
|
||||||
char const pr_program[] = PR_PROGRAM;
|
|
||||||
|
|
||||||
/* 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 args[1]; /* Format + 4 args, each '\0' terminated, concatenated. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* 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.
|
|
||||||
NAME should normally be the file name. */
|
|
||||||
|
|
||||||
void
|
|
||||||
perror_with_name (char const *name)
|
|
||||||
{
|
|
||||||
error (0, errno, "%s", name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Use when a system call returns non-zero status and that is fatal. */
|
|
||||||
|
|
||||||
void
|
|
||||||
pfatal_with_name (char const *name)
|
|
||||||
{
|
|
||||||
int e = errno;
|
|
||||||
print_message_queue ();
|
|
||||||
error (EXIT_TROUBLE, e, "%s", name);
|
|
||||||
abort ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Print an error message containing MSGID, then exit. */
|
|
||||||
|
|
||||||
void
|
|
||||||
fatal (char const *msgid)
|
|
||||||
{
|
|
||||||
print_message_queue ();
|
|
||||||
error (EXIT_TROUBLE, 0, "%s", _(msgid));
|
|
||||||
abort ();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Like printf, except if -l in effect then save the message and print later.
|
|
||||||
This is used for things like "Only in ...". */
|
|
||||||
|
|
||||||
void
|
|
||||||
message (char const *format_msgid, char const *arg1, char const *arg2)
|
|
||||||
{
|
|
||||||
message5 (format_msgid, arg1, arg2, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
message5 (char const *format_msgid, char const *arg1, char const *arg2,
|
|
||||||
char const *arg3, char const *arg4)
|
|
||||||
{
|
|
||||||
if (paginate)
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
char const *arg[5];
|
|
||||||
int i;
|
|
||||||
size_t size[5];
|
|
||||||
size_t total_size = offsetof (struct msg, args);
|
|
||||||
struct msg *new;
|
|
||||||
|
|
||||||
arg[0] = format_msgid;
|
|
||||||
arg[1] = arg1;
|
|
||||||
arg[2] = arg2;
|
|
||||||
arg[3] = arg3 ? arg3 : "";
|
|
||||||
arg[4] = arg4 ? arg4 : "";
|
|
||||||
|
|
||||||
for (i = 0; i < 5; i++)
|
|
||||||
total_size += size[i] = strlen (arg[i]) + 1;
|
|
||||||
|
|
||||||
new = xmalloc (total_size);
|
|
||||||
|
|
||||||
for (i = 0, p = new->args; i < 5; p += size[i++])
|
|
||||||
memcpy (p, arg[i], size[i]);
|
|
||||||
|
|
||||||
*msg_chain_end = new;
|
|
||||||
new->next = 0;
|
|
||||||
msg_chain_end = &new->next;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (sdiff_merge_assist)
|
|
||||||
putchar (' ');
|
|
||||||
printf (_(format_msgid), arg1, arg2, arg3, arg4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Output all the messages that were saved up by calls to `message'. */
|
|
||||||
|
|
||||||
void
|
|
||||||
print_message_queue (void)
|
|
||||||
{
|
|
||||||
char const *arg[5];
|
|
||||||
int i;
|
|
||||||
struct msg *m = msg_chain;
|
|
||||||
|
|
||||||
while (m)
|
|
||||||
{
|
|
||||||
struct msg *next = m->next;
|
|
||||||
arg[0] = m->args;
|
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
arg[i + 1] = arg[i] + strlen (arg[i]) + 1;
|
|
||||||
printf (_(arg[0]), arg[1], arg[2], arg[3], arg[4]);
|
|
||||||
free (m);
|
|
||||||
m = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 bool currently_recursive;
|
|
||||||
|
|
||||||
void
|
|
||||||
setup_output (char const *name0, char const *name1, bool recursive)
|
|
||||||
{
|
|
||||||
current_name0 = name0;
|
|
||||||
current_name1 = name1;
|
|
||||||
currently_recursive = recursive;
|
|
||||||
outfile = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if HAVE_WORKING_FORK || HAVE_WORKING_VFORK
|
|
||||||
static pid_t pr_pid;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void
|
|
||||||
begin_output (void)
|
|
||||||
{
|
|
||||||
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 1003.1-2001 specifies this format. But there are some bugs in
|
|
||||||
the standard: it says that we must print only the last component
|
|
||||||
of the pathnames, and it requires two spaces after "diff" if
|
|
||||||
there are no options. These requirements are silly and do not
|
|
||||||
match historical practice. */
|
|
||||||
sprintf (name, "diff%s %s %s", switch_string, current_name0, current_name1);
|
|
||||||
|
|
||||||
if (paginate)
|
|
||||||
{
|
|
||||||
if (fflush (stdout) != 0)
|
|
||||||
pfatal_with_name (_("write failed"));
|
|
||||||
|
|
||||||
/* Make OUTFILE a pipe to a subsidiary `pr'. */
|
|
||||||
{
|
|
||||||
#if HAVE_WORKING_FORK || HAVE_WORKING_VFORK
|
|
||||||
int pipes[2];
|
|
||||||
|
|
||||||
if (pipe (pipes) != 0)
|
|
||||||
pfatal_with_name ("pipe");
|
|
||||||
|
|
||||||
pr_pid = vfork ();
|
|
||||||
if (pr_pid < 0)
|
|
||||||
pfatal_with_name ("fork");
|
|
||||||
|
|
||||||
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, "-h", name, (char *) 0);
|
|
||||||
_exit (errno == ENOENT ? 127 : 126);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
close (pipes[0]);
|
|
||||||
outfile = fdopen (pipes[1], "w");
|
|
||||||
if (!outfile)
|
|
||||||
pfatal_with_name ("fdopen");
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
char *command = xmalloc (sizeof pr_program - 1 + 7
|
|
||||||
+ quote_system_arg ((char *) 0, name) + 1);
|
|
||||||
char *p;
|
|
||||||
sprintf (command, "%s -f -h ", pr_program);
|
|
||||||
p = command + sizeof pr_program - 1 + 7;
|
|
||||||
p += quote_system_arg (p, name);
|
|
||||||
*p = 0;
|
|
||||||
errno = 0;
|
|
||||||
outfile = popen (command, "w");
|
|
||||||
if (!outfile)
|
|
||||||
pfatal_with_name (command);
|
|
||||||
free (command);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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 (currently_recursive)
|
|
||||||
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, false);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case OUTPUT_UNIFIED:
|
|
||||||
print_context_header (files, true);
|
|
||||||
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 (void)
|
|
||||||
{
|
|
||||||
if (outfile != 0 && outfile != stdout)
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
int wstatus;
|
|
||||||
int werrno = 0;
|
|
||||||
if (ferror (outfile))
|
|
||||||
fatal ("write failed");
|
|
||||||
#if ! (HAVE_WORKING_FORK || HAVE_WORKING_VFORK)
|
|
||||||
wstatus = pclose (outfile);
|
|
||||||
if (wstatus == -1)
|
|
||||||
werrno = errno;
|
|
||||||
#else
|
|
||||||
if (fclose (outfile) != 0)
|
|
||||||
pfatal_with_name (_("write failed"));
|
|
||||||
if (waitpid (pr_pid, &wstatus, 0) < 0)
|
|
||||||
pfatal_with_name ("waitpid");
|
|
||||||
#endif
|
|
||||||
status = (! werrno && WIFEXITED (wstatus)
|
|
||||||
? WEXITSTATUS (wstatus)
|
|
||||||
: INT_MAX);
|
|
||||||
if (status)
|
|
||||||
error (EXIT_TROUBLE, werrno,
|
|
||||||
_(status == 126
|
|
||||||
? "subsidiary program `%s' could not be invoked"
|
|
||||||
: status == 127
|
|
||||||
? "subsidiary program `%s' not found"
|
|
||||||
: status == INT_MAX
|
|
||||||
? "subsidiary program `%s' failed"
|
|
||||||
: "subsidiary program `%s' failed (exit status %d)"),
|
|
||||||
pr_program, status);
|
|
||||||
}
|
|
||||||
|
|
||||||
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. */
|
|
||||||
|
|
||||||
bool
|
|
||||||
lines_differ (char const *s1, char const *s2)
|
|
||||||
{
|
|
||||||
register char const *t1 = s1;
|
|
||||||
register char const *t2 = s2;
|
|
||||||
size_t column = 0;
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
switch (ignore_white_space)
|
|
||||||
{
|
|
||||||
case IGNORE_ALL_SPACE:
|
|
||||||
/* For -w, just skip past any white space. */
|
|
||||||
while (isspace (c1) && c1 != '\n') c1 = *t1++;
|
|
||||||
while (isspace (c2) && c2 != '\n') c2 = *t2++;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IGNORE_SPACE_CHANGE:
|
|
||||||
/* 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'
|
|
||||||
&& s1 + 1 < t1
|
|
||||||
&& isspace ((unsigned char) t1[-2]))
|
|
||||||
{
|
|
||||||
--t1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (c1 == ' ' && c2 != '\n'
|
|
||||||
&& s2 + 1 < t2
|
|
||||||
&& isspace ((unsigned char) t2[-2]))
|
|
||||||
{
|
|
||||||
--t2;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IGNORE_TAB_EXPANSION:
|
|
||||||
if ((c1 == ' ' && c2 == '\t')
|
|
||||||
|| (c1 == '\t' && c2 == ' '))
|
|
||||||
{
|
|
||||||
size_t column2 = column;
|
|
||||||
for (;; c1 = *t1++)
|
|
||||||
{
|
|
||||||
if (c1 == ' ')
|
|
||||||
column++;
|
|
||||||
else if (c1 == '\t')
|
|
||||||
column += tabsize - column % tabsize;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
for (;; c2 = *t2++)
|
|
||||||
{
|
|
||||||
if (c2 == ' ')
|
|
||||||
column2++;
|
|
||||||
else if (c2 == '\t')
|
|
||||||
column2 += tabsize - column2 % tabsize;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (column != column2)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case IGNORE_NO_WHITE_SPACE:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lowercase all letters if -i is specified. */
|
|
||||||
|
|
||||||
if (ignore_case)
|
|
||||||
{
|
|
||||||
c1 = tolower (c1);
|
|
||||||
c2 = tolower (c2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c1 != c2)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (c1 == '\n')
|
|
||||||
return false;
|
|
||||||
|
|
||||||
column += c1 == '\t' ? tabsize - column % tabsize : 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the consecutive changes at the start of the script START.
|
|
||||||
Return the last link before the first gap. */
|
|
||||||
|
|
||||||
struct change *
|
|
||||||
find_change (struct change *start)
|
|
||||||
{
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct change *
|
|
||||||
find_reverse_change (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 (struct change *script,
|
|
||||||
struct change * (*hunkfun) (struct change *),
|
|
||||||
void (*printfun) (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 (char const *line_flag, char const *const *line)
|
|
||||||
{
|
|
||||||
char const *base = 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 = initial_tab ? "%s\t" : "%s ";
|
|
||||||
fprintf (out, flag_format, line_flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
output_1_line (base, limit, flag_format, line_flag);
|
|
||||||
|
|
||||||
if ((!line_flag || line_flag[0]) && limit[-1] != '\n')
|
|
||||||
fprintf (out, "\n\\ %s\n", _("No newline at end of file"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Output a line from BASE up to LIMIT.
|
|
||||||
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 (char const *base, char const *limit, char const *flag_format,
|
|
||||||
char const *line_flag)
|
|
||||||
{
|
|
||||||
if (!expand_tabs)
|
|
||||||
fwrite (base, sizeof (char), limit - base, outfile);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
register FILE *out = outfile;
|
|
||||||
register unsigned char c;
|
|
||||||
register char const *t = base;
|
|
||||||
register size_t column = 0;
|
|
||||||
size_t tab_size = tabsize;
|
|
||||||
|
|
||||||
while (t < limit)
|
|
||||||
switch ((c = *t++))
|
|
||||||
{
|
|
||||||
case '\t':
|
|
||||||
{
|
|
||||||
size_t spaces = tab_size - column % tab_size;
|
|
||||||
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:
|
|
||||||
column += isprint (c) != 0;
|
|
||||||
putc (c, out);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char const change_letter[] = { 0, 'd', 'a', '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 I. 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. */
|
|
||||||
|
|
||||||
lin
|
|
||||||
translate_line_number (struct file_data const *file, lin i)
|
|
||||||
{
|
|
||||||
return i + file->prefix_lines + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Translate a line number range. This is always done for printing,
|
|
||||||
so for convenience translate to long int rather than lin, so that the
|
|
||||||
caller can use printf with "%ld" without casting. */
|
|
||||||
|
|
||||||
void
|
|
||||||
translate_range (struct file_data const *file,
|
|
||||||
lin a, lin b,
|
|
||||||
long int *aptr, long int *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 (char sepchar, struct file_data *file, lin a, lin b)
|
|
||||||
{
|
|
||||||
long 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, "%ld%c%ld", trans_a, sepchar, trans_b);
|
|
||||||
else
|
|
||||||
fprintf (outfile, "%ld", 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.
|
|
||||||
|
|
||||||
Return UNCHANGED if only ignorable lines are inserted or deleted,
|
|
||||||
OLD if lines of file 0 are deleted,
|
|
||||||
NEW if lines of file 1 are inserted,
|
|
||||||
and CHANGED if both kinds of changes are found. */
|
|
||||||
|
|
||||||
enum changes
|
|
||||||
analyze_hunk (struct change *hunk,
|
|
||||||
lin *first0, lin *last0,
|
|
||||||
lin *first1, lin *last1)
|
|
||||||
{
|
|
||||||
struct change *next;
|
|
||||||
lin l0, l1;
|
|
||||||
lin show_from, show_to;
|
|
||||||
lin i;
|
|
||||||
bool trivial = ignore_blank_lines || ignore_regexp.fastmap;
|
|
||||||
size_t trivial_length = ignore_blank_lines - 1;
|
|
||||||
/* If 0, ignore zero-length lines;
|
|
||||||
if SIZE_MAX, do not ignore lines just because of their length. */
|
|
||||||
bool skip_leading_white_space =
|
|
||||||
(ignore_blank_lines && IGNORE_SPACE_CHANGE <= ignore_white_space);
|
|
||||||
|
|
||||||
char const * const *linbuf0 = files[0].linbuf; /* Help the compiler. */
|
|
||||||
char const * const *linbuf1 = files[1].linbuf;
|
|
||||||
|
|
||||||
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++)
|
|
||||||
{
|
|
||||||
char const *line = linbuf0[i];
|
|
||||||
char const *newline = linbuf0[i + 1] - 1;
|
|
||||||
size_t len = newline - line;
|
|
||||||
char const *p = line;
|
|
||||||
if (skip_leading_white_space)
|
|
||||||
while (isspace ((unsigned char) *p) && *p != '\n')
|
|
||||||
p++;
|
|
||||||
if (newline - p != trivial_length
|
|
||||||
&& (! ignore_regexp.fastmap
|
|
||||||
|| re_search (&ignore_regexp, line, len, 0, len, 0) < 0))
|
|
||||||
trivial = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = next->line1; i <= l1 && trivial; i++)
|
|
||||||
{
|
|
||||||
char const *line = linbuf1[i];
|
|
||||||
char const *newline = linbuf1[i + 1] - 1;
|
|
||||||
size_t len = newline - line;
|
|
||||||
char const *p = line;
|
|
||||||
if (skip_leading_white_space)
|
|
||||||
while (isspace ((unsigned char) *p) && *p != '\n')
|
|
||||||
p++;
|
|
||||||
if (newline - p != trivial_length
|
|
||||||
&& (! ignore_regexp.fastmap
|
|
||||||
|| re_search (&ignore_regexp, line, len, 0, len, 0) < 0))
|
|
||||||
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)
|
|
||||||
return UNCHANGED;
|
|
||||||
|
|
||||||
return (show_from ? OLD : UNCHANGED) | (show_to ? NEW : UNCHANGED);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Concatenate three strings, returning a newly malloc'd string. */
|
|
||||||
|
|
||||||
char *
|
|
||||||
concat (char const *s1, char const *s2, char const *s3)
|
|
||||||
{
|
|
||||||
char *new = xmalloc (strlen (s1) + strlen (s2) + strlen (s3) + 1);
|
|
||||||
sprintf (new, "%s%s%s", s1, s2, s3);
|
|
||||||
return new;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Yield a new block of SIZE bytes, initialized to zero. */
|
|
||||||
|
|
||||||
void *
|
|
||||||
zalloc (size_t size)
|
|
||||||
{
|
|
||||||
void *p = xmalloc (size);
|
|
||||||
memset (p, 0, size);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Yield the newly malloc'd pathname
|
|
||||||
of the file in DIR whose filename is FILE. */
|
|
||||||
|
|
||||||
char *
|
|
||||||
dir_file_pathname (char const *dir, char const *file)
|
|
||||||
{
|
|
||||||
char const *base = base_name (dir);
|
|
||||||
bool omit_slash = !*base || base[strlen (base) - 1] == '/';
|
|
||||||
return concat (dir, "/" + omit_slash, file);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
debug_script (struct change *sp)
|
|
||||||
{
|
|
||||||
fflush (stdout);
|
|
||||||
|
|
||||||
for (; sp; sp = sp->link)
|
|
||||||
{
|
|
||||||
long int line0 = sp->line0;
|
|
||||||
long int line1 = sp->line1;
|
|
||||||
long int deleted = sp->deleted;
|
|
||||||
long int inserted = sp->inserted;
|
|
||||||
fprintf (stderr, "%3ld %3ld delete %ld insert %ld\n",
|
|
||||||
line0, line1, deleted, inserted);
|
|
||||||
}
|
|
||||||
|
|
||||||
fflush (stderr);
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
.include <src.opts.mk>
|
.include <src.opts.mk>
|
||||||
|
|
||||||
SUBDIR.${MK_DIALOG}+= dialog
|
SUBDIR.${MK_DIALOG}+= dialog
|
||||||
SUBDIR.${MK_GNU_DIFF}+= diff3
|
|
||||||
SUBDIR.${MK_TESTS}+= tests
|
SUBDIR.${MK_TESTS}+= tests
|
||||||
|
|
||||||
SUBDIR_PARALLEL=
|
SUBDIR_PARALLEL=
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
PACKAGE= diff3
|
|
||||||
|
|
||||||
DIFFSRC=${SRCTOP}/contrib/diff/src
|
|
||||||
.PATH: ${DIFFSRC} \
|
|
||||||
${SRCTOP}/contrib/diff/lib \
|
|
||||||
${SRCTOP}/contrib/diff/man
|
|
||||||
PROG= diff3
|
|
||||||
SRCS= diff3.c version-etc.c \
|
|
||||||
xmalloc.c error.c c-stack.c exitfail.c cmpbuf.c
|
|
||||||
|
|
||||||
# Important for ctype macros!
|
|
||||||
CFLAGS+=-funsigned-char
|
|
||||||
|
|
||||||
CFLAGS+=-I${SRCTOP}/contrib/diff/
|
|
||||||
CFLAGS+=-I${SRCTOP}/contrib/diff/src
|
|
||||||
CFLAGS+=-I${SRCTOP}/contrib/diff/lib
|
|
||||||
CFLAGS+=-DHAVE_CONFIG_H
|
|
||||||
CFLAGS+=-DDEFAULT_DIFF_PROGRAM=\"/usr/bin/diff\"
|
|
||||||
|
|
||||||
WARNS?= 2
|
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
# Autogenerated - do NOT edit!
|
|
||||||
|
|
||||||
DIRDEPS = \
|
|
||||||
include \
|
|
||||||
include/xlocale \
|
|
||||||
lib/${CSU_DIR} \
|
|
||||||
lib/libc \
|
|
||||||
lib/libcompiler_rt \
|
|
||||||
|
|
||||||
|
|
||||||
.include <dirdeps.mk>
|
|
||||||
|
|
||||||
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
|
|
||||||
# local dependencies - needed for -jN in clean tree
|
|
||||||
.endif
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-License-Identifier: ISC
|
|
||||||
*/
|
|
||||||
|
|
||||||
comment = "GNU 3-way file comparison and merge utility"
|
|
||||||
|
|
||||||
desc = <<EOD
|
|
||||||
Compares three files line by line, optionally merging them.
|
|
||||||
EOD
|
|
||||||
|
|
||||||
licenses = [ "GPL-2.0-or-later" ]
|
|
||||||
|
|
||||||
annotations {
|
|
||||||
set = "optional,optional-jail"
|
|
||||||
}
|
|
||||||
@@ -763,11 +763,6 @@ Do not build or install
|
|||||||
.Xr ftp 1 .
|
.Xr ftp 1 .
|
||||||
.It Va WITHOUT_GAMES
|
.It Va WITHOUT_GAMES
|
||||||
Do not build games.
|
Do not build games.
|
||||||
.It Va WITH_GNU_DIFF
|
|
||||||
Build and install GNU
|
|
||||||
.Xr diff3 1
|
|
||||||
instead of BSD
|
|
||||||
.Xr diff3 1 .
|
|
||||||
.It Va WITHOUT_GOOGLETEST
|
.It Va WITHOUT_GOOGLETEST
|
||||||
Neither build nor install
|
Neither build nor install
|
||||||
.Lb libgmock ,
|
.Lb libgmock ,
|
||||||
|
|||||||
@@ -208,7 +208,6 @@ __DEFAULT_NO_OPTIONS = \
|
|||||||
DTRACE_ASAN \
|
DTRACE_ASAN \
|
||||||
DTRACE_TESTS \
|
DTRACE_TESTS \
|
||||||
EXPERIMENTAL \
|
EXPERIMENTAL \
|
||||||
GNU_DIFF \
|
|
||||||
HESIOD \
|
HESIOD \
|
||||||
IPFILTER_IPFS \
|
IPFILTER_IPFS \
|
||||||
LOADER_VERBOSE \
|
LOADER_VERBOSE \
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ DIRDEPS = \
|
|||||||
gnu/usr.bin/binutils/libopcodes \
|
gnu/usr.bin/binutils/libopcodes \
|
||||||
gnu/usr.bin/binutils/objdump \
|
gnu/usr.bin/binutils/objdump \
|
||||||
gnu/usr.bin/dialog \
|
gnu/usr.bin/dialog \
|
||||||
gnu/usr.bin/diff3 \
|
|
||||||
gnu/usr.bin/gdb/doc \
|
gnu/usr.bin/gdb/doc \
|
||||||
gnu/usr.bin/gdb/gdb \
|
gnu/usr.bin/gdb/gdb \
|
||||||
gnu/usr.bin/gdb/gdbserver \
|
gnu/usr.bin/gdb/gdbserver \
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
Do not build GNU
|
|
||||||
.Xr diff3 1 ;
|
|
||||||
build BSD
|
|
||||||
.Xr diff3 1
|
|
||||||
instead.
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
Build and install GNU
|
|
||||||
.Xr diff3 1
|
|
||||||
instead of BSD
|
|
||||||
.Xr diff3 1 .
|
|
||||||
@@ -206,9 +206,7 @@ SUBDIR.${MK_GAMES}+= pom
|
|||||||
SUBDIR.${MK_GAMES}+= primes
|
SUBDIR.${MK_GAMES}+= primes
|
||||||
SUBDIR.${MK_GAMES}+= random
|
SUBDIR.${MK_GAMES}+= random
|
||||||
SUBDIR+= gh-bc
|
SUBDIR+= gh-bc
|
||||||
.if ${MK_GNU_DIFF} == "no"
|
|
||||||
SUBDIR+= diff3
|
SUBDIR+= diff3
|
||||||
.endif
|
|
||||||
SUBDIR.${MK_HESIOD}+= hesinfo
|
SUBDIR.${MK_HESIOD}+= hesinfo
|
||||||
SUBDIR.${MK_ICONV}+= iconv
|
SUBDIR.${MK_ICONV}+= iconv
|
||||||
SUBDIR.${MK_ICONV}+= mkcsmapper
|
SUBDIR.${MK_ICONV}+= mkcsmapper
|
||||||
|
|||||||
Reference in New Issue
Block a user