diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2019-06-28 20:34:33 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2019-06-28 20:34:49 -0400 |
commit | e8b42e513fa97af5c9978eb95ea97712f0ea5bbb (patch) | |
tree | de9d429c0ca37e1cbff85f57a324564e1bfda76e | |
parent | 0473beaa2e3a46dd782af1182413fcdd4d33e275 (diff) |
Merge everything into one filesingle-file
-rw-r--r-- | Makefile | 19 | ||||
-rw-r--r-- | bfs.c | 14265 | ||||
-rw-r--r-- | bfs.h | 32 | ||||
-rw-r--r-- | bftw.c | 1551 | ||||
-rw-r--r-- | bftw.h | 238 | ||||
-rw-r--r-- | cmdline.h | 132 | ||||
-rw-r--r-- | color.c | 931 | ||||
-rw-r--r-- | color.h | 124 | ||||
-rw-r--r-- | diag.c | 64 | ||||
-rw-r--r-- | diag.h | 60 | ||||
-rw-r--r-- | dstring.c | 152 | ||||
-rw-r--r-- | dstring.h | 130 | ||||
-rw-r--r-- | eval.c | 1391 | ||||
-rw-r--r-- | eval.h | 81 | ||||
-rw-r--r-- | exec.c | 618 | ||||
-rw-r--r-- | exec.h | 118 | ||||
-rw-r--r-- | expr.h | 223 | ||||
-rw-r--r-- | fsade.c | 297 | ||||
-rw-r--r-- | fsade.h | 70 | ||||
-rw-r--r-- | main.c | 111 | ||||
-rw-r--r-- | mtab.c | 229 | ||||
-rw-r--r-- | mtab.h | 70 | ||||
-rw-r--r-- | opt.c | 870 | ||||
-rw-r--r-- | parse.c | 3462 | ||||
-rw-r--r-- | printf.c | 862 | ||||
-rw-r--r-- | printf.h | 64 | ||||
-rw-r--r-- | spawn.c | 226 | ||||
-rw-r--r-- | spawn.h | 103 | ||||
-rw-r--r-- | stat.c | 353 | ||||
-rw-r--r-- | stat.h | 150 | ||||
-rw-r--r-- | trie.c | 692 | ||||
-rw-r--r-- | trie.h | 157 | ||||
-rw-r--r-- | typo.c | 176 | ||||
-rw-r--r-- | typo.h | 31 | ||||
-rw-r--r-- | util.c | 383 | ||||
-rw-r--r-- | util.h | 220 |
36 files changed, 14266 insertions, 14389 deletions
@@ -68,24 +68,7 @@ default: bfs all: bfs tests/mksock -bfs: \ - bftw.o \ - color.o \ - diag.o \ - dstring.o \ - eval.o \ - exec.o \ - fsade.o \ - main.o \ - mtab.o \ - opt.o \ - parse.o \ - printf.o \ - spawn.o \ - stat.o \ - trie.o \ - typo.o \ - util.o +bfs: bfs.o $(CC) $(ALL_LDFLAGS) $^ $(ALL_LDLIBS) -o $@ release: CFLAGS := -g $(WFLAGS) -O3 -flto -DNDEBUG @@ -0,0 +1,14265 @@ +/**************************************************************************** + * bfs * + * Copyright (C) 2016-2019 Tavian Barnes <tavianator@tavianator.com> * + * * + * Permission to use, copy, modify, and/or distribute this software for any * + * purpose with or without fee is hereby granted. * + * * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * + ****************************************************************************/ + +/** + * Assorted utilities that don't belong anywhere else. + */ + +#ifndef BFS_UTIL_H +#define BFS_UTIL_H + +#include <dirent.h> +#include <fcntl.h> +#include <fnmatch.h> +#include <regex.h> +#include <stdbool.h> +#include <sys/types.h> +#include <time.h> + +// Some portability concerns + +#ifdef __has_feature +# define BFS_HAS_FEATURE(feature, fallback) __has_feature(feature) +#else +# define BFS_HAS_FEATURE(feature, fallback) fallback +#endif + +#ifdef __has_include +# define BFS_HAS_INCLUDE(header, fallback) __has_include(header) +#else +# define BFS_HAS_INCLUDE(header, fallback) fallback +#endif + +#ifndef BFS_HAS_MNTENT +# define BFS_HAS_MNTENT BFS_HAS_INCLUDE(<mntent.h>, __GLIBC__) +#endif + +#ifndef BFS_HAS_SYS_ACL +# define BFS_HAS_SYS_ACL BFS_HAS_INCLUDE(<sys/acl.h>, true) +#endif + +#ifndef BFS_HAS_SYS_CAPABILITY +# define BFS_HAS_SYS_CAPABILITY BFS_HAS_INCLUDE(<sys/capability.h>, __linux__) +#endif + +#ifndef BFS_HAS_SYS_MKDEV +# define BFS_HAS_SYS_MKDEV BFS_HAS_INCLUDE(<sys/mkdev.h>, false) +#endif + +#ifndef BFS_HAS_SYS_PARAM +# define BFS_HAS_SYS_PARAM BFS_HAS_INCLUDE(<sys/param.h>, true) +#endif + +#ifndef BFS_HAS_SYS_SYSMACROS +# define BFS_HAS_SYS_SYSMACROS BFS_HAS_INCLUDE(<sys/sysmacros.h>, __GLIBC__) +#endif + +#ifndef BFS_HAS_SYS_XATTR +# define BFS_HAS_SYS_XATTR BFS_HAS_INCLUDE(<sys/xattr.h>, __linux__) +#endif + +#if !defined(FNM_CASEFOLD) && defined(FNM_IGNORECASE) +# define FNM_CASEFOLD FNM_IGNORECASE +#endif + +#ifndef O_DIRECTORY +# define O_DIRECTORY 0 +#endif + +/** + * Adds compiler warnings for bad printf()-style function calls, if supported. + */ +#if __GNUC__ +# define BFS_FORMATTER(fmt, args) __attribute__((format(printf, fmt, args))) +#else +# define BFS_FORMATTER(fmt, args) +#endif + +/** + * readdir() wrapper that makes error handling cleaner. + */ +int xreaddir(DIR *dir, struct dirent **de); + +/** + * readlinkat() wrapper that dynamically allocates the result. + * + * @param fd + * The base directory descriptor. + * @param path + * The path to the link, relative to fd. + * @param size + * An estimate for the size of the link name (pass 0 if unknown). + * @return The target of the link, allocated with malloc(), or NULL on failure. + */ +char *xreadlinkat(int fd, const char *path, size_t size); + +/** + * Check if a file descriptor is open. + */ +bool isopen(int fd); + +/** + * Open a file and redirect it to a particular descriptor. + * + * @param fd + * The file descriptor to redirect. + * @param path + * The path to open. + * @param flags + * The flags passed to open(). + * @param mode + * The mode passed to open() (optional). + * @return fd on success, -1 on failure. + */ +int redirect(int fd, const char *path, int flags, ...); + +/** + * Like dup(), but set the FD_CLOEXEC flag. + * + * @param fd + * The file descriptor to duplicate. + * @return A duplicated file descriptor, or -1 on failure. + */ +int dup_cloexec(int fd); + +/** + * Like pipe(), but set the FD_CLOEXEC flag. + * + * @param pipefd + * The array to hold the two file descriptors. + * @return 0 on success, -1 on failure. + */ +int pipe_cloexec(int pipefd[2]); + +/** + * Dynamically allocate a regex error message. + * + * @param err + * The error code to stringify. + * @param regex + * The (partially) compiled regex. + * @return A human-readable description of the error, allocated with malloc(). + */ +char *xregerror(int err, const regex_t *regex); + +/** + * localtime_r() wrapper that calls tzset() first. + * + * @param timep + * The time_t to convert. + * @param result + * Buffer to hold the result. + * @return 0 on success, -1 on failure. + */ +int xlocaltime(const time_t *timep, struct tm *result); + +/** + * Format a mode like ls -l (e.g. -rw-r--r--). + * + * @param mode + * The mode to format. + * @param str + * The string to hold the formatted mode. + */ +void format_mode(mode_t mode, char str[11]); + +/** + * basename() variant that doesn't modify the input. + * + * @param path + * The path in question. + * @return A pointer into path at the base name offset. + */ +const char *xbasename(const char *path); + +/** + * Wrapper for faccessat() that handles some portability issues. + */ +int xfaccessat(int fd, const char *path, int amode); + +/** + * Return whether an error code is due to a path not existing. + */ +bool is_nonexistence_error(int error); + +/** + * Process a yes/no prompt. + * + * @return 1 for yes, 0 for no, and -1 for unknown. + */ +int ynprompt(void); + +/** + * Portable version of makedev(). + */ +dev_t bfs_makedev(int ma, int mi); + +/** + * Portable version of major(). + */ +int bfs_major(dev_t dev); + +/** + * Portable version of minor(). + */ +int bfs_minor(dev_t dev); + +#endif // BFS_UTIL_H +/**************************************************************************** + * bfs * + * Copyright (C) 2018-2019 Tavian Barnes <tavianator@tavianator.com> * + * * + * Permission to use, copy, modify, and/or distribute this software for any * + * purpose with or without fee is hereby granted. * + * * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * + ****************************************************************************/ + +/** + * A facade over the stat() API that unifies some details that diverge between + * implementations, like the names of the timespec fields and the presence of + * file "birth" times. On new enough Linux kernels, the facade is backed by + * statx() instead, and so it exposes a similar interface with a mask for which + * fields were successfully returned. + */ + +#ifndef BFS_STAT_H +#define BFS_STAT_H + +#include <sys/types.h> +#include <sys/stat.h> +#include <time.h> + +#if BFS_HAS_SYS_PARAM +# include <sys/param.h> +#endif + +/** + * bfs_stat field bitmask. + */ +enum bfs_stat_field { + BFS_STAT_DEV = 1 << 0, + BFS_STAT_INO = 1 << 1, + BFS_STAT_TYPE = 1 << 2, + BFS_STAT_MODE = 1 << 3, + BFS_STAT_NLINK = 1 << 4, + BFS_STAT_GID = 1 << 5, + BFS_STAT_UID = 1 << 6, + BFS_STAT_SIZE = 1 << 7, + BFS_STAT_BLOCKS = 1 << 8, + BFS_STAT_RDEV = 1 << 9, + BFS_STAT_ATIME = 1 << 10, + BFS_STAT_BTIME = 1 << 11, + BFS_STAT_CTIME = 1 << 12, + BFS_STAT_MTIME = 1 << 13, +}; + +/** + * 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 { + /** Follow symlinks (the default). */ + BFS_STAT_FOLLOW = 0, + /** Never follow symlinks. */ + BFS_STAT_NOFOLLOW = 1 << 0, + /** Try to follow symlinks, but fall back to the link itself if broken. */ + BFS_STAT_TRYFOLLOW = 1 << 1, +}; + +#ifdef DEV_BSIZE +# define BFS_STAT_BLKSIZE DEV_BSIZE +#elif defined(S_BLKSIZE) +# define BFS_STAT_BLKSIZE S_BLKSIZE +#else +# define BFS_STAT_BLKSIZE 512 +#endif + +/** + * Facade over struct stat. + */ +struct bfs_stat { + /** Bitmask indicating filled fields. */ + enum bfs_stat_field mask; + + /** Device ID containing the file. */ + dev_t dev; + /** Inode number. */ + ino_t ino; + /** File type and access mode. */ + mode_t mode; + /** Number of hard links. */ + nlink_t nlink; + /** Owner group ID. */ + gid_t gid; + /** Owner user ID. */ + uid_t uid; + /** File size in bytes. */ + off_t size; + /** Number of disk blocks allocated (of size BFS_STAT_BLKSIZE). */ + blkcnt_t blocks; + /** The device ID represented by this file. */ + dev_t rdev; + + /** Access time. */ + struct timespec atime; + /** Birth/creation time. */ + struct timespec btime; + /** Status change time. */ + struct timespec ctime; + /** Modification time. */ + struct timespec mtime; +}; + +/** + * Facade over fstatat(). + * + * @param at_fd + * The base file descriptor for the lookup. + * @param at_path + * The path to stat, relative to at_fd. Pass NULL to fstat() at_fd + * itself. + * @param flags + * Flags that affect the lookup. + * @param[out] buf + * A place to store the stat buffer, if successful. + * @return + * 0 on success, -1 on error. + */ +int bfs_stat(int at_fd, const char *at_path, enum bfs_stat_flag flags, struct bfs_stat *buf); + +/** + * Get a particular time field from a bfs_stat() buffer. + */ +const struct timespec *bfs_stat_time(const struct bfs_stat *buf, enum bfs_stat_field field); + +/** + * A unique ID for a file. + */ +typedef unsigned char bfs_file_id[sizeof(dev_t) + sizeof(ino_t)]; + +/** + * Compute a unique ID for a file. + */ +void bfs_stat_id(const struct bfs_stat *buf, bfs_file_id *id); + +#endif // BFS_STAT_H +/**************************************************************************** + * bfs * + * Copyright (C) 2015-2018 Tavian Barnes <tavianator@tavianator.com> * + * * + * Permission to use, copy, modify, and/or distribute this software for any * + * purpose with or without fee is hereby granted. * + * * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * + ****************************************************************************/ + +/** + * Utilities for colored output on ANSI terminals. + */ + +#ifndef BFS_COLOR_H +#define BFS_COLOR_H + +#include <stdarg.h> +#include <stdbool.h> +#include <stdio.h> + +/** + * A lookup table for colors. + */ +struct colors; + +/** + * Parse a color table. + * + * @param ls_colors + * A color table in the LS_COLORS environment variable format. + * @return The parsed color table. + */ +struct colors *parse_colors(const char *ls_colors); + +/** + * Free a color table. + * + * @param colors + * The color table to free. + */ +void free_colors(struct colors *colors); + +/** + * A file/stream with associated colors. + */ +typedef struct CFILE { + /** The underlying file/stream. */ + FILE *file; + /** The color table to use, if any. */ + const struct colors *colors; + /** Whether to close the underlying stream. */ + bool close; +} CFILE; + +/** + * Open a file for colored output. + * + * @param path + * The path to the file to open. + * @param colors + * The color table to use if file is a TTY. + * @return A colored file stream. + */ +CFILE *cfopen(const char *path, const struct colors *colors); + +/** + * Make a colored copy of an open file. + * + * @param file + * The underlying file. + * @param colors + * The color table to use if file is a TTY. + * @return A colored wrapper around file. + */ +CFILE *cfdup(FILE *file, const struct colors *colors); + +/** + * Close a colored file. + * + * @param cfile + * The colored file to close. + * @return 0 on success, -1 on failure. + */ +int cfclose(CFILE *cfile); + +/** + * Colored, formatted output. + * + * @param cfile + * The colored stream to print to. + * @param format + * A printf()-style format string, supporting these format specifiers: + * + * %c: A single character + * %d: An integer + * %g: A double + * %s: A string + * %zu: A size_t + * %m: strerror(errno) + * %pP: A colored file path, from a const struct BFTW * argument + * %pL: A colored link target, from a const struct BFTW * argument + * %%: A literal '%' + * ${cc}: Change the color to 'cc' + * $$: A literal '$' + * @return 0 on success, -1 on failure. + */ +BFS_FORMATTER(2, 3) +int cfprintf(CFILE *cfile, const char *format, ...); + +/** + * cfprintf() variant that takes a va_list. + */ +int cvfprintf(CFILE *cfile, const char *format, va_list args); + +#endif // BFS_COLOR_H +/**************************************************************************** + * bfs * + * Copyright (C) 2019 Tavian Barnes <tavianator@tavianator.com> * + * * + * Permission to use, copy, modify, and/or distribute this software for any * + * purpose with or without fee is hereby granted. * + * * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * + ****************************************************************************/ + +#ifndef BFS_TRIE_H +#define BFS_TRIE_H + +#include <stdbool.h> +#include <stddef.h> +#include <stdint.h> + +/** + * A trie that holds a set of fixed- or variable-length strings. + */ +struct trie { + uintptr_t root; +}; + +/** + * A leaf of a trie. + */ +struct trie_leaf { + /** + * An arbitrary value associated with this leaf. + */ + void *value; + + /** + * The length of the key in bytes. + */ + size_t length; + + /** + * The key itself, stored inline. + */ + char key[]; +}; + +/** + * Initialize an empty trie. + */ +void trie_init(struct trie *trie); + +/** + * Get the first (lexicographically earliest) leaf in the trie. + * + * @param trie + * The trie to search. + * @return + * The first leaf, or NULL if the trie is empty. + */ +struct trie_leaf *trie_first_leaf(const struct trie *trie); + +/** + * Find the leaf for a string key. + * + * @param trie + * The trie to search. + * @param key + * The key to look up. + * @return + * The found leaf, or NULL if the key is not present. + */ +struct trie_leaf *trie_find_str(const struct trie *trie, const char *key); + +/** + * Find the leaf for a fixed-size key. + * + * @param trie + * The trie to search. + * @param key + * The key to look up. + * @param length + * The length of the key in bytes. + * @return + * The found leaf, or NULL if the key is not present. + */ +struct trie_leaf *trie_find_mem(const struct trie *trie, const void *key, size_t length); + +/** + * Find the shortest leaf that starts with a given key. + * + * @param trie + * The trie to search. + * @param key + * The key to look up. + * @return + * A leaf that starts with the given key, or NULL. + */ +struct trie_leaf *trie_find_postfix(const struct trie *trie, const char *key); + +/** + * Find the leaf that is the longest prefix of the given key. + * + * @param trie + * The trie to search. + * @param key + * The key to look up. + * @return + * The longest prefix match for the given key, or NULL. + */ +struct trie_leaf *trie_find_prefix(const struct trie *trie, const char *key); + +/** + * Insert a string key into the trie. + * + * @param trie + * The trie to modify. + * @param key + * The key to insert. + * @return + * The inserted leaf, or NULL on failure. + */ +struct trie_leaf *trie_insert_str(struct trie *trie, const char *key); + +/** + * Insert a fixed-size key into the trie. + * + * @param trie + * The trie to modify. + * @param key + * The key to insert. + * @param length + * The length of the key in bytes. + * @return + * The inserted leaf, or NULL on failure. + */ +struct trie_leaf *trie_insert_mem(struct trie *trie, const void *key, size_t length); + +/** + * Remove a leaf from a trie. + * + * @param trie + * The trie to modify. + * @param leaf + * The leaf to remove. + */ +void trie_remove(struct trie *trie, struct trie_leaf *leaf); + +/** + * Destroy a trie and its contents. + */ +void trie_destroy(struct trie *trie); + +#endif // BFS_TRIE_H +/**************************************************************************** + * bfs * + * Copyright (C) 2015-2018 Tavian Barnes <tavianator@tavianator.com> * + * * + * Permission to use, copy, modify, and/or distribute this software for any * + * purpose with or without fee is hereby granted. * + * * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * + ****************************************************************************/ + +/** + * The expression tree representation. + */ + +#ifndef BFS_EXPR_H +#define BFS_EXPR_H + +#include <regex.h> +#include <stdbool.h> +#include <stddef.h> +#include <sys/types.h> +#include <time.h> + +/** + * A command line expression. + */ +struct expr; + +/** + * Ephemeral state for evaluating an expression. + */ +struct eval_state; + +/** + * Expression evaluation function. + * + * @param expr + * The current expression. + * @param state + * The current evaluation state. + * @return + * The result of the test. + */ +typedef bool eval_fn(const struct expr *expr, struct eval_state *state); + +/** + * Possible types of numeric comparison. + */ +enum cmp_flag { + /** Exactly n. */ + CMP_EXACT, + /** Less than n. */ + CMP_LESS, + /** Greater than n. */ + CMP_GREATER, +}; + +/** + * Possible types of mode comparison. + */ +enum mode_cmp { + /** Mode is an exact match (MODE). */ + MODE_EXACT, + /** Mode has all these bits (-MODE). */ + MODE_ALL, + /** Mode has any of these bits (/MODE). */ + MODE_ANY, +}; + +/** + * Possible time units. + */ +enum time_unit { + /** Minutes. */ + MINUTES, + /** Days. */ + DAYS, +}; + +/** + * Possible file size units. + */ +enum size_unit { + /** 512-byte blocks. */ + SIZE_BLOCKS, + /** Single bytes. */ + SIZE_BYTES, + /** Two-byte words. */ + SIZE_WORDS, + /** Kibibytes. */ + SIZE_KB, + /** Mebibytes. */ + SIZE_MB, + /** Gibibytes. */ + SIZE_GB, + /** Tebibytes. */ + SIZE_TB, + /** Pebibytes. */ + SIZE_PB, +}; + +struct expr { + /** The function that evaluates this expression. */ + eval_fn *eval; + + /** The left hand side of the expression. */ + struct expr *lhs; + /** The right hand side of the expression. */ + struct expr *rhs; + + /** Whether this expression has no side effects. */ + bool pure; + /** Whether this expression always evaluates to true. */ + bool always_true; + /** Whether this expression always evaluates to false. */ + bool always_false; + + /** Estimated cost. */ + double cost; + /** Estimated probability of success. */ + double probability; + /** Number of times this predicate was executed. */ + size_t evaluations; + /** Number of times this predicate succeeded. */ + size_t successes; + /** Total time spent running this predicate. */ + struct timespec elapsed; + + /** The number of command line arguments for this expression. */ + size_t argc; + /** The command line arguments comprising this expression. */ + char **argv; + + /** The optional comparison flag. */ + enum cmp_flag cmp_flag; + + /** The mode comparison flag. */ + enum mode_cmp mode_cmp; + /** Mode to use for files. */ + mode_t file_mode; + /** Mode to use for directories (different due to X). */ + mode_t dir_mode; + + /** The optional stat field to look at. */ + enum bfs_stat_field stat_field; + /** The optional reference time. */ + struct timespec reftime; + /** The optional time unit. */ + enum time_unit time_unit; + + /** The optional size unit. */ + enum size_unit size_unit; + + /** Optional device number for a target file. */ + dev_t dev; + /** Optional inode number for a target file. */ + ino_t ino; + + /** File to output to. */ + CFILE *cfile; + + /** Optional compiled regex. */ + regex_t *regex; + + /** Optional exec command. */ + struct bfs_exec *execbuf; + + /** Optional printf command. */ + struct bfs_printf *printf; + + /** Optional integer data for this expression. */ + long long idata; + + /** Optional string data for this expression. */ + const char *sdata; + + /** The number of files this expression keeps open between evaluations. */ + int persistent_fds; + /** The number of files this expression opens during evaluation. */ + int ephemeral_fds; +}; + +/** Singleton true expression instance. */ +extern struct expr expr_true; +/** Singleton false expression instance. */ +extern struct expr expr_false; + +/** + * Create a new expression. + */ +struct expr *new_expr(eval_fn *eval, size_t argc, char **argv); + +/** + * @return Whether expr is known to always quit. + */ +bool expr_never_returns(const struct expr *expr); + +/** + * @return The result of the comparison for this expression. + */ +bool expr_cmp(const struct expr *expr, long long n); + +/** + * Dump a parsed expression. + */ +void dump_expr(CFILE *cfile, const struct expr *expr, bool verbose); + +/** + * Free an expression tree. + */ +void free_expr(struct expr *expr); + +#endif // BFS_EXPR_H +/**************************************************************************** + * bfs * + * Copyright (C) 2015-2019 Tavian Barnes <tavianator@tavianator.com> * + * * + * Permission to use, copy, modify, and/or distribute this software for any * + * purpose with or without fee is hereby granted. * + * * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * + ****************************************************************************/ + +/** + * Constants about the bfs program itself. + */ + +#ifndef BFS_H +#define BFS_H + +#ifndef BFS_VERSION +# define BFS_VERSION "1.5" +#endif + +#ifndef BFS_HOMEPAGE +# define BFS_HOMEPAGE "https://github.com/tavianator/bfs" +#endif + +#endif // BFS_H +/**************************************************************************** + * bfs |