Merge branch 'jc/grep' into next

* jc/grep:
  builtin-grep: tighten argument parsing.
This commit is contained in:
Junio C Hamano 2006-05-09 13:05:53 -07:00
commit 07c747ee18

View File

@ -494,20 +494,30 @@ static const char builtin_grep_usage[] =
int cmd_grep(int argc, const char **argv, char **envp) int cmd_grep(int argc, const char **argv, char **envp)
{ {
int hit = 0; int hit = 0;
int no_more_flags = 0;
int cached = 0; int cached = 0;
int seen_dashdash = 0;
struct grep_opt opt; struct grep_opt opt;
struct object_list *list, **tail, *object_list = NULL; struct object_list *list, **tail, *object_list = NULL;
const char *prefix = setup_git_directory(); const char *prefix = setup_git_directory();
const char **paths = NULL; const char **paths = NULL;
int i;
memset(&opt, 0, sizeof(opt)); memset(&opt, 0, sizeof(opt));
opt.pattern_tail = &opt.pattern_list; opt.pattern_tail = &opt.pattern_list;
opt.regflags = REG_NEWLINE; opt.regflags = REG_NEWLINE;
/* /*
* No point using rev_info, really. * If there is no -- then the paths must exist in the working
* tree. If there is no explicit pattern specified with -e or
* -f, we take the first unrecognized non option to be the
* pattern, but then what follows it must be zero or more
* valid refs up to the -- (if exists), and then existing
* paths. If there is an explicit pattern, then the first
* unrecocnized non option is the beginning of the refs list
* that continues up to the -- (if exists), and then paths.
*/ */
tail = &object_list;
while (1 < argc) { while (1 < argc) {
const char *arg = argv[1]; const char *arg = argv[1];
argc--; argv++; argc--; argv++;
@ -618,7 +628,7 @@ int cmd_grep(int argc, const char **argv, char **envp)
usage(builtin_grep_usage); usage(builtin_grep_usage);
patterns = fopen(argv[1], "r"); patterns = fopen(argv[1], "r");
if (!patterns) if (!patterns)
die("'%s': %s", strerror(errno)); die("'%s': %s", argv[1], strerror(errno));
while (fgets(buf, sizeof(buf), patterns)) { while (fgets(buf, sizeof(buf), patterns)) {
int len = strlen(buf); int len = strlen(buf);
if (buf[len-1] == '\n') if (buf[len-1] == '\n')
@ -642,47 +652,61 @@ int cmd_grep(int argc, const char **argv, char **envp)
} }
usage(builtin_grep_usage); usage(builtin_grep_usage);
} }
if (!strcmp("--", arg)) { if (!strcmp("--", arg))
no_more_flags = 1; break;
continue; if (*arg == '-')
}
/* Either unrecognized option or a single pattern */
if (!no_more_flags && *arg == '-')
usage(builtin_grep_usage); usage(builtin_grep_usage);
/* First unrecognized non-option token */
if (!opt.pattern_list) { if (!opt.pattern_list) {
add_pattern(&opt, arg, "command line", 0); add_pattern(&opt, arg, "command line", 0);
break; break;
} }
else { else {
/* We are looking at the first path or rev; /* We are looking at the first path or rev;
* it is found at argv[0] after leaving the * it is found at argv[1] after leaving the
* loop. * loop.
*/ */
argc++; argv--; argc++; argv--;
break; break;
} }
} }
if (!opt.pattern_list) if (!opt.pattern_list)
die("no pattern given."); die("no pattern given.");
compile_patterns(&opt); compile_patterns(&opt);
tail = &object_list;
while (1 < argc) { /* Check revs and then paths */
struct object *object; for (i = 1; i < argc; i++) {
struct object_list *elem; const char *arg = argv[i];
const char *arg = argv[1];
unsigned char sha1[20]; unsigned char sha1[20];
if (get_sha1(arg, sha1) < 0) /* Is it a rev? */
break; if (!get_sha1(arg, sha1)) {
object = parse_object(sha1); struct object *object = parse_object(sha1);
struct object_list *elem;
if (!object) if (!object)
die("bad object %s", arg); die("bad object %s", arg);
elem = object_list_insert(object, tail); elem = object_list_insert(object, tail);
elem->name = arg; elem->name = arg;
tail = &elem->next; tail = &elem->next;
argc--; argv++; continue;
} }
if (1 < argc) if (!strcmp(arg, "--")) {
paths = get_pathspec(prefix, argv + 1); i++;
seen_dashdash = 1;
}
break;
}
/* The rest are paths */
if (!seen_dashdash) {
int j;
for (j = i; j < argc; i++)
verify_filename(prefix, argv[j]);
}
if (i < argc)
paths = get_pathspec(prefix, argv + i);
else if (prefix) { else if (prefix) {
paths = xcalloc(2, sizeof(const char *)); paths = xcalloc(2, sizeof(const char *));
paths[0] = prefix; paths[0] = prefix;