diff options
-rw-r--r-- | fsck.c | 76 | ||||
-rw-r--r-- | fsck.h | 9 |
2 files changed, 80 insertions, 5 deletions
@@ -108,13 +108,79 @@ static int fsck_msg_type(enum fsck_msg_id msg_id, { int msg_type; - msg_type = msg_id_info[msg_id].msg_type; - if (options->strict && msg_type == FSCK_WARN) - msg_type = FSCK_ERROR; + assert(msg_id >= 0 && msg_id < FSCK_MSG_MAX); + + if (options->msg_type) + msg_type = options->msg_type[msg_id]; + else { + msg_type = msg_id_info[msg_id].msg_type; + if (options->strict && msg_type == FSCK_WARN) + msg_type = FSCK_ERROR; + } return msg_type; } +static int parse_msg_type(const char *str) +{ + if (!strcmp(str, "error")) + return FSCK_ERROR; + else if (!strcmp(str, "warn")) + return FSCK_WARN; + else + die("Unknown fsck message type: '%s'", str); +} + +void fsck_set_msg_type(struct fsck_options *options, + const char *msg_id, const char *msg_type) +{ + int id = parse_msg_id(msg_id), type; + + if (id < 0) + die("Unhandled message id: %s", msg_id); + type = parse_msg_type(msg_type); + + if (!options->msg_type) { + int i; + int *msg_type = xmalloc(sizeof(int) * FSCK_MSG_MAX); + for (i = 0; i < FSCK_MSG_MAX; i++) + msg_type[i] = fsck_msg_type(i, options); + options->msg_type = msg_type; + } + + options->msg_type[id] = type; +} + +void fsck_set_msg_types(struct fsck_options *options, const char *values) +{ + char *buf = xstrdup(values), *to_free = buf; + int done = 0; + + while (!done) { + int len = strcspn(buf, " ,|"), equal; + + done = !buf[len]; + if (!len) { + buf++; + continue; + } + buf[len] = '\0'; + + for (equal = 0; + equal < len && buf[equal] != '=' && buf[equal] != ':'; + equal++) + buf[equal] = tolower(buf[equal]); + buf[equal] = '\0'; + + if (equal == len) + die("Missing '=': '%s'", buf); + + fsck_set_msg_type(options, buf, buf + equal + 1); + buf += len + 1; + } + free(to_free); +} + __attribute__((format (printf, 4, 5))) static int report(struct fsck_options *options, struct object *object, enum fsck_msg_id id, const char *fmt, ...) @@ -604,6 +670,10 @@ int fsck_object(struct object *obj, void *data, unsigned long size, int fsck_error_function(struct object *obj, int msg_type, const char *message) { + if (msg_type == FSCK_WARN) { + warning("object %s: %s", sha1_to_hex(obj->sha1), message); + return 0; + } error("object %s: %s", sha1_to_hex(obj->sha1), message); return 1; } @@ -6,6 +6,10 @@ struct fsck_options; +void fsck_set_msg_type(struct fsck_options *options, + const char *msg_id, const char *msg_type); +void fsck_set_msg_types(struct fsck_options *options, const char *values); + /* * callback function for fsck_walk * type is the expected type of the object or OBJ_ANY @@ -25,10 +29,11 @@ struct fsck_options { fsck_walk_func walk; fsck_error error_func; unsigned strict:1; + int *msg_type; }; -#define FSCK_OPTIONS_DEFAULT { NULL, fsck_error_function, 0 } -#define FSCK_OPTIONS_STRICT { NULL, fsck_error_function, 1 } +#define FSCK_OPTIONS_DEFAULT { NULL, fsck_error_function, 0, NULL } +#define FSCK_OPTIONS_STRICT { NULL, fsck_error_function, 1, NULL } /* descend in all linked child objects * the return value is: |