1
0
Fork 0
mirror of https://github.com/git/git.git synced 2024-10-28 04:49:43 +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++;
}
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;
}
}

View file

@ -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);