builtin/apply: move 'p_value' global into 'struct apply_state'
To libify the apply functionality the 'p_value' variable should not be static and global to the file. Let's move it into 'struct apply_state'. Reviewed-by: Stefan Beller <sbeller@google.com> Signed-off-by: Christian Couder <chriscool@tuxfamily.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Christian Couder committed
May 24, 2016 at 10:11 UTC
dbd23433e7b3d95bb03b44e9da86f713f1e35e17
1 file changed
+99
-52
builtin/apply.c
+99
-52
@@ -51,6 +51,7 @@ struct apply_state {
51
const char *fake_ancestor;
52
const char *patch_input_file;
53
int line_termination;
54
+ int p_value;
55
unsigned int p_context;
56
57
/* Exclude and include path parameters */
@@ -60,7 +61,6 @@ struct apply_state {
61
62
static int newfd = -1;
63
63
-static int state_p_value = 1;
64
static int p_value_known;
65
66
static const char * const apply_usage[] = {
@@ -881,24 +881,24 @@ static void parse_traditional_patch(struct apply_state *state,
881
q = guess_p_value(state, second);
882
if (p < 0) p = q;
883
if (0 <= p && p == q) {
884
- state_p_value = p;
884
+ state->p_value = p;
885
p_value_known = 1;
886
}
887
}
888
if (is_dev_null(first)) {
889
patch->is_new = 1;
890
patch->is_delete = 0;
891
- name = find_name_traditional(second, NULL, state_p_value);
891
+ name = find_name_traditional(second, NULL, state->p_value);
892
patch->new_name = name;
893
} else if (is_dev_null(second)) {
894
patch->is_new = 0;
895
patch->is_delete = 1;
896
- name = find_name_traditional(first, NULL, state_p_value);
896
+ name = find_name_traditional(first, NULL, state->p_value);
897
patch->old_name = name;
898
} else {
899
char *first_name;
900
- first_name = find_name_traditional(first, NULL, state_p_value);
901
- name = find_name_traditional(second, first_name, state_p_value);
900
+ first_name = find_name_traditional(first, NULL, state->p_value);
901
+ name = find_name_traditional(second, first_name, state->p_value);
902
free(first_name);
903
if (has_epoch_timestamp(first)) {
904
patch->is_new = 1;
@@ -917,7 +917,9 @@ static void parse_traditional_patch(struct apply_state *state,
917
die(_("unable to find filename in patch at line %d"), state_linenr);
918
}
919
920
-static int gitdiff_hdrend(const char *line, struct patch *patch)
920
+static int gitdiff_hdrend(struct apply_state *state,
921
+ const char *line,
922
+ struct patch *patch)
923
{
924
return -1;
925
}
@@ -934,10 +936,14 @@ static int gitdiff_hdrend(const char *line, struct patch *patch)
936
#define DIFF_OLD_NAME 0
937
#define DIFF_NEW_NAME 1
938
937
-static void gitdiff_verify_name(const char *line, int isnull, char **name, int side)
939
+static void gitdiff_verify_name(struct apply_state *state,
940
+ const char *line,
941
+ int isnull,
942
+ char **name,
943
+ int side)
944
{
945
if (!*name && !isnull) {
940
- *name = find_name(line, NULL, state_p_value, TERM_TAB);
946
+ *name = find_name(line, NULL, state->p_value, TERM_TAB);
947
return;
948
}
949
@@ -947,7 +953,7 @@ static void gitdiff_verify_name(const char *line, int isnull, char **name, int s
953
if (isnull)
954
die(_("git apply: bad git-diff - expected /dev/null, got %s on line %d"),
955
*name, state_linenr);
950
- another = find_name(line, NULL, state_p_value, TERM_TAB);
956
+ another = find_name(line, NULL, state->p_value, TERM_TAB);
957
if (!another || memcmp(another, *name, len + 1))
958
die((side == DIFF_NEW_NAME) ?
959
_("git apply: bad git-diff - inconsistent new filename on line %d") :
@@ -960,81 +966,105 @@ static void gitdiff_verify_name(const char *line, int isnull, char **name, int s
966
}
967
}
968
963
-static int gitdiff_oldname(const char *line, struct patch *patch)
969
+static int gitdiff_oldname(struct apply_state *state,
970
+ const char *line,
971
+ struct patch *patch)
972
{
965
- gitdiff_verify_name(line, patch->is_new, &patch->old_name,
973
+ gitdiff_verify_name(state, line,
974
+ patch->is_new, &patch->old_name,
975
DIFF_OLD_NAME);
976
return 0;
977
}
978
970
-static int gitdiff_newname(const char *line, struct patch *patch)
979
+static int gitdiff_newname(struct apply_state *state,
980
+ const char *line,
981
+ struct patch *patch)
982
{
972
- gitdiff_verify_name(line, patch->is_delete, &patch->new_name,
983
+ gitdiff_verify_name(state, line,
984
+ patch->is_delete, &patch->new_name,
985
DIFF_NEW_NAME);
986
return 0;
987
}
988
977
-static int gitdiff_oldmode(const char *line, struct patch *patch)
989
+static int gitdiff_oldmode(struct apply_state *state,
990
+ const char *line,
991
+ struct patch *patch)
992
{
993
patch->old_mode = strtoul(line, NULL, 8);
994
return 0;
995
}
996
983
-static int gitdiff_newmode(const char *line, struct patch *patch)
997
+static int gitdiff_newmode(struct apply_state *state,
998
+ const char *line,
999
+ struct patch *patch)
1000
{
1001
patch->new_mode = strtoul(line, NULL, 8);
1002
return 0;
1003
}
1004
989
-static int gitdiff_delete(const char *line, struct patch *patch)
1005
+static int gitdiff_delete(struct apply_state *state,
1006
+ const char *line,
1007
+ struct patch *patch)
1008
{
1009
patch->is_delete = 1;
1010
free(patch->old_name);
1011
patch->old_name = xstrdup_or_null(patch->def_name);
994
- return gitdiff_oldmode(line, patch);
1012
+ return gitdiff_oldmode(state, line, patch);
1013
}
1014
997
-static int gitdiff_newfile(const char *line, struct patch *patch)
1015
+static int gitdiff_newfile(struct apply_state *state,
1016
+ const char *line,
1017
+ struct patch *patch)
1018
{
1019
patch->is_new = 1;
1020
free(patch->new_name);
1021
patch->new_name = xstrdup_or_null(patch->def_name);
1002
- return gitdiff_newmode(line, patch);
1022
+ return gitdiff_newmode(state, line, patch);
1023
}
1024
1005
-static int gitdiff_copysrc(const char *line, struct patch *patch)
1025
+static int gitdiff_copysrc(struct apply_state *state,
1026
+ const char *line,
1027
+ struct patch *patch)
1028
{
1029
patch->is_copy = 1;
1030
free(patch->old_name);
1009
- patch->old_name = find_name(line, NULL, state_p_value ? state_p_value - 1 : 0, 0);
1031
+ patch->old_name = find_name(line, NULL, state->p_value ? state->p_value - 1 : 0, 0);
1032
return 0;
1033
}
1034
1013
-static int gitdiff_copydst(const char *line, struct patch *patch)
1035
+static int gitdiff_copydst(struct apply_state *state,
1036
+ const char *line,
1037
+ struct patch *patch)
1038
{
1039
patch->is_copy = 1;
1040
free(patch->new_name);
1017
- patch->new_name = find_name(line, NULL, state_p_value ? state_p_value - 1 : 0, 0);
1041
+ patch->new_name = find_name(line, NULL, state->p_value ? state->p_value - 1 : 0, 0);
1042
return 0;
1043
}
1044
1021
-static int gitdiff_renamesrc(const char *line, struct patch *patch)
1045
+static int gitdiff_renamesrc(struct apply_state *state,
1046
+ const char *line,
1047
+ struct patch *patch)
1048
{
1049
patch->is_rename = 1;
1050
free(patch->old_name);
1025
- patch->old_name = find_name(line, NULL, state_p_value ? state_p_value - 1 : 0, 0);
1051
+ patch->old_name = find_name(line, NULL, state->p_value ? state->p_value - 1 : 0, 0);
1052
return 0;
1053
}
1054
1029
-static int gitdiff_renamedst(const char *line, struct patch *patch)
1055
+static int gitdiff_renamedst(struct apply_state *state,
1056
+ const char *line,
1057
+ struct patch *patch)
1058
{
1059
patch->is_rename = 1;
1060
free(patch->new_name);
1033
- patch->new_name = find_name(line, NULL, state_p_value ? state_p_value - 1 : 0, 0);
1061
+ patch->new_name = find_name(line, NULL, state->p_value ? state->p_value - 1 : 0, 0);
1062
return 0;
1063
}
1064
1037
-static int gitdiff_similarity(const char *line, struct patch *patch)
1065
+static int gitdiff_similarity(struct apply_state *state,
1066
+ const char *line,
1067
+ struct patch *patch)
1068
{
1069
unsigned long val = strtoul(line, NULL, 10);
1070
if (val <= 100)
@@ -1042,7 +1072,9 @@ static int gitdiff_similarity(const char *line, struct patch *patch)
1072
return 0;
1073
}
1074
1045
-static int gitdiff_dissimilarity(const char *line, struct patch *patch)
1075
+static int gitdiff_dissimilarity(struct apply_state *state,
1076
+ const char *line,
1077
+ struct patch *patch)
1078
{
1079
unsigned long val = strtoul(line, NULL, 10);
1080
if (val <= 100)
@@ -1050,7 +1082,9 @@ static int gitdiff_dissimilarity(const char *line, struct patch *patch)
1082
return 0;
1083
}
1084
1053
-static int gitdiff_index(const char *line, struct patch *patch)
1085
+static int gitdiff_index(struct apply_state *state,
1086
+ const char *line,
1087
+ struct patch *patch)
1088
{
1089
/*
1090
* index line is N hexadecimal, "..", N hexadecimal,
@@ -1087,7 +1121,9 @@ static int gitdiff_index(const char *line, struct patch *patch)
1121
* This is normal for a diff that doesn't change anything: we'll fall through
1122
* into the next diff. Tell the parser to break out.
1123
*/
1090
-static int gitdiff_unrecognized(const char *line, struct patch *patch)
1124
+static int gitdiff_unrecognized(struct apply_state *state,
1125
+ const char *line,
1126
+ struct patch *patch)
1127
{
1128
return -1;
1129
}
@@ -1096,15 +1132,17 @@ static int gitdiff_unrecognized(const char *line, struct patch *patch)
1132
* Skip p_value leading components from "line"; as we do not accept
1133
* absolute paths, return NULL in that case.
1134
*/
1099
-static const char *skip_tree_prefix(const char *line, int llen)
1135
+static const char *skip_tree_prefix(struct apply_state *state,
1136
+ const char *line,
1137
+ int llen)
1138
{
1139
int nslash;
1140
int i;
1141
1104
- if (!state_p_value)
1142
+ if (!state->p_value)
1143
return (llen && line[0] == '/') ? NULL : line;
1144
1107
- nslash = state_p_value;
1145
+ nslash = state->p_value;
1146
for (i = 0; i < llen; i++) {
1147
int ch = line[i];
1148
if (ch == '/' && --nslash <= 0)
@@ -1121,7 +1159,9 @@ static const char *skip_tree_prefix(const char *line, int llen)
1159
* creation or deletion of an empty file. In any of these cases,
1160
* both sides are the same name under a/ and b/ respectively.
1161
*/
1124
-static char *git_header_name(const char *line, int llen)
1162
+static char *git_header_name(struct apply_state *state,
1163
+ const char *line,
1164
+ int llen)
1165
{
1166
const char *name;
1167
const char *second = NULL;
@@ -1139,7 +1179,7 @@ static char *git_header_name(const char *line, int llen)
1179
goto free_and_fail1;
1180
1181
/* strip the a/b prefix including trailing slash */
1142
- cp = skip_tree_prefix(first.buf, first.len);
1182
+ cp = skip_tree_prefix(state, first.buf, first.len);
1183
if (!cp)
1184
goto free_and_fail1;
1185
strbuf_remove(&first, 0, cp - first.buf);
@@ -1156,7 +1196,7 @@ static char *git_header_name(const char *line, int llen)
1196
if (*second == '"') {
1197
if (unquote_c_style(&sp, second, NULL))
1198
goto free_and_fail1;
1159
- cp = skip_tree_prefix(sp.buf, sp.len);
1199
+ cp = skip_tree_prefix(state, sp.buf, sp.len);
1200
if (!cp)
1201
goto free_and_fail1;
1202
/* They must match, otherwise ignore */
@@ -1167,7 +1207,7 @@ static char *git_header_name(const char *line, int llen)
1207
}
1208
1209
/* unquoted second */
1170
- cp = skip_tree_prefix(second, line + llen - second);
1210
+ cp = skip_tree_prefix(state, second, line + llen - second);
1211
if (!cp)
1212
goto free_and_fail1;
1213
if (line + llen - cp != first.len ||
@@ -1182,7 +1222,7 @@ static char *git_header_name(const char *line, int llen)
1222
}
1223
1224
/* unquoted first name */
1185
- name = skip_tree_prefix(line, llen);
1225
+ name = skip_tree_prefix(state, line, llen);
1226
if (!name)
1227
return NULL;
1228
@@ -1198,7 +1238,7 @@ static char *git_header_name(const char *line, int llen)
1238
if (unquote_c_style(&sp, second, NULL))
1239
goto free_and_fail2;
1240
1201
- np = skip_tree_prefix(sp.buf, sp.len);
1241
+ np = skip_tree_prefix(state, sp.buf, sp.len);
1242
if (!np)
1243
goto free_and_fail2;
1244
@@ -1242,7 +1282,7 @@ static char *git_header_name(const char *line, int llen)
1282
*/
1283
if (!name[len + 1])
1284
return NULL; /* no postimage name */
1245
- second = skip_tree_prefix(name + len + 1,
1285
+ second = skip_tree_prefix(state, name + len + 1,
1286
line_len - (len + 1));
1287
if (!second)
1288
return NULL;
@@ -1258,7 +1298,11 @@ static char *git_header_name(const char *line, int llen)
1298
}
1299
1300
/* Verify that we recognize the lines following a git header */
1261
-static int parse_git_header(const char *line, int len, unsigned int size, struct patch *patch)
1301
+static int parse_git_header(struct apply_state *state,
1302
+ const char *line,
1303
+ int len,
1304
+ unsigned int size,
1305
+ struct patch *patch)
1306
{
1307
unsigned long offset;
1308
@@ -1272,7 +1316,7 @@ static int parse_git_header(const char *line, int len, unsigned int size, struct
1316
* or removing or adding empty files), so we get
1317
* the default name from the header.
1318
*/
1275
- patch->def_name = git_header_name(line, len);
1319
+ patch->def_name = git_header_name(state, line, len);
1320
if (patch->def_name && root.len) {
1321
char *s = xstrfmt("%s%s", root.buf, patch->def_name);
1322
free(patch->def_name);
@@ -1285,7 +1329,7 @@ static int parse_git_header(const char *line, int len, unsigned int size, struct
1329
for (offset = len ; size > 0 ; offset += len, size -= len, line += len, state_linenr++) {
1330
static const struct opentry {
1331
const char *str;
1288
- int (*fn)(const char *, struct patch *);
1332
+ int (*fn)(struct apply_state *, const char *, struct patch *);
1333
} optable[] = {
1334
{ "@@ -", gitdiff_hdrend },
1335
{ "--- ", gitdiff_oldname },
@@ -1315,7 +1359,7 @@ static int parse_git_header(const char *line, int len, unsigned int size, struct
1359
int oplen = strlen(p->str);
1360
if (len < oplen || memcmp(p->str, line, oplen))
1361
continue;
1318
- if (p->fn(line + oplen, patch) < 0)
1362
+ if (p->fn(state, line + oplen, patch) < 0)
1363
return offset;
1364
break;
1365
}
@@ -1485,7 +1529,7 @@ static int find_header(struct apply_state *state,
1529
* or mode change, so we handle that specially
1530
*/
1531
if (!memcmp("diff --git ", line, 11)) {
1488
- int git_hdr_len = parse_git_header(line, len, size, patch);
1532
+ int git_hdr_len = parse_git_header(state, line, len, size, patch);
1533
if (git_hdr_len <= len)
1534
continue;
1535
if (!patch->old_name && !patch->new_name) {
@@ -1494,8 +1538,8 @@ static int find_header(struct apply_state *state,
1538
"%d leading pathname component (line %d)",
1539
"git diff header lacks filename information when removing "
1540
"%d leading pathname components (line %d)",
1497
- state_p_value),
1498
- state_p_value, state_linenr);
1541
+ state->p_value),
1542
+ state->p_value, state_linenr);
1543
patch->old_name = xstrdup(patch->def_name);
1544
patch->new_name = xstrdup(patch->def_name);
1545
}
@@ -4539,9 +4583,11 @@ static int option_parse_include(const struct option *opt,
4583
}
4584
4585
static int option_parse_p(const struct option *opt,
4542
- const char *arg, int unset)
4586
+ const char *arg,
4587
+ int unset)
4588
{
4544
- state_p_value = atoi(arg);
4589
+ struct apply_state *state = opt->value;
4590
+ state->p_value = atoi(arg);
4591
p_value_known = 1;
4592
return 0;
4593
}
@@ -4582,6 +4628,7 @@ static void init_apply_state(struct apply_state *state, const char *prefix)
4628
state->prefix_length = state->prefix ? strlen(state->prefix) : 0;
4629
state->apply = 1;
4630
state->line_termination = '\n';
4631
+ state->p_value = 1;
4632
state->p_context = UINT_MAX;
4633
4634
git_apply_config();
@@ -4615,7 +4662,7 @@ int cmd_apply(int argc, const char **argv, const char *prefix)
4662
{ OPTION_CALLBACK, 0, "include", &state, N_("path"),
4663
N_("apply changes matching the given path"),
4664
0, option_parse_include },
4618
- { OPTION_CALLBACK, 'p', NULL, NULL, N_("num"),
4665
+ { OPTION_CALLBACK, 'p', NULL, &state, N_("num"),
4666
N_("remove <num> leading slashes from traditional diff paths"),
4667
0, option_parse_p },
4668
OPT_BOOL(0, "no-add", &state.no_add,