diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2018-12-25 18:08:43 -0500 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2018-12-25 18:13:15 -0500 |
commit | 36cb1762dd647a6c9cbb0ab36993c83798c854f1 (patch) | |
tree | 4bc2fc1cca1400774855e0b2618b967bb9466947 | |
parent | b2e69d3f76270fc4051801cac923307514184055 (diff) | |
download | bfs-36cb1762dd647a6c9cbb0ab36993c83798c854f1.tar.xz |
stat: Provide a helper for getting human-readable field names
And fix -newerXY if the Y time doesn't exist.
-rw-r--r-- | eval.c | 25 | ||||
-rw-r--r-- | parse.c | 67 | ||||
-rw-r--r-- | stat.c | 36 | ||||
-rw-r--r-- | stat.h | 5 |
4 files changed, 73 insertions, 60 deletions
@@ -215,32 +215,11 @@ bool eval_capable(const struct expr *expr, struct eval_state *state) { */ static const struct timespec *eval_stat_time(const struct bfs_stat *statbuf, enum bfs_stat_field field, const struct eval_state *state) { const struct timespec *ret = bfs_stat_time(statbuf, field); - if (!ret) { - const char *kind; - switch (field) { - case BFS_STAT_ATIME: - kind = "access"; - break; - case BFS_STAT_BTIME: - kind = "birth"; - break; - case BFS_STAT_CTIME: - kind = "change"; - break; - case BFS_STAT_MTIME: - kind = "modification"; - break; - default: - assert(false); - kind = "???"; - break; - } - - cfprintf(state->cmdline->cerr, "%{er}error: '%s': Couldn't get file %s time: %s%{rs}\n", state->ftwbuf->path, kind, strerror(errno)); + cfprintf(state->cmdline->cerr, "%{er}error: '%s': Couldn't get file %s time: %m%{rs}\n", + state->ftwbuf->path, bfs_stat_field_name(field)); *state->ret = EXIT_FAILURE; } - return ret; } @@ -1518,6 +1518,22 @@ static struct expr *parse_lname(struct parser_state *state, int casefold, int ar return parse_fnmatch(state, expr, casefold); } +/** Get the bfs_stat_field for X/Y in -newerXY */ +static enum bfs_stat_field parse_newerxy_field(char c) { + switch (c) { + case 'a': + return BFS_STAT_ATIME; + case 'B': + return BFS_STAT_BTIME; + case 'c': + return BFS_STAT_CTIME; + case 'm': + return BFS_STAT_MTIME; + default: + return 0; + } +} + /** * Parse -newerXY. */ @@ -1535,21 +1551,8 @@ static struct expr *parse_newerxy(struct parser_state *state, int arg1, int arg2 goto fail; } - switch (arg[6]) { - case 'a': - expr->stat_field = BFS_STAT_ATIME; - break; - case 'c': - expr->stat_field = BFS_STAT_CTIME; - break; - case 'm': - expr->stat_field = BFS_STAT_MTIME; - break; - case 'B': - expr->stat_field = BFS_STAT_BTIME; - break; - - default: + expr->stat_field = parse_newerxy_field(arg[6]); + if (!expr->stat_field) { cfprintf(cerr, "%{er}error: %s: For -newerXY, X should be 'a', 'c', 'm', or 'B'.%{rs}\n", arg); goto fail; } @@ -1558,35 +1561,25 @@ static struct expr *parse_newerxy(struct parser_state *state, int arg1, int arg2 cfprintf(cerr, "%{er}error: %s: Explicit reference times ('t') are not supported.%{rs}\n", arg); goto fail; } else { + enum bfs_stat_field field = parse_newerxy_field(arg[7]); + if (!field) { + cfprintf(cerr, "%{er}error: %s: For -newerXY, Y should be 'a', 'c', 'm', 'B', or 't'.%{rs}\n", arg); + goto fail; + } + struct bfs_stat sb; if (stat_arg(state, expr, &sb) != 0) { goto fail; } - switch (arg[7]) { - case 'a': - expr->reftime = sb.atime; - break; - case 'c': - expr->reftime = sb.ctime; - break; - case 'm': - expr->reftime = sb.mtime; - break; - - case 'B': - if (sb.mask & BFS_STAT_BTIME) { - expr->reftime = sb.btime; - } else { - cfprintf(cerr, "%{er}error: '%s': Couldn't get file birth time.%{rs}\n", expr->sdata); - goto fail; - } - break; - - default: - cfprintf(cerr, "%{er}error: %s: For -newerXY, Y should be 'a', 'c', 'm', 'B', or 't'.%{rs}\n", arg); + const struct timespec *reftime = bfs_stat_time(&sb, field); + if (!reftime) { + cfprintf(cerr, "%{er}error: '%s': Couldn't get file %s: %m.%{rs}\n", + expr->sdata, bfs_stat_field_name(field)); goto fail; } + + expr->reftime = *reftime; } return expr; @@ -42,6 +42,42 @@ # define st_birthtim st_birthtimespec #endif +const char *bfs_stat_field_name(enum bfs_stat_field field) { + switch (field) { + case BFS_STAT_DEV: + return "device number"; + case BFS_STAT_INO: + return "inode nunmber"; + case BFS_STAT_TYPE: + return "type"; + case BFS_STAT_MODE: + return "mode"; + case BFS_STAT_NLINK: + return "link count"; + case BFS_STAT_GID: + return "group ID"; + case BFS_STAT_UID: + return "user ID"; + case BFS_STAT_SIZE: + return "size"; + case BFS_STAT_BLOCKS: + return "block count"; + case BFS_STAT_RDEV: + return "underlying device"; + case BFS_STAT_ATIME: + return "access time"; + case BFS_STAT_BTIME: + return "birth time"; + case BFS_STAT_CTIME: + return "change time"; + case BFS_STAT_MTIME: + return "modification time"; + } + + assert(false); + return "???"; +} + /** * Check if we should retry a failed stat() due to a potentially broken link. */ @@ -47,6 +47,11 @@ enum bfs_stat_field { }; /** + * Get the human-readable name of a bfs_stat field. + */ +const char *bfs_stat_field_name(enum bfs_stat_field field); + +/** * bfs_stat() flags. */ enum bfs_stat_flag { |