sequencer: remove the 'arg' field from todo_item
authorAlban Gruin <alban.gruin@gmail.com>
Tue, 29 Jan 2019 15:01:46 +0000 (16:01 +0100)
committerJunio C Hamano <gitster@pobox.com>
Tue, 29 Jan 2019 20:09:24 +0000 (12:09 -0800)
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>
sequencer.c
sequencer.h
index 25cc7a9a91af2e8ad09c8d45c5a80e0a7913deb1..c844a9b7f30c8a465e24c090807a1b8237bb25cc 100644 (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;
                }
        }
index c6360bac66b033ef2bbc76d1dc5c720442972ff9..50d552429c476c69f93cefbd3a1fa0962c0950a0 100644 (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);