fsck: introduce fsck options
Just like the diff machinery, we are about to introduce more settings, therefore it makes sense to carry them around as a (pointer to a) struct containing all of them. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Johannes Schindelin committed
Jun 22, 2015 at 17:25 UTC
22410549fc71b3973a61666f82b7c76317da5df0
5 files changed
+114
-93
builtin/fsck.c
+14
-6
@@ -25,6 +25,8 @@ static int include_reflogs = 1;
25
static int check_full = 1;
26
static int check_strict;
27
static int keep_cache_objects;
28
+static struct fsck_options fsck_walk_options = FSCK_OPTIONS_DEFAULT;
29
+static struct fsck_options fsck_obj_options = FSCK_OPTIONS_DEFAULT;
30
static struct object_id head_oid;
31
static const char *head_points_at;
32
static int errors_found;
@@ -76,7 +78,7 @@ static int fsck_error_func(struct object *obj, int type, const char *err, ...)
78
79
static struct object_array pending;
80
79
-static int mark_object(struct object *obj, int type, void *data)
81
+static int mark_object(struct object *obj, int type, void *data, struct fsck_options *options)
82
{
83
struct object *parent = data;
84
@@ -119,7 +121,7 @@ static int mark_object(struct object *obj, int type, void *data)
121
122
static void mark_object_reachable(struct object *obj)
123
{
122
- mark_object(obj, OBJ_ANY, NULL);
124
+ mark_object(obj, OBJ_ANY, NULL, NULL);
125
}
126
127
static int traverse_one_object(struct object *obj)
@@ -132,7 +134,7 @@ static int traverse_one_object(struct object *obj)
134
if (parse_tree(tree) < 0)
135
return 1; /* error already displayed */
136
}
135
- result = fsck_walk(obj, mark_object, obj);
137
+ result = fsck_walk(obj, obj, &fsck_walk_options);
138
if (tree)
139
free_tree_buffer(tree);
140
return result;
@@ -158,7 +160,7 @@ static int traverse_reachable(void)
160
return !!result;
161
}
162
161
-static int mark_used(struct object *obj, int type, void *data)
163
+static int mark_used(struct object *obj, int type, void *data, struct fsck_options *options)
164
{
165
if (!obj)
166
return 1;
@@ -296,9 +298,9 @@ static int fsck_obj(struct object *obj)
298
fprintf(stderr, "Checking %s %s\n",
299
typename(obj->type), sha1_to_hex(obj->sha1));
300
299
- if (fsck_walk(obj, mark_used, NULL))
301
+ if (fsck_walk(obj, NULL, &fsck_obj_options))
302
objerror(obj, "broken links");
301
- if (fsck_object(obj, NULL, 0, check_strict, fsck_error_func))
303
+ if (fsck_object(obj, NULL, 0, &fsck_obj_options))
304
return -1;
305
306
if (obj->type == OBJ_TREE) {
@@ -632,6 +634,12 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
634
635
argc = parse_options(argc, argv, prefix, fsck_opts, fsck_usage, 0);
636
637
+ fsck_walk_options.walk = mark_object;
638
+ fsck_obj_options.walk = mark_used;
639
+ fsck_obj_options.error_func = fsck_error_func;
640
+ if (check_strict)
641
+ fsck_obj_options.strict = 1;
642
+
643
if (show_progress == -1)
644
show_progress = isatty(2);
645
if (verbose)
builtin/index-pack.c
+5
-4
@@ -75,6 +75,7 @@ static int nr_threads;
75
static int from_stdin;
76
static int strict;
77
static int do_fsck_object;
78
+static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
79
static int verbose;
80
static int show_stat;
81
static int check_self_contained_and_connected;
@@ -192,7 +193,7 @@ static void cleanup_thread(void)
193
#endif
194
195
195
-static int mark_link(struct object *obj, int type, void *data)
196
+static int mark_link(struct object *obj, int type, void *data, struct fsck_options *options)
197
{
198
if (!obj)
199
return -1;
@@ -838,10 +839,9 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
839
if (!obj)
840
die(_("invalid %s"), typename(type));
841
if (do_fsck_object &&
841
- fsck_object(obj, buf, size, 1,
842
- fsck_error_function))
842
+ fsck_object(obj, buf, size, &fsck_options))
843
die(_("Error in object"));
844
- if (fsck_walk(obj, mark_link, NULL))
844
+ if (fsck_walk(obj, NULL, &fsck_options))
845
die(_("Not all child objects of %s are reachable"), sha1_to_hex(obj->sha1));
846
847
if (obj->type == OBJ_TREE) {
@@ -1615,6 +1615,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
1615
usage(index_pack_usage);
1616
1617
check_replace_refs = 0;
1618
+ fsck_options.walk = mark_link;
1619
1620
reset_pack_idx_option(&opts);
1621
git_config(git_index_pack_config, &opts);
builtin/unpack-objects.c
+6
-5
@@ -20,6 +20,7 @@ static unsigned char buffer[4096];
20
static unsigned int offset, len;
21
static off_t consumed_bytes;
22
static git_SHA_CTX ctx;
23
+static struct fsck_options fsck_options = FSCK_OPTIONS_STRICT;
24
25
/*
26
* When running under --strict mode, objects whose reachability are
@@ -178,7 +179,7 @@ static void write_cached_object(struct object *obj, struct obj_buffer *obj_buf)
179
* that have reachability requirements and calls this function.
180
* Verify its reachability and validity recursively and write it out.
181
*/
181
-static int check_object(struct object *obj, int type, void *data)
182
+static int check_object(struct object *obj, int type, void *data, struct fsck_options *options)
183
{
184
struct obj_buffer *obj_buf;
185
@@ -203,10 +204,10 @@ static int check_object(struct object *obj, int type, void *data)
204
obj_buf = lookup_object_buffer(obj);
205
if (!obj_buf)
206
die("Whoops! Cannot find object '%s'", sha1_to_hex(obj->sha1));
206
- if (fsck_object(obj, obj_buf->buffer, obj_buf->size, 1,
207
- fsck_error_function))
207
+ if (fsck_object(obj, obj_buf->buffer, obj_buf->size, &fsck_options))
208
die("Error in object");
209
- if (fsck_walk(obj, check_object, NULL))
209
+ fsck_options.walk = check_object;
210
+ if (fsck_walk(obj, NULL, &fsck_options))
211
die("Error on reachable objects of %s", sha1_to_hex(obj->sha1));
212
write_cached_object(obj, obj_buf);
213
return 0;
@@ -217,7 +218,7 @@ static void write_rest(void)
218
unsigned i;
219
for (i = 0; i < nr_objects; i++) {
220
if (obj_list[i].obj)
220
- check_object(obj_list[i].obj, OBJ_ANY, NULL);
221
+ check_object(obj_list[i].obj, OBJ_ANY, NULL, NULL);
222
}
223
}
224
fsck.c
+75
-75
@@ -9,7 +9,7 @@
9
#include "refs.h"
10
#include "utf8.h"
11
12
-static int fsck_walk_tree(struct tree *tree, fsck_walk_func walk, void *data)
12
+static int fsck_walk_tree(struct tree *tree, void *data, struct fsck_options *options)
13
{
14
struct tree_desc desc;
15
struct name_entry entry;
@@ -25,9 +25,9 @@ static int fsck_walk_tree(struct tree *tree, fsck_walk_func walk, void *data)
25
if (S_ISGITLINK(entry.mode))
26
continue;
27
if (S_ISDIR(entry.mode))
28
- result = walk(&lookup_tree(entry.sha1)->object, OBJ_TREE, data);
28
+ result = options->walk(&lookup_tree(entry.sha1)->object, OBJ_TREE, data, options);
29
else if (S_ISREG(entry.mode) || S_ISLNK(entry.mode))
30
- result = walk(&lookup_blob(entry.sha1)->object, OBJ_BLOB, data);
30
+ result = options->walk(&lookup_blob(entry.sha1)->object, OBJ_BLOB, data, options);
31
else {
32
result = error("in tree %s: entry %s has bad mode %.6o",
33
sha1_to_hex(tree->object.sha1), entry.path, entry.mode);
@@ -40,7 +40,7 @@ static int fsck_walk_tree(struct tree *tree, fsck_walk_func walk, void *data)
40
return res;
41
}
42
43
-static int fsck_walk_commit(struct commit *commit, fsck_walk_func walk, void *data)
43
+static int fsck_walk_commit(struct commit *commit, void *data, struct fsck_options *options)
44
{
45
struct commit_list *parents;
46
int res;
@@ -49,14 +49,14 @@ static int fsck_walk_commit(struct commit *commit, fsck_walk_func walk, void *da
49
if (parse_commit(commit))
50
return -1;
51
52
- result = walk((struct object *)commit->tree, OBJ_TREE, data);
52
+ result = options->walk((struct object *)commit->tree, OBJ_TREE, data, options);
53
if (result < 0)
54
return result;
55
res = result;
56
57
parents = commit->parents;
58
while (parents) {
59
- result = walk((struct object *)parents->item, OBJ_COMMIT, data);
59
+ result = options->walk((struct object *)parents->item, OBJ_COMMIT, data, options);
60
if (result < 0)
61
return result;
62
if (!res)
@@ -66,14 +66,14 @@ static int fsck_walk_commit(struct commit *commit, fsck_walk_func walk, void *da
66
return res;
67
}
68
69
-static int fsck_walk_tag(struct tag *tag, fsck_walk_func walk, void *data)
69
+static int fsck_walk_tag(struct tag *tag, void *data, struct fsck_options *options)
70
{
71
if (parse_tag(tag))
72
return -1;
73
- return walk(tag->tagged, OBJ_ANY, data);
73
+ return options->walk(tag->tagged, OBJ_ANY, data, options);
74
}
75
76
-int fsck_walk(struct object *obj, fsck_walk_func walk, void *data)
76
+int fsck_walk(struct object *obj, void *data, struct fsck_options *options)
77
{
78
if (!obj)
79
return -1;
@@ -81,11 +81,11 @@ int fsck_walk(struct object *obj, fsck_walk_func walk, void *data)
81
case OBJ_BLOB:
82
return 0;
83
case OBJ_TREE:
84
- return fsck_walk_tree((struct tree *)obj, walk, data);
84
+ return fsck_walk_tree((struct tree *)obj, data, options);
85
case OBJ_COMMIT:
86
- return fsck_walk_commit((struct commit *)obj, walk, data);
86
+ return fsck_walk_commit((struct commit *)obj, data, options);
87
case OBJ_TAG:
88
- return fsck_walk_tag((struct tag *)obj, walk, data);
88
+ return fsck_walk_tag((struct tag *)obj, data, options);
89
default:
90
error("Unknown object type for %s", sha1_to_hex(obj->sha1));
91
return -1;
@@ -138,7 +138,7 @@ static int verify_ordered(unsigned mode1, const char *name1, unsigned mode2, con
138
return c1 < c2 ? 0 : TREE_UNORDERED;
139
}
140
141
-static int fsck_tree(struct tree *item, int strict, fsck_error error_func)
141
+static int fsck_tree(struct tree *item, struct fsck_options *options)
142
{
143
int retval;
144
int has_null_sha1 = 0;
@@ -194,7 +194,7 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func)
194
* bits..
195
*/
196
case S_IFREG | 0664:
197
- if (!strict)
197
+ if (!options->strict)
198
break;
199
default:
200
has_bad_modes = 1;
@@ -219,30 +219,30 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func)
219
220
retval = 0;
221
if (has_null_sha1)
222
- retval += error_func(&item->object, FSCK_WARN, "contains entries pointing to null sha1");
222
+ retval += options->error_func(&item->object, FSCK_WARN, "contains entries pointing to null sha1");
223
if (has_full_path)
224
- retval += error_func(&item->object, FSCK_WARN, "contains full pathnames");
224
+ retval += options->error_func(&item->object, FSCK_WARN, "contains full pathnames");
225
if (has_empty_name)
226
- retval += error_func(&item->object, FSCK_WARN, "contains empty pathname");
226
+ retval += options->error_func(&item->object, FSCK_WARN, "contains empty pathname");
227
if (has_dot)
228
- retval += error_func(&item->object, FSCK_WARN, "contains '.'");
228
+ retval += options->error_func(&item->object, FSCK_WARN, "contains '.'");
229
if (has_dotdot)
230
- retval += error_func(&item->object, FSCK_WARN, "contains '..'");
230
+ retval += options->error_func(&item->object, FSCK_WARN, "contains '..'");
231
if (has_dotgit)
232
- retval += error_func(&item->object, FSCK_WARN, "contains '.git'");
232
+ retval += options->error_func(&item->object, FSCK_WARN, "contains '.git'");
233
if (has_zero_pad)
234
- retval += error_func(&item->object, FSCK_WARN, "contains zero-padded file modes");
234
+ retval += options->error_func(&item->object, FSCK_WARN, "contains zero-padded file modes");
235
if (has_bad_modes)
236
- retval += error_func(&item->object, FSCK_WARN, "contains bad file modes");
236
+ retval += options->error_func(&item->object, FSCK_WARN, "contains bad file modes");
237
if (has_dup_entries)
238
- retval += error_func(&item->object, FSCK_ERROR, "contains duplicate file entries");
238
+ retval += options->error_func(&item->object, FSCK_ERROR, "contains duplicate file entries");
239
if (not_properly_sorted)
240
- retval += error_func(&item->object, FSCK_ERROR, "not properly sorted");
240
+ retval += options->error_func(&item->object, FSCK_ERROR, "not properly sorted");
241
return retval;
242
}
243
244
static int require_end_of_header(const void *data, unsigned long size,
245
- struct object *obj, fsck_error error_func)
245
+ struct object *obj, struct fsck_options *options)
246
{
247
const char *buffer = (const char *)data;
248
unsigned long i;
@@ -250,7 +250,7 @@ static int require_end_of_header(const void *data, unsigned long size,
250
for (i = 0; i < size; i++) {
251
switch (buffer[i]) {
252
case '\0':
253
- return error_func(obj, FSCK_ERROR,
253
+ return options->error_func(obj, FSCK_ERROR,
254
"unterminated header: NUL at offset %d", i);
255
case '\n':
256
if (i + 1 < size && buffer[i + 1] == '\n')
@@ -258,36 +258,36 @@ static int require_end_of_header(const void *data, unsigned long size,
258
}
259
}
260
261
- return error_func(obj, FSCK_ERROR, "unterminated header");
261
+ return options->error_func(obj, FSCK_ERROR, "unterminated header");
262
}
263
264
-static int fsck_ident(const char **ident, struct object *obj, fsck_error error_func)
264
+static int fsck_ident(const char **ident, struct object *obj, struct fsck_options *options)
265
{
266
char *end;
267
268
if (**ident == '<')
269
- return error_func(obj, FSCK_ERROR, "invalid author/committer line - missing space before email");
269
+ return options->error_func(obj, FSCK_ERROR, "invalid author/committer line - missing space before email");
270
*ident += strcspn(*ident, "<>\n");
271
if (**ident == '>')
272
- return error_func(obj, FSCK_ERROR, "invalid author/committer line - bad name");
272
+ return options->error_func(obj, FSCK_ERROR, "invalid author/committer line - bad name");
273
if (**ident != '<')
274
- return error_func(obj, FSCK_ERROR, "invalid author/committer line - missing email");
274
+ return options->error_func(obj, FSCK_ERROR, "invalid author/committer line - missing email");
275
if ((*ident)[-1] != ' ')
276
- return error_func(obj, FSCK_ERROR, "invalid author/committer line - missing space before email");
276
+ return options->error_func(obj, FSCK_ERROR, "invalid author/committer line - missing space before email");
277
(*ident)++;
278
*ident += strcspn(*ident, "<>\n");
279
if (**ident != '>')
280
- return error_func(obj, FSCK_ERROR, "invalid author/committer line - bad email");
280
+ return options->error_func(obj, FSCK_ERROR, "invalid author/committer line - bad email");
281
(*ident)++;
282
if (**ident != ' ')
283
- return error_func(obj, FSCK_ERROR, "invalid author/committer line - missing space before date");
283
+ return options->error_func(obj, FSCK_ERROR, "invalid author/committer line - missing space before date");
284
(*ident)++;
285
if (**ident == '0' && (*ident)[1] != ' ')
286
- return error_func(obj, FSCK_ERROR, "invalid author/committer line - zero-padded date");
286
+ return options->error_func(obj, FSCK_ERROR, "invalid author/committer line - zero-padded date");
287
if (date_overflows(strtoul(*ident, &end, 10)))
288
- return error_func(obj, FSCK_ERROR, "invalid author/committer line - date causes integer overflow");
288
+ return options->error_func(obj, FSCK_ERROR, "invalid author/committer line - date causes integer overflow");
289
if (end == *ident || *end != ' ')
290
- return error_func(obj, FSCK_ERROR, "invalid author/committer line - bad date");
290
+ return options->error_func(obj, FSCK_ERROR, "invalid author/committer line - bad date");
291
*ident = end + 1;
292
if ((**ident != '+' && **ident != '-') ||
293
!isdigit((*ident)[1]) ||
@@ -295,30 +295,30 @@ static int fsck_ident(const char **ident, struct object *obj, fsck_error error_f
295
!isdigit((*ident)[3]) ||
296
!isdigit((*ident)[4]) ||
297
((*ident)[5] != '\n'))
298
- return error_func(obj, FSCK_ERROR, "invalid author/committer line - bad time zone");
298
+ return options->error_func(obj, FSCK_ERROR, "invalid author/committer line - bad time zone");
299
(*ident) += 6;
300
return 0;
301
}
302
303
static int fsck_commit_buffer(struct commit *commit, const char *buffer,
304
- unsigned long size, fsck_error error_func)
304
+ unsigned long size, struct fsck_options *options)
305
{
306
unsigned char tree_sha1[20], sha1[20];
307
struct commit_graft *graft;
308
unsigned parent_count, parent_line_count = 0;
309
int err;
310
311
- if (require_end_of_header(buffer, size, &commit->object, error_func))
311
+ if (require_end_of_header(buffer, size, &commit->object, options))
312
return -1;
313
314
if (!skip_prefix(buffer, "tree ", &buffer))
315
- return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'tree' line");
315
+ return options->error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'tree' line");
316
if (get_sha1_hex(buffer, tree_sha1) || buffer[40] != '\n')
317
- return error_func(&commit->object, FSCK_ERROR, "invalid 'tree' line format - bad sha1");
317
+ return options->error_func(&commit->object, FSCK_ERROR, "invalid 'tree' line format - bad sha1");
318
buffer += 41;
319
while (skip_prefix(buffer, "parent ", &buffer)) {
320
if (get_sha1_hex(buffer, sha1) || buffer[40] != '\n')
321
- return error_func(&commit->object, FSCK_ERROR, "invalid 'parent' line format - bad sha1");
321
+ return options->error_func(&commit->object, FSCK_ERROR, "invalid 'parent' line format - bad sha1");
322
buffer += 41;
323
parent_line_count++;
324
}
@@ -328,39 +328,39 @@ static int fsck_commit_buffer(struct commit *commit, const char *buffer,
328
if (graft->nr_parent == -1 && !parent_count)
329
; /* shallow commit */
330
else if (graft->nr_parent != parent_count)
331
- return error_func(&commit->object, FSCK_ERROR, "graft objects missing");
331
+ return options->error_func(&commit->object, FSCK_ERROR, "graft objects missing");
332
} else {
333
if (parent_count != parent_line_count)
334
- return error_func(&commit->object, FSCK_ERROR, "parent objects missing");
334
+ return options->error_func(&commit->object, FSCK_ERROR, "parent objects missing");
335
}
336
if (!skip_prefix(buffer, "author ", &buffer))
337
- return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'author' line");
338
- err = fsck_ident(&buffer, &commit->object, error_func);
337
+ return options->error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'author' line");
338
+ err = fsck_ident(&buffer, &commit->object, options);
339
if (err)
340
return err;
341
if (!skip_prefix(buffer, "committer ", &buffer))
342
- return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'committer' line");
343
- err = fsck_ident(&buffer, &commit->object, error_func);
342
+ return options->error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'committer' line");
343
+ err = fsck_ident(&buffer, &commit->object, options);
344
if (err)
345
return err;
346
if (!commit->tree)
347
- return error_func(&commit->object, FSCK_ERROR, "could not load commit's tree %s", sha1_to_hex(tree_sha1));
347
+ return options->error_func(&commit->object, FSCK_ERROR, "could not load commit's tree %s", sha1_to_hex(tree_sha1));
348
349
return 0;
350
}
351
352
static int fsck_commit(struct commit *commit, const char *data,
353
- unsigned long size, fsck_error error_func)
353
+ unsigned long size, struct fsck_options *options)
354
{
355
const char *buffer = data ? data : get_commit_buffer(commit, &size);
356
- int ret = fsck_commit_buffer(commit, buffer, size, error_func);
356
+ int ret = fsck_commit_buffer(commit, buffer, size, options);
357
if (!data)
358
unuse_commit_buffer(commit, buffer);
359
return ret;
360
}
361
362
static int fsck_tag_buffer(struct tag *tag, const char *data,
363
- unsigned long size, fsck_error error_func)
363
+ unsigned long size, struct fsck_options *options)
364
{
365
unsigned char sha1[20];
366
int ret = 0;
@@ -376,65 +376,65 @@ static int fsck_tag_buffer(struct tag *tag, const char *data,
376
buffer = to_free =
377
read_sha1_file(tag->object.sha1, &type, &size);
378
if (!buffer)
379
- return error_func(&tag->object, FSCK_ERROR,
379
+ return options->error_func(&tag->object, FSCK_ERROR,
380
"cannot read tag object");
381
382
if (type != OBJ_TAG) {
383
- ret = error_func(&tag->object, FSCK_ERROR,
383
+ ret = options->error_func(&tag->object, FSCK_ERROR,
384
"expected tag got %s",
385
typename(type));
386
goto done;
387
}
388
}
389
390
- if (require_end_of_header(buffer, size, &tag->object, error_func))
390
+ if (require_end_of_header(buffer, size, &tag->object, options))
391
goto done;
392
393
if (!skip_prefix(buffer, "object ", &buffer)) {
394
- ret = error_func(&tag->object, FSCK_ERROR, "invalid format - expected 'object' line");
394
+ ret = options->error_func(&tag->object, FSCK_ERROR, "invalid format - expected 'object' line");
395
goto done;
396
}
397
if (get_sha1_hex(buffer, sha1) || buffer[40] != '\n') {
398
- ret = error_func(&tag->object, FSCK_ERROR, "invalid 'object' line format - bad sha1");
398
+ ret = options->error_func(&tag->object, FSCK_ERROR, "invalid 'object' line format - bad sha1");
399
goto done;
400
}
401
buffer += 41;
402
403
if (!skip_prefix(buffer, "type ", &buffer)) {
404
- ret = error_func(&tag->object, FSCK_ERROR, "invalid format - expected 'type' line");
404
+ ret = options->error_func(&tag->object, FSCK_ERROR, "invalid format - expected 'type' line");
405
goto done;
406
}
407
eol = strchr(buffer, '\n');
408
if (!eol) {
409
- ret = error_func(&tag->object, FSCK_ERROR, "invalid format - unexpected end after 'type' line");
409
+ ret = options->error_func(&tag->object, FSCK_ERROR, "invalid format - unexpected end after 'type' line");
410
goto done;
411
}
412
if (type_from_string_gently(buffer, eol - buffer, 1) < 0)
413
- ret = error_func(&tag->object, FSCK_ERROR, "invalid 'type' value");
413
+ ret = options->error_func(&tag->object, FSCK_ERROR, "invalid 'type' value");
414
if (ret)
415
goto done;
416
buffer = eol + 1;
417
418
if (!skip_prefix(buffer, "tag ", &buffer)) {
419
- ret = error_func(&tag->object, FSCK_ERROR, "invalid format - expected 'tag' line");
419
+ ret = options->error_func(&tag->object, FSCK_ERROR, "invalid format - expected 'tag' line");
420
goto done;
421
}
422
eol = strchr(buffer, '\n');
423
if (!eol) {
424
- ret = error_func(&tag->object, FSCK_ERROR, "invalid format - unexpected end after 'type' line");
424
+ ret = options->error_func(&tag->object, FSCK_ERROR, "invalid format - unexpected end after 'type' line");
425
goto done;
426
}
427
strbuf_addf(&sb, "refs/tags/%.*s", (int)(eol - buffer), buffer);
428
if (check_refname_format(sb.buf, 0))
429
- error_func(&tag->object, FSCK_WARN, "invalid 'tag' name: %.*s",
429
+ options->error_func(&tag->object, FSCK_WARN, "invalid 'tag' name: %.*s",
430
(int)(eol - buffer), buffer);
431
buffer = eol + 1;
432
433
if (!skip_prefix(buffer, "tagger ", &buffer))
434
/* early tags do not contain 'tagger' lines; warn only */
435
- error_func(&tag->object, FSCK_WARN, "invalid format - expected 'tagger' line");
435
+ options->error_func(&tag->object, FSCK_WARN, "invalid format - expected 'tagger' line");
436
else
437
- ret = fsck_ident(&buffer, &tag->object, error_func);
437
+ ret = fsck_ident(&buffer, &tag->object, options);
438
439
done:
440
strbuf_release(&sb);
@@ -443,34 +443,34 @@ done:
443
}
444
445
static int fsck_tag(struct tag *tag, const char *data,
446
- unsigned long size, fsck_error error_func)
446
+ unsigned long size, struct fsck_options *options)
447
{
448
struct object *tagged = tag->tagged;
449
450
if (!tagged)
451
- return error_func(&tag->object, FSCK_ERROR, "could not load tagged object");
451
+ return options->error_func(&tag->object, FSCK_ERROR, "could not load tagged object");
452
453
- return fsck_tag_buffer(tag, data, size, error_func);
453
+ return fsck_tag_buffer(tag, data, size, options);
454
}
455
456
int fsck_object(struct object *obj, void *data, unsigned long size,
457
- int strict, fsck_error error_func)
457
+ struct fsck_options *options)
458
{
459
if (!obj)
460
- return error_func(obj, FSCK_ERROR, "no valid object to fsck");
460
+ return options->error_func(obj, FSCK_ERROR, "no valid object to fsck");
461
462
if (obj->type == OBJ_BLOB)
463
return 0;
464
if (obj->type == OBJ_TREE)
465
- return fsck_tree((struct tree *) obj, strict, error_func);
465
+ return fsck_tree((struct tree *) obj, options);
466
if (obj->type == OBJ_COMMIT)
467
return fsck_commit((struct commit *) obj, (const char *) data,
468
- size, error_func);
468
+ size, options);
469
if (obj->type == OBJ_TAG)
470
return fsck_tag((struct tag *) obj, (const char *) data,
471
- size, error_func);
471
+ size, options);
472
473
- return error_func(obj, FSCK_ERROR, "unknown type '%d' (internal fsck error)",
473
+ return options->error_func(obj, FSCK_ERROR, "unknown type '%d' (internal fsck error)",
474
obj->type);
475
}
476
fsck.h
+14
-3
@@ -4,6 +4,8 @@
4
#define FSCK_ERROR 1
5
#define FSCK_WARN 2
6
7
+struct fsck_options;
8
+
9
/*
10
* callback function for fsck_walk
11
* type is the expected type of the object or OBJ_ANY
@@ -12,7 +14,7 @@
14
* <0 error signaled and abort
15
* >0 error signaled and do not abort
16
*/
15
-typedef int (*fsck_walk_func)(struct object *obj, int type, void *data);
17
+typedef int (*fsck_walk_func)(struct object *obj, int type, void *data, struct fsck_options *options);
18
19
/* callback for fsck_object, type is FSCK_ERROR or FSCK_WARN */
20
typedef int (*fsck_error)(struct object *obj, int type, const char *err, ...);
@@ -20,6 +22,15 @@ typedef int (*fsck_error)(struct object *obj, int type, const char *err, ...);
22
__attribute__((format (printf, 3, 4)))
23
int fsck_error_function(struct object *obj, int type, const char *fmt, ...);
24
25
+struct fsck_options {
26
+ fsck_walk_func walk;
27
+ fsck_error error_func;
28
+ unsigned strict:1;
29
+};
30
+
31
+#define FSCK_OPTIONS_DEFAULT { NULL, fsck_error_function, 0 }
32
+#define FSCK_OPTIONS_STRICT { NULL, fsck_error_function, 1 }
33
+
34
/* descend in all linked child objects
35
* the return value is:
36
* -1 error in processing the object
@@ -27,9 +38,9 @@ int fsck_error_function(struct object *obj, int type, const char *fmt, ...);
38
* >0 return value of the first signaled error >0 (in the case of no other errors)
39
* 0 everything OK
40
*/
30
-int fsck_walk(struct object *obj, fsck_walk_func walk, void *data);
41
+int fsck_walk(struct object *obj, void *data, struct fsck_options *options);
42
/* If NULL is passed for data, we assume the object is local and read it. */
43
int fsck_object(struct object *obj, void *data, unsigned long size,
33
- int strict, fsck_error error_func);
44
+ struct fsck_options *options);
45
46
#endif