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,