X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=tig.c;h=77e1d8183372669bc1fed7fda0cbb97ada649417;hb=bb46d935db3f3548bbe2d411f58588943058148c;hp=bfa88e8c4650bd68d33909ec7797861ff4ff3404;hpb=9d7281d114548bf491d00c9aa207f280b9e658e2;p=tig.git diff --git a/tig.c b/tig.c index bfa88e8..77e1d81 100644 --- a/tig.c +++ b/tig.c @@ -140,13 +140,6 @@ static struct ref_list *get_ref_list(const char *id); static void foreach_ref(bool (*visitor)(void *data, const struct ref *ref), void *data); static int load_refs(void); -enum format_flags { - FORMAT_ALL, /* Perform replacement in all arguments. */ - FORMAT_NONE /* No replacement should be performed. */ -}; - -static bool format_argv(const char *dst[], const char *src[], enum format_flags flags); - enum input_status { INPUT_OK, INPUT_SKIP, @@ -688,13 +681,15 @@ argv_free(const char *argv[]) argv[0] = NULL; } -static void +static bool argv_copy(const char *dst[], const char *src[]) { int argc; for (argc = 0; src[argc]; argc++) - dst[argc] = src[argc]; + if (!(dst[argc] = strdup(src[argc]))) + return FALSE; + return TRUE; } @@ -712,12 +707,9 @@ enum io_type { }; struct io { - enum io_type type; /* The requested type of pipe. */ - const char *dir; /* Directory from which to execute. */ - pid_t pid; /* PID of spawned process. */ int pipe; /* Pipe end for reading or writing. */ + pid_t pid; /* PID of spawned process. */ int error; /* Error status. */ - const char *argv[SIZEOF_ARG]; /* Shell command arguments. */ char *buf; /* Read buffer. */ size_t bufalloc; /* Allocated buffer size. */ size_t bufsize; /* Buffer content size. */ @@ -726,37 +718,10 @@ struct io { }; static void -io_reset(struct io *io) +io_init(struct io *io) { + memset(io, 0, sizeof(*io)); io->pipe = -1; - io->pid = 0; - io->buf = io->bufpos = NULL; - io->bufalloc = io->bufsize = 0; - io->error = 0; - io->eof = 0; -} - -static void -io_init(struct io *io, const char *dir, enum io_type type) -{ - io_reset(io); - io->type = type; - io->dir = dir; -} - -static void -io_prepare(struct io *io, const char *dir, enum io_type type, const char *argv[]) -{ - io_init(io, dir, type); - argv_copy(io->argv, argv); -} - -static bool -io_format(struct io *io, const char *dir, enum io_type type, - const char *argv[], enum format_flags flags) -{ - io_init(io, dir, type); - return format_argv(io->argv, argv, flags); } static bool @@ -766,7 +731,7 @@ io_open(struct io *io, const char *fmt, ...) bool fits; va_list args; - io_init(io, NULL, IO_FD); + io_init(io); va_start(args, fmt); fits = vsnprintf(name, sizeof(name), fmt, args) < sizeof(name); @@ -796,7 +761,7 @@ io_done(struct io *io) if (io->pipe != -1) close(io->pipe); free(io->buf); - io_reset(io); + io_init(io); while (pid > 0) { int status; @@ -819,35 +784,37 @@ io_done(struct io *io) } static bool -io_start(struct io *io) +io_run(struct io *io, enum io_type type, const char *dir, const char *argv[], ...) { int pipefds[2] = { -1, -1 }; + va_list args; - if (io->type == IO_FD) - return TRUE; + io_init(io); - if ((io->type == IO_RD || io->type == IO_WR) && pipe(pipefds) < 0) { + if ((type == IO_RD || type == IO_WR) && pipe(pipefds) < 0) { io->error = errno; return FALSE; - } else if (io->type == IO_AP) { - pipefds[1] = io->pipe; + } else if (type == IO_AP) { + va_start(args, argv); + pipefds[1] = va_arg(args, int); + va_end(args); } if ((io->pid = fork())) { if (io->pid == -1) io->error = errno; - if (pipefds[!(io->type == IO_WR)] != -1) - close(pipefds[!(io->type == IO_WR)]); + if (pipefds[!(type == IO_WR)] != -1) + close(pipefds[!(type == IO_WR)]); if (io->pid != -1) { - io->pipe = pipefds[!!(io->type == IO_WR)]; + io->pipe = pipefds[!!(type == IO_WR)]; return TRUE; } } else { - if (io->type != IO_FG) { + if (type != IO_FG) { int devnull = open("/dev/null", O_RDWR); - int readfd = io->type == IO_WR ? pipefds[0] : devnull; - int writefd = (io->type == IO_RD || io->type == IO_AP) + int readfd = type == IO_WR ? pipefds[0] : devnull; + int writefd = (type == IO_RD || type == IO_AP) ? pipefds[1] : devnull; dup2(readfd, STDIN_FILENO); @@ -861,33 +828,24 @@ io_start(struct io *io) close(pipefds[1]); } - if (io->dir && *io->dir && chdir(io->dir) == -1) + if (dir && *dir && chdir(dir) == -1) exit(errno); - execvp(io->argv[0], (char *const*) io->argv); + execvp(argv[0], (char *const*) argv); exit(errno); } - if (pipefds[!!(io->type == IO_WR)] != -1) - close(pipefds[!!(io->type == IO_WR)]); + if (pipefds[!!(type == IO_WR)] != -1) + close(pipefds[!!(type == IO_WR)]); return FALSE; } -static bool -io_run(struct io *io, const char **argv, const char *dir, enum io_type type) -{ - io_prepare(io, dir, type, argv); - return io_start(io); -} - static bool io_complete(enum io_type type, const char **argv, const char *dir, int fd) { - struct io io = {}; + struct io io; - io_prepare(&io, dir, type, argv); - io.pipe = fd; - return io_start(&io) && io_done(&io); + return io_run(&io, type, dir, argv, fd) && io_done(&io); } static bool @@ -905,7 +863,7 @@ io_run_fg(const char **argv, const char *dir) static bool io_run_append(const char **argv, int fd) { - return io_complete(IO_AP, argv, NULL, -1); + return io_complete(IO_AP, argv, NULL, fd); } static bool @@ -1040,10 +998,9 @@ io_read_buf(struct io *io, char buf[], size_t bufsize) static bool io_run_buf(const char **argv, char buf[], size_t bufsize) { - struct io io = {}; + struct io io; - io_prepare(&io, NULL, IO_RD, argv); - return io_start(&io) && io_read_buf(&io, buf, bufsize); + return io_run(&io, IO_RD, NULL, argv) && io_read_buf(&io, buf, bufsize); } static int @@ -1053,9 +1010,6 @@ io_load(struct io *io, const char *separators, char *name; int state = OK; - if (!io_start(io)) - return ERR; - while (state == OK && (name = io_get(io, '\n', TRUE))) { char *value; size_t namelen; @@ -1088,9 +1042,10 @@ static int io_run_load(const char **argv, const char *separators, int (*read_property)(char *, size_t, char *, size_t)) { - struct io io = {}; + struct io io; - io_prepare(&io, NULL, IO_RD, argv); + if (!io_run(&io, IO_RD, NULL, argv)) + return ERR; return io_load(&io, separators, read_property); } @@ -1743,7 +1698,7 @@ add_run_request(enum keymap keymap, int key, int argc, const char **argv) req->key = key; req->argv[0] = NULL; - if (!format_argv(req->argv, argv, FORMAT_NONE)) + if (!argv_copy(req->argv, argv)) return REQ_NONE; return REQ_NONE + ++run_requests; @@ -2133,7 +2088,7 @@ read_option(char *opt, size_t optlen, char *value, size_t valuelen) static void load_option_file(const char *path) { - struct io io = {}; + struct io io; /* It's OK that the file doesn't exist. */ if (!io_open(&io, "%s", path)) @@ -2258,6 +2213,8 @@ struct view { bool has_scrolled; /* View was scrolled. */ /* Loading */ + const char *argv[SIZEOF_ARG]; /* Shell command arguments. */ + const char *dir; /* Directory from which to execute. */ struct io io; struct io *pipe; time_t start_time; @@ -3185,11 +3142,10 @@ format_arg(const char *name) } static bool -format_argv(const char *dst_argv[], const char *src_argv[], enum format_flags flags) +format_argv(const char *dst_argv[], const char *src_argv[], bool replace) { char buf[SIZEOF_STR]; int argc; - bool noreplace = flags == FORMAT_NONE; argv_free(dst_argv); @@ -3202,7 +3158,7 @@ format_argv(const char *dst_argv[], const char *src_argv[], enum format_flags fl int len = next - arg; const char *value; - if (!next || noreplace) { + if (!next || !replace) { len = strlen(arg); value = ""; @@ -3217,7 +3173,7 @@ format_argv(const char *dst_argv[], const char *src_argv[], enum format_flags fl if (!string_format_from(buf, &bufpos, "%.*s%s", len, arg, value)) return FALSE; - arg = next && !noreplace ? strchr(next, ')') + 1 : NULL; + arg = next && replace ? strchr(next, ')') + 1 : NULL; } dst_argv[argc] = strdup(buf); @@ -3276,12 +3232,19 @@ setup_update(struct view *view, const char *vid) view->start_time = time(NULL); } +static bool +prepare_io(struct view *view, const char *dir, const char *argv[], bool replace) +{ + view->dir = dir; + return format_argv(view->argv, argv, replace); +} + static bool prepare_update(struct view *view, const char *argv[], const char *dir) { if (view->pipe) end_update(view, TRUE); - return io_format(&view->io, dir, IO_RD, argv, FORMAT_NONE); + return prepare_io(view, dir, argv, FALSE); } static bool @@ -3289,8 +3252,8 @@ start_update(struct view *view, const char **argv, const char *dir) { if (view->pipe) io_done(view->pipe); - return io_format(&view->io, dir, IO_RD, argv, FORMAT_NONE) && - io_start(&view->io); + return prepare_io(view, dir, argv, FALSE) && + io_run(&view->io, IO_RD, dir, view->argv); } static bool @@ -3298,6 +3261,7 @@ prepare_update_file(struct view *view, const char *name) { if (view->pipe) end_update(view, TRUE); + argv_free(view->argv); return io_open(&view->io, "%s/%s", opt_cdup[0] ? opt_cdup : ".", name); } @@ -3311,7 +3275,7 @@ begin_update(struct view *view, bool refresh) if (view->ops->prepare) { if (!view->ops->prepare(view)) return FALSE; - } else if (!io_format(&view->io, NULL, IO_RD, view->ops->argv, FORMAT_ALL)) { + } else if (!prepare_io(view, NULL, view->ops->argv, TRUE)) { return FALSE; } @@ -3322,7 +3286,7 @@ begin_update(struct view *view, bool refresh) string_copy_rev(view->ref, view->id); } - if (!io_start(&view->io)) + if (view->argv[0] && !io_run(&view->io, IO_RD, view->dir, view->argv)) return FALSE; setup_update(view, view->id); @@ -3608,7 +3572,7 @@ open_run_request(enum request request) return; } - if (format_argv(argv, req->argv, FORMAT_ALL)) + if (format_argv(argv, req->argv, TRUE)) open_external_viewer(argv, NULL); argv_free(argv); } @@ -4820,7 +4784,7 @@ tree_prepare(struct view *view) opt_path[0] = 0; } - return io_format(&view->io, opt_cdup, IO_RD, view->ops->argv, FORMAT_ALL); + return prepare_io(view, opt_cdup, view->ops->argv, TRUE); } static const char *tree_argv[SIZEOF_ARG] = { @@ -5150,12 +5114,12 @@ setup_blame_parent_line(struct view *view, struct blame *blame) "git", "diff-tree", "-U0", blame->commit->id, "--", blame->commit->filename, NULL }; - struct io io = {}; + struct io io; int parent_lineno = -1; int blamed_lineno = -1; char *line; - if (!io_run(&io, diff_tree_argv, NULL, IO_RD)) + if (!io_run(&io, IO_RD, NULL, diff_tree_argv)) return; while ((line = io_get(&io, '\n', TRUE))) { @@ -5566,9 +5530,9 @@ status_run(struct view *view, const char *argv[], char status, enum line_type ty { struct status *unmerged = NULL; char *buf; - struct io io = {}; + struct io io; - if (!io_run(&io, argv, opt_cdup, IO_RD)) + if (!io_run(&io, IO_RD, opt_cdup, argv)) return FALSE; add_line_data(view, NULL, type); @@ -5716,7 +5680,7 @@ status_update_onbranch(void) continue; if (!*opt_head) { - struct io io = {}; + struct io io; if (io_open(&io, "%s/rebase-merge/head-name", opt_git_dir) && io_read_buf(&io, buf, sizeof(buf))) { @@ -5963,11 +5927,11 @@ status_update_prepare(struct io *io, enum line_type type) switch (type) { case LINE_STAT_STAGED: - return io_run(io, staged_argv, opt_cdup, IO_WR); + return io_run(io, IO_WR, opt_cdup, staged_argv); case LINE_STAT_UNSTAGED: case LINE_STAT_UNTRACKED: - return io_run(io, others_argv, opt_cdup, IO_WR); + return io_run(io, IO_WR, opt_cdup, others_argv); default: die("line type %d not handled in switch", type); @@ -6006,7 +5970,7 @@ status_update_write(struct io *io, struct status *status, enum line_type type) static bool status_update_file(struct status *status, enum line_type type) { - struct io io = {}; + struct io io; bool result; if (!status_update_prepare(&io, type)) @@ -6020,7 +5984,7 @@ static bool status_update_files(struct view *view, struct line *line) { char buf[sizeof(view->ref)]; - struct io io = {}; + struct io io; bool result = TRUE; struct line *pos = view->line + view->lines; int files = 0; @@ -6293,7 +6257,7 @@ stage_apply_chunk(struct view *view, struct line *chunk, bool revert) "git", "apply", "--whitespace=nowarn", NULL }; struct line *diff_hdr; - struct io io = {}; + struct io io; int argc = 3; diff_hdr = stage_diff_find(view, chunk, LINE_DIFF_HEADER); @@ -6306,7 +6270,7 @@ stage_apply_chunk(struct view *view, struct line *chunk, bool revert) apply_argv[argc++] = "-R"; apply_argv[argc++] = "-"; apply_argv[argc++] = NULL; - if (!io_run(&io, apply_argv, opt_cdup, IO_WR)) + if (!io_run(&io, IO_WR, opt_cdup, apply_argv)) return FALSE; if (!stage_diff_write(&io, diff_hdr, chunk) ||