Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
G
git2
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
git2
Commits
17572f67
Commit
17572f67
authored
Apr 21, 2016
by
Edward Thomson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
git_patch_parse_ctx: refcount the context
parent
9be638ec
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
172 additions
and
102 deletions
+172
-102
src/patch.h
+0
-15
src/patch_parse.c
+144
-87
src/patch_parse.h
+25
-0
tests/apply/fromfile.c
+1
-0
tests/patch/parse.c
+1
-0
tests/patch/print.c
+1
-0
No files found.
src/patch.h
View file @
17572f67
...
@@ -61,21 +61,6 @@ typedef struct {
...
@@ -61,21 +61,6 @@ typedef struct {
#define GIT_PATCH_OPTIONS_INIT { 1 }
#define GIT_PATCH_OPTIONS_INIT { 1 }
/**
* Create a patch for a single file from the contents of a patch buffer.
*
* @param out The patch to be created
* @param contents The contents of a patch file
* @param contents_len The length of the patch file
* @param opts The git_patch_options
* @return 0 on success, <0 on failure.
*/
extern
int
git_patch_from_buffer
(
git_patch
**
out
,
const
char
*
contents
,
size_t
contents_len
,
git_patch_options
*
opts
);
extern
void
git_patch_free
(
git_patch
*
patch
);
extern
void
git_patch_free
(
git_patch
*
patch
);
#endif
#endif
src/patch_parse.c
View file @
17572f67
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#include "git2/patch.h"
#include "git2/patch.h"
#include "patch.h"
#include "patch.h"
#include "path.h"
#include "path.h"
...
@@ -6,13 +12,24 @@
...
@@ -6,13 +12,24 @@
( giterr_set(GITERR_PATCH, __VA_ARGS__), -1 )
( giterr_set(GITERR_PATCH, __VA_ARGS__), -1 )
typedef
struct
{
typedef
struct
{
git_patch
base
;
git_refcount
rc
;
const
char
*
content
;
size_t
content_len
;
git_patch_options
opts
;
git_patch_options
opts
;
/* the patch contents, which lines will point into. */
const
char
*
line
;
/* TODO: allow us to point somewhere refcounted. */
size_t
line_len
;
char
*
content
;
size_t
line_num
;
size_t
remain
;
}
git_patch_parse_ctx
;
typedef
struct
{
git_patch
base
;
git_patch_parse_ctx
*
ctx
;
/* the paths from the `diff --git` header, these will be used if this is not
/* the paths from the `diff --git` header, these will be used if this is not
* a rename (and rename paths are specified) or if no `+++`/`---` line specify
* a rename (and rename paths are specified) or if no `+++`/`---` line specify
...
@@ -30,20 +47,9 @@ typedef struct {
...
@@ -30,20 +47,9 @@ typedef struct {
char
*
old_prefix
,
*
new_prefix
;
char
*
old_prefix
,
*
new_prefix
;
}
git_patch_parsed
;
}
git_patch_parsed
;
typedef
struct
{
const
char
*
content
;
size_t
content_len
;
const
char
*
line
;
size_t
line_len
;
size_t
line_num
;
size_t
remain
;
}
patch_parse_ctx
;
GIT_INLINE
(
bool
)
parse_ctx_contains
(
GIT_INLINE
(
bool
)
parse_ctx_contains
(
patch_parse_ctx
*
ctx
,
const
char
*
str
,
size_t
len
)
git_
patch_parse_ctx
*
ctx
,
const
char
*
str
,
size_t
len
)
{
{
return
(
ctx
->
line_len
>=
len
&&
memcmp
(
ctx
->
line
,
str
,
len
)
==
0
);
return
(
ctx
->
line_len
>=
len
&&
memcmp
(
ctx
->
line
,
str
,
len
)
==
0
);
}
}
...
@@ -51,7 +57,7 @@ GIT_INLINE(bool) parse_ctx_contains(
...
@@ -51,7 +57,7 @@ GIT_INLINE(bool) parse_ctx_contains(
#define parse_ctx_contains_s(ctx, str) \
#define parse_ctx_contains_s(ctx, str) \
parse_ctx_contains(ctx, str, sizeof(str) - 1)
parse_ctx_contains(ctx, str, sizeof(str) - 1)
static
void
parse_advance_line
(
patch_parse_ctx
*
ctx
)
static
void
parse_advance_line
(
git_
patch_parse_ctx
*
ctx
)
{
{
ctx
->
line
+=
ctx
->
line_len
;
ctx
->
line
+=
ctx
->
line_len
;
ctx
->
remain
-=
ctx
->
line_len
;
ctx
->
remain
-=
ctx
->
line_len
;
...
@@ -59,7 +65,7 @@ static void parse_advance_line(patch_parse_ctx *ctx)
...
@@ -59,7 +65,7 @@ static void parse_advance_line(patch_parse_ctx *ctx)
ctx
->
line_num
++
;
ctx
->
line_num
++
;
}
}
static
void
parse_advance_chars
(
patch_parse_ctx
*
ctx
,
size_t
char_cnt
)
static
void
parse_advance_chars
(
git_
patch_parse_ctx
*
ctx
,
size_t
char_cnt
)
{
{
ctx
->
line
+=
char_cnt
;
ctx
->
line
+=
char_cnt
;
ctx
->
remain
-=
char_cnt
;
ctx
->
remain
-=
char_cnt
;
...
@@ -67,7 +73,7 @@ static void parse_advance_chars(patch_parse_ctx *ctx, size_t char_cnt)
...
@@ -67,7 +73,7 @@ static void parse_advance_chars(patch_parse_ctx *ctx, size_t char_cnt)
}
}
static
int
parse_advance_expected
(
static
int
parse_advance_expected
(
patch_parse_ctx
*
ctx
,
git_
patch_parse_ctx
*
ctx
,
const
char
*
expected
,
const
char
*
expected
,
size_t
expected_len
)
size_t
expected_len
)
{
{
...
@@ -84,7 +90,7 @@ static int parse_advance_expected(
...
@@ -84,7 +90,7 @@ static int parse_advance_expected(
#define parse_advance_expected_s(ctx, str) \
#define parse_advance_expected_s(ctx, str) \
parse_advance_expected(ctx, str, sizeof(str) - 1)
parse_advance_expected(ctx, str, sizeof(str) - 1)
static
int
parse_advance_ws
(
patch_parse_ctx
*
ctx
)
static
int
parse_advance_ws
(
git_
patch_parse_ctx
*
ctx
)
{
{
int
ret
=
-
1
;
int
ret
=
-
1
;
...
@@ -100,7 +106,7 @@ static int parse_advance_ws(patch_parse_ctx *ctx)
...
@@ -100,7 +106,7 @@ static int parse_advance_ws(patch_parse_ctx *ctx)
return
ret
;
return
ret
;
}
}
static
int
parse_advance_nl
(
patch_parse_ctx
*
ctx
)
static
int
parse_advance_nl
(
git_
patch_parse_ctx
*
ctx
)
{
{
if
(
ctx
->
line_len
!=
1
||
ctx
->
line
[
0
]
!=
'\n'
)
if
(
ctx
->
line_len
!=
1
||
ctx
->
line
[
0
]
!=
'\n'
)
return
-
1
;
return
-
1
;
...
@@ -109,7 +115,7 @@ static int parse_advance_nl(patch_parse_ctx *ctx)
...
@@ -109,7 +115,7 @@ static int parse_advance_nl(patch_parse_ctx *ctx)
return
0
;
return
0
;
}
}
static
int
header_path_len
(
patch_parse_ctx
*
ctx
)
static
int
header_path_len
(
git_
patch_parse_ctx
*
ctx
)
{
{
bool
inquote
=
0
;
bool
inquote
=
0
;
bool
quoted
=
(
ctx
->
line_len
>
0
&&
ctx
->
line
[
0
]
==
'"'
);
bool
quoted
=
(
ctx
->
line_len
>
0
&&
ctx
->
line
[
0
]
==
'"'
);
...
@@ -129,7 +135,7 @@ static int header_path_len(patch_parse_ctx *ctx)
...
@@ -129,7 +135,7 @@ static int header_path_len(patch_parse_ctx *ctx)
return
len
;
return
len
;
}
}
static
int
parse_header_path_buf
(
git_buf
*
path
,
patch_parse_ctx
*
ctx
)
static
int
parse_header_path_buf
(
git_buf
*
path
,
git_
patch_parse_ctx
*
ctx
)
{
{
int
path_len
,
error
=
0
;
int
path_len
,
error
=
0
;
...
@@ -154,7 +160,7 @@ done:
...
@@ -154,7 +160,7 @@ done:
return
error
;
return
error
;
}
}
static
int
parse_header_path
(
char
**
out
,
patch_parse_ctx
*
ctx
)
static
int
parse_header_path
(
char
**
out
,
git_
patch_parse_ctx
*
ctx
)
{
{
git_buf
path
=
GIT_BUF_INIT
;
git_buf
path
=
GIT_BUF_INIT
;
int
error
=
parse_header_path_buf
(
&
path
,
ctx
);
int
error
=
parse_header_path_buf
(
&
path
,
ctx
);
...
@@ -165,18 +171,18 @@ static int parse_header_path(char **out, patch_parse_ctx *ctx)
...
@@ -165,18 +171,18 @@ static int parse_header_path(char **out, patch_parse_ctx *ctx)
}
}
static
int
parse_header_git_oldpath
(
static
int
parse_header_git_oldpath
(
git_patch_parsed
*
patch
,
patch_parse_ctx
*
ctx
)
git_patch_parsed
*
patch
,
git_
patch_parse_ctx
*
ctx
)
{
{
return
parse_header_path
(
&
patch
->
old_path
,
ctx
);
return
parse_header_path
(
&
patch
->
old_path
,
ctx
);
}
}
static
int
parse_header_git_newpath
(
static
int
parse_header_git_newpath
(
git_patch_parsed
*
patch
,
patch_parse_ctx
*
ctx
)
git_patch_parsed
*
patch
,
git_
patch_parse_ctx
*
ctx
)
{
{
return
parse_header_path
(
&
patch
->
new_path
,
ctx
);
return
parse_header_path
(
&
patch
->
new_path
,
ctx
);
}
}
static
int
parse_header_mode
(
uint16_t
*
mode
,
patch_parse_ctx
*
ctx
)
static
int
parse_header_mode
(
uint16_t
*
mode
,
git_
patch_parse_ctx
*
ctx
)
{
{
const
char
*
end
;
const
char
*
end
;
int32_t
m
;
int32_t
m
;
...
@@ -201,7 +207,7 @@ static int parse_header_mode(uint16_t *mode, patch_parse_ctx *ctx)
...
@@ -201,7 +207,7 @@ static int parse_header_mode(uint16_t *mode, patch_parse_ctx *ctx)
static
int
parse_header_oid
(
static
int
parse_header_oid
(
git_oid
*
oid
,
git_oid
*
oid
,
int
*
oid_len
,
int
*
oid_len
,
patch_parse_ctx
*
ctx
)
git_
patch_parse_ctx
*
ctx
)
{
{
size_t
len
;
size_t
len
;
...
@@ -223,7 +229,7 @@ static int parse_header_oid(
...
@@ -223,7 +229,7 @@ static int parse_header_oid(
}
}
static
int
parse_header_git_index
(
static
int
parse_header_git_index
(
git_patch_parsed
*
patch
,
patch_parse_ctx
*
ctx
)
git_patch_parsed
*
patch
,
git_
patch_parse_ctx
*
ctx
)
{
{
if
(
parse_header_oid
(
&
patch
->
base
.
delta
->
old_file
.
id
,
if
(
parse_header_oid
(
&
patch
->
base
.
delta
->
old_file
.
id
,
&
patch
->
base
.
delta
->
old_file
.
id_abbrev
,
ctx
)
<
0
||
&
patch
->
base
.
delta
->
old_file
.
id_abbrev
,
ctx
)
<
0
||
...
@@ -251,20 +257,20 @@ static int parse_header_git_index(
...
@@ -251,20 +257,20 @@ static int parse_header_git_index(
}
}
static
int
parse_header_git_oldmode
(
static
int
parse_header_git_oldmode
(
git_patch_parsed
*
patch
,
patch_parse_ctx
*
ctx
)
git_patch_parsed
*
patch
,
git_
patch_parse_ctx
*
ctx
)
{
{
return
parse_header_mode
(
&
patch
->
base
.
delta
->
old_file
.
mode
,
ctx
);
return
parse_header_mode
(
&
patch
->
base
.
delta
->
old_file
.
mode
,
ctx
);
}
}
static
int
parse_header_git_newmode
(
static
int
parse_header_git_newmode
(
git_patch_parsed
*
patch
,
patch_parse_ctx
*
ctx
)
git_patch_parsed
*
patch
,
git_
patch_parse_ctx
*
ctx
)
{
{
return
parse_header_mode
(
&
patch
->
base
.
delta
->
new_file
.
mode
,
ctx
);
return
parse_header_mode
(
&
patch
->
base
.
delta
->
new_file
.
mode
,
ctx
);
}
}
static
int
parse_header_git_deletedfilemode
(
static
int
parse_header_git_deletedfilemode
(
git_patch_parsed
*
patch
,
git_patch_parsed
*
patch
,
patch_parse_ctx
*
ctx
)
git_
patch_parse_ctx
*
ctx
)
{
{
git__free
((
char
*
)
patch
->
base
.
delta
->
old_file
.
path
);
git__free
((
char
*
)
patch
->
base
.
delta
->
old_file
.
path
);
...
@@ -277,7 +283,7 @@ static int parse_header_git_deletedfilemode(
...
@@ -277,7 +283,7 @@ static int parse_header_git_deletedfilemode(
static
int
parse_header_git_newfilemode
(
static
int
parse_header_git_newfilemode
(
git_patch_parsed
*
patch
,
git_patch_parsed
*
patch
,
patch_parse_ctx
*
ctx
)
git_
patch_parse_ctx
*
ctx
)
{
{
git__free
((
char
*
)
patch
->
base
.
delta
->
new_file
.
path
);
git__free
((
char
*
)
patch
->
base
.
delta
->
new_file
.
path
);
...
@@ -290,7 +296,7 @@ static int parse_header_git_newfilemode(
...
@@ -290,7 +296,7 @@ static int parse_header_git_newfilemode(
static
int
parse_header_rename
(
static
int
parse_header_rename
(
char
**
out
,
char
**
out
,
patch_parse_ctx
*
ctx
)
git_
patch_parse_ctx
*
ctx
)
{
{
git_buf
path
=
GIT_BUF_INIT
;
git_buf
path
=
GIT_BUF_INIT
;
...
@@ -305,20 +311,20 @@ static int parse_header_rename(
...
@@ -305,20 +311,20 @@ static int parse_header_rename(
}
}
static
int
parse_header_renamefrom
(
static
int
parse_header_renamefrom
(
git_patch_parsed
*
patch
,
patch_parse_ctx
*
ctx
)
git_patch_parsed
*
patch
,
git_
patch_parse_ctx
*
ctx
)
{
{
patch
->
base
.
delta
->
status
=
GIT_DELTA_RENAMED
;
patch
->
base
.
delta
->
status
=
GIT_DELTA_RENAMED
;
return
parse_header_rename
(
&
patch
->
rename_old_path
,
ctx
);
return
parse_header_rename
(
&
patch
->
rename_old_path
,
ctx
);
}
}
static
int
parse_header_renameto
(
static
int
parse_header_renameto
(
git_patch_parsed
*
patch
,
patch_parse_ctx
*
ctx
)
git_patch_parsed
*
patch
,
git_
patch_parse_ctx
*
ctx
)
{
{
patch
->
base
.
delta
->
status
=
GIT_DELTA_RENAMED
;
patch
->
base
.
delta
->
status
=
GIT_DELTA_RENAMED
;
return
parse_header_rename
(
&
patch
->
rename_new_path
,
ctx
);
return
parse_header_rename
(
&
patch
->
rename_new_path
,
ctx
);
}
}
static
int
parse_header_percent
(
uint16_t
*
out
,
patch_parse_ctx
*
ctx
)
static
int
parse_header_percent
(
uint16_t
*
out
,
git_
patch_parse_ctx
*
ctx
)
{
{
int32_t
val
;
int32_t
val
;
const
char
*
end
;
const
char
*
end
;
...
@@ -340,7 +346,7 @@ static int parse_header_percent(uint16_t *out, patch_parse_ctx *ctx)
...
@@ -340,7 +346,7 @@ static int parse_header_percent(uint16_t *out, patch_parse_ctx *ctx)
}
}
static
int
parse_header_similarity
(
static
int
parse_header_similarity
(
git_patch_parsed
*
patch
,
patch_parse_ctx
*
ctx
)
git_patch_parsed
*
patch
,
git_
patch_parse_ctx
*
ctx
)
{
{
if
(
parse_header_percent
(
&
patch
->
base
.
delta
->
similarity
,
ctx
)
<
0
)
if
(
parse_header_percent
(
&
patch
->
base
.
delta
->
similarity
,
ctx
)
<
0
)
return
parse_err
(
"invalid similarity percentage at line %d"
,
return
parse_err
(
"invalid similarity percentage at line %d"
,
...
@@ -350,7 +356,7 @@ static int parse_header_similarity(
...
@@ -350,7 +356,7 @@ static int parse_header_similarity(
}
}
static
int
parse_header_dissimilarity
(
static
int
parse_header_dissimilarity
(
git_patch_parsed
*
patch
,
patch_parse_ctx
*
ctx
)
git_patch_parsed
*
patch
,
git_
patch_parse_ctx
*
ctx
)
{
{
uint16_t
dissimilarity
;
uint16_t
dissimilarity
;
...
@@ -365,7 +371,7 @@ static int parse_header_dissimilarity(
...
@@ -365,7 +371,7 @@ static int parse_header_dissimilarity(
typedef
struct
{
typedef
struct
{
const
char
*
str
;
const
char
*
str
;
int
(
*
fn
)(
git_patch_parsed
*
,
patch_parse_ctx
*
);
int
(
*
fn
)(
git_patch_parsed
*
,
git_
patch_parse_ctx
*
);
}
header_git_op
;
}
header_git_op
;
static
const
header_git_op
header_git_ops
[]
=
{
static
const
header_git_op
header_git_ops
[]
=
{
...
@@ -388,7 +394,7 @@ static const header_git_op header_git_ops[] = {
...
@@ -388,7 +394,7 @@ static const header_git_op header_git_ops[] = {
static
int
parse_header_git
(
static
int
parse_header_git
(
git_patch_parsed
*
patch
,
git_patch_parsed
*
patch
,
patch_parse_ctx
*
ctx
)
git_
patch_parse_ctx
*
ctx
)
{
{
size_t
i
;
size_t
i
;
int
error
=
0
;
int
error
=
0
;
...
@@ -443,7 +449,7 @@ done:
...
@@ -443,7 +449,7 @@ done:
return
error
;
return
error
;
}
}
static
int
parse_number
(
git_off_t
*
out
,
patch_parse_ctx
*
ctx
)
static
int
parse_number
(
git_off_t
*
out
,
git_
patch_parse_ctx
*
ctx
)
{
{
const
char
*
end
;
const
char
*
end
;
int64_t
num
;
int64_t
num
;
...
@@ -463,7 +469,7 @@ static int parse_number(git_off_t *out, patch_parse_ctx *ctx)
...
@@ -463,7 +469,7 @@ static int parse_number(git_off_t *out, patch_parse_ctx *ctx)
return
0
;
return
0
;
}
}
static
int
parse_int
(
int
*
out
,
patch_parse_ctx
*
ctx
)
static
int
parse_int
(
int
*
out
,
git_
patch_parse_ctx
*
ctx
)
{
{
git_off_t
num
;
git_off_t
num
;
...
@@ -476,7 +482,7 @@ static int parse_int(int *out, patch_parse_ctx *ctx)
...
@@ -476,7 +482,7 @@ static int parse_int(int *out, patch_parse_ctx *ctx)
static
int
parse_hunk_header
(
static
int
parse_hunk_header
(
git_patch_hunk
*
hunk
,
git_patch_hunk
*
hunk
,
patch_parse_ctx
*
ctx
)
git_
patch_parse_ctx
*
ctx
)
{
{
const
char
*
header_start
=
ctx
->
line
;
const
char
*
header_start
=
ctx
->
line
;
...
@@ -530,7 +536,7 @@ fail:
...
@@ -530,7 +536,7 @@ fail:
static
int
parse_hunk_body
(
static
int
parse_hunk_body
(
git_patch_parsed
*
patch
,
git_patch_parsed
*
patch
,
git_patch_hunk
*
hunk
,
git_patch_hunk
*
hunk
,
patch_parse_ctx
*
ctx
)
git_
patch_parse_ctx
*
ctx
)
{
{
git_diff_line
*
line
;
git_diff_line
*
line
;
int
error
=
0
;
int
error
=
0
;
...
@@ -621,9 +627,9 @@ done:
...
@@ -621,9 +627,9 @@ done:
return
error
;
return
error
;
}
}
static
int
parse
d
_patch_header
(
static
int
parse_patch_header
(
git_patch_parsed
*
patch
,
git_patch_parsed
*
patch
,
patch_parse_ctx
*
ctx
)
git_
patch_parse_ctx
*
ctx
)
{
{
int
error
=
0
;
int
error
=
0
;
...
@@ -671,9 +677,9 @@ done:
...
@@ -671,9 +677,9 @@ done:
return
error
;
return
error
;
}
}
static
int
parse
d
_patch_binary_side
(
static
int
parse_patch_binary_side
(
git_diff_binary_file
*
binary
,
git_diff_binary_file
*
binary
,
patch_parse_ctx
*
ctx
)
git_
patch_parse_ctx
*
ctx
)
{
{
git_diff_binary_t
type
=
GIT_DIFF_BINARY_NONE
;
git_diff_binary_t
type
=
GIT_DIFF_BINARY_NONE
;
git_buf
base85
=
GIT_BUF_INIT
,
decoded
=
GIT_BUF_INIT
;
git_buf
base85
=
GIT_BUF_INIT
,
decoded
=
GIT_BUF_INIT
;
...
@@ -750,9 +756,9 @@ done:
...
@@ -750,9 +756,9 @@ done:
return
error
;
return
error
;
}
}
static
int
parse
d
_patch_binary
(
static
int
parse_patch_binary
(
git_patch_parsed
*
patch
,
git_patch_parsed
*
patch
,
patch_parse_ctx
*
ctx
)
git_
patch_parse_ctx
*
ctx
)
{
{
int
error
;
int
error
;
...
@@ -761,7 +767,7 @@ static int parsed_patch_binary(
...
@@ -761,7 +767,7 @@ static int parsed_patch_binary(
return
parse_err
(
"corrupt git binary header at line %d"
,
ctx
->
line_num
);
return
parse_err
(
"corrupt git binary header at line %d"
,
ctx
->
line_num
);
/* parse old->new binary diff */
/* parse old->new binary diff */
if
((
error
=
parse
d
_patch_binary_side
(
if
((
error
=
parse_patch_binary_side
(
&
patch
->
base
.
binary
.
new_file
,
ctx
))
<
0
)
&
patch
->
base
.
binary
.
new_file
,
ctx
))
<
0
)
return
error
;
return
error
;
...
@@ -770,7 +776,7 @@ static int parsed_patch_binary(
...
@@ -770,7 +776,7 @@ static int parsed_patch_binary(
ctx
->
line_num
);
ctx
->
line_num
);
/* parse new->old binary diff */
/* parse new->old binary diff */
if
((
error
=
parse
d
_patch_binary_side
(
if
((
error
=
parse_patch_binary_side
(
&
patch
->
base
.
binary
.
old_file
,
ctx
))
<
0
)
&
patch
->
base
.
binary
.
old_file
,
ctx
))
<
0
)
return
error
;
return
error
;
...
@@ -778,9 +784,9 @@ static int parsed_patch_binary(
...
@@ -778,9 +784,9 @@ static int parsed_patch_binary(
return
0
;
return
0
;
}
}
static
int
parse
d
_patch_hunks
(
static
int
parse_patch_hunks
(
git_patch_parsed
*
patch
,
git_patch_parsed
*
patch
,
patch_parse_ctx
*
ctx
)
git_
patch_parse_ctx
*
ctx
)
{
{
git_patch_hunk
*
hunk
;
git_patch_hunk
*
hunk
;
int
error
=
0
;
int
error
=
0
;
...
@@ -803,14 +809,14 @@ done:
...
@@ -803,14 +809,14 @@ done:
return
error
;
return
error
;
}
}
static
int
parse
d
_patch_body
(
static
int
parse_patch_body
(
git_patch_parsed
*
patch
,
patch_parse_ctx
*
ctx
)
git_patch_parsed
*
patch
,
git_
patch_parse_ctx
*
ctx
)
{
{
if
(
parse_ctx_contains_s
(
ctx
,
"GIT binary patch"
))
if
(
parse_ctx_contains_s
(
ctx
,
"GIT binary patch"
))
return
parse
d
_patch_binary
(
patch
,
ctx
);
return
parse_patch_binary
(
patch
,
ctx
);
else
if
(
parse_ctx_contains_s
(
ctx
,
"@@ -"
))
else
if
(
parse_ctx_contains_s
(
ctx
,
"@@ -"
))
return
parse
d
_patch_hunks
(
patch
,
ctx
);
return
parse_patch_hunks
(
patch
,
ctx
);
return
0
;
return
0
;
}
}
...
@@ -840,12 +846,13 @@ static int check_prefix(
...
@@ -840,12 +846,13 @@ static int check_prefix(
const
char
*
path_start
)
const
char
*
path_start
)
{
{
const
char
*
path
=
path_start
;
const
char
*
path
=
path_start
;
uint32_t
remain
=
patch
->
opts
.
prefix_len
;
size_t
prefix_len
=
patch
->
ctx
->
opts
.
prefix_len
;
size_t
remain
=
prefix_len
;
*
out
=
NULL
;
*
out
=
NULL
;
*
out_len
=
0
;
*
out_len
=
0
;
if
(
p
atch
->
opts
.
p
refix_len
==
0
)
if
(
prefix_len
==
0
)
goto
done
;
goto
done
;
/* leading slashes do not count as part of the prefix in git apply */
/* leading slashes do not count as part of the prefix in git apply */
...
@@ -860,8 +867,9 @@ static int check_prefix(
...
@@ -860,8 +867,9 @@ static int check_prefix(
}
}
if
(
remain
||
!*
path
)
if
(
remain
||
!*
path
)
return
parse_err
(
"header filename does not contain %d path components"
,
return
parse_err
(
patch
->
opts
.
prefix_len
);
"header filename does not contain %d path components"
,
prefix_len
);
done:
done:
*
out_len
=
(
path
-
path_start
);
*
out_len
=
(
path
-
path_start
);
...
@@ -938,6 +946,50 @@ static int check_patch(git_patch_parsed *patch)
...
@@ -938,6 +946,50 @@ static int check_patch(git_patch_parsed *patch)
return
0
;
return
0
;
}
}
static
git_patch_parse_ctx
*
git_patch_parse_ctx_init
(
const
char
*
content
,
size_t
content_len
,
const
git_patch_options
*
opts
)
{
git_patch_parse_ctx
*
ctx
;
git_patch_options
default_opts
=
GIT_PATCH_OPTIONS_INIT
;
if
((
ctx
=
git__calloc
(
1
,
sizeof
(
git_patch_parse_ctx
)))
==
NULL
)
return
NULL
;
if
(
content_len
)
{
if
((
ctx
->
content
=
git__malloc
(
content_len
))
==
NULL
)
return
NULL
;
memcpy
((
char
*
)
ctx
->
content
,
content
,
content_len
);
}
ctx
->
content_len
=
content_len
;
ctx
->
remain
=
content_len
;
if
(
opts
)
memcpy
(
&
ctx
->
opts
,
opts
,
sizeof
(
git_patch_options
));
else
memcpy
(
&
ctx
->
opts
,
&
default_opts
,
sizeof
(
git_patch_options
));
GIT_REFCOUNT_INC
(
ctx
);
return
ctx
;
}
static
void
patch_parse_ctx_free
(
git_patch_parse_ctx
*
ctx
)
{
if
(
!
ctx
)
return
;
git__free
((
char
*
)
ctx
->
content
);
git__free
(
ctx
);
}
static
void
git_patch_parse_ctx_free
(
git_patch_parse_ctx
*
ctx
)
{
GIT_REFCOUNT_DEC
(
ctx
,
patch_parse_ctx_free
);
}
static
void
patch_parsed__free
(
git_patch
*
p
)
static
void
patch_parsed__free
(
git_patch
*
p
)
{
{
git_patch_parsed
*
patch
=
(
git_patch_parsed
*
)
p
;
git_patch_parsed
*
patch
=
(
git_patch_parsed
*
)
p
;
...
@@ -945,6 +997,8 @@ static void patch_parsed__free(git_patch *p)
...
@@ -945,6 +997,8 @@ static void patch_parsed__free(git_patch *p)
if
(
!
patch
)
if
(
!
patch
)
return
;
return
;
git_patch_parse_ctx_free
(
patch
->
ctx
);
git__free
((
char
*
)
patch
->
base
.
binary
.
old_file
.
data
);
git__free
((
char
*
)
patch
->
base
.
binary
.
old_file
.
data
);
git__free
((
char
*
)
patch
->
base
.
binary
.
new_file
.
data
);
git__free
((
char
*
)
patch
->
base
.
binary
.
new_file
.
data
);
git_array_clear
(
patch
->
base
.
hunks
);
git_array_clear
(
patch
->
base
.
hunks
);
...
@@ -959,30 +1013,25 @@ static void patch_parsed__free(git_patch *p)
...
@@ -959,30 +1013,25 @@ static void patch_parsed__free(git_patch *p)
git__free
(
patch
->
rename_new_path
);
git__free
(
patch
->
rename_new_path
);
git__free
(
patch
->
old_path
);
git__free
(
patch
->
old_path
);
git__free
(
patch
->
new_path
);
git__free
(
patch
->
new_path
);
git__free
(
patch
->
content
);
git__free
(
patch
);
git__free
(
patch
);
}
}
int
git_patch_from_buffer
(
static
int
git_patch_parse
(
git_patch
**
out
,
git_patch
**
out
,
const
char
*
content
,
git_patch_parse_ctx
*
ctx
)
size_t
content_len
,
git_patch_options
*
opts
)
{
{
patch_parse_ctx
ctx
=
{
0
};
git_patch_parsed
*
patch
;
git_patch_parsed
*
patch
;
git_patch_options
default_opts
=
GIT_PATCH_OPTIONS_INIT
;
int
error
=
0
;
int
error
=
0
;
assert
(
out
&&
ctx
);
*
out
=
NULL
;
*
out
=
NULL
;
patch
=
git__calloc
(
1
,
sizeof
(
git_patch_parsed
));
patch
=
git__calloc
(
1
,
sizeof
(
git_patch_parsed
));
GITERR_CHECK_ALLOC
(
patch
);
GITERR_CHECK_ALLOC
(
patch
);
if
(
opts
)
patch
->
ctx
=
ctx
;
memcpy
(
&
patch
->
opts
,
opts
,
sizeof
(
git_patch_options
));
GIT_REFCOUNT_INC
(
patch
->
ctx
);
else
memcpy
(
&
patch
->
opts
,
&
default_opts
,
sizeof
(
git_patch_options
));
patch
->
base
.
free_fn
=
patch_parsed__free
;
patch
->
base
.
free_fn
=
patch_parsed__free
;
...
@@ -992,19 +1041,8 @@ int git_patch_from_buffer(
...
@@ -992,19 +1041,8 @@ int git_patch_from_buffer(
patch
->
base
.
delta
->
status
=
GIT_DELTA_MODIFIED
;
patch
->
base
.
delta
->
status
=
GIT_DELTA_MODIFIED
;
patch
->
base
.
delta
->
nfiles
=
2
;
patch
->
base
.
delta
->
nfiles
=
2
;
if
(
content_len
)
{
if
((
error
=
parse_patch_header
(
patch
,
ctx
))
<
0
||
patch
->
content
=
git__malloc
(
content_len
);
(
error
=
parse_patch_body
(
patch
,
ctx
))
<
0
||
GITERR_CHECK_ALLOC
(
patch
->
content
);
memcpy
(
patch
->
content
,
content
,
content_len
);
}
ctx
.
content
=
patch
->
content
;
ctx
.
content_len
=
content_len
;
ctx
.
remain
=
content_len
;
if
((
error
=
parsed_patch_header
(
patch
,
&
ctx
))
<
0
||
(
error
=
parsed_patch_body
(
patch
,
&
ctx
))
<
0
||
(
error
=
check_patch
(
patch
))
<
0
)
(
error
=
check_patch
(
patch
))
<
0
)
goto
done
;
goto
done
;
...
@@ -1021,3 +1059,22 @@ done:
...
@@ -1021,3 +1059,22 @@ done:
return
error
;
return
error
;
}
}
int
git_patch_from_buffer
(
git_patch
**
out
,
const
char
*
content
,
size_t
content_len
,
const
git_patch_options
*
opts
)
{
git_patch_parse_ctx
*
ctx
;
int
error
;
ctx
=
git_patch_parse_ctx_init
(
content
,
content_len
,
opts
);
GITERR_CHECK_ALLOC
(
ctx
);
error
=
git_patch_parse
(
out
,
ctx
);
git_patch_parse_ctx_free
(
ctx
);
return
error
;
}
src/patch_parse.h
0 → 100644
View file @
17572f67
/*
* Copyright (C) the libgit2 contributors. All rights reserved.
*
* This file is part of libgit2, distributed under the GNU GPL v2 with
* a Linking Exception. For full terms see the included COPYING file.
*/
#ifndef INCLUDE_patch_parse_h__
#define INCLUDE_patch_parse_h__
/**
* Create a patch for a single file from the contents of a patch buffer.
*
* @param out The patch to be created
* @param contents The contents of a patch file
* @param contents_len The length of the patch file
* @param opts The git_patch_options
* @return 0 on success, <0 on failure.
*/
extern
int
git_patch_from_buffer
(
git_patch
**
out
,
const
char
*
contents
,
size_t
contents_len
,
const
git_patch_options
*
opts
);
#endif
tests/apply/fromfile.c
View file @
17572f67
...
@@ -3,6 +3,7 @@
...
@@ -3,6 +3,7 @@
#include "apply.h"
#include "apply.h"
#include "patch.h"
#include "patch.h"
#include "patch_parse.h"
#include "repository.h"
#include "repository.h"
#include "buf_text.h"
#include "buf_text.h"
...
...
tests/patch/parse.c
View file @
17572f67
#include "clar_libgit2.h"
#include "clar_libgit2.h"
#include "patch.h"
#include "patch.h"
#include "patch_parse.h"
#include "patch_common.h"
#include "patch_common.h"
...
...
tests/patch/print.c
View file @
17572f67
#include "clar_libgit2.h"
#include "clar_libgit2.h"
#include "patch.h"
#include "patch.h"
#include "patch_parse.h"
#include "patch_common.h"
#include "patch_common.h"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment