commit - d136cfcb987bd2fd865f8711449dc47b7f63455f
commit + 13add98862efe69781a0693d9af2c45d235f1f43
blob - aad8017a1963e96977883c2dadfcef0fce8eac58
blob + 082650a7623054ef35d2d467e3d678240ee3ddf3
--- tog/tog.c
+++ tog/tog.c
struct got_repository *repo;
int log_complete;
sig_atomic_t *quit;
- struct tog_view *view;
struct commit_queue_entry **first_displayed_entry;
struct commit_queue_entry **selected_entry;
+ int *searching;
+ int *search_next_done;
+ regex_t *regex;
};
struct tog_log_view_state {
}
static const struct got_error *
+match_commit(int *have_match, struct got_object_id *id,
+ struct got_commit_object *commit, regex_t *regex)
+{
+ const struct got_error *err = NULL;
+ regmatch_t regmatch;
+ char *id_str = NULL, *logmsg = NULL;
+
+ *have_match = 0;
+
+ err = got_object_id_str(&id_str, id);
+ if (err)
+ return err;
+
+ err = got_object_commit_get_logmsg(&logmsg, commit);
+ if (err)
+ goto done;
+
+ if (regexec(regex, got_object_commit_get_author(commit), 1,
+ ®match, 0) == 0 ||
+ regexec(regex, got_object_commit_get_committer(commit), 1,
+ ®match, 0) == 0 ||
+ regexec(regex, id_str, 1, ®match, 0) == 0 ||
+ regexec(regex, logmsg, 1, ®match, 0) == 0)
+ *have_match = 1;
+done:
+ free(id_str);
+ free(logmsg);
+ return err;
+}
+
+static const struct got_error *
queue_commits(struct got_commit_graph *graph, struct commit_queue *commits,
- int minqueue, struct got_repository *repo, const char *path)
+ int minqueue, struct got_repository *repo, const char *path,
+ int *searching, int *search_next_done, regex_t *regex)
{
const struct got_error *err = NULL;
- int nqueued = 0;
+ int nqueued = 0, have_match = 0;
/*
* We keep all commits open throughout the lifetime of the log
* view in order to avoid having to re-fetch commits from disk
* while updating the display.
*/
- while (nqueued < minqueue) {
+ while (nqueued < minqueue ||
+ (*searching == TOG_SEARCH_FORWARD && !*search_next_done)) {
struct got_object_id *id;
struct got_commit_object *commit;
struct commit_queue_entry *entry;
errcode = pthread_mutex_lock(&tog_mutex);
if (errcode) {
- err = got_error_set_errno(errcode, "pthread_mutex_lock");
+ err = got_error_set_errno(errcode,
+ "pthread_mutex_lock");
break;
}
nqueued++;
commits->ncommits++;
+ if (*searching == TOG_SEARCH_FORWARD && !*search_next_done) {
+ err = match_commit(&have_match, id, commit, regex);
+ if (err) {
+ pthread_mutex_lock(&tog_mutex);
+ break;
+ }
+ }
+
errcode = pthread_mutex_unlock(&tog_mutex);
if (errcode && err == NULL)
err = got_error_set_errno(errcode,
"pthread_mutex_unlock");
+
+ if (have_match)
+ break;
}
return err;
while (!done && !err && !tog_sigpipe_received) {
err = queue_commits(a->graph, a->commits, 1, a->repo,
- a->in_repo_path);
+ a->in_repo_path, a->searching, a->search_next_done,
+ a->regex);
if (err) {
if (err->code != GOT_ERR_ITER_COMPLETED)
return (void *)err;
return NULL;
}
-static int
-match_commit(struct got_commit_object *commit, const char *id_str,
- const char *logmsg, regex_t *regex)
-{
- regmatch_t regmatch;
-
- if (regexec(regex, got_object_commit_get_author(commit), 1,
- ®match, 0) == 0 ||
- regexec(regex, got_object_commit_get_committer(commit), 1,
- ®match, 0) == 0 ||
- regexec(regex, id_str, 1, ®match, 0) == 0 ||
- regexec(regex, logmsg, 1, ®match, 0) == 0)
- return 1;
-
- return 0;
-}
-
static const struct got_error *
search_next_log_view(struct tog_view *view)
{
}
if (s->search_entry) {
- if (wgetch(view->window) == KEY_BACKSPACE) {
+ int errcode, ch;
+ errcode = pthread_mutex_unlock(&tog_mutex);
+ if (errcode)
+ return got_error_set_errno(errcode,
+ "pthread_mutex_unlock");
+ ch = wgetch(view->window);
+ errcode = pthread_mutex_lock(&tog_mutex);
+ if (errcode)
+ return got_error_set_errno(errcode,
+ "pthread_mutex_lock");
+ if (ch == KEY_BACKSPACE) {
view->search_next_done = 1;
return NULL;
}
}
while (1) {
- char *id_str, *logmsg;
+ int have_match = 0;
+
if (entry == NULL) {
if (s->thread_args.log_complete ||
view->searching == TOG_SEARCH_BACKWARD) {
&s->thread_args.need_commits);
}
- err = got_object_id_str(&id_str, entry->id);
- if (err)
- return err;
-
- err = got_object_commit_get_logmsg(&logmsg, entry->commit);
+ err = match_commit(&have_match, entry->id, entry->commit,
+ &view->regex);
if (err)
- return err;
- if (match_commit(entry->commit, id_str, logmsg, &view->regex)) {
- free(logmsg);
+ break;
+ if (have_match) {
view->search_next_done = 1;
s->matched_entry = entry;
- free(id_str);
break;
}
- free(logmsg);
- free(id_str);
+
s->search_entry = entry;
if (view->searching == TOG_SEARCH_FORWARD)
entry = TAILQ_NEXT(entry, entry);
s->thread_args.repo = thread_repo;
s->thread_args.log_complete = 0;
s->thread_args.quit = &s->quit;
- s->thread_args.view = view;
s->thread_args.first_displayed_entry = &s->first_displayed_entry;
s->thread_args.selected_entry = &s->selected_entry;
+ s->thread_args.searching = &view->searching;
+ s->thread_args.search_next_done = &view->search_next_done;
+ s->thread_args.regex = &view->regex;
done:
if (err)
close_log_view(view);