mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-16 10:20:30 +00:00
Merge in/out comflicts caused by Diffutils-2.7 import...
In future, it should be as easy as "update -j ....", but this time I had to go over it by hand. Not nice..
This commit is contained in:
parent
ffb120cc30
commit
efce212686
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=11886
@ -1,9 +1,12 @@
|
||||
/* config.h. Generated automatically by configure. */
|
||||
/* config.h.in. Generated automatically from configure.in by autoheader. */
|
||||
/* config.hin. Generated automatically from configure.in by autoheader. */
|
||||
|
||||
/* Define if using alloca.c. */
|
||||
/* #undef C_ALLOCA */
|
||||
|
||||
/* Define if the closedir function returns void instead of int. */
|
||||
/* #undef CLOSEDIR_VOID */
|
||||
|
||||
/* Define to empty if the keyword does not work. */
|
||||
/* #undef const */
|
||||
|
||||
@ -11,10 +14,7 @@
|
||||
This function is required for alloca.c support on those systems. */
|
||||
/* #undef CRAY_STACKSEG_END */
|
||||
|
||||
/* Define if you have dirent.h. */
|
||||
#define DIRENT 1
|
||||
|
||||
/* Define if you have alloca.h and it should be used (not Ultrix). */
|
||||
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
|
||||
/* #undef HAVE_ALLOCA_H */
|
||||
|
||||
/* Define if you don't have vprintf but do have _doprnt. */
|
||||
@ -23,7 +23,7 @@
|
||||
/* Define if your struct stat has st_blksize. */
|
||||
#define HAVE_ST_BLKSIZE 1
|
||||
|
||||
/* Define if you have vfork.h. */
|
||||
/* Define if you have <vfork.h>. */
|
||||
/* #undef HAVE_VFORK_H */
|
||||
|
||||
/* Define if you have the vprintf function. */
|
||||
@ -32,9 +32,6 @@
|
||||
/* Define if on MINIX. */
|
||||
/* #undef _MINIX */
|
||||
|
||||
/* Define if you don't have dirent.h, but have ndir.h. */
|
||||
/* #undef NDIR */
|
||||
|
||||
/* Define to `int' if <sys/types.h> doesn't define. */
|
||||
/* #undef pid_t */
|
||||
|
||||
@ -63,32 +60,32 @@
|
||||
/* Define if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Define if you don't have dirent.h, but have sys/dir.h. */
|
||||
/* #undef SYSDIR */
|
||||
|
||||
/* Define if you don't have dirent.h, but have sys/ndir.h. */
|
||||
/* #undef SYSNDIR */
|
||||
/* Define if <sys/wait.h> is compatible with Posix applications. */
|
||||
#define HAVE_SYS_WAIT_H 1
|
||||
|
||||
/* Define vfork as fork if vfork does not work. */
|
||||
/* #undef vfork */
|
||||
|
||||
/* Define if the closedir function returns void instead of int. */
|
||||
/* #undef VOID_CLOSEDIR */
|
||||
|
||||
/* Define if you have dup2. */
|
||||
/* Define if you have the dup2 function. */
|
||||
#define HAVE_DUP2 1
|
||||
|
||||
/* Define if you have memchr. */
|
||||
/* Define if you have the memchr function. */
|
||||
#define HAVE_MEMCHR 1
|
||||
|
||||
/* Define if you have sigaction. */
|
||||
/* Define if you have the sigaction function. */
|
||||
#define HAVE_SIGACTION 1
|
||||
|
||||
/* Define if you have strerror. */
|
||||
/* Define if you have the strchr function. */
|
||||
#define HAVE_STRCHR 1
|
||||
|
||||
/* Define if you have the strerror function. */
|
||||
#define HAVE_STRERROR 1
|
||||
|
||||
/* Define if you have waitpid. */
|
||||
#define HAVE_WAITPID 1
|
||||
/* Define if you have the tmpnam function. */
|
||||
#define HAVE_TMPNAM 1
|
||||
|
||||
/* Define if you have the <dirent.h> header file. */
|
||||
#define HAVE_DIRENT_H 1
|
||||
|
||||
/* Define if you have the <fcntl.h> header file. */
|
||||
#define HAVE_FCNTL_H 1
|
||||
@ -96,14 +93,23 @@
|
||||
/* Define if you have the <limits.h> header file. */
|
||||
#define HAVE_LIMITS_H 1
|
||||
|
||||
/* Define if you have the <ndir.h> header file. */
|
||||
/* #undef HAVE_NDIR_H */
|
||||
|
||||
/* Define if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define if you have the <sys/wait.h> header file. */
|
||||
#define HAVE_SYS_WAIT_H 1
|
||||
/* Define if you have the <sys/dir.h> header file. */
|
||||
/* #undef HAVE_SYS_DIR_H */
|
||||
|
||||
/* Define if you have the <sys/file.h> header file. */
|
||||
#define HAVE_SYS_FILE_H 1
|
||||
|
||||
/* Define if you have the <sys/ndir.h> header file. */
|
||||
/* #undef HAVE_SYS_NDIR_H */
|
||||
|
||||
/* Define if you have the <time.h> header file. */
|
||||
#define HAVE_TIME_H 1
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Context-format output routines for GNU DIFF.
|
||||
Copyright (C) 1988, 89, 91, 92, 93 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988,1989,1991,1992,1993,1994 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU DIFF.
|
||||
|
||||
@ -45,9 +45,13 @@ print_context_label (mark, inf, label)
|
||||
if (label)
|
||||
fprintf (outfile, "%s %s\n", mark, label);
|
||||
else
|
||||
/* See Posix.2 section 4.17.6.1.4 for this format. */
|
||||
fprintf (outfile, "%s %s\t%s",
|
||||
mark, inf->name, ctime (&inf->stat.st_mtime));
|
||||
{
|
||||
char const *ct = ctime (&inf->stat.st_mtime);
|
||||
if (!ct)
|
||||
ct = "?\n";
|
||||
/* See Posix.2 section 4.17.6.1.4 for this format. */
|
||||
fprintf (outfile, "%s %s\t%s", mark, inf->name, ct);
|
||||
}
|
||||
}
|
||||
|
||||
/* Print a header for a context diff, with the file names and dates. */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* GNU DIFF main routine.
|
||||
Copyright (C) 1988, 1989, 1992, 1993 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988, 1989, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU DIFF.
|
||||
|
||||
@ -22,6 +22,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#define GDIFF_MAIN
|
||||
#include "diff.h"
|
||||
#include <signal.h>
|
||||
#include "getopt.h"
|
||||
#include "fnmatch.h"
|
||||
|
||||
@ -42,7 +43,9 @@ static int specify_format PARAMS((char **, char *));
|
||||
static void add_exclude PARAMS((char const *));
|
||||
static void add_regexp PARAMS((struct regexp_list **, char const *));
|
||||
static void specify_style PARAMS((enum output_style));
|
||||
static void usage PARAMS((char const *));
|
||||
static void try_help PARAMS((char const *));
|
||||
static void check_stdout PARAMS((void));
|
||||
static void usage PARAMS((void));
|
||||
|
||||
/* Nonzero for -r: if comparing two directories,
|
||||
compare their common subdirectories recursively. */
|
||||
@ -53,6 +56,11 @@ static int recursive;
|
||||
|
||||
int no_discards;
|
||||
|
||||
#if HAVE_SETMODE
|
||||
/* I/O mode: nonzero only if using binary input/output. */
|
||||
static int binary_I_O;
|
||||
#endif
|
||||
|
||||
/* Return a string containing the command options with which diff was invoked.
|
||||
Spaces appear between what were separate ARGV-elements.
|
||||
There is a space at the beginning but none at the end.
|
||||
@ -189,7 +197,6 @@ static struct option const longopts[] =
|
||||
{"print", 0, 0, 'l'}, /* An alias, no longer recommended */
|
||||
{"rcs", 0, 0, 'n'},
|
||||
{"show-c-function", 0, 0, 'p'},
|
||||
{"binary", 0, 0, 'q'}, /* An alias, no longer recommended */
|
||||
{"brief", 0, 0, 'q'},
|
||||
{"recursive", 0, 0, 'r'},
|
||||
{"report-identical-files", 0, 0, 's'},
|
||||
@ -213,6 +220,7 @@ static struct option const longopts[] =
|
||||
{"changed-group-format", 1, 0, 139},
|
||||
{"horizon-lines", 1, 0, 140},
|
||||
{"help", 0, 0, 141},
|
||||
{"binary", 0, 0, 142},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@ -225,12 +233,13 @@ main (argc, argv)
|
||||
int c;
|
||||
int prev = -1;
|
||||
int width = DEFAULT_WIDTH;
|
||||
int show_c_function = 0;
|
||||
|
||||
/* Do our initializations. */
|
||||
program = argv[0];
|
||||
initialize_main (&argc, &argv);
|
||||
program_name = argv[0];
|
||||
output_style = OUTPUT_NORMAL;
|
||||
context = -1;
|
||||
line_end_char = '\n';
|
||||
|
||||
/* Decode the options. */
|
||||
|
||||
@ -270,8 +279,8 @@ main (argc, argv)
|
||||
case 'b':
|
||||
/* Ignore changes in amount of white space. */
|
||||
ignore_space_change_flag = 1;
|
||||
length_varies = 1;
|
||||
ignore_some_changes = 1;
|
||||
ignore_some_line_changes = 1;
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
@ -362,6 +371,7 @@ main (argc, argv)
|
||||
/* Ignore changes in case. */
|
||||
ignore_case_flag = 1;
|
||||
ignore_some_changes = 1;
|
||||
ignore_some_line_changes = 1;
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
@ -374,6 +384,14 @@ main (argc, argv)
|
||||
case 'l':
|
||||
/* Pass the output through `pr' to paginate it. */
|
||||
paginate_flag = 1;
|
||||
#if !defined(SIGCHLD) && defined(SIGCLD)
|
||||
#define SIGCHLD SIGCLD
|
||||
#endif
|
||||
#ifdef SIGCHLD
|
||||
/* Pagination requires forking and waiting, and
|
||||
System V fork+wait does not work if SIGCHLD is ignored. */
|
||||
signal (SIGCHLD, SIG_DFL);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
@ -400,7 +418,7 @@ main (argc, argv)
|
||||
|
||||
case 'p':
|
||||
/* Make context-style output and show name of last C function. */
|
||||
specify_style (OUTPUT_CONTEXT);
|
||||
show_c_function = 1;
|
||||
add_regexp (&function_regexp_list, "^[_a-zA-Z$]");
|
||||
break;
|
||||
|
||||
@ -451,14 +469,14 @@ main (argc, argv)
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
printf ("GNU diff version %s\n", version_string);
|
||||
printf ("diff - GNU diffutils version %s\n", version_string);
|
||||
exit (0);
|
||||
|
||||
case 'w':
|
||||
/* Ignore horizontal white space when comparing lines. */
|
||||
ignore_all_space_flag = 1;
|
||||
ignore_some_changes = 1;
|
||||
length_varies = 1;
|
||||
ignore_some_line_changes = 1;
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
@ -529,16 +547,27 @@ main (argc, argv)
|
||||
break;
|
||||
|
||||
case 141:
|
||||
usage (0);
|
||||
usage ();
|
||||
check_stdout ();
|
||||
exit (0);
|
||||
|
||||
case 142:
|
||||
/* Use binary I/O when reading and writing data.
|
||||
On Posix hosts, this has no effect. */
|
||||
#if HAVE_SETMODE
|
||||
binary_I_O = 1;
|
||||
setmode (STDOUT_FILENO, O_BINARY);
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
usage ("");
|
||||
try_help (0);
|
||||
}
|
||||
prev = c;
|
||||
}
|
||||
|
||||
if (optind != argc - 2)
|
||||
usage (optind < argc - 2 ? "extra operand" : "missing operand");
|
||||
if (argc - optind != 2)
|
||||
try_help (argc - optind < 2 ? "missing operand" : "extra operand");
|
||||
|
||||
|
||||
{
|
||||
@ -558,6 +587,9 @@ main (argc, argv)
|
||||
sdiff_column2_offset = sdiff_half_width ? off : width;
|
||||
}
|
||||
|
||||
if (show_c_function && output_style != OUTPUT_UNIFIED)
|
||||
specify_style (OUTPUT_CONTEXT);
|
||||
|
||||
if (output_style != OUTPUT_CONTEXT && output_style != OUTPUT_UNIFIED)
|
||||
context = 0;
|
||||
else if (context == -1)
|
||||
@ -566,6 +598,10 @@ main (argc, argv)
|
||||
|
||||
if (output_style == OUTPUT_IFDEF)
|
||||
{
|
||||
/* Format arrays are char *, not char const *,
|
||||
because integer formats are temporarily modified.
|
||||
But it is safe to assign a constant like "%=" to a format array,
|
||||
since "%=" does not format any integers. */
|
||||
int i;
|
||||
for (i = 0; i < sizeof (line_format) / sizeof (*line_format); i++)
|
||||
if (!line_format[i])
|
||||
@ -597,8 +633,7 @@ main (argc, argv)
|
||||
/* Print any messages that were saved up for last. */
|
||||
print_message_queue ();
|
||||
|
||||
if (ferror (stdout) || fclose (stdout) != 0)
|
||||
fatal ("write error");
|
||||
check_stdout ();
|
||||
exit (val);
|
||||
return val;
|
||||
}
|
||||
@ -626,37 +661,96 @@ add_regexp (reglist, pattern)
|
||||
}
|
||||
|
||||
static void
|
||||
usage (reason)
|
||||
try_help (reason)
|
||||
char const *reason;
|
||||
{
|
||||
if (reason && *reason)
|
||||
fprintf (stderr, "%s: %s\n", program, reason);
|
||||
fflush (stderr);
|
||||
printf ("Usage: %s [options] from-file to-file\n", program);
|
||||
printf ("Options:\n\
|
||||
[-abBcdefhHilnNpPqrstTuvwy] [-C lines] [-D name] [-F regexp]\n\
|
||||
[-I regexp] [-L from-label [-L to-label]] [-S starting-file] [-U lines]\n\
|
||||
[-W columns] [-x pattern] [-X pattern-file]\n");
|
||||
printf ("\
|
||||
[--brief] [--changed-group-format=format] [--context[=lines]] [--ed]\n\
|
||||
[--exclude=pattern] [--exclude-from=pattern-file] [--expand-tabs]\n\
|
||||
[--forward-ed] [--help] [--horizon-lines=lines] [--ifdef=name]\n\
|
||||
[--ignore-all-space] [--ignore-blank-lines] [--ignore-case]\n");
|
||||
printf ("\
|
||||
[--ignore-matching-lines=regexp] [--ignore-space-change]\n\
|
||||
[--initial-tab] [--label=from-label [--label=to-label]]\n\
|
||||
[--left-column] [--minimal] [--new-file] [--new-group-format=format]\n\
|
||||
[--new-line-format=format] [--old-group-format=format]\n");
|
||||
printf ("\
|
||||
[--old-line-format=format] [--paginate] [--rcs] [--recursive]\n\
|
||||
[--report-identical-files] [--sdiff-merge-assist] [--show-c-function]\n\
|
||||
[--show-function-line=regexp] [--side-by-side] [--speed-large-files]\n\
|
||||
[--starting-file=starting-file] [--suppress-common-lines] [--text]\n");
|
||||
printf ("\
|
||||
[--unchanged-group-format=format] [--unchanged-line-format=format]\n\
|
||||
[--unidirectional-new-file] [--unified[=lines]] [--version]\n\
|
||||
[--width=columns]\n");
|
||||
exit (reason ? 2 : 0);
|
||||
if (reason)
|
||||
error ("%s", reason, 0);
|
||||
error ("Try `%s --help' for more information.", program_name, 0);
|
||||
exit (2);
|
||||
}
|
||||
|
||||
static void
|
||||
check_stdout ()
|
||||
{
|
||||
if (ferror (stdout) || fclose (stdout) != 0)
|
||||
fatal ("write error");
|
||||
}
|
||||
|
||||
static char const * const option_help[] = {
|
||||
"-i --ignore-case Consider upper- and lower-case to be the same.",
|
||||
"-w --ignore-all-space Ignore all white space.",
|
||||
"-b --ignore-space-change Ignore changes in the amount of white space.",
|
||||
"-B --ignore-blank-lines Ignore changes whose lines are all blank.",
|
||||
"-I RE --ignore-matching-lines=RE Ignore changes whose lines all match RE.",
|
||||
#if HAVE_SETMODE
|
||||
"--binary Read and write data in binary mode.",
|
||||
#endif
|
||||
"-a --text Treat all files as text.\n",
|
||||
"-c -C NUM --context[=NUM] Output NUM (default 2) lines of copied context.",
|
||||
"-u -U NUM --unified[=NUM] Output NUM (default 2) lines of unified context.",
|
||||
" -NUM Use NUM context lines.",
|
||||
" -L LABEL --label LABEL Use LABEL instead of file name.",
|
||||
" -p --show-c-function Show which C function each change is in.",
|
||||
" -F RE --show-function-line=RE Show the most recent line matching RE.",
|
||||
"-q --brief Output only whether files differ.",
|
||||
"-e --ed Output an ed script.",
|
||||
"-n --rcs Output an RCS format diff.",
|
||||
"-y --side-by-side Output in two columns.",
|
||||
" -w NUM --width=NUM Output at most NUM (default 130) characters per line.",
|
||||
" --left-column Output only the left column of common lines.",
|
||||
" --suppress-common-lines Do not output common lines.",
|
||||
"-DNAME --ifdef=NAME Output merged file to show `#ifdef NAME' diffs.",
|
||||
"--GTYPE-group-format=GFMT Similar, but format GTYPE input groups with GFMT.",
|
||||
"--line-format=LFMT Similar, but format all input lines with LFMT.",
|
||||
"--LTYPE-line-format=LFMT Similar, but format LTYPE input lines with LFMT.",
|
||||
" LTYPE is `old', `new', or `unchanged'. GTYPE is LTYPE or `changed'.",
|
||||
" GFMT may contain:",
|
||||
" %< lines from FILE1",
|
||||
" %> lines from FILE2",
|
||||
" %= lines common to FILE1 and FILE2",
|
||||
" %[-][WIDTH][.[PREC]]{doxX}LETTER printf-style spec for LETTER",
|
||||
" LETTERs are as follows for new group, lower case for old group:",
|
||||
" F first line number",
|
||||
" L last line number",
|
||||
" N number of lines = L-F+1",
|
||||
" E F-1",
|
||||
" M L+1",
|
||||
" LFMT may contain:",
|
||||
" %L contents of line",
|
||||
" %l contents of line, excluding any trailing newline",
|
||||
" %[-][WIDTH][.[PREC]]{doxX}n printf-style spec for input line number",
|
||||
" Either GFMT or LFMT may contain:",
|
||||
" %% %",
|
||||
" %c'C' the single character C",
|
||||
" %c'\\OOO' the character with octal code OOO\n",
|
||||
"-l --paginate Pass the output through `pr' to paginate it.",
|
||||
"-t --expand-tabs Expand tabs to spaces in output.",
|
||||
"-T --initial-tab Make tabs line up by prepending a tab.\n",
|
||||
"-r --recursive Recursively compare any subdirectories found.",
|
||||
"-N --new-file Treat absent files as empty.",
|
||||
"-P --unidirectional-new-file Treat absent first files as empty.",
|
||||
"-s --report-identical-files Report when two files are the same.",
|
||||
"-x PAT --exclude=PAT Exclude files that match PAT.",
|
||||
"-X FILE --exclude-from=FILE Exclude files that match any pattern in FILE.",
|
||||
"-S FILE --starting-file=FILE Start with FILE when comparing directories.\n",
|
||||
"--horizon-lines=NUM Keep NUM lines of the common prefix and suffix.",
|
||||
"-d --minimal Try hard to find a smaller set of changes.",
|
||||
"-H --speed-large-files Assume large files and many scattered small changes.\n",
|
||||
"-v --version Output version info.",
|
||||
"--help Output this help.",
|
||||
0
|
||||
};
|
||||
|
||||
static void
|
||||
usage ()
|
||||
{
|
||||
char const * const *p;
|
||||
|
||||
printf ("Usage: %s [OPTION]... FILE1 FILE2\n\n", program_name);
|
||||
for (p = option_help; *p; p++)
|
||||
printf (" %s\n", *p);
|
||||
printf ("\nIf FILE1 or FILE2 is `-', read standard input.\n");
|
||||
}
|
||||
|
||||
static int
|
||||
@ -710,8 +804,19 @@ filetype (st)
|
||||
if (S_ISFIFO (st->st_mode)) return "fifo";
|
||||
#endif
|
||||
|
||||
/* other Posix.1b file types */
|
||||
#ifdef S_TYPEISMQ
|
||||
if (S_TYPEISMQ (st)) return "message queue";
|
||||
#endif
|
||||
#ifdef S_TYPEISSEM
|
||||
if (S_TYPEISSEM (st)) return "semaphore";
|
||||
#endif
|
||||
#ifdef S_TYPEISSHM
|
||||
if (S_TYPEISSHM (st)) return "shared memory object";
|
||||
#endif
|
||||
|
||||
/* other popular file types */
|
||||
/* S_ISLNK is impossible with `stat'. */
|
||||
/* S_ISLNK is impossible with `fstat' and `stat'. */
|
||||
#ifdef S_ISSOCK
|
||||
if (S_ISSOCK (st->st_mode)) return "socket";
|
||||
#endif
|
||||
@ -781,7 +886,7 @@ compare_files (dir0, name0, dir1, name1, depth)
|
||||
{
|
||||
int stat_result;
|
||||
|
||||
if (i && strcmp (inf[i].name, inf[0].name) == 0)
|
||||
if (i && filename_cmp (inf[i].name, inf[0].name) == 0)
|
||||
{
|
||||
inf[i].stat = inf[0].stat;
|
||||
stat_result = 0;
|
||||
@ -835,7 +940,7 @@ compare_files (dir0, name0, dir1, name1, depth)
|
||||
int dir_arg = 1 - fnm_arg;
|
||||
char const *fnm = inf[fnm_arg].name;
|
||||
char const *dir = inf[dir_arg].name;
|
||||
char const *p = strrchr (fnm, '/');
|
||||
char const *p = filename_lastdirchar (fnm);
|
||||
char const *filename = inf[dir_arg].name
|
||||
= dir_file_pathname (dir, p ? p + 1 : fnm);
|
||||
|
||||
@ -859,11 +964,8 @@ compare_files (dir0, name0, dir1, name1, depth)
|
||||
val = 2;
|
||||
|
||||
}
|
||||
else if ((same_files = inf[0].stat.st_ino == inf[1].stat.st_ino
|
||||
&& inf[0].stat.st_dev == inf[1].stat.st_dev
|
||||
&& inf[0].stat.st_size == inf[1].stat.st_size
|
||||
&& inf[0].desc != -1
|
||||
&& inf[1].desc != -1)
|
||||
else if ((same_files = inf[0].desc != -1 && inf[1].desc != -1
|
||||
&& 0 < same_file (&inf[0].stat, &inf[1].stat))
|
||||
&& no_diff_means_no_output)
|
||||
{
|
||||
/* The two named files are actually the same physical file.
|
||||
@ -957,6 +1059,13 @@ compare_files (dir0, name0, dir1, name1, depth)
|
||||
failed = 1;
|
||||
}
|
||||
|
||||
#if HAVE_SETMODE
|
||||
if (binary_I_O)
|
||||
for (i = 0; i <= 1; i++)
|
||||
if (0 <= inf[i].desc)
|
||||
setmode (inf[i].desc, O_BINARY);
|
||||
#endif
|
||||
|
||||
/* Compare the files, if no error was found. */
|
||||
|
||||
val = failed ? 2 : diff_2_files (inf, depth);
|
||||
|
@ -18,14 +18,9 @@ along with GNU DIFF; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "system.h"
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include "gnuregex.h"
|
||||
|
||||
#ifndef PR_FILE_NAME
|
||||
#define PR_FILE_NAME "/bin/pr"
|
||||
#endif
|
||||
|
||||
#define TAB_WIDTH 8
|
||||
|
||||
/* Variables for command line options */
|
||||
@ -84,9 +79,9 @@ EXTERN int ignore_all_space_flag;
|
||||
/* Ignore changes that affect only blank lines (-B). */
|
||||
EXTERN int ignore_blank_lines_flag;
|
||||
|
||||
/* 1 if lines may match even if their lengths are different.
|
||||
/* 1 if lines may match even if their contents do not match exactly.
|
||||
This depends on various options. */
|
||||
EXTERN int length_varies;
|
||||
EXTERN int ignore_some_line_changes;
|
||||
|
||||
/* 1 if files may match even if their contents are not byte-for-byte identical.
|
||||
This depends on various options. */
|
||||
@ -117,9 +112,6 @@ EXTERN int no_details_flag;
|
||||
Normally nothing is output when that happens. */
|
||||
EXTERN int print_file_same_flag;
|
||||
|
||||
/* character that ends a line. Currently this is always `\n'. */
|
||||
EXTERN char line_end_char;
|
||||
|
||||
/* Output the differences with exactly 8 columns added to each line
|
||||
so that any tabs in the text line up properly (-T). */
|
||||
EXTERN int tab_align_flag;
|
||||
@ -184,7 +176,7 @@ EXTERN char * switch_string;
|
||||
EXTERN int heuristic;
|
||||
|
||||
/* Name of program the user invoked (for error messages). */
|
||||
EXTERN char * program;
|
||||
EXTERN char *program_name;
|
||||
|
||||
/* The result of comparison is an "edit script": a chain of `struct change'.
|
||||
Each `struct change' represents one place where some lines are deleted
|
||||
@ -322,7 +314,7 @@ VOID *xrealloc PARAMS((VOID *, size_t));
|
||||
char *concat PARAMS((char const *, char const *, char const *));
|
||||
char *dir_file_pathname PARAMS((char const *, char const *));
|
||||
int change_letter PARAMS((int, int));
|
||||
int line_cmp PARAMS((char const *, size_t, char const *, size_t));
|
||||
int line_cmp PARAMS((char const *, char const *));
|
||||
int translate_line_number PARAMS((struct file_data const *, int));
|
||||
struct change *find_change PARAMS((struct change *));
|
||||
struct change *find_reverse_change PARAMS((struct change *));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Three way file comparison program (diff3) for Project GNU.
|
||||
Copyright (C) 1988, 1989, 1992, 1993 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988, 1989, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -19,7 +19,7 @@
|
||||
|
||||
#include "system.h"
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#include "getopt.h"
|
||||
|
||||
extern char const version_string[];
|
||||
@ -163,9 +163,7 @@ static int simple_only;
|
||||
/* If nonzero, do not output information for non-overlapping diffs. */
|
||||
static int overlap_only;
|
||||
|
||||
/* If nonzero, show information for 3_way and DIFF_2ND diffs.
|
||||
1= show 2nd only when 1st and 3rd differ
|
||||
2= show 2nd when DIFF_2ND (1 and 3 have same change relative to 2) */
|
||||
/* If nonzero, show information for DIFF_2ND diffs. */
|
||||
static int show_2nd;
|
||||
|
||||
/* If nonzero, include `:wq' at the end of the script
|
||||
@ -175,7 +173,7 @@ static int finalwrite;
|
||||
/* If nonzero, output a merged file. */
|
||||
static int merge;
|
||||
|
||||
static char *argv0;
|
||||
static char *program_name;
|
||||
|
||||
static VOID *xmalloc PARAMS((size_t));
|
||||
static VOID *xrealloc PARAMS((VOID *, size_t));
|
||||
@ -194,11 +192,13 @@ static struct diff3_block *make_3way_diff PARAMS((struct diff_block *, struct di
|
||||
static struct diff3_block *reverse_diff3_blocklist PARAMS((struct diff3_block *));
|
||||
static struct diff3_block *using_to_diff3_block PARAMS((struct diff_block *[2], struct diff_block *[2], int, int, struct diff3_block const *));
|
||||
static struct diff_block *process_diff PARAMS((char const *, char const *, struct diff_block **));
|
||||
static void check_stdout PARAMS((void));
|
||||
static void fatal PARAMS((char const *));
|
||||
static void output_diff3 PARAMS((FILE *, struct diff3_block *, int const[3], int const[3]));
|
||||
static void perror_with_exit PARAMS((char const *));
|
||||
static void try_help PARAMS((char const *));
|
||||
static void undotlines PARAMS((FILE *, int, int, int));
|
||||
static void usage PARAMS((int));
|
||||
static void usage PARAMS((void));
|
||||
|
||||
static char const diff_program[] = DIFF_PROGRAM;
|
||||
|
||||
@ -206,7 +206,6 @@ static struct option const longopts[] =
|
||||
{
|
||||
{"text", 0, 0, 'a'},
|
||||
{"show-all", 0, 0, 'A'},
|
||||
{"show-bogus-conflicts", 0, 0, 'B'},
|
||||
{"ed", 0, 0, 'e'},
|
||||
{"show-overlap", 0, 0, 'E'},
|
||||
{"label", 1, 0, 'L'},
|
||||
@ -231,7 +230,7 @@ main (argc, argv)
|
||||
int c, i;
|
||||
int mapping[3];
|
||||
int rev_mapping[3];
|
||||
int incompat;
|
||||
int incompat = 0;
|
||||
int conflicts_found;
|
||||
struct diff_block *thread0, *thread1, *last_block;
|
||||
struct diff3_block *diff3;
|
||||
@ -241,22 +240,18 @@ main (argc, argv)
|
||||
char **file;
|
||||
struct stat statb;
|
||||
|
||||
incompat = 0;
|
||||
initialize_main (&argc, &argv);
|
||||
program_name = argv[0];
|
||||
|
||||
argv0 = argv[0];
|
||||
|
||||
while ((c = getopt_long (argc, argv, "aeimvx3ABEL:TX", longopts, 0)) != EOF)
|
||||
while ((c = getopt_long (argc, argv, "aeimvx3AEL:TX", longopts, 0)) != EOF)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'a':
|
||||
always_text = 1;
|
||||
break;
|
||||
case 'B':
|
||||
++show_2nd;
|
||||
/* Falls through */
|
||||
case 'A':
|
||||
++show_2nd;
|
||||
show_2nd = 1;
|
||||
flagging = 1;
|
||||
incompat++;
|
||||
break;
|
||||
@ -287,10 +282,12 @@ main (argc, argv)
|
||||
tab_align_flag = 1;
|
||||
break;
|
||||
case 'v':
|
||||
printf ("GNU diff3 version %s\n", version_string);
|
||||
printf ("diff3 - GNU diffutils version %s\n", version_string);
|
||||
exit (0);
|
||||
case 129:
|
||||
usage (0);
|
||||
usage ();
|
||||
check_stdout ();
|
||||
exit (0);
|
||||
case 'L':
|
||||
/* Handle up to three -L options. */
|
||||
if (tag_count < 3)
|
||||
@ -298,9 +295,9 @@ main (argc, argv)
|
||||
tag_strings[tag_count++] = optarg;
|
||||
break;
|
||||
}
|
||||
/* Falls through */
|
||||
try_help ("Too many labels were given. The limit is 3.");
|
||||
default:
|
||||
usage (2);
|
||||
try_help (0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -310,9 +307,11 @@ main (argc, argv)
|
||||
|
||||
if (incompat > 1 /* Ensure at most one of -AeExX3. */
|
||||
|| finalwrite & merge /* -i -m would rewrite input file. */
|
||||
|| (tag_count && ! flagging) /* -L requires one of -AEX. */
|
||||
|| argc - optind != 3)
|
||||
usage (2);
|
||||
|| (tag_count && ! flagging)) /* -L requires one of -AEX. */
|
||||
try_help ("incompatible options");
|
||||
|
||||
if (argc - optind != 3)
|
||||
try_help (argc - optind < 3 ? "missing operand" : "extra operand");
|
||||
|
||||
file = &argv[optind];
|
||||
|
||||
@ -355,11 +354,20 @@ main (argc, argv)
|
||||
perror_with_exit (file[i]);
|
||||
else if (S_ISDIR(statb.st_mode))
|
||||
{
|
||||
fprintf (stderr, "%s: %s: Is a directory\n", argv0, file[i]);
|
||||
fprintf (stderr, "%s: %s: Is a directory\n",
|
||||
program_name, file[i]);
|
||||
exit (2);
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(SIGCHLD) && defined(SIGCLD)
|
||||
#define SIGCHLD SIGCLD
|
||||
#endif
|
||||
#ifdef SIGCHLD
|
||||
/* System V fork+wait does not work if SIGCHLD is ignored. */
|
||||
signal (SIGCHLD, SIG_DFL);
|
||||
#endif
|
||||
|
||||
commonname = file[rev_mapping[FILEC]];
|
||||
thread1 = process_diff (file[rev_mapping[FILE1]], commonname, &last_block);
|
||||
if (thread1)
|
||||
@ -390,30 +398,54 @@ main (argc, argv)
|
||||
conflicts_found = 0;
|
||||
}
|
||||
|
||||
if (ferror (stdout) || fclose (stdout) != 0)
|
||||
fatal ("write error");
|
||||
check_stdout ();
|
||||
exit (conflicts_found);
|
||||
return conflicts_found;
|
||||
}
|
||||
|
||||
static void
|
||||
try_help (reason)
|
||||
char const *reason;
|
||||
{
|
||||
if (reason)
|
||||
fprintf (stderr, "%s: %s\n", program_name, reason);
|
||||
fprintf (stderr, "%s: Try `%s --help' for more information.\n",
|
||||
program_name, program_name);
|
||||
exit (2);
|
||||
}
|
||||
|
||||
static void
|
||||
check_stdout ()
|
||||
{
|
||||
if (ferror (stdout) || fclose (stdout) != 0)
|
||||
fatal ("write error");
|
||||
}
|
||||
|
||||
/*
|
||||
* Explain, patiently and kindly, how to use this program. Then exit.
|
||||
* Explain, patiently and kindly, how to use this program.
|
||||
*/
|
||||
static void
|
||||
usage (status)
|
||||
int status;
|
||||
usage ()
|
||||
{
|
||||
fflush (stderr);
|
||||
printf ("\
|
||||
Usage: %s [options] my-file older-file your-file\n\
|
||||
Options:\n\
|
||||
[-exABEX3aTv] [-i|-m] [-L label1 [-L label2 [-L label3]]]\n\
|
||||
[--easy-only] [--ed] [--help] [--initial-tab]\n\
|
||||
[--label=label1 [--label=label2 [--label=label3]]] [--merge]\n\
|
||||
[--overlap-only] [--show-all] [ --show-bogus-conflicts ]\n\
|
||||
[--show-overlap] [--text] [--version]\n\
|
||||
Only one of [exABEX3] is allowed\n", argv0);
|
||||
exit (status);
|
||||
printf ("Usage: %s [OPTION]... MYFILE OLDFILE YOURFILE\n\n", program_name);
|
||||
|
||||
printf ("%s", "\
|
||||
-e --ed Output unmerged changes from OLDFILE to YOURFILE into MYFILE.\n\
|
||||
-E --show-overlap Output unmerged changes, bracketing conflicts.\n\
|
||||
-A --show-all Output all changes, bracketing conflicts.\n\
|
||||
-x --overlap-only Output overlapping changes.\n\
|
||||
-X Output overlapping changes, bracketing them.\n\
|
||||
-3 --easy-only Output unmerged nonoverlapping changes.\n\n");
|
||||
printf ("%s", "\
|
||||
-m --merge Output merged file instead of ed script (default -A).\n\
|
||||
-L LABEL --label=LABEL Use LABEL instead of file name.\n\
|
||||
-i Append `w' and `q' commands to ed scripts.\n\
|
||||
-a --text Treat all files as text.\n\
|
||||
-T --initial-tab Make tabs line up by prepending a tab.\n\n");
|
||||
printf ("%s", "\
|
||||
-v --version Output version info.\n\
|
||||
--help Output this help.\n\n");
|
||||
printf ("If a FILE is `-', read standard input.\n");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -903,8 +935,6 @@ compare_line_list (list1, lengths1, list2, lengths2, nl)
|
||||
|
||||
extern char **environ;
|
||||
|
||||
#define DIFF_CHUNK_SIZE 10000
|
||||
|
||||
static struct diff_block *
|
||||
process_diff (filea, fileb, last_block)
|
||||
char const *filea, *fileb;
|
||||
@ -931,7 +961,7 @@ process_diff (filea, fileb, last_block)
|
||||
dt = process_diff_control (&scan_diff, bptr);
|
||||
if (dt == ERROR || *scan_diff != '\n')
|
||||
{
|
||||
fprintf (stderr, "%s: diff error: ", argv0);
|
||||
fprintf (stderr, "%s: diff error: ", program_name);
|
||||
do
|
||||
{
|
||||
putc (*scan_diff, stderr);
|
||||
@ -1039,9 +1069,9 @@ process_diff_control (string, db)
|
||||
|
||||
#define SKIPWHITE(s) { while (*s == ' ' || *s == '\t') s++; }
|
||||
#define READNUM(s, num) \
|
||||
{ unsigned char c = *s; if (!isdigit (c)) return ERROR; holdnum = 0; \
|
||||
{ unsigned char c = *s; if (!ISDIGIT (c)) return ERROR; holdnum = 0; \
|
||||
do { holdnum = (c - '0' + holdnum * 10); } \
|
||||
while (isdigit (c = *++s)); (num) = holdnum; }
|
||||
while (ISDIGIT (c = *++s)); (num) = holdnum; }
|
||||
|
||||
/* Read first set of digits */
|
||||
SKIPWHITE (s);
|
||||
@ -1103,12 +1133,20 @@ read_diff (filea, fileb, output_placement)
|
||||
{
|
||||
char *diff_result;
|
||||
size_t bytes, current_chunk_size, total;
|
||||
int fd, wstatus;
|
||||
struct stat pipestat;
|
||||
|
||||
/* 302 / 1000 is log10(2.0) rounded up. Subtract 1 for the sign bit;
|
||||
add 1 for integer division truncation; add 1 more for a minus sign. */
|
||||
#define INT_STRLEN_BOUND(type) ((sizeof(type)*CHAR_BIT - 1) * 302 / 1000 + 2)
|
||||
|
||||
#if HAVE_FORK
|
||||
|
||||
char const *argv[7];
|
||||
char horizon_arg[256];
|
||||
char horizon_arg[17 + INT_STRLEN_BOUND (int)];
|
||||
char const **ap;
|
||||
int fds[2];
|
||||
pid_t pid;
|
||||
int wstatus;
|
||||
|
||||
ap = argv;
|
||||
*ap++ = diff_program;
|
||||
@ -1121,8 +1159,8 @@ read_diff (filea, fileb, output_placement)
|
||||
*ap++ = fileb;
|
||||
*ap = 0;
|
||||
|
||||
if (pipe (fds) < 0)
|
||||
perror_with_exit ("pipe failed");
|
||||
if (pipe (fds) != 0)
|
||||
perror_with_exit ("pipe");
|
||||
|
||||
pid = vfork ();
|
||||
if (pid == 0)
|
||||
@ -1145,11 +1183,37 @@ read_diff (filea, fileb, output_placement)
|
||||
perror_with_exit ("fork failed");
|
||||
|
||||
close (fds[1]); /* Prevent erroneous lack of EOF */
|
||||
current_chunk_size = DIFF_CHUNK_SIZE;
|
||||
fd = fds[0];
|
||||
|
||||
#else /* ! HAVE_FORK */
|
||||
|
||||
FILE *fpipe;
|
||||
char *command = xmalloc (sizeof (diff_program) + 30 + INT_STRLEN_BOUND (int)
|
||||
+ 4 * (strlen (filea) + strlen (fileb)));
|
||||
char *p;
|
||||
sprintf (command, "%s -a --horizon-lines=%d -- ",
|
||||
diff_program, horizon_lines);
|
||||
p = command + strlen (command);
|
||||
SYSTEM_QUOTE_ARG (p, filea);
|
||||
*p++ = ' ';
|
||||
SYSTEM_QUOTE_ARG (p, fileb);
|
||||
*p = '\0';
|
||||
fpipe = popen (command, "r");
|
||||
if (!fpipe)
|
||||
perror_with_exit (command);
|
||||
free (command);
|
||||
fd = fileno (fpipe);
|
||||
|
||||
#endif /* ! HAVE_FORK */
|
||||
|
||||
current_chunk_size = 8 * 1024;
|
||||
if (fstat (fd, &pipestat) == 0)
|
||||
current_chunk_size = max (current_chunk_size, STAT_BLOCKSIZE (pipestat));
|
||||
|
||||
diff_result = xmalloc (current_chunk_size);
|
||||
total = 0;
|
||||
do {
|
||||
bytes = myread (fds[0],
|
||||
bytes = myread (fd,
|
||||
diff_result + total,
|
||||
current_chunk_size - total);
|
||||
total += bytes;
|
||||
@ -1170,18 +1234,18 @@ read_diff (filea, fileb, output_placement)
|
||||
|
||||
*output_placement = diff_result;
|
||||
|
||||
#if HAVE_WAITPID
|
||||
#if ! HAVE_FORK
|
||||
|
||||
wstatus = pclose (fpipe);
|
||||
|
||||
#else /* HAVE_FORK */
|
||||
|
||||
if (close (fd) != 0)
|
||||
perror_with_exit ("pipe close");
|
||||
if (waitpid (pid, &wstatus, 0) < 0)
|
||||
perror_with_exit ("waitpid failed");
|
||||
#else
|
||||
for (;;) {
|
||||
pid_t w = wait (&wstatus);
|
||||
if (w < 0)
|
||||
perror_with_exit ("wait failed");
|
||||
if (w == pid)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_FORK */
|
||||
|
||||
if (! (WIFEXITED (wstatus) && WEXITSTATUS (wstatus) < 2))
|
||||
fatal ("subsidiary diff failed");
|
||||
@ -1198,15 +1262,15 @@ read_diff (filea, fileb, output_placement)
|
||||
* are used as call-by-reference values.
|
||||
*/
|
||||
static char *
|
||||
scan_diff_line (scan_ptr, set_start, set_length, limit, firstchar)
|
||||
scan_diff_line (scan_ptr, set_start, set_length, limit, leadingchar)
|
||||
char *scan_ptr, **set_start;
|
||||
size_t *set_length;
|
||||
char *limit;
|
||||
char firstchar;
|
||||
int leadingchar;
|
||||
{
|
||||
char *line_ptr;
|
||||
|
||||
if (!(scan_ptr[0] == (firstchar)
|
||||
if (!(scan_ptr[0] == leadingchar
|
||||
&& scan_ptr[1] == ' '))
|
||||
fatal ("invalid diff format; incorrect leading line chars");
|
||||
|
||||
@ -1223,7 +1287,7 @@ scan_diff_line (scan_ptr, set_start, set_length, limit, firstchar)
|
||||
if (line_ptr < limit && *line_ptr == '\\')
|
||||
{
|
||||
if (edscript)
|
||||
fprintf (stderr, "%s:", argv0);
|
||||
fprintf (stderr, "%s:", program_name);
|
||||
else
|
||||
--*set_length;
|
||||
line_ptr++;
|
||||
@ -1430,7 +1494,7 @@ output_diff3_edscript (outputfile, diff, mapping, rev_mapping,
|
||||
switch (type)
|
||||
{
|
||||
default: continue;
|
||||
case DIFF_2ND: if (show_2nd < 2) continue; conflict = 1; break;
|
||||
case DIFF_2ND: if (!show_2nd) continue; conflict = 1; break;
|
||||
case DIFF_3RD: if (overlap_only) continue; conflict = 0; break;
|
||||
case DIFF_ALL: if (simple_only) continue; conflict = flagging; break;
|
||||
}
|
||||
@ -1559,7 +1623,7 @@ output_diff3_merge (infile, outputfile, diff, mapping, rev_mapping,
|
||||
switch (type)
|
||||
{
|
||||
default: continue;
|
||||
case DIFF_2ND: if (show_2nd < 2) continue; conflict = 1; break;
|
||||
case DIFF_2ND: if (!show_2nd) continue; conflict = 1; break;
|
||||
case DIFF_3RD: if (overlap_only) continue; conflict = 0; break;
|
||||
case DIFF_ALL: if (simple_only) continue; conflict = flagging;
|
||||
format_2nd = "||||||| %s\n";
|
||||
@ -1698,7 +1762,7 @@ static void
|
||||
fatal (string)
|
||||
char const *string;
|
||||
{
|
||||
fprintf (stderr, "%s: %s\n", argv0, string);
|
||||
fprintf (stderr, "%s: %s\n", program_name, string);
|
||||
exit (2);
|
||||
}
|
||||
|
||||
@ -1707,7 +1771,7 @@ perror_with_exit (string)
|
||||
char const *string;
|
||||
{
|
||||
int e = errno;
|
||||
fprintf (stderr, "%s: ", argv0);
|
||||
fprintf (stderr, "%s: ", program_name);
|
||||
errno = e;
|
||||
perror (string);
|
||||
exit (2);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Read, sort and compare two directories. Used for GNU DIFF.
|
||||
Copyright (C) 1988, 1989, 1992, 1993 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988, 1989, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU DIFF.
|
||||
|
||||
@ -75,7 +75,7 @@ dir_sort (dir, dirdata)
|
||||
while ((errno = 0, (next = readdir (reading)) != 0))
|
||||
{
|
||||
char *d_name = next->d_name;
|
||||
size_t d_size;
|
||||
size_t d_size = NAMLEN (next) + 1;
|
||||
|
||||
/* Ignore the files `.' and `..' */
|
||||
if (d_name[0] == '.'
|
||||
@ -85,7 +85,6 @@ dir_sort (dir, dirdata)
|
||||
if (excluded_filename (d_name))
|
||||
continue;
|
||||
|
||||
d_size = strlen (d_name) + 1;
|
||||
while (data_alloc < data_used + d_size)
|
||||
dirdata->data = data = xrealloc (data, data_alloc *= 2);
|
||||
memcpy (data + data_used, d_name, d_size);
|
||||
@ -99,7 +98,7 @@ dir_sort (dir, dirdata)
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
#if VOID_CLOSEDIR
|
||||
#if CLOSEDIR_VOID
|
||||
closedir (reading);
|
||||
#else
|
||||
if (closedir (reading) != 0)
|
||||
@ -129,7 +128,8 @@ static int
|
||||
compare_names (file1, file2)
|
||||
void const *file1, *file2;
|
||||
{
|
||||
return strcmp (* (char const *const *) file1, * (char const *const *) file2);
|
||||
return filename_cmp (* (char const *const *) file1,
|
||||
* (char const *const *) file2);
|
||||
}
|
||||
|
||||
/* Compare the contents of two directories named in FILEVEC[0] and FILEVEC[1].
|
||||
@ -182,9 +182,9 @@ diff_dirs (filevec, handle_file, depth)
|
||||
|
||||
if (dir_start_file && depth == 0)
|
||||
{
|
||||
while (*names0 && strcmp (*names0, dir_start_file) < 0)
|
||||
while (*names0 && filename_cmp (*names0, dir_start_file) < 0)
|
||||
names0++;
|
||||
while (*names1 && strcmp (*names1, dir_start_file) < 0)
|
||||
while (*names1 && filename_cmp (*names1, dir_start_file) < 0)
|
||||
names1++;
|
||||
}
|
||||
|
||||
@ -195,7 +195,7 @@ diff_dirs (filevec, handle_file, depth)
|
||||
At the end of a dir,
|
||||
pretend the "next name" in that dir is very large. */
|
||||
int nameorder = (!*names0 ? 1 : !*names1 ? -1
|
||||
: strcmp (*names0, *names1));
|
||||
: filename_cmp (*names0, *names1));
|
||||
int v1 = (*handle_file) (name0, 0 < nameorder ? 0 : *names0++,
|
||||
name1, nameorder < 0 ? 0 : *names1++,
|
||||
depth + 1);
|
||||
|
@ -1,209 +0,0 @@
|
||||
/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
|
||||
NOTE: The canonical source of this file is maintained with the GNU C Library.
|
||||
Bugs can be reported to bug-glibc@prep.ai.mit.edu.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#if defined (CONFIG_BROKETS)
|
||||
/* We use <config.h> instead of "config.h" so that a compilation
|
||||
using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
|
||||
(which it would do because it found this file in $srcdir). */
|
||||
#include <config.h>
|
||||
#else
|
||||
#include "config.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <fnmatch.h>
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
|
||||
|
||||
|
||||
#if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
/* Match STRING against the filename pattern PATTERN, returning zero if
|
||||
it matches, nonzero if not. */
|
||||
int
|
||||
fnmatch (pattern, string, flags)
|
||||
const char *pattern;
|
||||
const char *string;
|
||||
int flags;
|
||||
{
|
||||
register const char *p = pattern, *n = string;
|
||||
register char c;
|
||||
|
||||
/* Note that this evalutes C many times. */
|
||||
#define FOLD(c) ((flags & FNM_CASEFOLD) && isupper (c) ? tolower (c) : (c))
|
||||
|
||||
while ((c = *p++) != '\0')
|
||||
{
|
||||
c = FOLD (c);
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '?':
|
||||
if (*n == '\0')
|
||||
return FNM_NOMATCH;
|
||||
else if ((flags & FNM_FILE_NAME) && *n == '/')
|
||||
return FNM_NOMATCH;
|
||||
else if ((flags & FNM_PERIOD) && *n == '.' &&
|
||||
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
if (!(flags & FNM_NOESCAPE))
|
||||
{
|
||||
c = *p++;
|
||||
c = FOLD (c);
|
||||
}
|
||||
if (FOLD (*n) != c)
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
case '*':
|
||||
if ((flags & FNM_PERIOD) && *n == '.' &&
|
||||
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
|
||||
if (((flags & FNM_FILE_NAME) && *n == '/') ||
|
||||
(c == '?' && *n == '\0'))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (c == '\0')
|
||||
return 0;
|
||||
|
||||
{
|
||||
char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
|
||||
c1 = FOLD (c1);
|
||||
for (--p; *n != '\0'; ++n)
|
||||
if ((c == '[' || FOLD (*n) == c1) &&
|
||||
fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
|
||||
return 0;
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
case '[':
|
||||
{
|
||||
/* Nonzero if the sense of the character class is inverted. */
|
||||
register int not;
|
||||
|
||||
if (*n == '\0')
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if ((flags & FNM_PERIOD) && *n == '.' &&
|
||||
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
|
||||
return FNM_NOMATCH;
|
||||
|
||||
not = (*p == '!' || *p == '^');
|
||||
if (not)
|
||||
++p;
|
||||
|
||||
c = *p++;
|
||||
for (;;)
|
||||
{
|
||||
register char cstart = c, cend = c;
|
||||
|
||||
if (!(flags & FNM_NOESCAPE) && c == '\\')
|
||||
cstart = cend = *p++;
|
||||
|
||||
cstart = cend = FOLD (cstart);
|
||||
|
||||
if (c == '\0')
|
||||
/* [ (unterminated) loses. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
c = *p++;
|
||||
c = FOLD (c);
|
||||
|
||||
if ((flags & FNM_FILE_NAME) && c == '/')
|
||||
/* [/] can never match. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if (c == '-' && *p != ']')
|
||||
{
|
||||
cend = *p++;
|
||||
if (!(flags & FNM_NOESCAPE) && cend == '\\')
|
||||
cend = *p++;
|
||||
if (cend == '\0')
|
||||
return FNM_NOMATCH;
|
||||
cend = FOLD (cend);
|
||||
|
||||
c = *p++;
|
||||
}
|
||||
|
||||
if (FOLD (*n) >= cstart && FOLD (*n) <= cend)
|
||||
goto matched;
|
||||
|
||||
if (c == ']')
|
||||
break;
|
||||
}
|
||||
if (!not)
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
matched:;
|
||||
/* Skip the rest of the [...] that already matched. */
|
||||
while (c != ']')
|
||||
{
|
||||
if (c == '\0')
|
||||
/* [... (unterminated) loses. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
c = *p++;
|
||||
if (!(flags & FNM_NOESCAPE) && c == '\\')
|
||||
/* XXX 1003.2d11 is unclear if this is right. */
|
||||
++p;
|
||||
}
|
||||
if (not)
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (c != FOLD (*n))
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
++n;
|
||||
}
|
||||
|
||||
if (*n == '\0')
|
||||
return 0;
|
||||
|
||||
if ((flags & FNM_LEADING_DIR) && *n == '/')
|
||||
/* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
|
||||
return 0;
|
||||
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
@ -3,7 +3,7 @@
|
||||
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
|
||||
before changing it!
|
||||
|
||||
Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
|
||||
Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it
|
||||
@ -20,15 +20,14 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#if defined (emacs) || defined (CONFIG_BROKETS)
|
||||
/* We use <config.h> instead of "config.h" so that a compilation
|
||||
using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
|
||||
(which it would do because it found this file in $srcdir). */
|
||||
#include <config.h>
|
||||
#else
|
||||
#include "config.h"
|
||||
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
|
||||
Ditto for AIX 3.2 and <stdlib.h>. */
|
||||
#ifndef _NO_PROTO
|
||||
#define _NO_PROTO
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifndef __STDC__
|
||||
@ -39,11 +38,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. */
|
||||
#ifndef _NO_PROTO
|
||||
#define _NO_PROTO
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
@ -65,11 +59,6 @@
|
||||
#include <stdlib.h>
|
||||
#endif /* GNU C library. */
|
||||
|
||||
/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
|
||||
long-named option. Because this is not POSIX.2 compliant, it is
|
||||
being phased out. */
|
||||
/* #define GETOPT_COMPAT */
|
||||
|
||||
/* This version of `getopt' appears to the caller like standard Unix `getopt'
|
||||
but it behaves differently for the user, since it allows the user
|
||||
to intersperse the options with the other arguments.
|
||||
@ -92,7 +81,7 @@
|
||||
Also, when `ordering' is RETURN_IN_ORDER,
|
||||
each non-option ARGV-element is returned here. */
|
||||
|
||||
char *optarg = 0;
|
||||
char *optarg = NULL;
|
||||
|
||||
/* Index in ARGV of the next element to be scanned.
|
||||
This is used for communication to and from the caller
|
||||
@ -162,6 +151,9 @@ static enum
|
||||
{
|
||||
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
||||
} ordering;
|
||||
|
||||
/* Value of POSIXLY_CORRECT environment variable. */
|
||||
static char *posixly_correct;
|
||||
|
||||
#ifdef __GNU_LIBRARY__
|
||||
/* We want to avoid inclusion of string.h with non-GNU libraries
|
||||
@ -192,19 +184,18 @@ my_index (str, chr)
|
||||
}
|
||||
|
||||
/* If using GCC, we can safely declare strlen this way.
|
||||
If not using GCC, it is ok not to declare it.
|
||||
(Supposedly there are some machines where it might get a warning,
|
||||
but changing this conditional to __STDC__ is too risky.) */
|
||||
If not using GCC, it is ok not to declare it. */
|
||||
#ifdef __GNUC__
|
||||
#ifdef IN_GCC
|
||||
#include "gstddef.h"
|
||||
#else
|
||||
#include <stddef.h>
|
||||
#endif
|
||||
extern size_t strlen (const char *);
|
||||
#endif
|
||||
/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
|
||||
That was relevant to code that was here before. */
|
||||
#ifndef __STDC__
|
||||
/* gcc with -traditional declares the built-in strlen to return int,
|
||||
and has done so at least since version 2.4.5. -- rms. */
|
||||
extern int strlen (const char *);
|
||||
#endif /* not __STDC__ */
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#endif /* GNU C library. */
|
||||
#endif /* not __GNU_LIBRARY__ */
|
||||
|
||||
/* Handle permutation of arguments. */
|
||||
|
||||
@ -279,6 +270,42 @@ exchange (argv)
|
||||
first_nonopt += (optind - last_nonopt);
|
||||
last_nonopt = optind;
|
||||
}
|
||||
|
||||
/* Initialize the internal data when the first call is made. */
|
||||
|
||||
static const char *
|
||||
_getopt_initialize (optstring)
|
||||
const char *optstring;
|
||||
{
|
||||
/* Start processing options with ARGV-element 1 (since ARGV-element 0
|
||||
is the program name); the sequence of previously skipped
|
||||
non-option ARGV-elements is empty. */
|
||||
|
||||
first_nonopt = last_nonopt = optind = 1;
|
||||
|
||||
nextchar = NULL;
|
||||
|
||||
posixly_correct = getenv ("POSIXLY_CORRECT");
|
||||
|
||||
/* Determine how to handle the ordering of options and nonoptions. */
|
||||
|
||||
if (optstring[0] == '-')
|
||||
{
|
||||
ordering = RETURN_IN_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (optstring[0] == '+')
|
||||
{
|
||||
ordering = REQUIRE_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (posixly_correct != NULL)
|
||||
ordering = REQUIRE_ORDER;
|
||||
else
|
||||
ordering = PERMUTE;
|
||||
|
||||
return optstring;
|
||||
}
|
||||
|
||||
/* Scan elements of ARGV (whose length is ARGC) for option characters
|
||||
given in OPTSTRING.
|
||||
@ -345,41 +372,15 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
int *longind;
|
||||
int long_only;
|
||||
{
|
||||
int option_index;
|
||||
|
||||
optarg = 0;
|
||||
|
||||
/* Initialize the internal data when the first call is made.
|
||||
Start processing options with ARGV-element 1 (since ARGV-element 0
|
||||
is the program name); the sequence of previously skipped
|
||||
non-option ARGV-elements is empty. */
|
||||
optarg = NULL;
|
||||
|
||||
if (optind == 0)
|
||||
{
|
||||
first_nonopt = last_nonopt = optind = 1;
|
||||
|
||||
nextchar = NULL;
|
||||
|
||||
/* Determine how to handle the ordering of options and nonoptions. */
|
||||
|
||||
if (optstring[0] == '-')
|
||||
{
|
||||
ordering = RETURN_IN_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (optstring[0] == '+')
|
||||
{
|
||||
ordering = REQUIRE_ORDER;
|
||||
++optstring;
|
||||
}
|
||||
else if (getenv ("POSIXLY_CORRECT") != NULL)
|
||||
ordering = REQUIRE_ORDER;
|
||||
else
|
||||
ordering = PERMUTE;
|
||||
}
|
||||
optstring = _getopt_initialize (optstring);
|
||||
|
||||
if (nextchar == NULL || *nextchar == '\0')
|
||||
{
|
||||
/* Advance to the next ARGV-element. */
|
||||
|
||||
if (ordering == PERMUTE)
|
||||
{
|
||||
/* If we have just processed some options following some non-options,
|
||||
@ -390,21 +391,16 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
else if (last_nonopt != optind)
|
||||
first_nonopt = optind;
|
||||
|
||||
/* Now skip any additional non-options
|
||||
/* Skip any additional non-options
|
||||
and extend the range of non-options previously skipped. */
|
||||
|
||||
while (optind < argc
|
||||
&& (argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||
#ifdef GETOPT_COMPAT
|
||||
&& (longopts == NULL
|
||||
|| argv[optind][0] != '+' || argv[optind][1] == '\0')
|
||||
#endif /* GETOPT_COMPAT */
|
||||
)
|
||||
&& (argv[optind][0] != '-' || argv[optind][1] == '\0'))
|
||||
optind++;
|
||||
last_nonopt = optind;
|
||||
}
|
||||
|
||||
/* Special ARGV-element `--' means premature end of options.
|
||||
/* The special ARGV-element `--' means premature end of options.
|
||||
Skip it like a null option,
|
||||
then exchange with previous non-options as if it were an option,
|
||||
then skip everything else like a non-option. */
|
||||
@ -437,12 +433,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
/* If we have come to a non-option and did not permute it,
|
||||
either stop the scan or describe it to the caller and pass it by. */
|
||||
|
||||
if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||
#ifdef GETOPT_COMPAT
|
||||
&& (longopts == NULL
|
||||
|| argv[optind][0] != '+' || argv[optind][1] == '\0')
|
||||
#endif /* GETOPT_COMPAT */
|
||||
)
|
||||
if ((argv[optind][0] != '-' || argv[optind][1] == '\0'))
|
||||
{
|
||||
if (ordering == REQUIRE_ORDER)
|
||||
return EOF;
|
||||
@ -451,36 +442,48 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
}
|
||||
|
||||
/* We have found another option-ARGV-element.
|
||||
Start decoding its characters. */
|
||||
Skip the initial punctuation. */
|
||||
|
||||
nextchar = (argv[optind] + 1
|
||||
+ (longopts != NULL && argv[optind][1] == '-'));
|
||||
}
|
||||
|
||||
/* Decode the current option-ARGV-element. */
|
||||
|
||||
/* Check whether the ARGV-element is a long option.
|
||||
|
||||
If long_only and the ARGV-element has the form "-f", where f is
|
||||
a valid short option, don't consider it an abbreviated form of
|
||||
a long option that starts with f. Otherwise there would be no
|
||||
way to give the -f short option.
|
||||
|
||||
On the other hand, if there's a long option "fubar" and
|
||||
the ARGV-element is "-fu", do consider that an abbreviation of
|
||||
the long option, just like "--fu", and not "-f" with arg "u".
|
||||
|
||||
This distinction seems to be the most useful approach. */
|
||||
|
||||
if (longopts != NULL
|
||||
&& ((argv[optind][0] == '-'
|
||||
&& (argv[optind][1] == '-' || long_only))
|
||||
#ifdef GETOPT_COMPAT
|
||||
|| argv[optind][0] == '+'
|
||||
#endif /* GETOPT_COMPAT */
|
||||
))
|
||||
&& (argv[optind][1] == '-'
|
||||
|| (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
|
||||
{
|
||||
char *nameend;
|
||||
const struct option *p;
|
||||
char *s = nextchar;
|
||||
const struct option *pfound = NULL;
|
||||
int exact = 0;
|
||||
int ambig = 0;
|
||||
const struct option *pfound = NULL;
|
||||
int indfound;
|
||||
int option_index;
|
||||
|
||||
while (*s && *s != '=')
|
||||
s++;
|
||||
for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
|
||||
/* Do nothing. */ ;
|
||||
|
||||
/* Test all options for either exact match or abbreviated matches. */
|
||||
for (p = longopts, option_index = 0; p->name;
|
||||
p++, option_index++)
|
||||
if (!strncmp (p->name, nextchar, s - nextchar))
|
||||
/* Test all long options for either exact match
|
||||
or abbreviated matches. */
|
||||
for (p = longopts, option_index = 0; p->name; p++, option_index++)
|
||||
if (!strncmp (p->name, nextchar, nameend - nextchar))
|
||||
{
|
||||
if (s - nextchar == strlen (p->name))
|
||||
if (nameend - nextchar == strlen (p->name))
|
||||
{
|
||||
/* Exact match found. */
|
||||
pfound = p;
|
||||
@ -495,7 +498,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
indfound = option_index;
|
||||
}
|
||||
else
|
||||
/* Second nonexact match found. */
|
||||
/* Second or later nonexact match found. */
|
||||
ambig = 1;
|
||||
}
|
||||
|
||||
@ -513,12 +516,12 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
{
|
||||
option_index = indfound;
|
||||
optind++;
|
||||
if (*s)
|
||||
if (*nameend)
|
||||
{
|
||||
/* Don't test has_arg with >, because some C compilers don't
|
||||
allow it to be used on enums. */
|
||||
if (pfound->has_arg)
|
||||
optarg = s + 1;
|
||||
optarg = nameend + 1;
|
||||
else
|
||||
{
|
||||
if (opterr)
|
||||
@ -561,14 +564,12 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
}
|
||||
return pfound->val;
|
||||
}
|
||||
|
||||
/* Can't find it as a long option. If this is not getopt_long_only,
|
||||
or the option starts with '--' or is not a valid short
|
||||
option, then it's an error.
|
||||
Otherwise interpret it as a short option. */
|
||||
if (!long_only || argv[optind][1] == '-'
|
||||
#ifdef GETOPT_COMPAT
|
||||
|| argv[optind][0] == '+'
|
||||
#endif /* GETOPT_COMPAT */
|
||||
|| my_index (optstring, *nextchar) == NULL)
|
||||
{
|
||||
if (opterr)
|
||||
@ -588,7 +589,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
}
|
||||
}
|
||||
|
||||
/* Look at and handle the next option-character. */
|
||||
/* Look at and handle the next short option-character. */
|
||||
|
||||
{
|
||||
char c = *nextchar++;
|
||||
@ -602,16 +603,11 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
#if 0
|
||||
if (c < 040 || c >= 0177)
|
||||
fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
|
||||
argv[0], c);
|
||||
if (posixly_correct)
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
|
||||
else
|
||||
fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
|
||||
#else
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
|
||||
#endif
|
||||
fprintf (stderr, "%s: invalid option -- %c\n", argv[0], c);
|
||||
}
|
||||
optopt = c;
|
||||
return '?';
|
||||
@ -627,7 +623,7 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
optind++;
|
||||
}
|
||||
else
|
||||
optarg = 0;
|
||||
optarg = NULL;
|
||||
nextchar = NULL;
|
||||
}
|
||||
else
|
||||
@ -644,14 +640,9 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||
{
|
||||
if (opterr)
|
||||
{
|
||||
#if 0
|
||||
fprintf (stderr, "%s: option `-%c' requires an argument\n",
|
||||
argv[0], c);
|
||||
#else
|
||||
/* 1003.2 specifies the format of this message. */
|
||||
fprintf (stderr, "%s: option requires an argument -- %c\n",
|
||||
argv[0], c);
|
||||
#endif
|
||||
}
|
||||
optopt = c;
|
||||
if (optstring[0] == ':')
|
||||
|
@ -17,15 +17,8 @@
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#if defined (emacs) || defined (CONFIG_BROKETS)
|
||||
/* We use <config.h> instead of "config.h" so that a compilation
|
||||
using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
|
||||
(which it would do because it found this file in $srcdir). */
|
||||
#include <config.h>
|
||||
#else
|
||||
#include "config.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* #ifdef-format output routines for GNU DIFF.
|
||||
Copyright (C) 1989, 91, 92, 93 Free Software Foundation, Inc.
|
||||
Copyright (C) 1989, 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU DIFF.
|
||||
|
||||
@ -27,10 +27,10 @@ struct group
|
||||
int from, upto; /* start and limit lines for this group of lines */
|
||||
};
|
||||
|
||||
static char *format_group PARAMS((FILE *, char *, int, struct group const[]));
|
||||
static char *format_group PARAMS((FILE *, char *, int, struct group const *));
|
||||
static char *scan_char_literal PARAMS((char *, int *));
|
||||
static char *scan_printf_spec PARAMS((char *));
|
||||
static int groups_letter_value PARAMS((struct group const[], int));
|
||||
static int groups_letter_value PARAMS((struct group const *, int));
|
||||
static void format_ifdef PARAMS((char *, int, int, int, int));
|
||||
static void print_ifdef_hunk PARAMS((struct change *));
|
||||
static void print_ifdef_lines PARAMS((FILE *, char *, struct group const *));
|
||||
@ -117,7 +117,7 @@ format_group (out, format, endchar, groups)
|
||||
register FILE *out;
|
||||
char *format;
|
||||
int endchar;
|
||||
struct group const groups[];
|
||||
struct group const *groups;
|
||||
{
|
||||
register char c;
|
||||
register char *f = format;
|
||||
@ -142,10 +142,10 @@ format_group (out, format, endchar, groups)
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
unsigned char f0 = f[0];
|
||||
if (isdigit (f0))
|
||||
if (ISDIGIT (f0))
|
||||
{
|
||||
value[i] = atoi (f);
|
||||
while (isdigit ((unsigned char) *++f))
|
||||
while (ISDIGIT ((unsigned char) *++f))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
@ -238,10 +238,10 @@ format_group (out, format, endchar, groups)
|
||||
Return -1 if LETTER is not a group format letter. */
|
||||
static int
|
||||
groups_letter_value (g, letter)
|
||||
struct group const g[];
|
||||
struct group const *g;
|
||||
int letter;
|
||||
{
|
||||
if (isupper (letter))
|
||||
if (ISUPPER (letter))
|
||||
{
|
||||
g++;
|
||||
letter = tolower (letter);
|
||||
@ -333,7 +333,7 @@ print_ifdef_lines (out, format, group)
|
||||
goto bad_format;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
case 'n':
|
||||
value = translate_line_number (file, from);
|
||||
break;
|
||||
|
||||
@ -412,10 +412,10 @@ scan_printf_spec (spec)
|
||||
|
||||
while ((c = *spec++) == '-')
|
||||
continue;
|
||||
while (isdigit (c))
|
||||
while (ISDIGIT (c))
|
||||
c = *spec++;
|
||||
if (c == '.')
|
||||
while (isdigit (c = *spec++))
|
||||
while (ISDIGIT (c = *spec++))
|
||||
continue;
|
||||
switch (c)
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* File I/O for GNU DIFF.
|
||||
Copyright (C) 1988, 1989, 1992, 1993 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988, 1989, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU DIFF.
|
||||
|
||||
@ -31,7 +31,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#define GUESS_LINES(n,s,t) (((t) - (s)) / ((n) < 10 ? 32 : (s) / ((n)-1)) + 5)
|
||||
|
||||
/* Type used for fast prefix comparison in find_identical_ends. */
|
||||
typedef int word;
|
||||
#ifndef word
|
||||
#define word int
|
||||
#endif
|
||||
|
||||
/* Lines are put into equivalence classes (of lines that match in line_cmp).
|
||||
Each equivalence class is represented by one of these structures,
|
||||
@ -42,13 +44,14 @@ struct equivclass
|
||||
int next; /* Next item in this bucket. */
|
||||
unsigned hash; /* Hash of lines in this class. */
|
||||
char const *line; /* A line that fits this class. */
|
||||
size_t length; /* The length of that line. */
|
||||
size_t length; /* That line's length, not counting its newline. */
|
||||
};
|
||||
|
||||
/* Hash-table: array of buckets, each being a chain of equivalence classes. */
|
||||
/* Hash-table: array of buckets, each being a chain of equivalence classes.
|
||||
buckets[-1] is reserved for incomplete lines. */
|
||||
static int *buckets;
|
||||
|
||||
/* Number of buckets in the hash table array. */
|
||||
/* Number of buckets in the hash table array, not counting buckets[-1]. */
|
||||
static int nbuckets;
|
||||
|
||||
/* Array in which the equivalence classes are allocated.
|
||||
@ -71,7 +74,7 @@ static void prepare_text_end PARAMS((struct file_data *));
|
||||
/* Return 1 if BUF contains a non text character.
|
||||
SIZE is the number of characters in BUF. */
|
||||
|
||||
#define binary_file_p(buf, size) (size != 0 && memchr (buf, '\0', size) != 0)
|
||||
#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,
|
||||
@ -97,12 +100,23 @@ sip (current, skip_test)
|
||||
if (! skip_test)
|
||||
{
|
||||
/* Check first part of file to see if it's a binary file. */
|
||||
current->buffered_chars = read (current->desc,
|
||||
current->buffer,
|
||||
current->bufsize);
|
||||
if (current->buffered_chars == -1)
|
||||
#if HAVE_SETMODE
|
||||
int oldmode = setmode (current->desc, O_BINARY);
|
||||
#endif
|
||||
size_t n = read (current->desc, current->buffer, current->bufsize);
|
||||
if (n == -1)
|
||||
pfatal_with_name (current->name);
|
||||
return binary_file_p (current->buffer, current->buffered_chars);
|
||||
current->buffered_chars = n;
|
||||
#if HAVE_SETMODE
|
||||
if (oldmode != O_BINARY)
|
||||
{
|
||||
if (lseek (current->desc, - (off_t) n, SEEK_CUR) == -1)
|
||||
pfatal_with_name (current->name);
|
||||
setmode (current->desc, oldmode);
|
||||
current->buffered_chars = 0;
|
||||
}
|
||||
#endif
|
||||
return binary_file_p (current->buffer, n);
|
||||
}
|
||||
}
|
||||
|
||||
@ -193,10 +207,7 @@ find_and_hash_each_line (current)
|
||||
int eqs_alloc = equivs_alloc;
|
||||
char const *suffix_begin = current->suffix_begin;
|
||||
char const *bufend = current->buffer + current->buffered_chars;
|
||||
char const *incomplete_tail
|
||||
= current->missing_newline && ROBUST_OUTPUT_STYLE (output_style)
|
||||
? bufend : (char const *) 0;
|
||||
int varies = length_varies;
|
||||
int use_line_cmp = ignore_some_line_changes;
|
||||
|
||||
while ((char const *) p < suffix_begin)
|
||||
{
|
||||
@ -212,42 +223,52 @@ find_and_hash_each_line (current)
|
||||
if (ignore_all_space_flag)
|
||||
while ((c = *p++) != '\n')
|
||||
{
|
||||
if (! isspace (c))
|
||||
h = HASH (h, isupper (c) ? tolower (c) : c);
|
||||
if (! ISSPACE (c))
|
||||
h = HASH (h, ISUPPER (c) ? tolower (c) : c);
|
||||
}
|
||||
else if (ignore_space_change_flag)
|
||||
while ((c = *p++) != '\n')
|
||||
{
|
||||
if (isspace (c))
|
||||
if (ISSPACE (c))
|
||||
{
|
||||
while (isspace (c = *p++))
|
||||
if (c == '\n')
|
||||
goto hashing_done;
|
||||
for (;;)
|
||||
{
|
||||
c = *p++;
|
||||
if (!ISSPACE (c))
|
||||
break;
|
||||
if (c == '\n')
|
||||
goto hashing_done;
|
||||
}
|
||||
h = HASH (h, ' ');
|
||||
}
|
||||
/* C is now the first non-space. */
|
||||
h = HASH (h, isupper (c) ? tolower (c) : c);
|
||||
h = HASH (h, ISUPPER (c) ? tolower (c) : c);
|
||||
}
|
||||
else
|
||||
while ((c = *p++) != '\n')
|
||||
h = HASH (h, isupper (c) ? tolower (c) : c);
|
||||
h = HASH (h, ISUPPER (c) ? tolower (c) : c);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ignore_all_space_flag)
|
||||
while ((c = *p++) != '\n')
|
||||
{
|
||||
if (! isspace (c))
|
||||
if (! ISSPACE (c))
|
||||
h = HASH (h, c);
|
||||
}
|
||||
else if (ignore_space_change_flag)
|
||||
while ((c = *p++) != '\n')
|
||||
{
|
||||
if (isspace (c))
|
||||
if (ISSPACE (c))
|
||||
{
|
||||
while (isspace (c = *p++))
|
||||
if (c == '\n')
|
||||
goto hashing_done;
|
||||
for (;;)
|
||||
{
|
||||
c = *p++;
|
||||
if (!ISSPACE (c))
|
||||
break;
|
||||
if (c == '\n')
|
||||
goto hashing_done;
|
||||
}
|
||||
h = HASH (h, ' ');
|
||||
}
|
||||
/* C is now the first non-space. */
|
||||
@ -260,7 +281,22 @@ find_and_hash_each_line (current)
|
||||
hashing_done:;
|
||||
|
||||
bucket = &buckets[h % nbuckets];
|
||||
length = (char const *) p - ip - ((char const *) p == incomplete_tail);
|
||||
length = (char const *) p - ip - 1;
|
||||
|
||||
if ((char const *) p == bufend
|
||||
&& current->missing_newline
|
||||
&& ROBUST_OUTPUT_STYLE (output_style))
|
||||
{
|
||||
/* This line is incomplete. If this is significant,
|
||||
put the line into bucket[-1]. */
|
||||
if (! (ignore_space_change_flag | ignore_all_space_flag))
|
||||
bucket = &buckets[-1];
|
||||
|
||||
/* Omit the inserted newline when computing linbuf later. */
|
||||
p--;
|
||||
bufend = suffix_begin = (char const *) p;
|
||||
}
|
||||
|
||||
for (i = *bucket; ; i = eqs[i].next)
|
||||
if (!i)
|
||||
{
|
||||
@ -276,11 +312,20 @@ find_and_hash_each_line (current)
|
||||
*bucket = i;
|
||||
break;
|
||||
}
|
||||
else if (eqs[i].hash == h
|
||||
&& (eqs[i].length == length || varies)
|
||||
&& ! line_cmp (eqs[i].line, eqs[i].length, ip, length))
|
||||
/* Reuse existing equivalence class. */
|
||||
break;
|
||||
else if (eqs[i].hash == h)
|
||||
{
|
||||
char const *eqline = eqs[i].line;
|
||||
|
||||
/* Reuse existing equivalence class if the lines are identical.
|
||||
This detects the common case of exact identity
|
||||
faster than complete comparison would. */
|
||||
if (eqs[i].length == length && memcmp (eqline, ip, length) == 0)
|
||||
break;
|
||||
|
||||
/* Reuse existing class if line_cmp reports the lines equal. */
|
||||
if (use_line_cmp && line_cmp (eqline, ip) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Maybe increase the size of the line table. */
|
||||
if (line == alloc_lines)
|
||||
@ -303,7 +348,7 @@ find_and_hash_each_line (current)
|
||||
for (i = 0; ; i++)
|
||||
{
|
||||
/* Record the line start for lines in the suffix that we care about.
|
||||
Record one more line start than lines,
|
||||
Record one more line start than lines,
|
||||
so that we can compute the length of any buffered line. */
|
||||
if (line == alloc_lines)
|
||||
{
|
||||
@ -317,10 +362,7 @@ find_and_hash_each_line (current)
|
||||
linbuf[line] = (char const *) p;
|
||||
|
||||
if ((char const *) p == bufend)
|
||||
{
|
||||
linbuf[line] -= (char const *) p == incomplete_tail;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
if (context <= i && no_diff_means_no_output)
|
||||
break;
|
||||
@ -343,7 +385,7 @@ find_and_hash_each_line (current)
|
||||
|
||||
/* Prepare the end of the text. Make sure it's initialized.
|
||||
Make sure text ends in a newline,
|
||||
but remember that we had to add one unless -B is in effect. */
|
||||
but remember that we had to add one. */
|
||||
|
||||
static void
|
||||
prepare_text_end (current)
|
||||
@ -358,7 +400,7 @@ prepare_text_end (current)
|
||||
{
|
||||
p[buffered_chars++] = '\n';
|
||||
current->buffered_chars = buffered_chars;
|
||||
current->missing_newline = ! ignore_blank_lines_flag;
|
||||
current->missing_newline = 1;
|
||||
}
|
||||
|
||||
/* Don't use uninitialized storage when planting or using sentinels. */
|
||||
@ -636,7 +678,13 @@ read_files (filevec, pretend_binary)
|
||||
filevec[1].buffered_chars = filevec[0].buffered_chars;
|
||||
}
|
||||
if (appears_binary)
|
||||
return 1;
|
||||
{
|
||||
#if HAVE_SETMODE
|
||||
setmode (filevec[0].desc, O_BINARY);
|
||||
setmode (filevec[1].desc, O_BINARY);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
find_identical_ends (filevec);
|
||||
|
||||
@ -651,16 +699,16 @@ read_files (filevec, pretend_binary)
|
||||
abort ();
|
||||
nbuckets = primes[i];
|
||||
|
||||
buckets = (int *) xmalloc (nbuckets * sizeof (*buckets));
|
||||
bzero (buckets, nbuckets * sizeof (*buckets));
|
||||
buckets = (int *) xmalloc ((nbuckets + 1) * sizeof (*buckets));
|
||||
bzero (buckets++, (nbuckets + 1) * sizeof (*buckets));
|
||||
|
||||
for (i = 0; i < 2; ++i)
|
||||
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);
|
||||
free (buckets - 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* SDIFF -- interactive merge front end to diff
|
||||
Copyright (C) 1992, 1993 Free Software Foundation, Inc.
|
||||
Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU DIFF.
|
||||
|
||||
@ -21,7 +21,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "system.h"
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <signal.h>
|
||||
#include "getopt.h"
|
||||
|
||||
@ -34,22 +33,25 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#endif
|
||||
|
||||
/* Users' editor of nonchoice */
|
||||
#ifndef DEFAULT_EDITOR
|
||||
#define DEFAULT_EDITOR "ed"
|
||||
#ifndef DEFAULT_EDITOR_PROGRAM
|
||||
#define DEFAULT_EDITOR_PROGRAM "ed"
|
||||
#endif
|
||||
|
||||
extern char version_string[];
|
||||
static char const *prog;
|
||||
static char const *program_name;
|
||||
static char const *diffbin = DIFF_PROGRAM;
|
||||
static char const *edbin = DEFAULT_EDITOR;
|
||||
static char const *edbin = DEFAULT_EDITOR_PROGRAM;
|
||||
static char const **diffargv;
|
||||
|
||||
static char *tmpname;
|
||||
static int volatile tmpmade;
|
||||
|
||||
#if HAVE_FORK
|
||||
static pid_t volatile diffpid;
|
||||
#endif
|
||||
|
||||
struct line_filter;
|
||||
|
||||
static FILE *ck_fdopen PARAMS((int, char const *));
|
||||
static FILE *ck_fopen PARAMS((char const *, char const *));
|
||||
static RETSIGTYPE catchsig PARAMS((int));
|
||||
static VOID *xmalloc PARAMS((size_t));
|
||||
@ -66,7 +68,7 @@ static void ck_fflush PARAMS((FILE *));
|
||||
static void ck_fwrite PARAMS((char const *, size_t, FILE *));
|
||||
static void cleanup PARAMS((void));
|
||||
static void diffarg PARAMS((char const *));
|
||||
static void execdiff PARAMS((int, char const *, char const *, char const *));
|
||||
static void execdiff PARAMS((void));
|
||||
static void exiterr PARAMS((void));
|
||||
static void fatal PARAMS((char const *));
|
||||
static void flush_line PARAMS((void));
|
||||
@ -76,14 +78,24 @@ static void lf_init PARAMS((struct line_filter *, FILE *));
|
||||
static void lf_skip PARAMS((struct line_filter *, int));
|
||||
static void perror_fatal PARAMS((char const *));
|
||||
static void trapsigs PARAMS((void));
|
||||
static void try_help PARAMS((char const *));
|
||||
static void untrapsig PARAMS((int));
|
||||
static void usage PARAMS((int));
|
||||
static void usage PARAMS((void));
|
||||
|
||||
/* this lossage until the gnu libc conquers the universe */
|
||||
#if HAVE_TMPNAM
|
||||
#define private_tempnam() tmpnam ((char *) 0)
|
||||
#else
|
||||
#ifndef PVT_tmpdir
|
||||
#define PVT_tmpdir "/tmp"
|
||||
static char *private_tempnam PARAMS((char const *, char const *, int, size_t *));
|
||||
static int diraccess PARAMS((char const *));
|
||||
#endif
|
||||
#ifndef TMPDIR_ENV
|
||||
#define TMPDIR_ENV "TMPDIR"
|
||||
#endif
|
||||
static char *private_tempnam PARAMS((void));
|
||||
static int exists PARAMS((char const *));
|
||||
#endif
|
||||
static int diraccess PARAMS((char const *));
|
||||
|
||||
/* Options: */
|
||||
|
||||
@ -113,27 +125,52 @@ static struct option const longopts[] =
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
/* prints usage message and quits */
|
||||
static void
|
||||
usage (status)
|
||||
int status;
|
||||
try_help (reason)
|
||||
char const *reason;
|
||||
{
|
||||
printf ("Usage: %s [options] from-file to-file\n", prog);
|
||||
printf ("Options:\n\
|
||||
[-abBdHilstv] [-I regexp] [-o outfile] [-w columns]\n\
|
||||
[--expand-tabs] [--help] [--ignore-all-space] [--ignore-blank-lines]\n\
|
||||
[--ignore-case] [--ignore-matching-lines=regexp]\n\
|
||||
[--ignore-space-change] [--left-column] [--minimal]\n\
|
||||
[--output=outfile] [--speed-large-files] [--suppress-common-lines]\n\
|
||||
[--text] [--version] [--width=columns]\n");
|
||||
exit (status);
|
||||
if (reason)
|
||||
fprintf (stderr, "%s: %s\n", program_name, reason);
|
||||
fprintf (stderr, "%s: Try `%s --help' for more information.\n",
|
||||
program_name, program_name);
|
||||
exit (2);
|
||||
}
|
||||
|
||||
static void
|
||||
usage ()
|
||||
{
|
||||
printf ("Usage: %s [OPTIONS]... FILE1 FILE2\n\n", program_name);
|
||||
printf ("%s", "\
|
||||
-o FILE --output=FILE Operate interactively, sending output to FILE.\n\n");
|
||||
printf ("%s", "\
|
||||
-i --ignore-case Consider upper- and lower-case to be the same.\n\
|
||||
-W --ignore-all-space Ignore all white space.\n\
|
||||
-b --ignore-space-change Ignore changes in the amount of white space.\n\
|
||||
-B --ignore-blank-lines Ignore changes whose lines are all blank.\n\
|
||||
-I RE --ignore-matching-lines=RE Ignore changes whose lines all match RE.\n\
|
||||
-a --text Treat all files as text.\n\n");
|
||||
printf ("%s", "\
|
||||
-w NUM --width=NUM Output at most NUM (default 130) characters per line.\n\
|
||||
-l --left-column Output only the left column of common lines.\n\
|
||||
-s --suppress-common-lines Do not output common lines.\n\n");
|
||||
printf ("\
|
||||
-t --expand-tabs Expand tabs to spaces in output.\n\n");
|
||||
printf ("%s", "\
|
||||
-d --minimal Try hard to find a smaller set of changes.\n\
|
||||
-H --speed-large-files Assume large files and many scattered small changes.\n\n");
|
||||
printf ("%s", "\
|
||||
-v --version Output version info.\n\
|
||||
--help Output this help.\n\n\
|
||||
If FILE1 or FILE2 is `-', read standard input.\n");
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup ()
|
||||
{
|
||||
#if HAVE_FORK
|
||||
if (0 < diffpid)
|
||||
kill (diffpid, SIGPIPE);
|
||||
#endif
|
||||
if (tmpmade)
|
||||
unlink (tmpname);
|
||||
}
|
||||
@ -151,7 +188,7 @@ static void
|
||||
fatal (msg)
|
||||
char const *msg;
|
||||
{
|
||||
fprintf (stderr, "%s: %s\n", prog, msg);
|
||||
fprintf (stderr, "%s: %s\n", program_name, msg);
|
||||
exiterr ();
|
||||
}
|
||||
|
||||
@ -161,7 +198,7 @@ perror_fatal (msg)
|
||||
{
|
||||
int e = errno;
|
||||
checksigs ();
|
||||
fprintf (stderr, "%s: ", prog);
|
||||
fprintf (stderr, "%s: ", program_name);
|
||||
errno = e;
|
||||
perror (msg);
|
||||
exiterr ();
|
||||
@ -189,18 +226,6 @@ ck_fopen (fname, type)
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static FILE *
|
||||
ck_fdopen (fd, type)
|
||||
int fd;
|
||||
char const *type;
|
||||
{
|
||||
FILE *r = fdopen (fd, type);
|
||||
if (!r)
|
||||
perror_fatal ("fdopen");
|
||||
return r;
|
||||
}
|
||||
|
||||
static void
|
||||
ck_fclose (f)
|
||||
FILE *f;
|
||||
@ -239,67 +264,21 @@ ck_fflush (f)
|
||||
perror_fatal ("output error");
|
||||
}
|
||||
|
||||
#if !HAVE_MEMCHR
|
||||
char *
|
||||
memchr (s, c, n)
|
||||
char const *s;
|
||||
int c;
|
||||
size_t n;
|
||||
{
|
||||
unsigned char const *p = (unsigned char const *) s, *lim = p + n;
|
||||
for (; p < lim; p++)
|
||||
if (*p == c)
|
||||
return (char *) p;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_WAITPID
|
||||
/* Emulate waitpid well enough for sdiff, which has at most two children. */
|
||||
static pid_t
|
||||
waitpid (pid, stat_loc, options)
|
||||
pid_t pid;
|
||||
int *stat_loc;
|
||||
int options;
|
||||
{
|
||||
static int ostatus;
|
||||
static pid_t opid;
|
||||
int npid, status;
|
||||
|
||||
if (pid == opid)
|
||||
{
|
||||
opid = 0;
|
||||
status = ostatus;
|
||||
}
|
||||
else
|
||||
while ((npid = wait (&status)) != pid)
|
||||
{
|
||||
if (npid < 0)
|
||||
return npid;
|
||||
opid = npid;
|
||||
ostatus = status;
|
||||
}
|
||||
*stat_loc = status;
|
||||
return pid;
|
||||
}
|
||||
#endif
|
||||
|
||||
static char const *
|
||||
expand_name (name, isdir, other_name)
|
||||
expand_name (name, is_dir, other_name)
|
||||
char *name;
|
||||
int isdir;
|
||||
int is_dir;
|
||||
char const *other_name;
|
||||
{
|
||||
if (strcmp (name, "-") == 0)
|
||||
fatal ("cannot interactively merge standard input");
|
||||
if (!isdir)
|
||||
if (!is_dir)
|
||||
return name;
|
||||
else
|
||||
{
|
||||
/* Yield NAME/BASE, where BASE is OTHER_NAME's basename. */
|
||||
char const
|
||||
*p = strrchr (other_name, '/'),
|
||||
*base = p ? p+1 : other_name;
|
||||
char const *p = filename_lastdirchar (other_name);
|
||||
char const *base = p ? p+1 : other_name;
|
||||
size_t namelen = strlen (name), baselen = strlen (base);
|
||||
char *r = xmalloc (namelen + baselen + 2);
|
||||
memcpy (r, name, namelen);
|
||||
@ -430,12 +409,16 @@ main (argc, argv)
|
||||
char *argv[];
|
||||
{
|
||||
int opt;
|
||||
char *editor = getenv ("EDITOR");
|
||||
char *differ = getenv ("DIFF");
|
||||
char *editor;
|
||||
char *differ;
|
||||
|
||||
prog = argv[0];
|
||||
initialize_main (&argc, &argv);
|
||||
program_name = argv[0];
|
||||
|
||||
editor = getenv ("EDITOR");
|
||||
if (editor)
|
||||
edbin = editor;
|
||||
differ = getenv ("DIFF");
|
||||
if (differ)
|
||||
diffbin = differ;
|
||||
|
||||
@ -493,7 +476,7 @@ main (argc, argv)
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
printf ("GNU sdiff version %s\n", version_string);
|
||||
printf ("sdiff - GNU diffutils version %s\n", version_string);
|
||||
exit (0);
|
||||
|
||||
case 'w':
|
||||
@ -506,25 +489,35 @@ main (argc, argv)
|
||||
break;
|
||||
|
||||
case 129:
|
||||
usage (0);
|
||||
usage ();
|
||||
if (ferror (stdout) || fclose (stdout) != 0)
|
||||
fatal ("write error");
|
||||
exit (0);
|
||||
|
||||
default:
|
||||
usage (2);
|
||||
try_help (0);
|
||||
}
|
||||
}
|
||||
|
||||
if (argc - optind != 2)
|
||||
usage (2);
|
||||
try_help (argc - optind < 2 ? "missing operand" : "extra operand");
|
||||
|
||||
if (! out_file)
|
||||
/* easy case: diff does everything for us */
|
||||
execdiff (suppress_common_flag, "-y", argv[optind], argv[optind + 1]);
|
||||
{
|
||||
/* easy case: diff does everything for us */
|
||||
if (suppress_common_flag)
|
||||
diffarg ("--suppress-common-lines");
|
||||
diffarg ("-y");
|
||||
diffarg ("--");
|
||||
diffarg (argv[optind]);
|
||||
diffarg (argv[optind + 1]);
|
||||
diffarg (0);
|
||||
execdiff ();
|
||||
}
|
||||
else
|
||||
{
|
||||
FILE *left, *right, *out, *diffout;
|
||||
int diff_fds[2];
|
||||
int interact_ok;
|
||||
pid_t pid;
|
||||
struct line_filter lfilt;
|
||||
struct line_filter rfilt;
|
||||
struct line_filter diff_filt;
|
||||
@ -539,33 +532,66 @@ main (argc, argv)
|
||||
right = ck_fopen (expand_name (argv[optind + 1], rightdir, argv[optind]), "r");
|
||||
out = ck_fopen (out_file, "w");
|
||||
|
||||
if (pipe (diff_fds))
|
||||
perror_fatal ("pipe");
|
||||
diffarg ("--sdiff-merge-assist");
|
||||
diffarg ("--");
|
||||
diffarg (argv[optind]);
|
||||
diffarg (argv[optind + 1]);
|
||||
diffarg (0);
|
||||
|
||||
trapsigs ();
|
||||
|
||||
diffpid = pid = vfork ();
|
||||
#if ! HAVE_FORK
|
||||
{
|
||||
size_t cmdsize = 1;
|
||||
char *p, *command;
|
||||
int i;
|
||||
|
||||
if (pid == 0)
|
||||
{
|
||||
signal (SIGINT, SIG_IGN); /* in case user interrupts editor */
|
||||
signal (SIGPIPE, SIG_DFL);
|
||||
for (i = 0; diffargv[i]; i++)
|
||||
cmdsize += 4 * strlen (diffargv[i]) + 3;
|
||||
command = p = xmalloc (cmdsize);
|
||||
for (i = 0; diffargv[i]; i++)
|
||||
{
|
||||
char const *a = diffargv[i];
|
||||
SYSTEM_QUOTE_ARG (p, a);
|
||||
*p++ = ' ';
|
||||
}
|
||||
p[-1] = '\0';
|
||||
diffout = popen (command, "r");
|
||||
if (!diffout)
|
||||
perror_fatal (command);
|
||||
free (command);
|
||||
}
|
||||
#else /* HAVE_FORK */
|
||||
{
|
||||
int diff_fds[2];
|
||||
|
||||
close (diff_fds[0]);
|
||||
if (diff_fds[1] != STDOUT_FILENO)
|
||||
{
|
||||
dup2 (diff_fds[1], STDOUT_FILENO);
|
||||
close (diff_fds[1]);
|
||||
}
|
||||
if (pipe (diff_fds) != 0)
|
||||
perror_fatal ("pipe");
|
||||
|
||||
execdiff (0, "--sdiff-merge-assist", argv[optind], argv[optind + 1]);
|
||||
}
|
||||
diffpid = vfork ();
|
||||
if (diffpid < 0)
|
||||
perror_fatal ("fork failed");
|
||||
if (!diffpid)
|
||||
{
|
||||
signal (SIGINT, SIG_IGN); /* in case user interrupts editor */
|
||||
signal (SIGPIPE, SIG_DFL);
|
||||
|
||||
if (pid < 0)
|
||||
perror_fatal ("fork failed");
|
||||
close (diff_fds[0]);
|
||||
if (diff_fds[1] != STDOUT_FILENO)
|
||||
{
|
||||
dup2 (diff_fds[1], STDOUT_FILENO);
|
||||
close (diff_fds[1]);
|
||||
}
|
||||
|
||||
close (diff_fds[1]);
|
||||
diffout = ck_fdopen (diff_fds[0], "r");
|
||||
execdiff ();
|
||||
}
|
||||
|
||||
close (diff_fds[1]);
|
||||
diffout = fdopen (diff_fds[0], "r");
|
||||
if (!diffout)
|
||||
perror_fatal ("fdopen");
|
||||
}
|
||||
#endif /* HAVE_FORK */
|
||||
|
||||
lf_init (&diff_filt, diffout);
|
||||
lf_init (&lfilt, left);
|
||||
@ -573,7 +599,6 @@ main (argc, argv)
|
||||
|
||||
interact_ok = interact (&diff_filt, &lfilt, &rfilt, out);
|
||||
|
||||
ck_fclose (diffout);
|
||||
ck_fclose (left);
|
||||
ck_fclose (right);
|
||||
ck_fclose (out);
|
||||
@ -581,12 +606,17 @@ main (argc, argv)
|
||||
{
|
||||
int wstatus;
|
||||
|
||||
while (waitpid (pid, &wstatus, 0) < 0)
|
||||
#if ! HAVE_FORK
|
||||
wstatus = pclose (diffout);
|
||||
#else
|
||||
ck_fclose (diffout);
|
||||
while (waitpid (diffpid, &wstatus, 0) < 0)
|
||||
if (errno == EINTR)
|
||||
checksigs ();
|
||||
else
|
||||
perror_fatal ("wait failed");
|
||||
diffpid = 0;
|
||||
#endif
|
||||
|
||||
if (tmpmade)
|
||||
{
|
||||
@ -608,8 +638,6 @@ main (argc, argv)
|
||||
return 0; /* Fool -Wall . . . */
|
||||
}
|
||||
|
||||
static char const **diffargv;
|
||||
|
||||
static void
|
||||
diffarg (a)
|
||||
char const *a;
|
||||
@ -633,18 +661,8 @@ diffarg (a)
|
||||
}
|
||||
|
||||
static void
|
||||
execdiff (differences_only, option, file1, file2)
|
||||
int differences_only;
|
||||
char const *option, *file1, *file2;
|
||||
execdiff ()
|
||||
{
|
||||
if (differences_only)
|
||||
diffarg ("--suppress-common-lines");
|
||||
diffarg (option);
|
||||
diffarg ("--");
|
||||
diffarg (file1);
|
||||
diffarg (file2);
|
||||
diffarg (0);
|
||||
|
||||
execvp (diffbin, (char **) diffargv);
|
||||
write (STDERR_FILENO, diffbin, strlen (diffbin));
|
||||
write (STDERR_FILENO, ": not found\n", 12);
|
||||
@ -734,6 +752,15 @@ trapsigs ()
|
||||
fatal ("signal error");
|
||||
}
|
||||
#endif /* ! HAVE_SIGACTION */
|
||||
|
||||
#if !defined(SIGCHLD) && defined(SIGCLD)
|
||||
#define SIGCHLD SIGCLD
|
||||
#endif
|
||||
#ifdef SIGCHLD
|
||||
/* System V fork+wait does not work if SIGCHLD is ignored. */
|
||||
signal (SIGCHLD, SIG_DFL);
|
||||
#endif
|
||||
|
||||
sigs_trapped = 1;
|
||||
}
|
||||
|
||||
@ -792,8 +819,13 @@ static int
|
||||
skip_white ()
|
||||
{
|
||||
int c;
|
||||
while (isspace (c = getchar ()) && c != '\n')
|
||||
checksigs ();
|
||||
for (;;)
|
||||
{
|
||||
c = getchar ();
|
||||
if (!ISSPACE (c) || c == '\n')
|
||||
break;
|
||||
checksigs ();
|
||||
}
|
||||
if (ferror (stdin))
|
||||
perror_fatal ("input error");
|
||||
return c;
|
||||
@ -903,7 +935,7 @@ edit (left, lenl, right, lenr, outfile)
|
||||
case 'q':
|
||||
return 0;
|
||||
case 'e':
|
||||
if (! tmpname && ! (tmpname = private_tempnam (0, "sdiff", 1, 0)))
|
||||
if (! tmpname && ! (tmpname = private_tempnam ()))
|
||||
perror_fatal ("temporary file name");
|
||||
|
||||
tmpmade = 1;
|
||||
@ -924,8 +956,14 @@ edit (left, lenl, right, lenr, outfile)
|
||||
ck_fflush (tmp);
|
||||
|
||||
{
|
||||
pid_t pid;
|
||||
int wstatus;
|
||||
#if ! HAVE_FORK
|
||||
char *command = xmalloc (strlen (edbin) + strlen (tmpname) + 2);
|
||||
sprintf (command, "%s %s", edbin, tmpname);
|
||||
wstatus = system (command);
|
||||
free (command);
|
||||
#else /* HAVE_FORK */
|
||||
pid_t pid;
|
||||
|
||||
ignore_SIGINT = 1;
|
||||
checksigs ();
|
||||
@ -956,8 +994,9 @@ edit (left, lenl, right, lenr, outfile)
|
||||
perror_fatal ("wait failed");
|
||||
|
||||
ignore_SIGINT = 0;
|
||||
#endif /* HAVE_FORK */
|
||||
|
||||
if (! (WIFEXITED (wstatus) && WEXITSTATUS (wstatus) < 1))
|
||||
if (wstatus != 0)
|
||||
fatal ("Subsidiary editor failed");
|
||||
}
|
||||
|
||||
@ -1063,131 +1102,79 @@ diraccess (dir)
|
||||
return stat (dir, &buf) == 0 && S_ISDIR (buf.st_mode);
|
||||
}
|
||||
|
||||
/* Return nonzero if FILE exists. */
|
||||
#if ! HAVE_TMPNAM
|
||||
|
||||
/* Return zero if we know that FILE does not exist. */
|
||||
static int
|
||||
exists (file)
|
||||
char const *file;
|
||||
{
|
||||
struct stat buf;
|
||||
return stat (file, &buf) == 0;
|
||||
return stat (file, &buf) == 0 || errno != ENOENT;
|
||||
}
|
||||
|
||||
/* These are the characters used in temporary filenames. */
|
||||
static char const letters[] =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
|
||||
/* Generate a temporary filename.
|
||||
If DIR_SEARCH is nonzero, DIR and PFX are used as
|
||||
described for tempnam. If not, a temporary filename
|
||||
in P_tmpdir with no special prefix is generated. If LENPTR
|
||||
is not 0, *LENPTR is set the to length (including the
|
||||
terminating '\0') of the resultant filename, which is returned.
|
||||
This goes through a cyclic pattern of all possible filenames
|
||||
consisting of five decimal digits of the current pid and three
|
||||
of the characters in `letters'. Data for tempnam and tmpnam
|
||||
is kept separate, but when tempnam is using P_tmpdir and no
|
||||
prefix (i.e, it is identical to tmpnam), the same data is used.
|
||||
Each potential filename is tested for an already-existing file of
|
||||
the same name, and no name of an existing file will be returned.
|
||||
When the cycle reaches its end (12345ZZZ), 0 is returned. */
|
||||
|
||||
|
||||
/* Generate a temporary filename and return it (in a newly allocated buffer).
|
||||
Use the prefix "dif" as in tempnam.
|
||||
This goes through a cyclic pattern of all possible
|
||||
filenames consisting of five decimal digits of the current pid and three
|
||||
of the characters in `letters'. Each potential filename is
|
||||
tested for an already-existing file of the same name, and no name of an
|
||||
existing file will be returned. When the cycle reaches its end
|
||||
return 0. */
|
||||
static char *
|
||||
private_tempnam (dir, pfx, dir_search, lenptr)
|
||||
char const *dir;
|
||||
char const *pfx;
|
||||
int dir_search;
|
||||
size_t *lenptr;
|
||||
private_tempnam ()
|
||||
{
|
||||
char const *dir = getenv (TMPDIR_ENV);
|
||||
static char const tmpdir[] = PVT_tmpdir;
|
||||
static struct
|
||||
{
|
||||
char buf[3];
|
||||
char *s;
|
||||
size_t i;
|
||||
} infos[2], *info;
|
||||
static char *buf;
|
||||
static size_t bufsize = 1;
|
||||
static pid_t oldpid = 0;
|
||||
size_t index;
|
||||
char *buf;
|
||||
pid_t pid = getpid ();
|
||||
register size_t len, plen;
|
||||
size_t dlen;
|
||||
|
||||
if (dir_search)
|
||||
{
|
||||
register char const *d = getenv ("TMPDIR");
|
||||
if (d && !diraccess (d))
|
||||
d = 0;
|
||||
if (!d && dir && diraccess (dir))
|
||||
d = dir;
|
||||
if (!d && diraccess (tmpdir))
|
||||
d = tmpdir;
|
||||
if (!d && diraccess ("/tmp"))
|
||||
d = "/tmp";
|
||||
if (!d)
|
||||
{
|
||||
errno = ENOENT;
|
||||
return 0;
|
||||
}
|
||||
dir = d;
|
||||
}
|
||||
else
|
||||
if (!dir)
|
||||
dir = tmpdir;
|
||||
|
||||
if (pfx && *pfx)
|
||||
{
|
||||
plen = strlen (pfx);
|
||||
if (plen > 5)
|
||||
plen = 5;
|
||||
}
|
||||
else
|
||||
plen = 0;
|
||||
dlen = strlen (dir);
|
||||
|
||||
if (dir != tmpdir && !strcmp (dir, tmpdir))
|
||||
dir = tmpdir;
|
||||
info = &infos[(plen == 0 && dir == tmpdir) ? 1 : 0];
|
||||
/* Remove trailing slashes from the directory name. */
|
||||
while (dlen && dir[dlen - 1] == '/')
|
||||
--dlen;
|
||||
|
||||
if (pid != oldpid)
|
||||
{
|
||||
oldpid = pid;
|
||||
info->buf[0] = info->buf[1] = info->buf[2] = '0';
|
||||
info->s = &info->buf[0];
|
||||
info->i = 0;
|
||||
}
|
||||
buf = xmalloc (dlen + 1 + 3 + 5 + 1 + 3 + 1);
|
||||
|
||||
len = strlen (dir) + 1 + plen + 8;
|
||||
if (bufsize <= len)
|
||||
sprintf (buf, "%.*s/.", (int) dlen, dir);
|
||||
if (diraccess (buf))
|
||||
{
|
||||
do
|
||||
for (index = 0;
|
||||
index < ((sizeof (letters) - 1) * (sizeof (letters) - 1)
|
||||
* (sizeof (letters) - 1));
|
||||
++index)
|
||||
{
|
||||
bufsize *= 2;
|
||||
}
|
||||
while (bufsize <= len);
|
||||
/* Construct a file name and see if it already exists.
|
||||
|
||||
if (buf)
|
||||
free (buf);
|
||||
buf = xmalloc (bufsize);
|
||||
}
|
||||
for (;;)
|
||||
{
|
||||
*info->s = letters[info->i];
|
||||
sprintf (buf, "%s/%.*s%.5lu%.3s", dir, (int) plen, pfx,
|
||||
(unsigned long) pid % 100000, info->buf);
|
||||
if (!exists (buf))
|
||||
break;
|
||||
++info->i;
|
||||
if (info->i > sizeof (letters) - 1)
|
||||
{
|
||||
info->i = 0;
|
||||
if (info->s == &info->buf[2])
|
||||
{
|
||||
errno = EEXIST;
|
||||
return 0;
|
||||
}
|
||||
++info->s;
|
||||
We use a single counter in INDEX to cycle each of three
|
||||
character positions through each of 62 possible letters. */
|
||||
|
||||
sprintf (buf, "%.*s/dif%.5lu.%c%c%c", (int) dlen, dir,
|
||||
(unsigned long) pid % 100000,
|
||||
letters[index % (sizeof (letters) - 1)],
|
||||
letters[(index / (sizeof (letters) - 1))
|
||||
% (sizeof (letters) - 1)],
|
||||
letters[index / ((sizeof (letters) - 1) *
|
||||
(sizeof (letters) - 1))]);
|
||||
|
||||
if (!exists (buf))
|
||||
return buf;
|
||||
}
|
||||
errno = EEXIST;
|
||||
}
|
||||
|
||||
if (lenptr)
|
||||
*lenptr = len;
|
||||
return buf;
|
||||
/* Don't free buf; `free' might change errno. We'll exit soon anyway. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* ! HAVE_TMPNAM */
|
||||
|
@ -139,7 +139,7 @@ print_half_line (line, indent, out_bound)
|
||||
break;
|
||||
|
||||
default:
|
||||
if (! isprint (c))
|
||||
if (! ISPRINT (c))
|
||||
goto control_char;
|
||||
/* falls through */
|
||||
case ' ':
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* System dependent declarations.
|
||||
Copyright (C) 1988, 1989, 1992, 1993 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988, 1989, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU DIFF.
|
||||
|
||||
@ -64,16 +64,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#define S_ISSOCK(mode) (((mode) & S_IFMT) == S_IFSOCK)
|
||||
#endif
|
||||
|
||||
#ifndef S_IXOTH
|
||||
#define S_IXOTH 1
|
||||
#endif
|
||||
#ifndef S_IXGRP
|
||||
#define S_IXGRP (S_IXOTH << 3)
|
||||
#endif
|
||||
#ifndef S_IXUSR
|
||||
#define S_IXUSR (S_IXGRP << 3)
|
||||
#endif
|
||||
|
||||
#if HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
@ -104,8 +94,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#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))
|
||||
@ -116,47 +108,39 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#endif
|
||||
|
||||
#if HAVE_SYS_WAIT_H
|
||||
#ifndef _POSIX_VERSION
|
||||
/* Prevent the NeXT prototype using union wait from causing problems. */
|
||||
#define wait system_wait
|
||||
#endif
|
||||
#include <sys/wait.h>
|
||||
#ifndef _POSIX_VERSION
|
||||
#undef wait
|
||||
#endif
|
||||
#endif /* HAVE_SYS_WAIT_H */
|
||||
|
||||
#ifndef WEXITSTATUS
|
||||
#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
|
||||
#undef WIFEXITED /* Avoid 4.3BSD incompatibility with Posix. */
|
||||
#define WEXITSTATUS(stat_val) ((unsigned) (stat_val) >> 8)
|
||||
#endif
|
||||
#ifndef WIFEXITED
|
||||
#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
|
||||
#endif
|
||||
|
||||
#ifndef STAT_BLOCKSIZE
|
||||
#if HAVE_ST_BLKSIZE
|
||||
#define STAT_BLOCKSIZE(s) (s).st_blksize
|
||||
#else
|
||||
#define STAT_BLOCKSIZE(s) (8 * 1024)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if DIRENT || defined (_POSIX_VERSION)
|
||||
#include <dirent.h>
|
||||
#else /* ! (DIRENT || defined (_POSIX_VERSION)) */
|
||||
#if SYSNDIR
|
||||
#include <sys/ndir.h>
|
||||
#if HAVE_DIRENT_H
|
||||
# include <dirent.h>
|
||||
# define NAMLEN(dirent) strlen((dirent)->d_name)
|
||||
#else
|
||||
#if SYSDIR
|
||||
#include <sys/dir.h>
|
||||
#else
|
||||
#include <ndir.h>
|
||||
# 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
|
||||
#endif
|
||||
#ifdef dirent
|
||||
#undef dirent
|
||||
#endif
|
||||
#define dirent direct
|
||||
#endif /* ! (DIRENT || defined (_POSIX_VERSION)) */
|
||||
|
||||
#if HAVE_VFORK_H
|
||||
#include <vfork.h>
|
||||
@ -182,28 +166,44 @@ char *getenv ();
|
||||
#define CHAR_BIT 8
|
||||
#endif
|
||||
|
||||
#if HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#ifndef bzero
|
||||
#define bzero(s,n) memset (s,0,n)
|
||||
#if STDC_HEADERS || HAVE_STRING_H
|
||||
# include <string.h>
|
||||
# ifndef bzero
|
||||
# define bzero(s, n) memset (s, 0, n)
|
||||
# endif
|
||||
#else
|
||||
# if !HAVE_STRCHR
|
||||
# define strchr index
|
||||
# define strrchr rindex
|
||||
# endif
|
||||
char *strchr (), *strrchr ();
|
||||
# if !HAVE_MEMCHR
|
||||
# define memcmp(s1, s2, n) bcmp (s1, s2, n)
|
||||
# define memcpy(d, s, n) bcopy (s, d, n)
|
||||
void *memchr ();
|
||||
# endif
|
||||
#endif
|
||||
#else /* !HAVE_STRING_H */
|
||||
#include <strings.h>
|
||||
#ifndef strchr
|
||||
#define strchr index
|
||||
|
||||
#include <ctype.h>
|
||||
/* CTYPE_DOMAIN (C) is nonzero if the unsigned char C can safely be given
|
||||
as an argument to <ctype.h> macros like `isspace'. */
|
||||
#if STDC_HEADERS
|
||||
#define CTYPE_DOMAIN(c) 1
|
||||
#else
|
||||
#define CTYPE_DOMAIN(c) ((unsigned) (c) <= 0177)
|
||||
#endif
|
||||
#ifndef strrchr
|
||||
#define strrchr rindex
|
||||
#ifndef ISPRINT
|
||||
#define ISPRINT(c) (CTYPE_DOMAIN (c) && isprint (c))
|
||||
#endif
|
||||
#ifndef memcpy
|
||||
#define memcpy(d,s,n) bcopy (s,d,n)
|
||||
#ifndef ISSPACE
|
||||
#define ISSPACE(c) (CTYPE_DOMAIN (c) && isspace (c))
|
||||
#endif
|
||||
#ifndef memcmp
|
||||
#define memcmp(s1,s2,n) bcmp (s1,s2,n)
|
||||
#ifndef ISUPPER
|
||||
#define ISUPPER(c) (CTYPE_DOMAIN (c) && isupper (c))
|
||||
#endif
|
||||
#endif /* !HAVE_STRING_H */
|
||||
#if !HAVE_MEMCHR
|
||||
char *memchr ();
|
||||
|
||||
#ifndef ISDIGIT
|
||||
#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
@ -211,5 +211,57 @@ char *memchr ();
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
#define min(a,b) ((a) <= (b) ? (a) : (b))
|
||||
#define max(a,b) ((a) >= (b) ? (a) : (b))
|
||||
|
||||
/* This section contains Posix-compliant defaults for macros
|
||||
that are meant to be overridden by hand in config.h as needed. */
|
||||
|
||||
#ifndef filename_cmp
|
||||
#define filename_cmp(a, b) strcmp (a, b)
|
||||
#endif
|
||||
|
||||
#ifndef filename_lastdirchar
|
||||
#define filename_lastdirchar(filename) strrchr (filename, '/')
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FORK
|
||||
#define HAVE_FORK 1
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SETMODE
|
||||
#define HAVE_SETMODE 0
|
||||
#endif
|
||||
|
||||
#ifndef initialize_main
|
||||
#define initialize_main(argcp, argvp)
|
||||
#endif
|
||||
|
||||
/* Do struct stat *S, *T describe the same file? Answer -1 if unknown. */
|
||||
#ifndef same_file
|
||||
#define same_file(s,t) ((s)->st_ino==(t)->st_ino && (s)->st_dev==(t)->st_dev)
|
||||
#endif
|
||||
|
||||
/* Place into Q a quoted version of A suitable for `popen' or `system',
|
||||
incrementing Q and junking A.
|
||||
Do not increment Q by more than 4 * strlen (A) + 2. */
|
||||
#ifndef SYSTEM_QUOTE_ARG
|
||||
#define SYSTEM_QUOTE_ARG(q, a) \
|
||||
{ \
|
||||
*(q)++ = '\''; \
|
||||
for (; *(a); *(q)++ = *(a)++) \
|
||||
if (*(a) == '\'') \
|
||||
{ \
|
||||
*(q)++ = '\''; \
|
||||
*(q)++ = '\\'; \
|
||||
*(q)++ = '\''; \
|
||||
} \
|
||||
*(q)++ = '\''; \
|
||||
}
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Support routines for GNU DIFF.
|
||||
Copyright (C) 1988, 1989, 1992, 1993 Free Software Foundation, Inc.
|
||||
Copyright (C) 1988, 1989, 1992, 1993, 1994 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU DIFF.
|
||||
|
||||
@ -19,6 +19,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "diff.h"
|
||||
|
||||
#ifndef PR_PROGRAM
|
||||
#define PR_PROGRAM "/bin/pr"
|
||||
#endif
|
||||
|
||||
/* Queue up one-line messages to be printed at the end,
|
||||
when -l is specified. Each message is recorded with a `struct msg'. */
|
||||
|
||||
@ -48,7 +52,7 @@ perror_with_name (text)
|
||||
char const *text;
|
||||
{
|
||||
int e = errno;
|
||||
fprintf (stderr, "%s: ", program);
|
||||
fprintf (stderr, "%s: ", program_name);
|
||||
errno = e;
|
||||
perror (text);
|
||||
}
|
||||
@ -61,7 +65,7 @@ pfatal_with_name (text)
|
||||
{
|
||||
int e = errno;
|
||||
print_message_queue ();
|
||||
fprintf (stderr, "%s: ", program);
|
||||
fprintf (stderr, "%s: ", program_name);
|
||||
errno = e;
|
||||
perror (text);
|
||||
exit (2);
|
||||
@ -74,7 +78,7 @@ void
|
||||
error (format, arg, arg1)
|
||||
char const *format, *arg, *arg1;
|
||||
{
|
||||
fprintf (stderr, "%s: ", program);
|
||||
fprintf (stderr, "%s: ", program_name);
|
||||
fprintf (stderr, format, arg, arg1);
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
@ -157,7 +161,9 @@ setup_output (name0, name1, depth)
|
||||
outfile = 0;
|
||||
}
|
||||
|
||||
#if HAVE_FORK
|
||||
static pid_t pr_pid;
|
||||
#endif
|
||||
|
||||
void
|
||||
begin_output ()
|
||||
@ -170,19 +176,20 @@ begin_output ()
|
||||
/* Construct the header of this piece of diff. */
|
||||
name = xmalloc (strlen (current_name0) + strlen (current_name1)
|
||||
+ strlen (switch_string) + 7);
|
||||
/* Posix.2 section 4.17.6.1.1 specifies this format. But there are some
|
||||
bugs in the first printing (IEEE Std 1003.2-1992 p 251 l 3304):
|
||||
it says that we must print only the last component of the pathnames,
|
||||
and it requires two spaces after "diff" if there are no options.
|
||||
These requirements are silly and do not match historical practice. */
|
||||
/* Posix.2 section 4.17.6.1.1 specifies this format. But there is a
|
||||
bug in the first printing (IEEE Std 1003.2-1992 p 251 l 3304):
|
||||
it says that we must print only the last component of the pathnames.
|
||||
This requirement is silly and does not match historical practice. */
|
||||
sprintf (name, "diff%s %s %s", switch_string, current_name0, current_name1);
|
||||
|
||||
if (paginate_flag)
|
||||
{
|
||||
/* Make OUTFILE a pipe to a subsidiary `pr'. */
|
||||
|
||||
#if HAVE_FORK
|
||||
int pipes[2];
|
||||
|
||||
/* Fork a `pr' and make OUTFILE a pipe to it. */
|
||||
if (pipe (pipes) < 0)
|
||||
if (pipe (pipes) != 0)
|
||||
pfatal_with_name ("pipe");
|
||||
|
||||
fflush (stdout);
|
||||
@ -201,14 +208,29 @@ begin_output ()
|
||||
close (pipes[0]);
|
||||
}
|
||||
|
||||
execl (PR_FILE_NAME, PR_FILE_NAME, "-f", "-h", name, 0);
|
||||
pfatal_with_name (PR_FILE_NAME);
|
||||
execl (PR_PROGRAM, PR_PROGRAM, "-f", "-h", name, 0);
|
||||
pfatal_with_name (PR_PROGRAM);
|
||||
}
|
||||
else
|
||||
{
|
||||
close (pipes[0]);
|
||||
outfile = fdopen (pipes[1], "w");
|
||||
if (!outfile)
|
||||
pfatal_with_name ("fdopen");
|
||||
}
|
||||
#else /* ! HAVE_FORK */
|
||||
char *command = xmalloc (4 * strlen (name) + strlen (PR_PROGRAM) + 10);
|
||||
char *p;
|
||||
char const *a = name;
|
||||
sprintf (command, "%s -f -h ", PR_PROGRAM);
|
||||
p = command + strlen (command);
|
||||
SYSTEM_QUOTE_ARG (p, a);
|
||||
*p = 0;
|
||||
outfile = popen (command, "w");
|
||||
if (!outfile)
|
||||
pfatal_with_name (command);
|
||||
free (command);
|
||||
#endif /* ! HAVE_FORK */
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -252,21 +274,15 @@ finish_output ()
|
||||
int wstatus;
|
||||
if (ferror (outfile))
|
||||
fatal ("write error");
|
||||
#if ! HAVE_FORK
|
||||
wstatus = pclose (outfile);
|
||||
#else /* HAVE_FORK */
|
||||
if (fclose (outfile) != 0)
|
||||
pfatal_with_name ("write error");
|
||||
#if HAVE_WAITPID
|
||||
if (waitpid (pr_pid, &wstatus, 0) < 0)
|
||||
pfatal_with_name ("waitpid");
|
||||
#else
|
||||
for (;;) {
|
||||
pid_t w = wait (&wstatus);
|
||||
if (w < 0)
|
||||
pfatal_with_name ("wait");
|
||||
if (w == pr_pid)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
if (! WIFEXITED (wstatus) || WEXITSTATUS (wstatus) != 0)
|
||||
#endif /* HAVE_FORK */
|
||||
if (wstatus != 0)
|
||||
fatal ("subsidiary pr failed");
|
||||
}
|
||||
|
||||
@ -275,56 +291,44 @@ finish_output ()
|
||||
|
||||
/* Compare two lines (typically one from each input file)
|
||||
according to the command line options.
|
||||
Return 1 if the lines differ, like `memcmp'. */
|
||||
For efficiency, this is invoked only when the lines do not match exactly
|
||||
but an option like -i might cause us to ignore the difference.
|
||||
Return nonzero if the lines differ. */
|
||||
|
||||
int
|
||||
line_cmp (s1, len1, s2, len2)
|
||||
line_cmp (s1, s2)
|
||||
char const *s1, *s2;
|
||||
size_t len1, len2;
|
||||
{
|
||||
register unsigned char const *t1, *t2;
|
||||
register unsigned char end_char = line_end_char;
|
||||
register unsigned char const *t1 = (unsigned char const *) s1;
|
||||
register unsigned char const *t2 = (unsigned char const *) s2;
|
||||
|
||||
/* Check first for exact identity.
|
||||
If that is true, return 0 immediately.
|
||||
This detects the common case of exact identity
|
||||
faster than complete comparison would. */
|
||||
|
||||
if (len1 == len2 && memcmp (s1, s2, len1) == 0)
|
||||
return 0;
|
||||
|
||||
/* Not exactly identical, but perhaps they match anyway
|
||||
when case or white space is ignored. */
|
||||
|
||||
if (ignore_case_flag | ignore_space_change_flag | ignore_all_space_flag)
|
||||
while (1)
|
||||
{
|
||||
t1 = (unsigned char const *) s1;
|
||||
t2 = (unsigned char const *) s2;
|
||||
register unsigned char c1 = *t1++;
|
||||
register unsigned char c2 = *t2++;
|
||||
|
||||
while (1)
|
||||
/* Test for exact char equality first, since it's a common case. */
|
||||
if (c1 != c2)
|
||||
{
|
||||
register unsigned char c1 = *t1++;
|
||||
register unsigned char c2 = *t2++;
|
||||
|
||||
/* Ignore horizontal white space if -b or -w is specified. */
|
||||
|
||||
if (ignore_all_space_flag)
|
||||
{
|
||||
/* For -w, just skip past any white space. */
|
||||
while (isspace (c1) && c1 != end_char) c1 = *t1++;
|
||||
while (isspace (c2) && c2 != end_char) c2 = *t2++;
|
||||
while (ISSPACE (c1) && c1 != '\n') c1 = *t1++;
|
||||
while (ISSPACE (c2) && c2 != '\n') c2 = *t2++;
|
||||
}
|
||||
else if (ignore_space_change_flag)
|
||||
{
|
||||
/* For -b, advance past any sequence of white space in line 1
|
||||
and consider it just one Space, or nothing at all
|
||||
if it is at the end of the line. */
|
||||
if (isspace (c1))
|
||||
if (ISSPACE (c1))
|
||||
{
|
||||
while (c1 != end_char)
|
||||
while (c1 != '\n')
|
||||
{
|
||||
c1 = *t1++;
|
||||
if (! isspace (c1))
|
||||
if (! ISSPACE (c1))
|
||||
{
|
||||
--t1;
|
||||
c1 = ' ';
|
||||
@ -334,12 +338,12 @@ line_cmp (s1, len1, s2, len2)
|
||||
}
|
||||
|
||||
/* Likewise for line 2. */
|
||||
if (isspace (c2))
|
||||
if (ISSPACE (c2))
|
||||
{
|
||||
while (c2 != end_char)
|
||||
while (c2 != '\n')
|
||||
{
|
||||
c2 = *t2++;
|
||||
if (! isspace (c2))
|
||||
if (! ISSPACE (c2))
|
||||
{
|
||||
--t2;
|
||||
c2 = ' ';
|
||||
@ -347,23 +351,44 @@ line_cmp (s1, len1, s2, len2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (c1 != c2)
|
||||
{
|
||||
/* If we went too far when doing the simple test
|
||||
for equality, go back to the first non-white-space
|
||||
character in both sides and try again. */
|
||||
if (c2 == ' ' && c1 != '\n'
|
||||
&& (unsigned char const *) s1 + 1 < t1
|
||||
&& ISSPACE(t1[-2]))
|
||||
{
|
||||
--t1;
|
||||
continue;
|
||||
}
|
||||
if (c1 == ' ' && c2 != '\n'
|
||||
&& (unsigned char const *) s2 + 1 < t2
|
||||
&& ISSPACE(t2[-2]))
|
||||
{
|
||||
--t2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Upcase all letters if -i is specified. */
|
||||
/* Lowercase all letters if -i is specified. */
|
||||
|
||||
if (ignore_case_flag)
|
||||
{
|
||||
if (islower (c1))
|
||||
c1 = toupper (c1);
|
||||
if (islower (c2))
|
||||
c2 = toupper (c2);
|
||||
if (ISUPPER (c1))
|
||||
c1 = tolower (c1);
|
||||
if (ISUPPER (c2))
|
||||
c2 = tolower (c2);
|
||||
}
|
||||
|
||||
if (c1 != c2)
|
||||
break;
|
||||
if (c1 == end_char)
|
||||
return 0;
|
||||
}
|
||||
if (c1 == '\n')
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (1);
|
||||
@ -454,8 +479,7 @@ print_1_line (line_flag, line)
|
||||
|
||||
output_1_line (text, limit, flag_format, line_flag);
|
||||
|
||||
if ((!line_flag || line_flag[0]) && limit[-1] != '\n'
|
||||
&& line_end_char == '\n')
|
||||
if ((!line_flag || line_flag[0]) && limit[-1] != '\n')
|
||||
fprintf (out, "\n\\ No newline at end of file\n");
|
||||
}
|
||||
|
||||
@ -505,7 +529,7 @@ output_1_line (text, limit, flag_format, line_flag)
|
||||
break;
|
||||
|
||||
default:
|
||||
if (isprint (c))
|
||||
if (ISPRINT (c))
|
||||
column++;
|
||||
putc (c, out);
|
||||
break;
|
||||
@ -558,7 +582,7 @@ translate_range (file, a, b, aptr, bptr)
|
||||
|
||||
void
|
||||
print_number_range (sepchar, file, a, b)
|
||||
char sepchar;
|
||||
int sepchar;
|
||||
struct file_data *file;
|
||||
int a, b;
|
||||
{
|
||||
@ -714,7 +738,8 @@ char *
|
||||
dir_file_pathname (dir, file)
|
||||
char const *dir, *file;
|
||||
{
|
||||
return concat (dir, "/" + (*dir && dir[strlen (dir) - 1] == '/'), file);
|
||||
char const *p = filename_lastdirchar (dir);
|
||||
return concat (dir, "/" + (p && !p[1]), file);
|
||||
}
|
||||
|
||||
void
|
||||
@ -727,18 +752,3 @@ debug_script (sp)
|
||||
sp->line0, sp->line1, sp->deleted, sp->inserted);
|
||||
fflush (stderr);
|
||||
}
|
||||
|
||||
#if !HAVE_MEMCHR
|
||||
char *
|
||||
memchr (s, c, n)
|
||||
char const *s;
|
||||
int c;
|
||||
size_t n;
|
||||
{
|
||||
unsigned char const *p = (unsigned char const *) s, *lim = p + n;
|
||||
for (; p < lim; p++)
|
||||
if (*p == c)
|
||||
return (char *) p;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
#include "config.h"
|
||||
|
||||
char const version_string[] = "2.6";
|
||||
char const version_string[] = "2.7";
|
||||
|
Loading…
Reference in New Issue
Block a user