1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-10-28 12:59:41 +01:00

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:
Alban Gruin 2019-01-29 16:01:46 +01:00 committed by Junio C Hamano
parent 5d94d54564
commit 6ad656db9b
2 changed files with 42 additions and 31 deletions

View file

@ -1999,8 +1999,14 @@ static struct todo_item *append_new_todo(struct todo_list *todo_list)
return todo_list->items + todo_list->nr++; 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, 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; struct object_id commit_oid;
char *end_of_object_name; 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) { if (bol == eol || *bol == '\r' || *bol == comment_line_char) {
item->command = TODO_COMMENT; item->command = TODO_COMMENT;
item->commit = NULL; item->commit = NULL;
item->arg = bol; item->arg_offset = bol - buf;
item->arg_len = eol - bol; item->arg_len = eol - bol;
return 0; 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'"), return error(_("%s does not accept arguments: '%s'"),
command_to_string(item->command), bol); command_to_string(item->command), bol);
item->commit = NULL; item->commit = NULL;
item->arg = bol; item->arg_offset = bol - buf;
item->arg_len = eol - bol; item->arg_len = eol - bol;
return 0; 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 || if (item->command == TODO_EXEC || item->command == TODO_LABEL ||
item->command == TODO_RESET) { item->command == TODO_RESET) {
item->commit = NULL; item->commit = NULL;
item->arg = bol; item->arg_offset = bol - buf;
item->arg_len = (int)(eol - bol); item->arg_len = (int)(eol - bol);
return 0; return 0;
} }
@ -2067,7 +2073,7 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,
} else { } else {
item->flags |= TODO_EDIT_MERGE_MSG; item->flags |= TODO_EDIT_MERGE_MSG;
item->commit = NULL; item->commit = NULL;
item->arg = bol; item->arg_offset = bol - buf;
item->arg_len = (int)(eol - bol); item->arg_len = (int)(eol - bol);
return 0; return 0;
} }
@ -2079,8 +2085,9 @@ static int parse_insn_line(struct repository *r, struct todo_item *item,
status = get_oid(bol, &commit_oid); status = get_oid(bol, &commit_oid);
*end_of_object_name = saved; *end_of_object_name = saved;
item->arg = end_of_object_name + strspn(end_of_object_name, " \t"); bol = end_of_object_name + strspn(end_of_object_name, " \t");
item->arg_len = (int)(eol - item->arg); item->arg_offset = bol - buf;
item->arg_len = (int)(eol - bol);
if (status < 0) if (status < 0)
return -1; return -1;
@ -2108,11 +2115,11 @@ int todo_list_parse_insn_buffer(struct repository *r, char *buf,
item = append_new_todo(todo_list); item = append_new_todo(todo_list);
item->offset_in_buf = p - todo_list->buf.buf; 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"), res = error(_("invalid line %d: %.*s"),
i, (int)(eol - p), p); i, (int)(eol - p), p);
item->command = TODO_COMMENT + 1; item->command = TODO_COMMENT + 1;
item->arg = p; item->arg_offset = p - buf;
item->arg_len = (int)(eol - p); item->arg_len = (int)(eol - p);
item->commit = NULL; item->commit = NULL;
} }
@ -2452,7 +2459,7 @@ static int walk_revs_populate_todo(struct todo_list *todo_list,
item->command = command; item->command = command;
item->commit = commit; item->commit = commit;
item->arg = NULL; item->arg_offset = 0;
item->arg_len = 0; item->arg_len = 0;
item->offset_in_buf = todo_list->buf.len; item->offset_in_buf = todo_list->buf.len;
subject_len = find_commit_subject(commit_buffer, &subject); 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) { while (todo_list->current < todo_list->nr) {
struct todo_item *item = todo_list->items + todo_list->current; 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)) if (save_todo(todo_list, opts))
return -1; return -1;
if (is_rebase_i(opts)) { if (is_rebase_i(opts)) {
@ -3542,10 +3551,9 @@ static int pick_commits(struct repository *r,
fprintf(stderr, fprintf(stderr,
_("Stopped at %s... %.*s\n"), _("Stopped at %s... %.*s\n"),
short_commit_name(commit), short_commit_name(commit),
item->arg_len, item->arg); item->arg_len, arg);
return error_with_patch(r, commit, return error_with_patch(r, commit,
item->arg, item->arg_len, opts, res, arg, item->arg_len, opts, res, !res);
!res);
} }
if (is_rebase_i(opts) && !res) if (is_rebase_i(opts) && !res)
record_in_rewritten(&item->commit->object.oid, record_in_rewritten(&item->commit->object.oid,
@ -3554,7 +3562,7 @@ static int pick_commits(struct repository *r,
if (res == 1) if (res == 1)
intend_to_amend(); intend_to_amend();
return error_failed_squash(r, item->commit, opts, 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) { } else if (res && is_rebase_i(opts) && item->commit) {
int to_amend = 0; int to_amend = 0;
struct object_id oid; struct object_id oid;
@ -3573,16 +3581,16 @@ static int pick_commits(struct repository *r,
to_amend = 1; to_amend = 1;
return res | error_with_patch(r, item->commit, return res | error_with_patch(r, item->commit,
item->arg, item->arg_len, opts, arg, item->arg_len, opts,
res, to_amend); res, to_amend);
} }
} else if (item->command == TODO_EXEC) { } 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; int saved = *end_of_arg;
struct stat st; struct stat st;
*end_of_arg = '\0'; *end_of_arg = '\0';
res = do_exec(r, item->arg); res = do_exec(r, arg);
*end_of_arg = saved; *end_of_arg = saved;
/* Reread the todo file if it has changed. */ /* Reread the todo file if it has changed. */
@ -3599,14 +3607,14 @@ static int pick_commits(struct repository *r,
todo_list->current = -1; todo_list->current = -1;
} }
} else if (item->command == TODO_LABEL) { } 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; reschedule = 1;
} else if (item->command == TODO_RESET) { } 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; reschedule = 1;
} else if (item->command == TODO_MERGE) { } else if (item->command == TODO_MERGE) {
if ((res = do_merge(r, item->commit, if ((res = do_merge(r, item->commit,
item->arg, item->arg_len, arg, item->arg_len,
item->flags, opts)) < 0) item->flags, opts)) < 0)
reschedule = 1; reschedule = 1;
else if (item->commit) else if (item->commit)
@ -3615,9 +3623,8 @@ static int pick_commits(struct repository *r,
if (res > 0) if (res > 0)
/* failed with merge conflicts */ /* failed with merge conflicts */
return error_with_patch(r, item->commit, return error_with_patch(r, item->commit,
item->arg, arg, item->arg_len,
item->arg_len, opts, opts, res, 0);
res, 0);
} else if (!is_noop(item->command)) } else if (!is_noop(item->command))
return error(_("unknown command %d"), item->command); return error(_("unknown command %d"), item->command);
@ -3632,9 +3639,8 @@ static int pick_commits(struct repository *r,
if (item->commit) if (item->commit)
return error_with_patch(r, return error_with_patch(r,
item->commit, item->commit,
item->arg, arg, item->arg_len,
item->arg_len, opts, opts, res, 0);
res, 0);
} }
todo_list->current++; 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++) { 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 the item is not a command write it and continue */
if (item->command >= TODO_COMMENT) { 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; continue;
} }
@ -4605,7 +4612,8 @@ int transform_todos(struct repository *r, unsigned flags)
if (!item->arg_len) if (!item->arg_len)
strbuf_addch(&buf, '\n'); strbuf_addch(&buf, '\n');
else 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); 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)) { if (commit && !*commit_seen_at(&commit_seen, commit)) {
strbuf_addf(&missing, " - %s %.*s\n", strbuf_addf(&missing, " - %s %.*s\n",
short_commit_name(commit), 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; *commit_seen_at(&commit_seen, commit) = 1;
} }
} }

View file

@ -104,9 +104,9 @@ struct todo_item {
enum todo_command command; enum todo_command command;
struct commit *commit; struct commit *commit;
unsigned int flags; unsigned int flags;
const char *arg;
int arg_len; 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 { struct todo_list {
@ -122,6 +122,8 @@ struct todo_list {
int todo_list_parse_insn_buffer(struct repository *r, char *buf, int todo_list_parse_insn_buffer(struct repository *r, char *buf,
struct todo_list *todo_list); struct todo_list *todo_list);
void todo_list_release(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 */ /* Call this to setup defaults before parsing command line options */
void sequencer_init_config(struct replay_opts *opts); void sequencer_init_config(struct replay_opts *opts);