return strbuf_detach(&sb, NULL);
}
-const char *prefix_filename(const char *pfx, const char *arg)
+char *prefix_filename(const char *pfx, const char *arg)
{
- static struct strbuf path = STRBUF_INIT;
+ struct strbuf path = STRBUF_INIT;
size_t pfx_len = pfx ? strlen(pfx) : 0;
#ifndef GIT_WINDOWS_NATIVE
if (!pfx_len || is_absolute_path(arg))
- return arg;
- strbuf_reset(&path);
+ return xstrdup(arg);
strbuf_add(&path, pfx, pfx_len);
strbuf_addstr(&path, arg);
#else
/* don't add prefix to absolute paths, but still replace '\' by '/' */
- strbuf_reset(&path);
if (is_absolute_path(arg))
pfx_len = 0;
else if (pfx_len)
strbuf_addstr(&path, arg);
convert_slashes(path.buf + pfx_len);
#endif
- return path.buf;
+ return strbuf_detach(&path, NULL);
}
char *old_name = *name;
if (!old_name)
return;
- *name = xstrdup(prefix_filename(state->prefix, *name));
+ *name = prefix_filename(state->prefix, *name);
free(old_name);
}
for (i = 0; i < argc; i++) {
const char *arg = argv[i];
+ char *to_free = NULL;
int fd;
if (!strcmp(arg, "-")) {
errs |= res;
read_stdin = 0;
continue;
- } else if (0 < state->prefix_length)
- arg = prefix_filename(state->prefix, arg);
+ } else
+ arg = to_free = prefix_filename(state->prefix, arg);
fd = open(arg, O_RDONLY);
if (fd < 0) {
error(_("can't open patch '%s': %s"), arg, strerror(errno));
res = -128;
+ free(to_free);
goto end;
}
read_stdin = 0;
set_default_whitespace_mode(state);
res = apply_patch(state, fd, arg, options);
close(fd);
+ free(to_free);
if (res < 0)
goto end;
errs |= res;
else if (given_config_source.file) {
if (!is_absolute_path(given_config_source.file) && prefix)
given_config_source.file =
- xstrdup(prefix_filename(prefix,
- given_config_source.file));
+ prefix_filename(prefix, given_config_source.file);
}
if (respect_includes == -1)
char *to_free = NULL;
if (prefix)
- arg = to_free = xstrdup(prefix_filename(prefix, arg));
+ arg = to_free = prefix_filename(prefix, arg);
hash_object(arg, type, no_filters ? NULL : vpath ? vpath : arg,
flags, literally);
free(to_free);
if (!output_directory)
return prefix;
- return xstrdup(prefix_filename(prefix, output_directory));
+ return prefix_filename(prefix, output_directory);
}
static const char * const builtin_format_patch_usage[] = {
static const char mailinfo_usage[] =
"git mailinfo [-k | -b] [-m | --message-id] [-u | --encoding=<encoding> | -n] [--scissors | --no-scissors] <msg> <patch> < mail >info";
-static char *prefix_copy(const char *prefix, const char *filename)
-{
- if (!prefix || is_absolute_path(filename))
- return xstrdup(filename);
- return xstrdup(prefix_filename(prefix, filename));
-}
-
int cmd_mailinfo(int argc, const char **argv, const char *prefix)
{
const char *def_charset;
mi.input = stdin;
mi.output = stdout;
- msgfile = prefix_copy(prefix, argv[1]);
- patchfile = prefix_copy(prefix, argv[2]);
+ msgfile = prefix_filename(prefix, argv[1]);
+ patchfile = prefix_filename(prefix, argv[2]);
status = !!mailinfo(&mi, msgfile, patchfile);
clear_mailinfo(&mi);
}
for (i = 0; i < 3; i++) {
- const char *fname = prefix_filename(prefix, argv[i]);
+ char *fname;
+ int ret;
+
if (!names[i])
names[i] = argv[i];
- if (read_mmfile(mmfs + i, fname))
+
+ fname = prefix_filename(prefix, argv[i]);
+ ret = read_mmfile(mmfs + i, fname);
+ free(fname);
+ if (ret)
return -1;
+
if (mmfs[i].size > MAX_XDIFF_SIZE ||
buffer_is_binary(mmfs[i].ptr, mmfs[i].size))
return error("Cannot merge binary files: %s",
if (ret >= 0) {
const char *filename = argv[0];
- const char *fpath = prefix_filename(prefix, argv[0]);
+ char *fpath = prefix_filename(prefix, argv[0]);
FILE *f = to_stdout ? stdout : fopen(fpath, "wb");
if (!f)
else if (fclose(f))
ret = error_errno("Could not close %s", filename);
free(result.ptr);
+ free(fpath);
}
if (ret > 127)
if ((filter & (DO_NONFLAGS|DO_NOREV)) == (DO_NONFLAGS|DO_NOREV)) {
if (output_prefix) {
const char *prefix = startup_info->prefix;
- show(prefix_filename(prefix, arg));
+ char *fname = prefix_filename(prefix, arg);
+ show(fname);
+ free(fname);
} else
show(arg);
return 1;
{
struct add_opts opts;
const char *new_branch_force = NULL;
- const char *path, *branch;
+ char *path;
+ const char *branch;
struct option options[] = {
OPT__FORCE(&opts.force, N_("checkout <branch> even if already checked out in other worktree")),
OPT_STRING('b', NULL, &opts.new_branch, N_("branch"),
* not have to interact with index entry; i.e. name of a random file
* on the filesystem.
*
- * The return value may point to static storage which will be overwritten by
- * further calls.
+ * The return value is always a newly allocated string (even if the
+ * prefix was empty).
*/
-extern const char *prefix_filename(const char *prefix, const char *path);
+extern char *prefix_filename(const char *prefix, const char *path);
extern int check_filename(const char *prefix, const char *name);
extern void verify_filename(const char *prefix,
*/
p = file_from_standard_input;
else if (prefix)
- p = xstrdup(prefix_filename(prefix, p));
+ p = prefix_filename(prefix, p);
paths[i] = p;
}
else if (!strcmp(arg, "--pickaxe-regex"))
options->pickaxe_opts |= DIFF_PICKAXE_REGEX;
else if ((argcount = short_opt('O', av, &optarg))) {
- const char *path = prefix_filename(prefix, optarg);
- options->orderfile = xstrdup(path);
+ options->orderfile = prefix_filename(prefix, optarg);
return argcount;
}
else if ((argcount = parse_long_opt("diff-filter", av, &optarg))) {
else if (!strcmp(arg, "--no-function-context"))
DIFF_OPT_CLR(options, FUNCCONTEXT);
else if ((argcount = parse_long_opt("output", av, &optarg))) {
- const char *path = prefix_filename(prefix, optarg);
+ char *path = prefix_filename(prefix, optarg);
options->file = fopen(path, "w");
if (!options->file)
die_errno("Could not open '%s'", path);
options->close_file = 1;
if (options->use_color != GIT_COLOR_ALWAYS)
options->use_color = GIT_COLOR_NEVER;
+ free(path);
return argcount;
} else
return 0;
if (!file || !*file || !prefix || is_absolute_path(*file)
|| !strcmp("-", *file))
return;
- *file = xstrdup(prefix_filename(prefix, *file));
+ *file = prefix_filename(prefix, *file);
}
static int opt_command_mode_error(const struct option *opt,
int check_filename(const char *prefix, const char *arg)
{
const char *name;
+ char *to_free = NULL;
struct stat st;
if (starts_with(arg, ":/")) {
return 1;
name = arg + 2;
} else if (prefix)
- name = prefix_filename(prefix, arg);
+ name = to_free = prefix_filename(prefix, arg);
else
name = arg;
- if (!lstat(name, &st))
+ if (!lstat(name, &st)) {
+ free(to_free);
return 1; /* file exists */
- if (errno == ENOENT || errno == ENOTDIR)
+ }
+ if (errno == ENOENT || errno == ENOTDIR) {
+ free(to_free);
return 0; /* file does not exist */
+ }
die_errno("failed to stat '%s'", arg);
}
{
struct worktree *wt;
char *path;
+ char *to_free = NULL;
if ((wt = find_worktree_by_suffix(list, arg)))
return wt;
- arg = prefix_filename(prefix, arg);
+ if (prefix)
+ arg = to_free = prefix_filename(prefix, arg);
path = real_pathdup(arg, 1);
for (; *list; list++)
if (!fspathcmp(path, real_path((*list)->path)))
break;
free(path);
+ free(to_free);
return *list;
}