зеркало из https://github.com/microsoft/git.git
sequencer: remove the 'arg' field from todo_item
The 'arg' field of todo_item used to store the address of the first byte of the parameter of a command in a todo list. It was associated with the length of the parameter (the 'arg_len' field). This replaces the 'arg' field by 'arg_offset'. This new field does not store the address of the parameter, but the position of the first character of the parameter in the buffer. todo_item_get_arg() is added to return the address of the parameter of an item. This will prevent todo_list_add_exec_commands() from having to do awful pointer arithmetics when growing the todo list buffer. Signed-off-by: Alban Gruin <alban.gruin@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
5d94d54564
Коммит
6ad656db9b
67
sequencer.c
67
sequencer.c
|
@ -1999,8 +1999,14 @@ static struct todo_item *append_new_todo(struct todo_list *todo_list)
|
|||
return todo_list->items + todo_list->nr++;
|
||||
}
|
||||
|
||||
const char *todo_item_get_arg(struct todo_list *todo_list,
|
||||
struct todo_item *item)
|
||||
{
|
||||
return todo_list->buf.buf + item->arg_offset;
|
||||
}
|
||||
|
||||
static int parse_insn_line(struct repository *r, struct todo_item *item,
|
||||
const char *bol, char *eol)
|
||||
const char *buf, const char *bol, char *eol)
|
||||
{
|
||||
struct object_id commit_oid;
|
||||
char *end_of_object_name;
|
||||
|
@ -2014,7 +2020,7 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,
|
|||
if (bol == eol || *bol == '\r' || *bol == comment_line_char) {
|
||||
item->command = TODO_COMMENT;
|
||||
item->commit = NULL;
|
||||
item->arg = bol;
|
||||
item->arg_offset = bol - buf;
|
||||
item->arg_len = eol - bol;
|
||||
return 0;
|
||||
}
|
||||
|
@ -2041,7 +2047,7 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,
|
|||
return error(_("%s does not accept arguments: '%s'"),
|
||||
command_to_string(item->command), bol);
|
||||
item->commit = NULL;
|
||||
item->arg = bol;
|
||||
item->arg_offset = bol - buf;
|
||||
item->arg_len = eol - bol;
|
||||
return 0;
|
||||
}
|
||||
|
@ -2053,7 +2059,7 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,
|
|||
if (item->command == TODO_EXEC || item->command == TODO_LABEL ||
|
||||
item->command == TODO_RESET) {
|
||||
item->commit = NULL;
|
||||
item->arg = bol;
|
||||
item->arg_offset = bol - buf;
|
||||
item->arg_len = (int)(eol - bol);
|
||||
return 0;
|
||||
}
|
||||
|
@ -2067,7 +2073,7 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,
|
|||
} else {
|
||||
item->flags |= TODO_EDIT_MERGE_MSG;
|
||||
item->commit = NULL;
|
||||
item->arg = bol;
|
||||
item->arg_offset = bol - buf;
|
||||
item->arg_len = (int)(eol - bol);
|
||||
return 0;
|
||||
}
|
||||
|
@ -2079,8 +2085,9 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,
|
|||
status = get_oid(bol, &commit_oid);
|
||||
*end_of_object_name = saved;
|
||||
|
||||
item->arg = end_of_object_name + strspn(end_of_object_name, " \t");
|
||||
item->arg_len = (int)(eol - item->arg);
|
||||
bol = end_of_object_name + strspn(end_of_object_name, " \t");
|
||||
item->arg_offset = bol - buf;
|
||||
item->arg_len = (int)(eol - bol);
|
||||
|
||||
if (status < 0)
|
||||
return -1;
|
||||
|
@ -2108,11 +2115,11 @@ int todo_list_parse_insn_buffer(struct repository *r, char *buf,
|
|||
|
||||
item = append_new_todo(todo_list);
|
||||
item->offset_in_buf = p - todo_list->buf.buf;
|
||||
if (parse_insn_line(r, item, p, eol)) {
|
||||
if (parse_insn_line(r, item, buf, p, eol)) {
|
||||
res = error(_("invalid line %d: %.*s"),
|
||||
i, (int)(eol - p), p);
|
||||
item->command = TODO_COMMENT + 1;
|
||||
item->arg = p;
|
||||
item->arg_offset = p - buf;
|
||||
item->arg_len = (int)(eol - p);
|
||||
item->commit = NULL;
|
||||
}
|
||||
|
@ -2452,7 +2459,7 @@ static int walk_revs_populate_todo(struct todo_list *todo_list,
|
|||
|
||||
item->command = command;
|
||||
item->commit = commit;
|
||||
item->arg = NULL;
|
||||
item->arg_offset = 0;
|
||||
item->arg_len = 0;
|
||||
item->offset_in_buf = todo_list->buf.len;
|
||||
subject_len = find_commit_subject(commit_buffer, &subject);
|
||||
|
@ -3491,6 +3498,8 @@ static int pick_commits(struct repository *r,
|
|||
|
||||
while (todo_list->current < todo_list->nr) {
|
||||
struct todo_item *item = todo_list->items + todo_list->current;
|
||||
const char *arg = todo_item_get_arg(todo_list, item);
|
||||
|
||||
if (save_todo(todo_list, opts))
|
||||
return -1;
|
||||
if (is_rebase_i(opts)) {
|
||||
|
@ -3542,10 +3551,9 @@ static int pick_commits(struct repository *r,
|
|||
fprintf(stderr,
|
||||
_("Stopped at %s... %.*s\n"),
|
||||
short_commit_name(commit),
|
||||
item->arg_len, item->arg);
|
||||
item->arg_len, arg);
|
||||
return error_with_patch(r, commit,
|
||||
item->arg, item->arg_len, opts, res,
|
||||
!res);
|
||||
arg, item->arg_len, opts, res, !res);
|
||||
}
|
||||
if (is_rebase_i(opts) && !res)
|
||||
record_in_rewritten(&item->commit->object.oid,
|
||||
|
@ -3554,7 +3562,7 @@ static int pick_commits(struct repository *r,
|
|||
if (res == 1)
|
||||
intend_to_amend();
|
||||
return error_failed_squash(r, item->commit, opts,
|
||||
item->arg_len, item->arg);
|
||||
item->arg_len, arg);
|
||||
} else if (res && is_rebase_i(opts) && item->commit) {
|
||||
int to_amend = 0;
|
||||
struct object_id oid;
|
||||
|
@ -3573,16 +3581,16 @@ static int pick_commits(struct repository *r,
|
|||
to_amend = 1;
|
||||
|
||||
return res | error_with_patch(r, item->commit,
|
||||
item->arg, item->arg_len, opts,
|
||||
arg, item->arg_len, opts,
|
||||
res, to_amend);
|
||||
}
|
||||
} else if (item->command == TODO_EXEC) {
|
||||
char *end_of_arg = (char *)(item->arg + item->arg_len);
|
||||
char *end_of_arg = (char *)(arg + item->arg_len);
|
||||
int saved = *end_of_arg;
|
||||
struct stat st;
|
||||
|
||||
*end_of_arg = '\0';
|
||||
res = do_exec(r, item->arg);
|
||||
res = do_exec(r, arg);
|
||||
*end_of_arg = saved;
|
||||
|
||||
/* Reread the todo file if it has changed. */
|
||||
|
@ -3599,14 +3607,14 @@ static int pick_commits(struct repository *r,
|
|||
todo_list->current = -1;
|
||||
}
|
||||
} else if (item->command == TODO_LABEL) {
|
||||
if ((res = do_label(r, item->arg, item->arg_len)))
|
||||
if ((res = do_label(r, arg, item->arg_len)))
|
||||
reschedule = 1;
|
||||
} else if (item->command == TODO_RESET) {
|
||||
if ((res = do_reset(r, item->arg, item->arg_len, opts)))
|
||||
if ((res = do_reset(r, arg, item->arg_len, opts)))
|
||||
reschedule = 1;
|
||||
} else if (item->command == TODO_MERGE) {
|
||||
if ((res = do_merge(r, item->commit,
|
||||
item->arg, item->arg_len,
|
||||
arg, item->arg_len,
|
||||
item->flags, opts)) < 0)
|
||||
reschedule = 1;
|
||||
else if (item->commit)
|
||||
|
@ -3615,9 +3623,8 @@ static int pick_commits(struct repository *r,
|
|||
if (res > 0)
|
||||
/* failed with merge conflicts */
|
||||
return error_with_patch(r, item->commit,
|
||||
item->arg,
|
||||
item->arg_len, opts,
|
||||
res, 0);
|
||||
arg, item->arg_len,
|
||||
opts, res, 0);
|
||||
} else if (!is_noop(item->command))
|
||||
return error(_("unknown command %d"), item->command);
|
||||
|
||||
|
@ -3632,9 +3639,8 @@ static int pick_commits(struct repository *r,
|
|||
if (item->commit)
|
||||
return error_with_patch(r,
|
||||
item->commit,
|
||||
item->arg,
|
||||
item->arg_len, opts,
|
||||
res, 0);
|
||||
arg, item->arg_len,
|
||||
opts, res, 0);
|
||||
}
|
||||
|
||||
todo_list->current++;
|
||||
|
@ -4575,7 +4581,8 @@ int transform_todos(struct repository *r, unsigned flags)
|
|||
for (item = todo_list.items, i = 0; i < todo_list.nr; i++, item++) {
|
||||
/* if the item is not a command write it and continue */
|
||||
if (item->command >= TODO_COMMENT) {
|
||||
strbuf_addf(&buf, "%.*s\n", item->arg_len, item->arg);
|
||||
strbuf_addf(&buf, "%.*s\n", item->arg_len,
|
||||
todo_item_get_arg(&todo_list, item));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -4605,7 +4612,8 @@ int transform_todos(struct repository *r, unsigned flags)
|
|||
if (!item->arg_len)
|
||||
strbuf_addch(&buf, '\n');
|
||||
else
|
||||
strbuf_addf(&buf, " %.*s\n", item->arg_len, item->arg);
|
||||
strbuf_addf(&buf, " %.*s\n", item->arg_len,
|
||||
todo_item_get_arg(&todo_list, item));
|
||||
}
|
||||
|
||||
i = write_message(buf.buf, buf.len, todo_file, 0);
|
||||
|
@ -4681,7 +4689,8 @@ int check_todo_list(struct repository *r)
|
|||
if (commit && !*commit_seen_at(&commit_seen, commit)) {
|
||||
strbuf_addf(&missing, " - %s %.*s\n",
|
||||
short_commit_name(commit),
|
||||
item->arg_len, item->arg);
|
||||
item->arg_len,
|
||||
todo_item_get_arg(&todo_list, item));
|
||||
*commit_seen_at(&commit_seen, commit) = 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,9 +104,9 @@ struct todo_item {
|
|||
enum todo_command command;
|
||||
struct commit *commit;
|
||||
unsigned int flags;
|
||||
const char *arg;
|
||||
int arg_len;
|
||||
size_t offset_in_buf;
|
||||
/* The offset of the command and its argument in the strbuf */
|
||||
size_t offset_in_buf, arg_offset;
|
||||
};
|
||||
|
||||
struct todo_list {
|
||||
|
@ -122,6 +122,8 @@ struct todo_list {
|
|||
int todo_list_parse_insn_buffer(struct repository *r, char *buf,
|
||||
struct todo_list *todo_list);
|
||||
void todo_list_release(struct todo_list *todo_list);
|
||||
const char *todo_item_get_arg(struct todo_list *todo_list,
|
||||
struct todo_item *item);
|
||||
|
||||
/* Call this to setup defaults before parsing command line options */
|
||||
void sequencer_init_config(struct replay_opts *opts);
|
||||
|
|
Загрузка…
Ссылка в новой задаче