static void filter_options(const char *argv[], bool rev_parse) { const char **flags = NULL; int next, flags_pos; update_options_from_argv(argv); if (!rev_parse) { opt_cmdline_args = argv; return; } /* Add known revision arguments in opt_rev_args and use * git-rev-parse to filter out the remaining options. */ for (next = flags_pos = 0; argv[next]; next++) { const char *arg = argv[next]; if (!strcmp(arg, "--")) while (argv[next]) argv[flags_pos++] = argv[next++]; else if (argv_parse_rev_flag(arg, NULL)) argv_append(&opt_rev_args, arg); else argv[flags_pos++] = arg; } argv[flags_pos] = NULL; filter_rev_parse(&opt_file_args, "--no-revs", "--no-flags", argv); filter_rev_parse(&flags, "--flags", "--no-revs", argv); if (flags) { for (next = flags_pos = 0; flags && flags[next]; next++) { const char *flag = flags[next]; if (argv_parse_rev_flag(flag, NULL)) argv_append(&opt_rev_args, flag); else flags[flags_pos++] = flag; } flags[flags_pos] = NULL; opt_cmdline_args = flags; } filter_rev_parse(&opt_rev_args, "--symbolic", "--revs-only", argv); }
void argv_printf_arglist (struct argv *a, const char *format, const unsigned int flags, va_list arglist) { struct gc_arena gc = gc_new (); char *term; const char *f = format; if (!(flags & APA_CAT)) argv_reset (a); argv_extend (a, 1); /* ensure trailing NULL */ while ((term = argv_term (&f)) != NULL) { if (term[0] == '%') { if (!strcmp (term, "%s")) { char *s = va_arg (arglist, char *); if (!s) s = ""; argv_append (a, string_alloc (s, NULL)); argv_system_str_append (a, s, true); } else if (!strcmp (term, "%sc")) { char *s = va_arg (arglist, char *); if (s) { int nparms; char *parms[MAX_PARMS+1]; int i; nparms = parse_line (s, parms, MAX_PARMS, "SCRIPT-ARGV", 0, D_ARGV_PARSE_CMD, &gc); if (nparms) { for (i = 0; i < nparms; ++i) argv_append (a, string_alloc (parms[i], NULL)); } else argv_append (a, string_alloc (s, NULL)); argv_system_str_append (a, s, false); } else { argv_append (a, string_alloc ("", NULL)); argv_system_str_append (a, "echo", false); } }
static enum status_code read_filter_args(char *name, size_t namelen, char *value, size_t valuelen, void *data) { const char ***filter_args = data; return argv_append(filter_args, name) ? SUCCESS : ERROR_OUT_OF_MEMORY; }
static void filter_options(const char *argv[], bool rev_parse) { const char **flags = NULL; int next, flags_pos; update_options_from_argv(argv); if (!rev_parse) { opt_cmdline_argv = argv; return; } filter_rev_parse(&opt_file_argv, "--no-revs", "--no-flags", argv); filter_rev_parse(&flags, "--flags", "--no-revs", argv); if (flags) { for (next = flags_pos = 0; flags && flags[next]; next++) { const char *flag = flags[next]; if (is_rev_flag(flag)) argv_append(&opt_rev_argv, flag); else flags[flags_pos++] = flag; } flags[flags_pos] = NULL; opt_cmdline_argv = flags; } filter_rev_parse(&opt_rev_argv, "--symbolic", "--revs-only", argv); }
static int read_filter_args(char *name, size_t namelen, char *value, size_t valuelen, void *data) { const char ***filter_args = data; return argv_append(filter_args, name) ? OK : ERR; }
static bool format_append_arg(struct format_context *format, const char ***dst_argv, const char *arg) { memset(format->buf, 0, sizeof(format->buf)); format->bufpos = 0; while (arg) { const char *var = strstr(arg, "%("); const char *closing = var ? strchr(var, ')') : NULL; const char *next = closing ? closing + 1 : NULL; const int len = var ? var - arg : strlen(arg); if (var && !closing) return FALSE; if (len && !string_format_from(format->buf, &format->bufpos, "%.*s", len, arg)) return FALSE; if (var && !format_expand_arg(format, var, next)) return FALSE; arg = next; } return argv_append(dst_argv, format->buf); }
struct argv argv_clone (const struct argv *a, const size_t headroom) { struct argv r; size_t i; argv_init (&r); for (i = 0; i < headroom; ++i) argv_append (&r, NULL); if (a) { for (i = 0; i < a->argc; ++i) argv_append (&r, string_alloc (a->argv[i], NULL)); r.system_str = string_alloc (a->system_str, NULL); } return r; }
bool argv_append_array(const char ***dst_argv, const char *src_argv[]) { int i; for (i = 0; src_argv && src_argv[i]; i++) if (!argv_append(dst_argv, src_argv[i])) return FALSE; return TRUE; }
bool argv_append_array(const char ***dst_argv, const char *src_argv[]) { int i; for (i = 0; src_argv && src_argv[i]; i++) if (!argv_append(dst_argv, src_argv[i])) return false; return true; }
bool argv_copy(const char ***dst, const char *src[]) { int argc; argv_free(*dst); for (argc = 0; src[argc]; argc++) if (!argv_append(dst, src[argc])) return FALSE; return TRUE; }
bool argv_copy(const char ***dst, const char *src[]) { int argc; argv_free(*dst); for (argc = 0; src[argc]; argc++) if (!argv_append(dst, src[argc])) return false; return true; }
int argv_insert(char ***target, int start, char **source) { int i, source_count, target_count; int suffix_count; /* Check for the bozo cases */ if (NULL == target || NULL == *target || start < 0) { return RT_FAILURE; } else if (NULL == source) { return RT_SUCCESS; } /* Easy case: appending to the end */ target_count = argv_count(*target); source_count = argv_count(source); if (start > target_count) { for (i = 0; i < source_count; ++i) { argv_append(&target_count, target, source[i]); } } /* Harder: insertting into the middle */ else { /* Alloc out new space */ *target = (char**) realloc(*target, sizeof(char *) * (target_count + source_count + 1)); /* Move suffix items down to the end */ suffix_count = target_count - start; for (i = suffix_count - 1; i >= 0; --i) { (*target)[start + source_count + i] = (*target)[start + i]; } (*target)[start + suffix_count + source_count] = NULL; /* Strdup in the source argv */ for (i = start; i < start + source_count; ++i) { (*target)[i] = strdup(source[i - start]); } } /* All done */ return RT_SUCCESS; }
int argv_insert_element(char ***target, int location, char *source) { int i, target_count; int suffix_count; /* Check for the bozo cases */ if (NULL == target || NULL == *target || location < 0) { return RT_FAILURE; } else if (NULL == source) { return RT_SUCCESS; } /* Easy case: appending to the end */ target_count = argv_count(*target); if (location > target_count) { argv_append(&target_count, target, source); return RT_SUCCESS; } /* Alloc out new space */ *target = (char**) realloc(*target, sizeof(char*) * (target_count + 2)); /* Move suffix items down to the end */ suffix_count = target_count - location; for (i = suffix_count - 1; i >= 0; --i) { (*target)[location + 1 + i] = (*target)[location + i]; } (*target)[location + suffix_count + 1] = NULL; /* Strdup in the source */ (*target)[location] = strdup(source); /* All done */ return RT_SUCCESS; }
static enum request parse_options(int argc, const char *argv[], bool pager_mode) { enum request request; const char *subcommand; bool seen_dashdash = false; bool rev_parse = true; const char **filter_argv = NULL; int i; request = pager_mode ? REQ_VIEW_PAGER : REQ_VIEW_MAIN; if (argc <= 1) return request; subcommand = argv[1]; if (!strcmp(subcommand, "status")) { request = REQ_VIEW_STATUS; } else if (!strcmp(subcommand, "blame")) { request = REQ_VIEW_BLAME; } else if (!strcmp(subcommand, "grep")) { request = REQ_VIEW_GREP; rev_parse = false; } else if (!strcmp(subcommand, "show")) { request = REQ_VIEW_DIFF; } else if (!strcmp(subcommand, "log")) { request = REQ_VIEW_LOG; } else if (!strcmp(subcommand, "stash")) { request = REQ_VIEW_STASH; } else if (!strcmp(subcommand, "refs")) { request = REQ_VIEW_REFS; } else { subcommand = NULL; } for (i = 1 + !!subcommand; i < argc; i++) { const char *opt = argv[i]; // stop parsing our options after -- and let rev-parse handle the rest if (!seen_dashdash) { if (!strcmp(opt, "--")) { seen_dashdash = true; continue; } else if (!strcmp(opt, "-v") || !strcmp(opt, "--version")) { printf("tig version %s\n", TIG_VERSION); exit(EXIT_SUCCESS); } else if (!strcmp(opt, "-h") || !strcmp(opt, "--help")) { printf("%s\n", usage_string); exit(EXIT_SUCCESS); } else if (strlen(opt) >= 2 && *opt == '+' && string_isnumber(opt + 1)) { int lineno = atoi(opt + 1); argv_env.goto_lineno = lineno > 0 ? lineno - 1 : 0; continue; } } if (!argv_append(&filter_argv, opt)) die("command too long"); } if (filter_argv) filter_options(filter_argv, rev_parse); return request; }
static enum request parse_options(int argc, const char *argv[], bool pager_mode) { enum request request; const char *subcommand; bool seen_dashdash = false; bool rev_parse = true; const char **filter_argv = NULL; int i; request = pager_mode ? REQ_VIEW_PAGER : REQ_VIEW_MAIN; /* Options that must come before any subcommand. */ for (i = 1; i < argc; i++) { const char *opt = argv[i]; if (!strncmp(opt, "-C", 2)) { if (chdir(opt + 2)) die("Failed to change directory to %s", opt + 2); continue; } else { break; } } if (i >= argc) return request; subcommand = argv[i++]; if (!strcmp(subcommand, "status")) { request = REQ_VIEW_STATUS; } else if (!strcmp(subcommand, "blame")) { request = REQ_VIEW_BLAME; } else if (!strcmp(subcommand, "grep")) { request = REQ_VIEW_GREP; rev_parse = false; } else if (!strcmp(subcommand, "show")) { request = REQ_VIEW_DIFF; } else if (!strcmp(subcommand, "log")) { request = REQ_VIEW_LOG; } else if (!strcmp(subcommand, "stash")) { request = REQ_VIEW_STASH; } else if (!strcmp(subcommand, "refs")) { request = REQ_VIEW_REFS; } else { subcommand = NULL; i--; /* revisit option in loop below */ } for (; i < argc; i++) { const char *opt = argv[i]; // stop parsing our options after -- and let rev-parse handle the rest if (!seen_dashdash) { if (!strcmp(opt, "--")) { seen_dashdash = true; } else if (!strcmp(opt, "-v") || !strcmp(opt, "--version")) { printf("tig version %s\n", TIG_VERSION); #ifdef NCURSES_VERSION printf("%s version %s.%d\n", #ifdef NCURSES_WIDECHAR "ncursesw", #else "ncurses", #endif NCURSES_VERSION, NCURSES_VERSION_PATCH); #endif #ifdef HAVE_READLINE printf("readline version %s\n", rl_library_version); #endif exit(EXIT_SUCCESS); } else if (!strcmp(opt, "-h") || !strcmp(opt, "--help")) { printf("%s\n", usage_string); exit(EXIT_SUCCESS); } else if (strlen(opt) >= 2 && *opt == '+' && string_isnumber(opt + 1)) { int lineno = atoi(opt + 1); argv_env.goto_lineno = lineno > 0 ? lineno - 1 : 0; continue; } } if (!argv_append(&filter_argv, opt)) die("command too long"); } if (filter_argv) filter_options(filter_argv, rev_parse); return request; }