Changeset View
Changeset View
Standalone View
Standalone View
usr.bin/diff/diff.c
Show All 34 Lines | |||||
#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"; | 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, algorithm_set; | ||||
static bool help = false; | static bool help = false; | ||||
int diff_format, diff_context, status; | int diff_format, diff_context, diff_algorithm, 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" | static struct algorithm { | ||||
const char *name; | |||||
int id; | |||||
} algorithms[] = { | |||||
{"stone", D_DIFFSTONE}, | |||||
{"myers", D_DIFFMYERS}, | |||||
{"patience", D_DIFFPATIENCE}, | |||||
{NULL, D_DIFFNONE} | |||||
}; | |||||
#define OPTIONS "0123456789A:aBbC:cdD:efF:HhI:iL:lnNPpqrS:sTtU:uwW:X:x:y" | |||||
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_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, | OPT_VERSION, | ||||
}; | }; | ||||
static struct option longopts[] = { | static struct option longopts[] = { | ||||
{ "algorithm", required_argument, 0, 'A' }, | |||||
{ "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' }, | ||||
{ "ed", no_argument, 0, 'e' }, | { "ed", no_argument, 0, 'e' }, | ||||
{ "forward-ed", no_argument, 0, 'f' }, | { "forward-ed", no_argument, 0, 'f' }, | ||||
{ "show-function-line", required_argument, 0, 'F' }, | { "show-function-line", required_argument, 0, 'F' }, | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | main(int argc, char **argv) | ||||
oargv = argv; | oargv = argv; | ||||
gotstdin = 0; | gotstdin = 0; | ||||
dflags = 0; | dflags = 0; | ||||
lastch = '\0'; | lastch = '\0'; | ||||
prevoptind = 1; | prevoptind = 1; | ||||
newarg = 1; | newarg = 1; | ||||
diff_context = 3; | diff_context = 3; | ||||
diff_format = D_UNSET; | diff_format = D_UNSET; | ||||
diff_algorithm = D_DIFFMYERS; | |||||
#define FORMAT_MISMATCHED(type) \ | #define FORMAT_MISMATCHED(type) \ | ||||
(diff_format != D_UNSET && diff_format != (type)) | (diff_format != D_UNSET && diff_format != (type)) | ||||
while ((ch = getopt_long(argc, argv, OPTIONS, longopts, NULL)) != -1) { | while ((ch = getopt_long(argc, argv, OPTIONS, longopts, NULL)) != -1) { | ||||
switch (ch) { | switch (ch) { | ||||
case '0': case '1': case '2': case '3': case '4': | case '0': case '1': case '2': case '3': case '4': | ||||
case '5': case '6': case '7': case '8': case '9': | case '5': case '6': case '7': case '8': case '9': | ||||
if (newarg) | if (newarg) | ||||
usage(); /* disallow -[0-9]+ */ | usage(); /* disallow -[0-9]+ */ | ||||
else if (lastch == 'c' || lastch == 'u') | else if (lastch == 'c' || lastch == 'u') | ||||
diff_context = 0; | diff_context = 0; | ||||
else if (!isdigit(lastch) || diff_context > INT_MAX / 10) | else if (!isdigit(lastch) || diff_context > INT_MAX / 10) | ||||
usage(); | usage(); | ||||
diff_context = (diff_context * 10) + (ch - '0'); | diff_context = (diff_context * 10) + (ch - '0'); | ||||
break; | |||||
case 'A': | |||||
algorithm_set = true; | |||||
diff_algorithm = D_DIFFNONE; | |||||
for (struct algorithm *a = algorithms; a->name;a++) { | |||||
if(strcasecmp(optarg, a->name) == 0) { | |||||
diff_algorithm = a->id; | |||||
break; | |||||
} | |||||
} | |||||
if (diff_algorithm == D_DIFFNONE) { | |||||
printf("unknown algorithm: %s\n", optarg); | |||||
usage(); | |||||
} | |||||
break; | break; | ||||
case 'a': | case 'a': | ||||
dflags |= D_FORCEASCII; | dflags |= D_FORCEASCII; | ||||
break; | break; | ||||
case 'b': | case 'b': | ||||
dflags |= D_FOLDBLANKS; | dflags |= D_FOLDBLANKS; | ||||
break; | break; | ||||
case 'C': | case 'C': | ||||
▲ Show 20 Lines • Show All 495 Lines • Show Last 20 Lines |