Skip to content

Commit

Permalink
Patch parsing from patch files
Browse files Browse the repository at this point in the history
  • Loading branch information
Edward Thomson authored and Edward Thomson committed May 26, 2016
1 parent 7cb904b commit d34f682
Show file tree
Hide file tree
Showing 12 changed files with 1,461 additions and 8 deletions.
14 changes: 8 additions & 6 deletions include/git2/diff.h
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,8 @@ typedef int (*git_diff_file_cb)(
float progress,
void *payload);

#define GIT_DIFF_HUNK_HEADER_SIZE 128

/**
* When producing a binary diff, the binary data returned will be
* either the deflated full ("literal") contents of the file, or
Expand Down Expand Up @@ -499,12 +501,12 @@ typedef int(*git_diff_binary_cb)(
* Structure describing a hunk of a diff.
*/
typedef struct {
int old_start; /**< Starting line number in old_file */
int old_lines; /**< Number of lines in old_file */
int new_start; /**< Starting line number in new_file */
int new_lines; /**< Number of lines in new_file */
size_t header_len; /**< Number of bytes in header text */
char header[128]; /**< Header text, NUL-byte terminated */
int old_start; /** Starting line number in old_file */
int old_lines; /** Number of lines in old_file */
int new_start; /** Starting line number in new_file */
int new_lines; /** Number of lines in new_file */
size_t header_len; /** Number of bytes in header text */
char header[GIT_DIFF_HUNK_HEADER_SIZE]; /** Header text, NUL-byte terminated */
} git_diff_hunk;

/**
Expand Down
13 changes: 13 additions & 0 deletions include/git2/patch.h
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,19 @@ GIT_EXTERN(int) git_patch_to_buf(
git_buf *out,
git_patch *patch);

/**
* Create a patch from the contents of a patch file.
*
* @param out The patch to be created
* @param patchfile The contents of a patch file
* @param patchfile_len The length of the patch file
* @return 0 on success, <0 on failure.
*/
GIT_EXTERN(int) git_patch_from_patchfile(
git_patch **out,
const char *patchfile,
size_t patchfile_len);

GIT_END_DECL

/**@}*/
Expand Down
75 changes: 75 additions & 0 deletions src/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -766,3 +766,78 @@ int git_buf_splice(
buf->ptr[buf->size] = '\0';
return 0;
}

/* Unquote per http://marc.info/?l=git&m=112927316408690&w=2 */
int git_buf_unquote(git_buf *buf)
{
size_t i, j;
char ch;

git_buf_rtrim(buf);

if (buf->size < 2 || buf->ptr[0] != '"' || buf->ptr[buf->size-1] != '"')
goto invalid;

for (i = 0, j = 1; j < buf->size-1; i++, j++) {
ch = buf->ptr[j];

if (ch == '\\') {
if (j == buf->size-2)
goto invalid;

ch = buf->ptr[++j];

switch (ch) {
/* \" or \\ simply copy the char in */
case '"': case '\\':
break;

/* add the appropriate escaped char */
case 'a': ch = '\a'; break;
case 'b': ch = '\b'; break;
case 'f': ch = '\f'; break;
case 'n': ch = '\n'; break;
case 'r': ch = '\r'; break;
case 't': ch = '\t'; break;
case 'v': ch = '\v'; break;

/* \xyz digits convert to the char*/
case '0': case '1': case '2':
if (j == buf->size-3) {
giterr_set(GITERR_INVALID,
"Truncated quoted character \\%c", ch);
return -1;
}

if (buf->ptr[j+1] < '0' || buf->ptr[j+1] > '7' ||
buf->ptr[j+2] < '0' || buf->ptr[j+2] > '7') {
giterr_set(GITERR_INVALID,
"Truncated quoted character \\%c%c%c",
buf->ptr[j], buf->ptr[j+1], buf->ptr[j+2]);
return -1;
}

ch = ((buf->ptr[j] - '0') << 6) |
((buf->ptr[j+1] - '0') << 3) |
(buf->ptr[j+2] - '0');
j += 2;
break;

default:
giterr_set(GITERR_INVALID, "Invalid quoted character \\%c", ch);
return -1;
}
}

buf->ptr[i] = ch;
}

buf->ptr[i] = '\0';
buf->size = i;

return 0;

invalid:
giterr_set(GITERR_INVALID, "Invalid quoted line");
return -1;
}
5 changes: 5 additions & 0 deletions src/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,11 @@ void git_buf_rtrim(git_buf *buf);

int git_buf_cmp(const git_buf *a, const git_buf *b);

/* Unquote a buffer as specified in
* http://marc.info/?l=git&m=112927316408690&w=2
*/
int git_buf_unquote(git_buf *buf);

/* Write data as base64 encoded in buffer */
int git_buf_encode_base64(git_buf *buf, const char *data, size_t len);
/* Decode the given bas64 and write the result to the buffer */
Expand Down
Loading

0 comments on commit d34f682

Please sign in to comment.