interdiff: teach show_interdiff() to indent interdiff
[gitweb.git] / builtin / grep.c
index 1e9cdbdf78ddbd803ba9fa65210fb79ff1e27583..61bcaf6e58d67c8bc66f6d8d260e91e7804caa5b 100644 (file)
@@ -93,8 +93,7 @@ static pthread_cond_t cond_result;
 
 static int skip_first_line;
 
-static void add_work(struct grep_opt *opt, enum grep_source_type type,
-                    const char *name, const char *path, const void *id)
+static void add_work(struct grep_opt *opt, const struct grep_source *gs)
 {
        grep_lock();
 
@@ -102,7 +101,7 @@ static void add_work(struct grep_opt *opt, enum grep_source_type type,
                pthread_cond_wait(&cond_write, &grep_mutex);
        }
 
-       grep_source_init(&todo[todo_end].source, type, name, path, id);
+       todo[todo_end].source = *gs;
        if (opt->binary != GREP_BINARY_TEXT)
                grep_source_load_driver(&todo[todo_end].source);
        todo[todo_end].done = 0;
@@ -308,7 +307,7 @@ static void *lock_and_read_oid_file(const struct object_id *oid, enum object_typ
        void *data;
 
        grep_read_lock();
-       data = read_sha1_file(oid->hash, type, size);
+       data = read_object_file(oid, type, size);
        grep_read_unlock();
        return data;
 }
@@ -318,6 +317,7 @@ static int grep_oid(struct grep_opt *opt, const struct object_id *oid,
                     const char *path)
 {
        struct strbuf pathbuf = STRBUF_INIT;
+       struct grep_source gs;
 
        if (opt->relative && opt->prefix_length) {
                quote_path_relative(filename + tree_name_len, opt->prefix, &pathbuf);
@@ -326,19 +326,22 @@ static int grep_oid(struct grep_opt *opt, const struct object_id *oid,
                strbuf_addstr(&pathbuf, filename);
        }
 
+       grep_source_init(&gs, GREP_SOURCE_OID, pathbuf.buf, path, oid);
+       strbuf_release(&pathbuf);
+
 #ifndef NO_PTHREADS
        if (num_threads) {
-               add_work(opt, GREP_SOURCE_OID, pathbuf.buf, path, oid);
-               strbuf_release(&pathbuf);
+               /*
+                * add_work() copies gs and thus assumes ownership of
+                * its fields, so do not call grep_source_clear()
+                */
+               add_work(opt, &gs);
                return 0;
        } else
 #endif
        {
-               struct grep_source gs;
                int hit;
 
-               grep_source_init(&gs, GREP_SOURCE_OID, pathbuf.buf, path, oid);
-               strbuf_release(&pathbuf);
                hit = grep_source(opt, &gs);
 
                grep_source_clear(&gs);
@@ -349,25 +352,29 @@ static int grep_oid(struct grep_opt *opt, const struct object_id *oid,
 static int grep_file(struct grep_opt *opt, const char *filename)
 {
        struct strbuf buf = STRBUF_INIT;
+       struct grep_source gs;
 
        if (opt->relative && opt->prefix_length)
                quote_path_relative(filename, opt->prefix, &buf);
        else
                strbuf_addstr(&buf, filename);
 
+       grep_source_init(&gs, GREP_SOURCE_FILE, buf.buf, filename, filename);
+       strbuf_release(&buf);
+
 #ifndef NO_PTHREADS
        if (num_threads) {
-               add_work(opt, GREP_SOURCE_FILE, buf.buf, filename, filename);
-               strbuf_release(&buf);
+               /*
+                * add_work() copies gs and thus assumes ownership of
+                * its fields, so do not call grep_source_clear()
+                */
+               add_work(opt, &gs);
                return 0;
        } else
 #endif
        {
-               struct grep_source gs;
                int hit;
 
-               grep_source_init(&gs, GREP_SOURCE_FILE, buf.buf, filename, filename);
-               strbuf_release(&buf);
                hit = grep_source(opt, &gs);
 
                grep_source_clear(&gs);
@@ -446,7 +453,7 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
                object = parse_object_or_die(oid, oid_to_hex(oid));
 
                grep_read_lock();
-               data = read_object_with_reference(object->oid.hash, tree_type,
+               data = read_object_with_reference(&object->oid, tree_type,
                                                  &size, NULL);
                grep_read_unlock();
 
@@ -481,7 +488,8 @@ static int grep_cache(struct grep_opt *opt, struct repository *repo,
                strbuf_addstr(&name, repo->submodule_prefix);
        }
 
-       repo_read_index(repo);
+       if (repo_read_index(repo) < 0)
+               die("index file corrupt");
 
        for (nr = 0; nr < repo->index->cache_nr; nr++) {
                const struct cache_entry *ce = repo->index->cache[nr];
@@ -595,8 +603,7 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
 }
 
 static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
-                      struct object *obj, const char *name, const char *path,
-                      struct repository *repo)
+                      struct object *obj, const char *name, const char *path)
 {
        if (obj->type == OBJ_BLOB)
                return grep_oid(opt, &obj->oid, name, 0, path);
@@ -608,7 +615,7 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
                int hit, len;
 
                grep_read_lock();
-               data = read_object_with_reference(obj->oid.hash, tree_type,
+               data = read_object_with_reference(&obj->oid, tree_type,
                                                  &size, NULL);
                grep_read_unlock();
 
@@ -623,16 +630,15 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
                }
                init_tree_desc(&tree, data, size);
                hit = grep_tree(opt, pathspec, &tree, &base, base.len,
-                               obj->type == OBJ_COMMIT, repo);
+                               obj->type == OBJ_COMMIT, the_repository);
                strbuf_release(&base);
                free(data);
                return hit;
        }
-       die(_("unable to grep from object of type %s"), typename(obj->type));
+       die(_("unable to grep from object of type %s"), type_name(obj->type));
 }
 
 static int grep_objects(struct grep_opt *opt, const struct pathspec *pathspec,
-                       struct repository *repo,
                        const struct object_array *list)
 {
        unsigned int i;
@@ -645,11 +651,11 @@ static int grep_objects(struct grep_opt *opt, const struct pathspec *pathspec,
 
                /* load the gitmodules file for this rev */
                if (recurse_submodules) {
-                       submodule_free();
+                       submodule_free(the_repository);
                        gitmodules_config_oid(&real_obj->oid);
                }
-               if (grep_object(opt, pathspec, real_obj, list->objects[i].name, list->objects[i].path,
-                               repo)) {
+               if (grep_object(opt, pathspec, real_obj, list->objects[i].name,
+                               list->objects[i].path)) {
                        hit = 1;
                        if (opt->status_only)
                                break;
@@ -822,6 +828,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
                            GREP_PATTERN_TYPE_PCRE),
                OPT_GROUP(""),
                OPT_BOOL('n', "line-number", &opt.linenum, N_("show line numbers")),
+               OPT_BOOL(0, "column", &opt.columnnum, N_("show column number of first match")),
                OPT_NEGBIT('h', NULL, &opt.pathname, N_("don't show filenames"), 1),
                OPT_BIT('H', NULL, &opt.pathname, N_("show filenames"), 1),
                OPT_NEGBIT(0, "full-name", &opt.relative,
@@ -833,8 +840,9 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
                OPT_BOOL('L', "files-without-match",
                        &opt.unmatch_name_only,
                        N_("show only the names of files without match")),
-               OPT_BOOL('z', "null", &opt.null_following_name,
-                       N_("print NUL after filenames")),
+               OPT_BOOL_F('z', "null", &opt.null_following_name,
+                          N_("print NUL after filenames"),
+                          PARSE_OPT_NOCOMPLETE),
                OPT_BOOL('c', "count", &opt.count,
                        N_("show the number of matches instead of matching lines")),
                OPT__COLOR(&opt.color, N_("highlight matches")),
@@ -879,15 +887,17 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
                           N_("indicate hit with exit status without output")),
                OPT_BOOL(0, "all-match", &opt.all_match,
                        N_("show only matches from files that match all patterns")),
-               { OPTION_SET_INT, 0, "debug", &opt.debug, NULL,
-                 N_("show parse tree for grep expression"),
-                 PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, 1 },
+               OPT_SET_INT_F(0, "debug", &opt.debug,
+                             N_("show parse tree for grep expression"),
+                             1, PARSE_OPT_HIDDEN),
                OPT_GROUP(""),
                { OPTION_STRING, 'O', "open-files-in-pager", &show_in_pager,
                        N_("pager"), N_("show matching files in the pager"),
-                       PARSE_OPT_OPTARG, NULL, (intptr_t)default_pager },
-               OPT_BOOL(0, "ext-grep", &external_grep_allowed__ignored,
-                        N_("allow calling of grep(1) (ignored by this build)")),
+                       PARSE_OPT_OPTARG | PARSE_OPT_NOCOMPLETE,
+                       NULL, (intptr_t)default_pager },
+               OPT_BOOL_F(0, "ext-grep", &external_grep_allowed__ignored,
+                          N_("allow calling of grep(1) (ignored by this build)"),
+                          PARSE_OPT_NOCOMPLETE),
                OPT_END()
        };
 
@@ -1098,7 +1108,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
                if (cached)
                        die(_("both --cached and trees are given."));
 
-               hit = grep_objects(&opt, &pathspec, the_repository, &list);
+               hit = grep_objects(&opt, &pathspec, &list);
        }
 
        if (num_threads)