]>
Commit | Line | Data |
---|---|---|
cfc5789a JH |
1 | #include "cache.h" |
2 | #include "resolve-undo.h" | |
3 | #include "string-list.h" | |
4 | ||
5 | /* The only error case is to run out of memory in string-list */ | |
6 | void record_resolve_undo(struct index_state *istate, struct cache_entry *ce) | |
7 | { | |
8 | struct string_list_item *lost; | |
9 | struct resolve_undo_info *ui; | |
10 | struct string_list *resolve_undo; | |
11 | int stage = ce_stage(ce); | |
12 | ||
13 | if (!stage) | |
14 | return; | |
15 | ||
16 | if (!istate->resolve_undo) { | |
17 | resolve_undo = xcalloc(1, sizeof(*resolve_undo)); | |
18 | resolve_undo->strdup_strings = 1; | |
19 | istate->resolve_undo = resolve_undo; | |
20 | } | |
21 | resolve_undo = istate->resolve_undo; | |
22 | lost = string_list_insert(ce->name, resolve_undo); | |
23 | if (!lost->util) | |
24 | lost->util = xcalloc(1, sizeof(*ui)); | |
25 | ui = lost->util; | |
26 | hashcpy(ui->sha1[stage - 1], ce->sha1); | |
27 | ui->mode[stage - 1] = ce->ce_mode; | |
28 | } | |
29 | ||
30 | static int write_one(struct string_list_item *item, void *cbdata) | |
31 | { | |
32 | struct strbuf *sb = cbdata; | |
33 | struct resolve_undo_info *ui = item->util; | |
34 | int i; | |
35 | ||
36 | if (!ui) | |
37 | return 0; | |
38 | strbuf_addstr(sb, item->string); | |
39 | strbuf_addch(sb, 0); | |
40 | for (i = 0; i < 3; i++) | |
41 | strbuf_addf(sb, "%o%c", ui->mode[i], 0); | |
42 | for (i = 0; i < 3; i++) { | |
43 | if (!ui->mode[i]) | |
44 | continue; | |
45 | strbuf_add(sb, ui->sha1[i], 20); | |
46 | } | |
47 | return 0; | |
48 | } | |
49 | ||
50 | void resolve_undo_write(struct strbuf *sb, struct string_list *resolve_undo) | |
51 | { | |
52 | for_each_string_list(write_one, resolve_undo, sb); | |
53 | } | |
54 | ||
55 | struct string_list *resolve_undo_read(void *data, unsigned long size) | |
56 | { | |
57 | struct string_list *resolve_undo; | |
58 | size_t len; | |
59 | char *endptr; | |
60 | int i; | |
61 | ||
62 | resolve_undo = xcalloc(1, sizeof(*resolve_undo)); | |
63 | resolve_undo->strdup_strings = 1; | |
64 | ||
65 | while (size) { | |
66 | struct string_list_item *lost; | |
67 | struct resolve_undo_info *ui; | |
68 | ||
69 | len = strlen(data) + 1; | |
70 | if (size <= len) | |
71 | goto error; | |
72 | lost = string_list_insert(data, resolve_undo); | |
73 | if (!lost->util) | |
74 | lost->util = xcalloc(1, sizeof(*ui)); | |
75 | ui = lost->util; | |
76 | size -= len; | |
77 | data += len; | |
78 | ||
79 | for (i = 0; i < 3; i++) { | |
80 | ui->mode[i] = strtoul(data, &endptr, 8); | |
81 | if (!endptr || endptr == data || *endptr) | |
82 | goto error; | |
83 | len = (endptr + 1) - (char*)data; | |
84 | if (size <= len) | |
85 | goto error; | |
86 | size -= len; | |
87 | data += len; | |
88 | } | |
89 | ||
90 | for (i = 0; i < 3; i++) { | |
91 | if (!ui->mode[i]) | |
92 | continue; | |
93 | if (size < 20) | |
94 | goto error; | |
95 | hashcpy(ui->sha1[i], data); | |
96 | size -= 20; | |
97 | data += 20; | |
98 | } | |
99 | } | |
100 | return resolve_undo; | |
101 | ||
102 | error: | |
103 | string_list_clear(resolve_undo, 1); | |
104 | error("Index records invalid resolve-undo information"); | |
105 | return NULL; | |
106 | } | |
107 | ||
108 | void resolve_undo_clear_index(struct index_state *istate) | |
109 | { | |
110 | struct string_list *resolve_undo = istate->resolve_undo; | |
111 | if (!resolve_undo) | |
112 | return; | |
113 | string_list_clear(resolve_undo, 1); | |
114 | free(resolve_undo); | |
115 | istate->resolve_undo = NULL; | |
116 | istate->cache_changed = 1; | |
117 | } |