Changeset View
Changeset View
Standalone View
Standalone View
usr.bin/diff/diff.c
Show All 32 Lines | |||||
#include <stdio.h> | #include <stdio.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <unistd.h> | #include <unistd.h> | ||||
#include <limits.h> | #include <limits.h> | ||||
#include "diff.h" | #include "diff.h" | ||||
#include "xmalloc.h" | #include "xmalloc.h" | ||||
static const char diff_version[] = "FreeBSD diff 20220309"; | |||||
bool lflag, Nflag, Pflag, rflag, sflag, Tflag, cflag; | bool lflag, Nflag, Pflag, rflag, sflag, Tflag, cflag; | ||||
bool ignore_file_case, suppress_common, color, noderef; | bool ignore_file_case, suppress_common, color, noderef; | ||||
static bool help = false; | |||||
int diff_format, diff_context, status; | int diff_format, diff_context, status; | ||||
int tabsize = 8, width = 130; | int tabsize = 8, width = 130; | ||||
static int colorflag = COLORFLAG_NEVER; | static int colorflag = COLORFLAG_NEVER; | ||||
char *start, *ifdefname, *diffargs, *label[2]; | char *start, *ifdefname, *diffargs, *label[2]; | ||||
char *ignore_pats, *most_recent_pat; | char *ignore_pats, *most_recent_pat; | ||||
char *group_format = NULL; | char *group_format = NULL; | ||||
const char *add_code, *del_code; | const char *add_code, *del_code; | ||||
struct stat stb1, stb2; | struct stat stb1, stb2; | ||||
struct excludes *excludes_list; | struct excludes *excludes_list; | ||||
regex_t ignore_re, most_recent_re; | regex_t ignore_re, most_recent_re; | ||||
#define OPTIONS "0123456789aBbC:cdD:efF:HhI:iL:lnNPpqrS:sTtU:uwW:X:x:y" | #define OPTIONS "0123456789aBbC:cdD:efF:HhI:iL:lnNPpqrS:sTtU:uwW:X:x:y" | ||||
pauamma_gundo.com: For full compatibility, also needs to support -v as a --version synonym here and *gestures… | |||||
enum { | enum { | ||||
OPT_TSIZE = CHAR_MAX + 1, | OPT_TSIZE = CHAR_MAX + 1, | ||||
OPT_STRIPCR, | OPT_STRIPCR, | ||||
OPT_IGN_FN_CASE, | OPT_IGN_FN_CASE, | ||||
OPT_NO_IGN_FN_CASE, | OPT_NO_IGN_FN_CASE, | ||||
OPT_NORMAL, | OPT_NORMAL, | ||||
OPT_HELP, | |||||
OPT_HORIZON_LINES, | OPT_HORIZON_LINES, | ||||
OPT_CHANGED_GROUP_FORMAT, | OPT_CHANGED_GROUP_FORMAT, | ||||
OPT_SUPPRESS_COMMON, | OPT_SUPPRESS_COMMON, | ||||
OPT_COLOR, | OPT_COLOR, | ||||
OPT_NO_DEREFERENCE, | OPT_NO_DEREFERENCE, | ||||
OPT_VERSION, | |||||
}; | }; | ||||
static struct option longopts[] = { | static struct option longopts[] = { | ||||
{ "text", no_argument, 0, 'a' }, | { "text", no_argument, 0, 'a' }, | ||||
{ "ignore-space-change", no_argument, 0, 'b' }, | { "ignore-space-change", no_argument, 0, 'b' }, | ||||
{ "context", optional_argument, 0, 'C' }, | { "context", optional_argument, 0, 'C' }, | ||||
{ "ifdef", required_argument, 0, 'D' }, | { "ifdef", required_argument, 0, 'D' }, | ||||
{ "minimal", no_argument, 0, 'd' }, | { "minimal", no_argument, 0, 'd' }, | ||||
Show All 18 Lines | static struct option longopts[] = { | ||||
{ "initial-tab", no_argument, 0, 'T' }, | { "initial-tab", no_argument, 0, 'T' }, | ||||
{ "unified", optional_argument, 0, 'U' }, | { "unified", optional_argument, 0, 'U' }, | ||||
{ "ignore-all-space", no_argument, 0, 'w' }, | { "ignore-all-space", no_argument, 0, 'w' }, | ||||
{ "width", required_argument, 0, 'W' }, | { "width", required_argument, 0, 'W' }, | ||||
{ "exclude", required_argument, 0, 'x' }, | { "exclude", required_argument, 0, 'x' }, | ||||
{ "exclude-from", required_argument, 0, 'X' }, | { "exclude-from", required_argument, 0, 'X' }, | ||||
{ "side-by-side", no_argument, NULL, 'y' }, | { "side-by-side", no_argument, NULL, 'y' }, | ||||
{ "ignore-file-name-case", no_argument, NULL, OPT_IGN_FN_CASE }, | { "ignore-file-name-case", no_argument, NULL, OPT_IGN_FN_CASE }, | ||||
{ "help", no_argument, NULL, OPT_HELP}, | |||||
{ "horizon-lines", required_argument, NULL, OPT_HORIZON_LINES }, | { "horizon-lines", required_argument, NULL, OPT_HORIZON_LINES }, | ||||
{ "no-dereference", no_argument, NULL, OPT_NO_DEREFERENCE}, | { "no-dereference", no_argument, NULL, OPT_NO_DEREFERENCE}, | ||||
{ "no-ignore-file-name-case", no_argument, NULL, OPT_NO_IGN_FN_CASE }, | { "no-ignore-file-name-case", no_argument, NULL, OPT_NO_IGN_FN_CASE }, | ||||
{ "normal", no_argument, NULL, OPT_NORMAL }, | { "normal", no_argument, NULL, OPT_NORMAL }, | ||||
{ "strip-trailing-cr", no_argument, NULL, OPT_STRIPCR }, | { "strip-trailing-cr", no_argument, NULL, OPT_STRIPCR }, | ||||
{ "tabsize", required_argument, NULL, OPT_TSIZE }, | { "tabsize", required_argument, NULL, OPT_TSIZE }, | ||||
{ "changed-group-format", required_argument, NULL, OPT_CHANGED_GROUP_FORMAT}, | { "changed-group-format", required_argument, NULL, OPT_CHANGED_GROUP_FORMAT}, | ||||
{ "suppress-common-lines", no_argument, NULL, OPT_SUPPRESS_COMMON }, | { "suppress-common-lines", no_argument, NULL, OPT_SUPPRESS_COMMON }, | ||||
{ "color", optional_argument, NULL, OPT_COLOR }, | { "color", optional_argument, NULL, OPT_COLOR }, | ||||
{ "version", no_argument, NULL, OPT_VERSION}, | |||||
{ NULL, 0, 0, '\0'} | { NULL, 0, 0, '\0'} | ||||
}; | }; | ||||
static void checked_regcomp(char const *, regex_t *); | static void checked_regcomp(char const *, regex_t *); | ||||
static void usage(void) __dead2; | static void usage(void) __dead2; | ||||
static void conflicting_format(void) __dead2; | static void conflicting_format(void) __dead2; | ||||
static void push_excludes(char *); | static void push_excludes(char *); | ||||
static void push_ignore_pats(char *); | static void push_ignore_pats(char *); | ||||
▲ Show 20 Lines • Show All 172 Lines • ▼ Show 20 Lines | case 'y': | ||||
diff_format = D_SIDEBYSIDE; | diff_format = D_SIDEBYSIDE; | ||||
break; | break; | ||||
case OPT_CHANGED_GROUP_FORMAT: | case OPT_CHANGED_GROUP_FORMAT: | ||||
if (FORMAT_MISMATCHED(D_GFORMAT)) | if (FORMAT_MISMATCHED(D_GFORMAT)) | ||||
conflicting_format(); | conflicting_format(); | ||||
diff_format = D_GFORMAT; | diff_format = D_GFORMAT; | ||||
group_format = optarg; | group_format = optarg; | ||||
break; | break; | ||||
case OPT_HELP: | |||||
help = true; | |||||
usage(); | |||||
break; | |||||
case OPT_HORIZON_LINES: | case OPT_HORIZON_LINES: | ||||
break; /* XXX TODO for compatibility with GNU diff3 */ | break; /* XXX TODO for compatibility with GNU diff3 */ | ||||
case OPT_IGN_FN_CASE: | case OPT_IGN_FN_CASE: | ||||
ignore_file_case = true; | ignore_file_case = true; | ||||
break; | break; | ||||
case OPT_NO_IGN_FN_CASE: | case OPT_NO_IGN_FN_CASE: | ||||
ignore_file_case = false; | ignore_file_case = false; | ||||
break; | break; | ||||
Show All 25 Lines | case OPT_COLOR: | ||||
else | else | ||||
errx(2, "unsupported --color value '%s' (must be always, auto, or never)", | errx(2, "unsupported --color value '%s' (must be always, auto, or never)", | ||||
optarg); | optarg); | ||||
break; | break; | ||||
case OPT_NO_DEREFERENCE: | case OPT_NO_DEREFERENCE: | ||||
rflag = true; | rflag = true; | ||||
noderef = true; | noderef = true; | ||||
break; | break; | ||||
case OPT_VERSION: | |||||
printf("%s\n", diff_version); | |||||
exit(0); | |||||
default: | default: | ||||
usage(); | usage(); | ||||
break; | break; | ||||
} | } | ||||
lastch = ch; | lastch = ch; | ||||
newarg = optind != prevoptind; | newarg = optind != prevoptind; | ||||
prevoptind = optind; | prevoptind = optind; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 218 Lines • ▼ Show 20 Lines | printf("File %s%s is not a regular file or directory and was skipped\n", | ||||
path2, entry); | path2, entry); | ||||
break; | break; | ||||
case D_ERROR: | case D_ERROR: | ||||
break; | break; | ||||
} | } | ||||
} | } | ||||
static void | static void | ||||
usage(void) | usage() | ||||
{ | { | ||||
(void)fprintf(stderr, | (void)fprintf(help ? stdout : stderr, | ||||
"usage: diff [-aBbdilpTtw] [-c | -e | -f | -n | -q | -u] [--ignore-case]\n" | "usage: diff [-aBbdilpTtw] [-c | -e | -f | -n | -q | -u] [--ignore-case]\n" | ||||
" [--no-ignore-case] [--normal] [--strip-trailing-cr] [--tabsize]\n" | " [--no-ignore-case] [--normal] [--strip-trailing-cr] [--tabsize]\n" | ||||
" [-I pattern] [-F pattern] [-L label] file1 file2\n" | " [-I pattern] [-F pattern] [-L label] file1 file2\n" | ||||
" diff [-aBbdilpTtw] [-I pattern] [-L label] [--ignore-case]\n" | " diff [-aBbdilpTtw] [-I pattern] [-L label] [--ignore-case]\n" | ||||
" [--no-ignore-case] [--normal] [--strip-trailing-cr] [--tabsize]\n" | " [--no-ignore-case] [--normal] [--strip-trailing-cr] [--tabsize]\n" | ||||
" [-F pattern] -C number file1 file2\n" | " [-F pattern] -C number file1 file2\n" | ||||
" diff [-aBbdiltw] [-I pattern] [--ignore-case] [--no-ignore-case]\n" | " diff [-aBbdiltw] [-I pattern] [--ignore-case] [--no-ignore-case]\n" | ||||
" [--normal] [--strip-trailing-cr] [--tabsize] -D string file1 file2\n" | " [--normal] [--strip-trailing-cr] [--tabsize] -D string file1 file2\n" | ||||
" diff [-aBbdilpTtw] [-I pattern] [-L label] [--ignore-case]\n" | " diff [-aBbdilpTtw] [-I pattern] [-L label] [--ignore-case]\n" | ||||
" [--no-ignore-case] [--normal] [--tabsize] [--strip-trailing-cr]\n" | " [--no-ignore-case] [--normal] [--tabsize] [--strip-trailing-cr]\n" | ||||
" [-F pattern] -U number file1 file2\n" | " [-F pattern] -U number file1 file2\n" | ||||
" diff [-aBbdilNPprsTtw] [-c | -e | -f | -n | -q | -u] [--ignore-case]\n" | " diff [-aBbdilNPprsTtw] [-c | -e | -f | -n | -q | -u] [--ignore-case]\n" | ||||
" [--no-ignore-case] [--normal] [--tabsize] [-I pattern] [-L label]\n" | " [--no-ignore-case] [--normal] [--tabsize] [-I pattern] [-L label]\n" | ||||
" [-F pattern] [-S name] [-X file] [-x pattern] dir1 dir2\n" | " [-F pattern] [-S name] [-X file] [-x pattern] dir1 dir2\n" | ||||
" diff [-aBbditwW] [--expand-tabs] [--ignore-all-blanks]\n" | " diff [-aBbditwW] [--expand-tabs] [--ignore-all-blanks]\n" | ||||
" [--ignore-blank-lines] [--ignore-case] [--minimal]\n" | " [--ignore-blank-lines] [--ignore-case] [--minimal]\n" | ||||
" [--no-ignore-file-name-case] [--strip-trailing-cr]\n" | " [--no-ignore-file-name-case] [--strip-trailing-cr]\n" | ||||
" [--suppress-common-lines] [--tabsize] [--text] [--width]\n" | " [--suppress-common-lines] [--tabsize] [--text] [--width]\n" | ||||
" -y | --side-by-side file1 file2\n"); | " -y | --side-by-side file1 file2\n" | ||||
" diff [--help] [--version]\n"); | |||||
if (help) | |||||
exit(0); | |||||
else | |||||
exit(2); | exit(2); | ||||
} | } | ||||
static void | static void | ||||
conflicting_format(void) | conflicting_format(void) | ||||
{ | { | ||||
fprintf(stderr, "error: conflicting output format options.\n"); | fprintf(stderr, "error: conflicting output format options.\n"); | ||||
usage(); | usage(); | ||||
Show All 39 Lines |
For full compatibility, also needs to support -v as a --version synonym here and *gestures vaguely toward the switch statement below*