Implement rebase_todo_list, which is a resizable array of rebase_todo_items. Signed-off-by: Paul Tan <pyokagan@xxxxxxxxx> --- rebase-todo.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rebase-todo.h | 27 +++++++++++++++ 2 files changed, 134 insertions(+) diff --git a/rebase-todo.c b/rebase-todo.c index ac6b222..4f14638 100644 --- a/rebase-todo.c +++ b/rebase-todo.c @@ -142,3 +142,110 @@ void strbuf_add_rebase_todo_item(struct strbuf *sb, strbuf_addch(sb, '\n'); } + +void rebase_todo_list_init(struct rebase_todo_list *list) +{ + list->items = NULL; + list->nr = 0; + list->alloc = 0; +} + +void rebase_todo_list_clear(struct rebase_todo_list *list) +{ + unsigned int i; + + for (i = 0; i < list->nr; i++) + rebase_todo_item_release(&list->items[i]); + free(list->items); + rebase_todo_list_init(list); +} + +void rebase_todo_list_swap(struct rebase_todo_list *dst, + struct rebase_todo_list *src) +{ + struct rebase_todo_list tmp = *dst; + + *dst = *src; + *src = tmp; +} + +unsigned int rebase_todo_list_count(const struct rebase_todo_list *list) +{ + unsigned int i, count = 0; + + for (i = 0; i < list->nr; i++) + if (list->items[i].action != REBASE_TODO_NONE) + count++; + return count; +} + +struct rebase_todo_item *rebase_todo_list_push(struct rebase_todo_list *list, const struct rebase_todo_item *src_item) +{ + struct rebase_todo_item *item = rebase_todo_list_push_empty(list); + + rebase_todo_item_copy(item, src_item); + return item; +} + +struct rebase_todo_item *rebase_todo_list_push_empty(struct rebase_todo_list *list) +{ + struct rebase_todo_item *item; + + ALLOC_GROW(list->items, list->nr + 1, list->alloc); + item = &list->items[list->nr++]; + rebase_todo_item_init(item); + return item; +} + +struct rebase_todo_item *rebase_todo_list_push_noop(struct rebase_todo_list *list) +{ + struct rebase_todo_item *item = rebase_todo_list_push_empty(list); + + item->action = REBASE_TODO_NOOP; + return item; +} + +int rebase_todo_list_load(struct rebase_todo_list *list, const char *path, int abbrev) +{ + struct strbuf sb = STRBUF_INIT; + FILE *fp; + + fp = fopen(path, "r"); + if (!fp) + return error(_("could not open %s for reading"), path); + + while (strbuf_getline(&sb, fp) != EOF) { + struct rebase_todo_item *item = rebase_todo_list_push_empty(list); + if (rebase_todo_item_parse(item, sb.buf, abbrev) < 0) { + rebase_todo_item_release(item); + list->nr--; + strbuf_release(&sb); + fclose(fp); + return -1; + } + } + strbuf_release(&sb); + fclose(fp); + return 0; +} + +void rebase_todo_list_save(const struct rebase_todo_list *list, const char *filename, unsigned int offset, int abbrev) +{ + char *tmpfile = mkpathdup("%s.new", filename); + struct strbuf sb = STRBUF_INIT; + int fd; + + for (; offset < list->nr; offset++) + strbuf_add_rebase_todo_item(&sb, &list->items[offset], abbrev); + + fd = xopen(tmpfile, O_WRONLY | O_CREAT | O_TRUNC, 0666); + if (write_in_full(fd, sb.buf, sb.len) != sb.len) + die_errno(_("could not write to %s"), tmpfile); + close(fd); + strbuf_release(&sb); + + if (rename(tmpfile, filename)) + die_errno(_("rename failed")); + + free(tmpfile); +} diff --git a/rebase-todo.h b/rebase-todo.h index 2eedbb0..f602fd2 100644 --- a/rebase-todo.h +++ b/rebase-todo.h @@ -25,4 +25,31 @@ int rebase_todo_item_parse(struct rebase_todo_item *, const char *line, int abbr void strbuf_add_rebase_todo_item(struct strbuf *, const struct rebase_todo_item *, int abbrev); +struct rebase_todo_list { + struct rebase_todo_item *items; + unsigned int nr, alloc; +}; + +#define REBASE_TODO_LIST_INIT { NULL, 0, 0 } + +void rebase_todo_list_init(struct rebase_todo_list *); + +void rebase_todo_list_clear(struct rebase_todo_list *); + +void rebase_todo_list_swap(struct rebase_todo_list *dst, struct rebase_todo_list *src); + +unsigned int rebase_todo_list_count(const struct rebase_todo_list *); + +struct rebase_todo_item *rebase_todo_list_push(struct rebase_todo_list *, + const struct rebase_todo_item *); + +struct rebase_todo_item *rebase_todo_list_push_empty(struct rebase_todo_list *); + +struct rebase_todo_item *rebase_todo_list_push_noop(struct rebase_todo_list *); + +int rebase_todo_list_load(struct rebase_todo_list *, const char *path, int abbrev); + +void rebase_todo_list_save(const struct rebase_todo_list *, const char *path, + unsigned int offset, int abbrev); + #endif /* REBASE_TODO_H */ -- 2.7.0 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html