/* GNU DIFF main routine. Copyright (C) 1988, 1989, 1992, 1993, 1994 Free Software Foundation, Inc. This file is part of GNU DIFF. GNU DIFF is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version. GNU DIFF is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details. You should have received a copy of the GNU General Public Licensealong with GNU DIFF; see the file COPYING. If not, write tothe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* GNU DIFF was written by Mike Haertel, David Hayes, Richard Stallman, Len Tower, and Paul Eggert. */ /* $FreeBSD: src/contrib/diff/diff.c,v 1.3 1999/11/26 02:51:44 obrien Exp $ */ #define GDIFF_MAIN#include "diff.h"#include <signal.h>#include "getopt.h"#ifdef __FreeBSD__#include <locale.h>#include <fnmatch.h>#else#include "fnmatch.h"#endif#include "prepend_args.h" #ifndef DEFAULT_WIDTH#define DEFAULT_WIDTH 130#endif #ifndef GUTTER_WIDTH_MINIMUM#define GUTTER_WIDTH_MINIMUM 3#endif static char const *filetype PARAMS((struct stat const *));static char *option_list PARAMS((char **, int));static int add_exclude_file PARAMS((char const *));static int ck_atoi PARAMS((char const *, int *));static int compare_files PARAMS((char const *, char const *, char const *, char const *, int));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 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. */ static int recursive; /* For debugging: don't do discard_confusing_lines. */ 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. If there were no options, the result is an empty string. Arguments: OPTIONVEC, a vector containing separate ARGV-elements, and COUNT, the length of that vector. */ static char *option_list (optionvec, count) char **optionvec; /* Was `vector', but that collides on Alliant. */ int count;{ int i; size_t length = 0; char *result; for (i = 0; i < count; i++) length += strlen (optionvec[i]) + 1; result = xmalloc (length + 1); result[0] = 0; for (i = 0; i < count; i++) { strcat (result, " "); strcat (result, optionvec[i]); } return result;}/* Convert STR to a positive integer, storing the result in *OUT. If STR is not a valid integer, return -1 (otherwise 0). */static intck_atoi (str, out) char const *str; int *out;{ char const *p; for (p = str; *p; p++) if (*p < '0' || *p > '9') return -1; *out = atoi (optarg); return 0;}/* Keep track of excluded file name patterns. */ static char const **exclude;static int exclude_alloc, exclude_count; intexcluded_filename (f) char const *f;{ int i; for (i = 0; i < exclude_count; i++) if (fnmatch (exclude[i], f, 0) == 0) return 1; return 0;} static voidadd_exclude (pattern) char const *pattern;{ if (exclude_alloc <= exclude_count) exclude = (char const **) (exclude_alloc == 0 ? xmalloc ((exclude_alloc = 64) * sizeof (*exclude)) : xrealloc (exclude, (exclude_alloc *= 2) * sizeof (*exclude))); exclude[exclude_count++] = pattern;} static intadd_exclude_file (name) char const *name;{ struct file_data f; char *p, *q, *lim; f.name = optarg; f.desc = (strcmp (name, "-") == 0 ? STDIN_FILENO : open (name, O_RDONLY, 0)); if (f.desc < 0 || fstat (f.desc, &f.stat) != 0) return -1; sip (&f, 1); slurp (&f); for (p = f.buffer, lim = p + f.buffered_chars; p < lim; p = q) { q = (char *) memchr (p, '\n', lim - p); if (!q) q = lim; *q++ = 0; add_exclude (p); } return close (f.desc);}/* The numbers 129- that appear in the fourth element of some entries tell the big switch in `main' how to process those options. */ static struct option const longopts[] ={ {"ignore-blank-lines", 0, 0, 'B'}, {"context", 2, 0, 'C'}, {"ifdef", 1, 0, 'D'}, {"show-function-line", 1, 0, 'F'}, {"speed-large-files", 0, 0, 'H'}, {"ignore-matching-lines", 1, 0, 'I'}, {"label", 1, 0, 'L'}, {"file-label", 1, 0, 'L'}, /* An alias, no longer recommended */ {"new-file", 0, 0, 'N'}, {"entire-new-file", 0, 0, 'N'}, /* An alias, no longer recommended */ {"unidirectional-new-file", 0, 0, 'P'}, {"starting-file", 1, 0, 'S'}, {"initial-tab", 0, 0, 'T'}, {"width", 1, 0, 'W'}, {"text", 0, 0, 'a'}, {"ascii", 0, 0, 'a'}, /* An alias, no longer recommended */ {"ignore-space-change", 0, 0, 'b'}, {"minimal", 0, 0, 'd'}, {"ed", 0, 0, 'e'}, {"forward-ed", 0, 0, 'f'}, {"ignore-case", 0, 0, 'i'}, {"paginate", 0, 0, 'l'}, {"print", 0, 0, 'l'}, /* An alias, no longer recommended */ {"rcs", 0, 0, 'n'}, {"show-c-function", 0, 0, 'p'}, {"brief", 0, 0, 'q'}, {"recursive", 0, 0, 'r'}, {"report-identical-files", 0, 0, 's'}, {"expand-tabs", 0, 0, 't'}, {"version", 0, 0, 'v'}, {"ignore-all-space", 0, 0, 'w'}, {"exclude", 1, 0, 'x'}, {"exclude-from", 1, 0, 'X'}, {"side-by-side", 0, 0, 'y'}, {"unified", 2, 0, 'U'}, {"left-column", 0, 0, 129}, {"suppress-common-lines", 0, 0, 130}, {"sdiff-merge-assist", 0, 0, 131}, {"old-line-format", 1, 0, 132}, {"new-line-format", 1, 0, 133}, {"unchanged-line-format", 1, 0, 134}, {"line-format", 1, 0, 135}, {"old-group-format", 1, 0, 136}, {"new-group-format", 1, 0, 137}, {"unchanged-group-format", 1, 0, 138}, {"changed-group-format", 1, 0, 139}, {"horizon-lines", 1, 0, 140}, {"help", 0, 0, 141}, {"binary", 0, 0, 142}, {0, 0, 0, 0}}; intmain (argc, argv) int argc; char *argv[];{ int val; int c; int prev = -1; int width = DEFAULT_WIDTH; int show_c_function = 0; #ifdef __FreeBSD__ setlocale(LC_ALL, "");#endif /* Do our initializations. */ initialize_main (&argc, &argv); program_name = argv[0]; output_style = OUTPUT_NORMAL; context = -1; prepend_default_options (getenv ("DIFF_OPTIONS"), &argc, &argv); /* Decode the options. */ while ((c = getopt_long (argc, argv, "0123456789abBcC:dD:efF:hHiI:lL:nNopPqrsS:tTuU:vwW:x:X:y", longopts, 0)) != EOF) { switch (c) { /* All digits combine in decimal to specify the context-size. */ case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '0': if (context == -1) context = 0; /* If a context length has already been specified, more digits allowed only if they follow right after the others. Reject two separate runs of digits, or digits after -C. */ else if (prev < '0' || prev > '9') fatal ("context length specified twice"); context = context * 10 + c - '0'; break; case 'a': /* Treat all files as text files; never treat as binary. */ always_text_flag = 1; break; case 'b': /* Ignore changes in amount of white space. */ ignore_space_change_flag = 1; ignore_some_changes = 1; ignore_some_line_changes = 1; break; case 'B': /* Ignore changes affecting only blank lines. */ ignore_blank_lines_flag = 1; ignore_some_changes = 1; break; case 'C': /* +context[=lines] */ case 'U': /* +unified[=lines] */ if (optarg) { if (context >= 0) fatal ("context length specified twice"); if (ck_atoi (optarg, &context)) fatal ("invalid context length argument"); } /* Falls through. */ case 'c': /* Make context-style output. */ specify_style (c == 'U' ? OUTPUT_UNIFIED : OUTPUT_CONTEXT); break; case 'd': /* Don't discard lines. This makes things slower (sometimes much slower) but will find a guaranteed minimal set of changes. */ no_discards = 1; break; case 'D': /* Make merged #ifdef output. */ specify_style (OUTPUT_IFDEF); { int i, err = 0; static char const C_ifdef_group_formats[] = "#ifndef %s\n%%<#endif /* not %s */\n%c#ifdef %s\n%%>#endif /* %s */\n%c%%=%c#ifndef %s\n%%<#else /* %s */\n%%>#endif /* %s */\n"; char *b = xmalloc (sizeof (C_ifdef_group_formats) + 7 * strlen(optarg) - 14 /* 7*"%s" */ - 8 /* 5*"%%" + 3*"%c" */); sprintf (b, C_ifdef_group_formats, optarg, optarg, 0, optarg, optarg, 0, 0, optarg, optarg, optarg); for (i = 0; i < 4; i++) { err |= specify_format (&group_format[i], b); b += strlen (b) + 1; } if (err) error ("conflicting #ifdef formats", 0, 0); } break; case 'e': /* Make output that is a valid `ed' script. */ specify_style (OUTPUT_ED); break; case 'f': /* Make output that looks vaguely like an `ed' script but has changes in the order they appear in the file. */ specify_style (OUTPUT_FORWARD_ED); break; case 'F': /* Show, for each set of changes, the previous line that matches the specified regexp. Currently affects only context-style output. */ add_regexp (&function_regexp_list, optarg); break; case 'h': /* Split the files into chunks of around 1500 lines for faster processing. Usually does not change the result. This currently has no effect. */ break; case 'H': /* Turn on heuristics that speed processing of large files with a small density of changes. */ heuristic = 1; break; case 'i': /* Ignore changes in case. */ ignore_case_flag = 1; ignore_some_changes = 1; ignore_some_line_changes = 1; break; case 'I': /* Ignore changes affecting only lines that match the specified regexp. */ add_regexp (&ignore_regexp_list, optarg); ignore_some_changes = 1; break; 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': /* Specify file labels for `-c' output headers. */ if (!file_label[0]) file_label[0] = optarg; else if (!file_label[1]) file_label[1] = optarg; else fatal ("too many file label options"); break; case 'n': /* Output RCS-style diffs, like `-f' except that each command specifies the number of lines affected. */ specify_style (OUTPUT_RCS); break; case 'N': /* When comparing directories, if a file appears only in one directory, treat it as present but empty in the other. */ entire_new_file_flag = 1; break; case 'o': /* Output in the old tradition style. */ specify_style (OUTPUT_NORMAL); break; case 'p': /* Make context-style output and show name of last C function. */ show_c_function = 1; add_regexp (&function_regexp_list, "^[_a-zA-Z$]"); break; case 'P': /* When comparing directories, if a file appears only in the second directory of the two, treat it as present but empty in the other. */ unidirectional_new_file_flag = 1; break; case 'q': no_details_flag = 1; break; case 'r': /* When comparing directories, recursively compare any subdirectories found. */ recursive = 1; break; case 's': /* Print a message if the files are the same. */ print_file_same_flag = 1; break; case 'S': /* When comparing directories, start with the specified file name. This is used for resuming an aborted comparison. */ dir_start_file = optarg; break; case 't': /* Expand tabs to spaces in the output so that it preserves the alignment of the input files. */ tab_expand_flag = 1; break; case 'T': /* Use a tab in the output, rather than a space, before the text of an input line, so as to keep the proper alignment in the input line without changing the characters in it. */ tab_align_flag = 1; break; case 'u': /* Output the context diff in unidiff format. */ specify_style (OUTPUT_UNIFIED); break; case 'v': 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; ignore_some_line_changes = 1; break; case 'x':Lines 1–500 of 1124. Load more
/* GNU DIFF main routine. Copyright (C) 1988, 1989, 1992, 1993, 1994 Free Software Foundation, Inc. This file is part of GNU DIFF. GNU DIFF is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. GNU DIFF is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU DIFF; see the file COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ /* GNU DIFF was written by Mike Haertel, David Hayes, Richard Stallman, Len Tower, and Paul Eggert. */ /* $FreeBSD: src/contrib/diff/diff.c,v 1.3 1999/11/26 02:51:44 obrien Exp $ */ #define GDIFF_MAIN #include "diff.h" #include <signal.h> #include "getopt.h" #ifdef __FreeBSD__ #include <locale.h> #include <fnmatch.h> #else #include "fnmatch.h" #endif #include "prepend_args.h" #ifndef DEFAULT_WIDTH #define DEFAULT_WIDTH 130 #endif #ifndef GUTTER_WIDTH_MINIMUM #define GUTTER_WIDTH_MINIMUM 3 #endif static char const *filetype PARAMS((struct stat const *)); static char *option_list PARAMS((char **, int)); static int add_exclude_file PARAMS((char const *)); static int ck_atoi PARAMS((char const *, int *)); static int compare_files PARAMS((char const *, char const *, char const *, char const *, int)); 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 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. */ static int recursive; /* For debugging: don't do discard_confusing_lines. */ 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. If there were no options, the result is an empty string. Arguments: OPTIONVEC, a vector containing separate ARGV-elements, and COUNT, the length of that vector. */ static char * option_list (optionvec, count) char **optionvec; /* Was `vector', but that collides on Alliant. */ int count; { int i; size_t length = 0; char *result; for (i = 0; i < count; i++) length += strlen (optionvec[i]) + 1; result = xmalloc (length + 1); result[0] = 0; for (i = 0; i < count; i++) { strcat (result, " "); strcat (result, optionvec[i]); } return result; } /* Convert STR to a positive integer, storing the result in *OUT. If STR is not a valid integer, return -1 (otherwise 0). */ static int ck_atoi (str, out) char const *str; int *out; { char const *p; for (p = str; *p; p++) if (*p < '0' || *p > '9') return -1; *out = atoi (optarg); return 0; } /* Keep track of excluded file name patterns. */ static char const **exclude; static int exclude_alloc, exclude_count; int excluded_filename (f) char const *f; { int i; for (i = 0; i < exclude_count; i++) if (fnmatch (exclude[i], f, 0) == 0) return 1; return 0; } static void add_exclude (pattern) char const *pattern; { if (exclude_alloc <= exclude_count) exclude = (char const **) (exclude_alloc == 0 ? xmalloc ((exclude_alloc = 64) * sizeof (*exclude)) : xrealloc (exclude, (exclude_alloc *= 2) * sizeof (*exclude))); exclude[exclude_count++] = pattern; } static int add_exclude_file (name) char const *name; { struct file_data f; char *p, *q, *lim; f.name = optarg; f.desc = (strcmp (name, "-") == 0 ? STDIN_FILENO : open (name, O_RDONLY, 0)); if (f.desc < 0 || fstat (f.desc, &f.stat) != 0) return -1; sip (&f, 1); slurp (&f); for (p = f.buffer, lim = p + f.buffered_chars; p < lim; p = q) { q = (char *) memchr (p, '\n', lim - p); if (!q) q = lim; *q++ = 0; add_exclude (p); } return close (f.desc); } /* The numbers 129- that appear in the fourth element of some entries tell the big switch in `main' how to process those options. */ static struct option const longopts[] = { {"ignore-blank-lines", 0, 0, 'B'}, {"context", 2, 0, 'C'}, {"ifdef", 1, 0, 'D'}, {"show-function-line", 1, 0, 'F'}, {"speed-large-files", 0, 0, 'H'}, {"ignore-matching-lines", 1, 0, 'I'}, {"label", 1, 0, 'L'}, {"file-label", 1, 0, 'L'}, /* An alias, no longer recommended */ {"new-file", 0, 0, 'N'}, {"entire-new-file", 0, 0, 'N'}, /* An alias, no longer recommended */ {"unidirectional-new-file", 0, 0, 'P'}, {"starting-file", 1, 0, 'S'}, {"initial-tab", 0, 0, 'T'}, {"width", 1, 0, 'W'}, {"text", 0, 0, 'a'}, {"ascii", 0, 0, 'a'}, /* An alias, no longer recommended */ {"ignore-space-change", 0, 0, 'b'}, {"minimal", 0, 0, 'd'}, {"ed", 0, 0, 'e'}, {"forward-ed", 0, 0, 'f'}, {"ignore-case", 0, 0, 'i'}, {"paginate", 0, 0, 'l'}, {"print", 0, 0, 'l'}, /* An alias, no longer recommended */ {"rcs", 0, 0, 'n'}, {"show-c-function", 0, 0, 'p'}, {"brief", 0, 0, 'q'}, {"recursive", 0, 0, 'r'}, {"report-identical-files", 0, 0, 's'}, {"expand-tabs", 0, 0, 't'}, {"version", 0, 0, 'v'}, {"ignore-all-space", 0, 0, 'w'}, {"exclude", 1, 0, 'x'}, {"exclude-from", 1, 0, 'X'}, {"side-by-side", 0, 0, 'y'}, {"unified", 2, 0, 'U'}, {"left-column", 0, 0, 129}, {"suppress-common-lines", 0, 0, 130}, {"sdiff-merge-assist", 0, 0, 131}, {"old-line-format", 1, 0, 132}, {"new-line-format", 1, 0, 133}, {"unchanged-line-format", 1, 0, 134}, {"line-format", 1, 0, 135}, {"old-group-format", 1, 0, 136}, {"new-group-format", 1, 0, 137}, {"unchanged-group-format", 1, 0, 138}, {"changed-group-format", 1, 0, 139}, {"horizon-lines", 1, 0, 140}, {"help", 0, 0, 141}, {"binary", 0, 0, 142}, {0, 0, 0, 0} }; int main (argc, argv) int argc; char *argv[]; { int val; int c; int prev = -1; int width = DEFAULT_WIDTH; int show_c_function = 0; #ifdef __FreeBSD__ setlocale(LC_ALL, ""); #endif /* Do our initializations. */ initialize_main (&argc, &argv); program_name = argv[0]; output_style = OUTPUT_NORMAL; context = -1; prepend_default_options (getenv ("DIFF_OPTIONS"), &argc, &argv); /* Decode the options. */ while ((c = getopt_long (argc, argv, "0123456789abBcC:dD:efF:hHiI:lL:nNopPqrsS:tTuU:vwW:x:X:y", longopts, 0)) != EOF) { switch (c) { /* All digits combine in decimal to specify the context-size. */ case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '0': if (context == -1) context = 0; /* If a context length has already been specified, more digits allowed only if they follow right after the others. Reject two separate runs of digits, or digits after -C. */ else if (prev < '0' || prev > '9') fatal ("context length specified twice"); context = context * 10 + c - '0'; break; case 'a': /* Treat all files as text files; never treat as binary. */ always_text_flag = 1; break; case 'b': /* Ignore changes in amount of white space. */ ignore_space_change_flag = 1; ignore_some_changes = 1; ignore_some_line_changes = 1; break; case 'B': /* Ignore changes affecting only blank lines. */ ignore_blank_lines_flag = 1; ignore_some_changes = 1; break; case 'C': /* +context[=lines] */ case 'U': /* +unified[=lines] */ if (optarg) { if (context >= 0) fatal ("context length specified twice"); if (ck_atoi (optarg, &context)) fatal ("invalid context length argument"); } /* Falls through. */ case 'c': /* Make context-style output. */ specify_style (c == 'U' ? OUTPUT_UNIFIED : OUTPUT_CONTEXT); break; case 'd': /* Don't discard lines. This makes things slower (sometimes much slower) but will find a guaranteed minimal set of changes. */ no_discards = 1; break; case 'D': /* Make merged #ifdef output. */ specify_style (OUTPUT_IFDEF); { int i, err = 0; static char const C_ifdef_group_formats[] = "#ifndef %s\n%%<#endif /* not %s */\n%c#ifdef %s\n%%>#endif /* %s */\n%c%%=%c#ifndef %s\n%%<#else /* %s */\n%%>#endif /* %s */\n"; char *b = xmalloc (sizeof (C_ifdef_group_formats) + 7 * strlen(optarg) - 14 /* 7*"%s" */ - 8 /* 5*"%%" + 3*"%c" */); sprintf (b, C_ifdef_group_formats, optarg, optarg, 0, optarg, optarg, 0, 0, optarg, optarg, optarg); for (i = 0; i < 4; i++) { err |= specify_format (&group_format[i], b); b += strlen (b) + 1; } if (err) error ("conflicting #ifdef formats", 0, 0); } break; case 'e': /* Make output that is a valid `ed' script. */ specify_style (OUTPUT_ED); break; case 'f': /* Make output that looks vaguely like an `ed' script but has changes in the order they appear in the file. */ specify_style (OUTPUT_FORWARD_ED); break; case 'F': /* Show, for each set of changes, the previous line that matches the specified regexp. Currently affects only context-style output. */ add_regexp (&function_regexp_list, optarg); break; case 'h': /* Split the files into chunks of around 1500 lines for faster processing. Usually does not change the result. This currently has no effect. */ break; case 'H': /* Turn on heuristics that speed processing of large files with a small density of changes. */ heuristic = 1; break; case 'i': /* Ignore changes in case. */ ignore_case_flag = 1; ignore_some_changes = 1; ignore_some_line_changes = 1; break; case 'I': /* Ignore changes affecting only lines that match the specified regexp. */ add_regexp (&ignore_regexp_list, optarg); ignore_some_changes = 1; break; 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': /* Specify file labels for `-c' output headers. */ if (!file_label[0]) file_label[0] = optarg; else if (!file_label[1]) file_label[1] = optarg; else fatal ("too many file label options"); break; case 'n': /* Output RCS-style diffs, like `-f' except that each command specifies the number of lines affected. */ specify_style (OUTPUT_RCS); break; case 'N': /* When comparing directories, if a file appears only in one directory, treat it as present but empty in the other. */ entire_new_file_flag = 1; break; case 'o': /* Output in the old tradition style. */ specify_style (OUTPUT_NORMAL); break; case 'p': /* Make context-style output and show name of last C function. */ show_c_function = 1; add_regexp (&function_regexp_list, "^[_a-zA-Z$]"); break; case 'P': /* When comparing directories, if a file appears only in the second directory of the two, treat it as present but empty in the other. */ unidirectional_new_file_flag = 1; break; case 'q': no_details_flag = 1; break; case 'r': /* When comparing directories, recursively compare any subdirectories found. */ recursive = 1; break; case 's': /* Print a message if the files are the same. */ print_file_same_flag = 1; break; case 'S': /* When comparing directories, start with the specified file name. This is used for resuming an aborted comparison. */ dir_start_file = optarg; break; case 't': /* Expand tabs to spaces in the output so that it preserves the alignment of the input files. */ tab_expand_flag = 1; break; case 'T': /* Use a tab in the output, rather than a space, before the text of an input line, so as to keep the proper alignment in the input line without changing the characters in it. */ tab_align_flag = 1; break; case 'u': /* Output the context diff in unidiff format. */ specify_style (OUTPUT_UNIFIED); break; case 'v': 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; ignore_some_line_changes = 1; break; case 'x':