summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
authorLibravatar Jonathan Nieder <jrnieder@gmail.com>2010-08-18 20:46:46 -0500
committerLibravatar Junio C Hamano <gitster@pobox.com>2010-08-21 23:04:22 -0700
commitbb7306b5a350fd2143347be3d9b7d8588567d715 (patch)
tree9796483bfcce04508d1c1247aecbb8b33b93f7db /builtin
parentGit 1.7.2 (diff)
downloadtgif-bb7306b5a350fd2143347be3d9b7d8588567d715.tar.xz
apply: split quoted filename handling into new function
The new find_name_gnu() function handles new-style '--- "a/foo"' patch header lines, leaving find_name() itself a bit less daunting. Functional change: do not clobber the p-value when there are not enough path components in a quoted file name to honor it. Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin')
-rw-r--r--builtin/apply.c68
1 files changed, 38 insertions, 30 deletions
diff --git a/builtin/apply.c b/builtin/apply.c
index 12ef9ea8af..efc109e5d0 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -416,44 +416,52 @@ static char *squash_slash(char *name)
return name;
}
+static char *find_name_gnu(const char *line, char *def, int p_value)
+{
+ struct strbuf name = STRBUF_INIT;
+ char *cp;
+
+ /*
+ * Proposed "new-style" GNU patch/diff format; see
+ * http://marc.theaimsgroup.com/?l=git&m=112927316408690&w=2
+ */
+ if (unquote_c_style(&name, line, NULL)) {
+ strbuf_release(&name);
+ return NULL;
+ }
+
+ for (cp = name.buf; p_value; p_value--) {
+ cp = strchr(cp, '/');
+ if (!cp) {
+ strbuf_release(&name);
+ return NULL;
+ }
+ cp++;
+ }
+
+ /* name can later be freed, so we need
+ * to memmove, not just return cp
+ */
+ strbuf_remove(&name, 0, cp - name.buf);
+ free(def);
+ if (root)
+ strbuf_insert(&name, 0, root, root_len);
+ return squash_slash(strbuf_detach(&name, NULL));
+}
+
static char *find_name(const char *line, char *def, int p_value, int terminate)
{
int len;
const char *start = NULL;
- if (p_value == 0)
- start = line;
-
if (*line == '"') {
- struct strbuf name = STRBUF_INIT;
-
- /*
- * Proposed "new-style" GNU patch/diff format; see
- * http://marc.theaimsgroup.com/?l=git&m=112927316408690&w=2
- */
- if (!unquote_c_style(&name, line, NULL)) {
- char *cp;
-
- for (cp = name.buf; p_value; p_value--) {
- cp = strchr(cp, '/');
- if (!cp)
- break;
- cp++;
- }
- if (cp) {
- /* name can later be freed, so we need
- * to memmove, not just return cp
- */
- strbuf_remove(&name, 0, cp - name.buf);
- free(def);
- if (root)
- strbuf_insert(&name, 0, root, root_len);
- return squash_slash(strbuf_detach(&name, NULL));
- }
- }
- strbuf_release(&name);
+ char *name = find_name_gnu(line, def, p_value);
+ if (name)
+ return name;
}
+ if (p_value == 0)
+ start = line;
for (;;) {
char c = *line;