summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2012-03-21 12:11:12 -0700
committerJunio C Hamano <gitster@pobox.com>2012-03-27 15:41:24 -0700
commitde11bf9015aa5c3be17c4ad19687100f0af505d3 (patch)
tree0a8e85d14c8d3fd1dfe4fe38e6f2fa65823a71f0
parent8192a2fafcd69fe1cad2fe84c99b03c63393c117 (diff)
downloadgit-jh/apply-free-patch.tar.gz
apply.c: WIP ownership auditjh/apply-free-patch
Add a few comments on ownership, and tighten constness of a few line buffer variables. Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--builtin/apply.c69
1 files changed, 59 insertions, 10 deletions
diff --git a/builtin/apply.c b/builtin/apply.c
index c65fb3f8da..8b02a23b26 100644
--- a/builtin/apply.c
+++ b/builtin/apply.c
@@ -151,6 +151,10 @@ struct fragment {
unsigned long leading, trailing;
unsigned long oldpos, oldlines;
unsigned long newpos, newlines;
+ /*
+ * 'patch' is usually borrowed from buf in apply_patch(),
+ * but some codepaths store an allocated buffer.
+ */
const char *patch;
unsigned free_patch:1,
rejected:1;
@@ -329,6 +333,11 @@ static void add_line_info(struct image *img, const char *bol, size_t len, unsign
img->nr++;
}
+/*
+ * "buf" has the file contents to be patched (read from various sources).
+ * attach it to "image" and add line-based index to it.
+ * "image" now owns the "buf".
+ */
static void prepare_image(struct image *image, char *buf, size_t len,
int prepare_linetable)
{
@@ -380,7 +389,6 @@ static void say_patch_name(FILE *output, const char *pre,
fputs(post, output);
}
-#define CHUNKSIZE (8192)
#define SLOP (16)
static void read_patch_file(struct strbuf *sb, int fd)
@@ -1086,7 +1094,7 @@ static const char *stop_at_slash(const char *line, int llen)
* creation or deletion of an empty file. In any of these cases,
* both sides are the same name under a/ and b/ respectively.
*/
-static char *git_header_name(char *line, int llen)
+static char *git_header_name(const char *line, int llen)
{
const char *name;
const char *second = NULL;
@@ -1213,7 +1221,7 @@ static char *git_header_name(char *line, int llen)
}
/* Verify that we recognize the lines following a git header */
-static int parse_git_header(char *line, int len, unsigned int size, struct patch *patch)
+static int parse_git_header(const char *line, int len, unsigned int size, struct patch *patch)
{
unsigned long offset;
@@ -1329,7 +1337,7 @@ static int parse_range(const char *line, int len, int offset, const char *expect
return offset + ex;
}
-static void recount_diff(char *line, int size, struct fragment *fragment)
+static void recount_diff(const char *line, int size, struct fragment *fragment)
{
int oldlines = 0, newlines = 0, ret = 0;
@@ -1383,7 +1391,7 @@ static void recount_diff(char *line, int size, struct fragment *fragment)
* Parse a unified diff fragment header of the
* form "@@ -a,b +c,d @@"
*/
-static int parse_fragment_header(char *line, int len, struct fragment *fragment)
+static int parse_fragment_header(const char *line, int len, struct fragment *fragment)
{
int offset;
@@ -1397,7 +1405,7 @@ static int parse_fragment_header(char *line, int len, struct fragment *fragment)
return offset;
}
-static int find_header(char *line, unsigned long size, int *hdrsize, struct patch *patch)
+static int find_header(const char *line, unsigned long size, int *hdrsize, struct patch *patch)
{
unsigned long offset, len;
@@ -1509,7 +1517,7 @@ static void check_whitespace(const char *line, int len, unsigned ws_rule)
* between a "---" that is part of a patch, and a "---" that starts
* the next patch is to look at the line counts..
*/
-static int parse_fragment(char *line, unsigned long size,
+static int parse_fragment(const char *line, unsigned long size,
struct patch *patch, struct fragment *fragment)
{
int added, deleted;
@@ -1605,7 +1613,15 @@ static int parse_fragment(char *line, unsigned long size,
return offset;
}
-static int parse_single_patch(char *line, unsigned long size, struct patch *patch)
+/*
+ * We have seen "diff --git a/... b/..." header (or a traditional patch
+ * header). Read hunks that belong to this patch into fragments and hang
+ * them to the given patch structure.
+ *
+ * The (fragment->patch, fragment->size) pair points into the memory given
+ * by the caller, not a copy, when we return.
+ */
+static int parse_single_patch(const char *line, unsigned long size, struct patch *patch)
{
unsigned long offset = 0;
unsigned long oldlines = 0, newlines = 0, context = 0;
@@ -1698,6 +1714,11 @@ static char *inflate_it(const void *data, unsigned long size,
return out;
}
+/*
+ * Read a binary hunk and return a new fragment; fragment->patch
+ * points at an allocated memory that the caller must free, so
+ * it is marked as "->free_patch = 1".
+ */
static struct fragment *parse_binary_hunk(char **buf_p,
unsigned long *sz_p,
int *status_p,
@@ -1851,6 +1872,13 @@ static int parse_binary(char *buffer, unsigned long size, struct patch *patch)
return used;
}
+/*
+ * Read the patch text in "buffer" taht extends for "size" bytes; stop
+ * reading after seeing a single patch (i.e. changes to a single file).
+ * Create fragments (i.e. patch hunks) and hang them to the given patch.
+ * Return the number of bytes consumed, so that the caller can call us
+ * again for the next patch.
+ */
static int parse_chunk(char *buffer, unsigned long size, struct patch *patch)
{
int hdrsize, patchsize;
@@ -2411,6 +2439,11 @@ static void remove_last_line(struct image *img)
img->len -= img->line[--img->nr].len;
}
+/*
+ * The change from "preimage" and "postimage" has been found to
+ * apply at applied_pos (counts in line numbers) in "img".
+ * Update "img" to remove "preimage" and replace it with "postimage".
+ */
static void update_image(struct image *img,
int applied_pos,
struct image *preimage,
@@ -2482,6 +2515,11 @@ static void update_image(struct image *img,
img->nr = nr;
}
+/*
+ * Use the patch-hunk text in "frag" to prepare two images (preimage and
+ * postimage) for the hunk. Find lines that match "preimage" in "img" and
+ * replace the part of "img" with "postimage" text.
+ */
static int apply_one_fragment(struct image *img, struct fragment *frag,
int inaccurate_eof, unsigned ws_rule,
int nth_fragment)
@@ -2772,6 +2810,12 @@ static int apply_binary_fragment(struct image *img, struct patch *patch)
return -1;
}
+/*
+ * Replace "img" with the result of applying the binary patch.
+ * The binary patch data itself in patch->fragment is still kept
+ * but the preimage prepared by the caller in "img" is freed here
+ * or in the helper function apply_binary_fragment() this calls.
+ */
static int apply_binary(struct image *img, struct patch *patch)
{
const char *name = patch->old_name ? patch->old_name : patch->new_name;
@@ -2979,7 +3023,7 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *
return error("patch %s has been renamed/deleted",
patch->old_name);
}
- /* We have a patched copy in memory use that */
+ /* We have a patched copy in memory; use that. */
strbuf_add(&buf, tpatch->result, tpatch->resultsize);
} else if (cached) {
if (read_file_or_gitlink(ce, &buf))
@@ -2992,6 +3036,7 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry *
/*
* There is no way to apply subproject
* patch without looking at the index.
+ * NEEDSWORK: shouldn't we free this?
*/
patch->fragments = NULL;
}
@@ -3134,6 +3179,10 @@ static int check_preimage(struct patch *patch, struct cache_entry **ce, struct s
return 0;
}
+/*
+ * Check and apply the patch in-core; leave the result in patch->result
+ * for the caller to write it out to the final destination.
+ */
static int check_patch(struct patch *patch)
{
struct stat st;
@@ -3721,7 +3770,7 @@ static void prefix_patches(struct patch *p)
static int apply_patch(int fd, const char *filename, int options)
{
size_t offset;
- struct strbuf buf = STRBUF_INIT;
+ struct strbuf buf = STRBUF_INIT; /* owns the patch text */
struct patch *list = NULL, **listp = &list;
int skipped_patch = 0;