summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2019-01-02 17:00:40 -0500
committerTavian Barnes <tavianator@tavianator.com>2019-01-02 17:01:06 -0500
commit29a49f5d150911428a35943be8d9fc226865eb1b (patch)
tree35ca4aa4fd793e6398c7943cee0b1732f29419c0
parent7fc7e98df2ea9c34dd1e0cb188554bed933a16df (diff)
downloadbfs-29a49f5d150911428a35943be8d9fc226865eb1b.tar.xz
color: Check format strings + args for cfprintf()
%{cc} is now ${cc} to avoid warnings about an unrecognized format specifier, and %P and %L are now %pP and %pL to make them look more like standard format strings.
-rw-r--r--color.c187
-rw-r--r--color.h11
-rw-r--r--diag.c4
-rw-r--r--diag.h3
-rw-r--r--eval.c9
-rw-r--r--opt.c2
-rw-r--r--parse.c440
-rw-r--r--util.h9
8 files changed, 353 insertions, 312 deletions
diff --git a/color.c b/color.c
index 9a19990..5807184 100644
--- a/color.c
+++ b/color.c
@@ -486,116 +486,139 @@ int cvfprintf(CFILE *cfile, const char *format, va_list args) {
int error = errno;
for (const char *i = format; *i; ++i) {
- const char *percent = strchr(i, '%');
- if (!percent) {
- if (fputs(i, file) == EOF) {
- return -1;
- }
- break;
- }
-
- size_t len = percent - i;
- if (fwrite(i, 1, len, file) != len) {
+ size_t verbatim = strcspn(i, "%$");
+ if (fwrite(i, 1, verbatim, file) != verbatim) {
return -1;
}
- i = percent + 1;
+ i += verbatim;
switch (*i) {
case '%':
- if (fputc('%', file) == EOF) {
- return -1;
- }
- break;
+ switch (*++i) {
+ case '%':
+ if (fputc('%', file) == EOF) {
+ return -1;
+ }
+ break;
- case 'c':
- if (fputc(va_arg(args, int), file) == EOF) {
- return -1;
- }
- break;
+ case 'c':
+ if (fputc(va_arg(args, int), file) == EOF) {
+ return -1;
+ }
+ break;
- case 'd':
- if (fprintf(file, "%d", va_arg(args, int)) < 0) {
- return -1;
- }
- break;
+ case 'd':
+ if (fprintf(file, "%d", va_arg(args, int)) < 0) {
+ return -1;
+ }
+ break;
- case 'g':
- if (fprintf(file, "%g", va_arg(args, double)) < 0) {
- return -1;
- }
- break;
+ case 'g':
+ if (fprintf(file, "%g", va_arg(args, double)) < 0) {
+ return -1;
+ }
+ break;
- case 's':
- if (fputs(va_arg(args, const char *), file) == EOF) {
- return -1;
- }
- break;
+ case 's':
+ if (fputs(va_arg(args, const char *), file) == EOF) {
+ return -1;
+ }
+ break;
+
+ case 'z':
+ ++i;
+ if (*i != 'u') {
+ goto invalid;
+ }
+ if (fprintf(file, "%zu", va_arg(args, size_t)) < 0) {
+ return -1;
+ }
+ break;
- case 'z':
- ++i;
- if (*i != 'u') {
+ case 'm':
+ if (fputs(strerror(error), file) == EOF) {
+ return -1;
+ }
+ break;
+
+ case 'p':
+ switch (*++i) {
+ case 'P':
+ if (print_path(cfile, va_arg(args, const struct BFTW *)) != 0) {
+ return -1;
+ }
+ break;
+
+ case 'L':
+ if (print_link(cfile, va_arg(args, const struct BFTW *)) != 0) {
+ return -1;
+ }
+ break;
+
+ default:
+ goto invalid;
+ }
+
+ break;
+
+ default:
goto invalid;
}
- if (fprintf(file, "%zu", va_arg(args, size_t)) < 0) {
- return -1;
- }
break;
- case 'm':
- if (fputs(strerror(error), file) == EOF) {
- return -1;
- }
- break;
+ case '$':
+ switch (*++i) {
+ case '$':
+ if (fputc('$', file) == EOF) {
+ return -1;
+ }
+ break;
- case 'P':
- if (print_path(cfile, va_arg(args, const struct BFTW *)) != 0) {
- return -1;
- }
- break;
+ case '{': {
+ ++i;
+ const char *end = strchr(i, '}');
+ if (!end) {
+ goto invalid;
+ }
+ if (!colors) {
+ i = end;
+ break;
+ }
- case 'L':
- if (print_link(cfile, va_arg(args, const struct BFTW *)) != 0) {
- return -1;
- }
- break;
+ size_t len = end - i;
+ char name[len + 1];
+ memcpy(name, i, len);
+ name[len] = '\0';
+
+ const char **esc = get_color(colors, name);
+ if (!esc) {
+ goto invalid;
+ }
+ if (*esc) {
+ if (print_esc(*esc, file) != 0) {
+ return -1;
+ }
+ }
- case '{': {
- ++i;
- const char *end = strchr(i, '}');
- if (!end) {
- goto invalid;
- }
- if (!colors) {
i = end;
break;
}
- size_t len = end - i;
- char name[len + 1];
- memcpy(name, i, len);
- name[len] = '\0';
-
- const char **esc = get_color(colors, name);
- if (!esc) {
+ default:
goto invalid;
}
- if (*esc) {
- if (print_esc(*esc, file) != 0) {
- return -1;
- }
- }
-
- i = end;
break;
- }
default:
- invalid:
- assert(false);
- errno = EINVAL;
- return -1;
+ return 0;
}
+
}
return 0;
+
+invalid:
+ assert(false);
+ errno = EINVAL;
+ return -1;
}
diff --git a/color.h b/color.h
index a68378e..78db64a 100644
--- a/color.h
+++ b/color.h
@@ -18,6 +18,7 @@
#define BFS_COLOR_H
#include "bftw.h"
+#include "util.h"
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
@@ -95,18 +96,20 @@ int cfclose(CFILE *cfile);
* @param format
* A printf()-style format string, supporting these format specifiers:
*
- * %%: A literal '%'
* %c: A single character
* %d: An integer
* %g: A double
* %s: A string
* %zu: A size_t
* %m: strerror(errno)
- * %P: A colored file path, from a const struct BFTW * argument
- * %L: A colored link target, from a const struct BFTW * argument
- * %{cc}: Change the color to 'cc'
+ * %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, ...);
/**
diff --git a/diag.c b/diag.c
index d45e38b..bdbf98e 100644
--- a/diag.c
+++ b/diag.c
@@ -56,9 +56,9 @@ void bfs_vwarning(const struct cmdline *cmdline, const char *format, va_list arg
}
void bfs_error_prefix(const struct cmdline *cmdline) {
- cfprintf(cmdline->cerr, "%{bld}%s:%{rs} %{er}error:%{rs} ", xbasename(cmdline->argv[0]));
+ cfprintf(cmdline->cerr, "${bld}%s:${rs} ${er}error:${rs} ", xbasename(cmdline->argv[0]));
}
void bfs_warning_prefix(const struct cmdline *cmdline) {
- cfprintf(cmdline->cerr, "%{bld}%s:%{rs} %{wr}warning:%{rs} ", xbasename(cmdline->argv[0]));
+ cfprintf(cmdline->cerr, "${bld}%s:${rs} ${wr}warning:${rs} ", xbasename(cmdline->argv[0]));
}
diff --git a/diag.h b/diag.h
index 24ee92a..e84bbc1 100644
--- a/diag.h
+++ b/diag.h
@@ -18,16 +18,19 @@
#define BFS_DIAG_H
#include "cmdline.h"
+#include "util.h"
#include <stdarg.h>
/**
* Shorthand for printing error messages.
*/
+BFS_FORMATTER(2, 3)
void bfs_error(const struct cmdline *cmdline, const char *format, ...);
/**
* Shorthand for printing warning messages.
*/
+BFS_FORMATTER(2, 3)
void bfs_warning(const struct cmdline *cmdline, const char *format, ...);
/**
diff --git a/eval.c b/eval.c
index f7632d8..5b55b8d 100644
--- a/eval.c
+++ b/eval.c
@@ -62,11 +62,12 @@ struct eval_state {
/**
* Print an error message.
*/
+BFS_FORMATTER(2, 3)
static void eval_error(const struct eval_state *state, const char *format, ...) {
int error = errno;
const struct cmdline *cmdline = state->cmdline;
- bfs_error(cmdline, "%P: ", state->ftwbuf);
+ bfs_error(cmdline, "%pP: ", state->ftwbuf);
va_list args;
va_start(args, format);
@@ -721,12 +722,12 @@ bool eval_fls(const struct expr *expr, struct eval_state *state) {
goto error;
}
- if (cfprintf(cfile, " %P", ftwbuf) < 0) {
+ if (cfprintf(cfile, " %pP", ftwbuf) < 0) {
goto error;
}
if (ftwbuf->typeflag == BFTW_LNK) {
- if (cfprintf(cfile, " -> %L", ftwbuf) < 0) {
+ if (cfprintf(cfile, " -> %pL", ftwbuf) < 0) {
goto error;
}
}
@@ -752,7 +753,7 @@ bool eval_fprint(const struct expr *expr, struct eval_state *state) {
eval_stat(state);
}
- if (cfprintf(cfile, "%P\n", state->ftwbuf) < 0) {
+ if (cfprintf(cfile, "%pP\n", state->ftwbuf) < 0) {
eval_report_error(state);
}
diff --git a/opt.c b/opt.c
index 5e3dc19..2ded162 100644
--- a/opt.c
+++ b/opt.c
@@ -108,7 +108,7 @@ static void debug_opt(const struct opt_state *state, const char *format, ...) {
break;
case 'g':
- cfprintf(cerr, "%{ylw}%g%{rs}", va_arg(args, double));
+ cfprintf(cerr, "${ylw}%g${rs}", va_arg(args, double));
break;
}
} else {
diff --git a/parse.c b/parse.c
index e678840..28a9f88 100644
--- a/parse.c
+++ b/parse.c
@@ -199,13 +199,13 @@ void dump_expr(CFILE *cfile, const struct expr *expr, bool verbose) {
fputs("(", cfile->file);
if (expr->lhs || expr->rhs) {
- cfprintf(cfile, "%{red}%s%{rs}", expr->argv[0]);
+ cfprintf(cfile, "${red}%s${rs}", expr->argv[0]);
} else {
- cfprintf(cfile, "%{blu}%s%{rs}", expr->argv[0]);
+ cfprintf(cfile, "${blu}%s${rs}", expr->argv[0]);
}
for (size_t i = 1; i < expr->argc; ++i) {
- cfprintf(cfile, " %{bld}%s%{rs}", expr->argv[i]);
+ cfprintf(cfile, " ${bld}%s${rs}", expr->argv[i]);
}
if (verbose) {
@@ -214,7 +214,7 @@ void dump_expr(CFILE *cfile, const struct expr *expr, bool verbose) {
rate = 100.0*expr->successes/expr->evaluations;
time = (1.0e9*expr->elapsed.tv_sec + expr->elapsed.tv_nsec)/expr->evaluations;
}
- cfprintf(cfile, " [%{ylw}%zu%{rs}/%{ylw}%zu%{rs}=%{ylw}%g%%%{rs}; %{ylw}%gns%{rs}]", expr->successes, expr->evaluations, rate, time);
+ cfprintf(cfile, " [${ylw}%zu${rs}/${ylw}%zu${rs}=${ylw}%g%%${rs}; ${ylw}%gns${rs}]", expr->successes, expr->evaluations, rate, time);
}
if (expr->lhs) {
@@ -373,6 +373,7 @@ enum token_type {
/**
* Print an error message during parsing.
*/
+BFS_FORMATTER(2, 3)
static void parse_error(const struct parser_state *state, const char *format, ...) {
va_list args;
va_start(args, format);
@@ -383,6 +384,7 @@ static void parse_error(const struct parser_state *state, const char *format, ..
/**
* Print a warning message during parsing.
*/
+BFS_FORMATTER(2, 3)
static void parse_warning(const struct parser_state *state, const char *format, ...) {
va_list args;
va_start(args, format);
@@ -837,15 +839,15 @@ static struct expr *parse_test_icmp(struct parser_state *state, eval_fn *eval) {
static void debug_help(CFILE *cfile) {
cfprintf(cfile, "Supported debug flags:\n\n");
- cfprintf(cfile, " %{bld}help%{rs}: This message.\n");
- cfprintf(cfile, " %{bld}cost%{rs}: Show cost estimates.\n");
- cfprintf(cfile, " %{bld}exec%{rs}: Print executed command details.\n");
- cfprintf(cfile, " %{bld}opt%{rs}: Print optimization details.\n");
- cfprintf(cfile, " %{bld}rates%{rs}: Print predicate success rates.\n");
- cfprintf(cfile, " %{bld}search%{rs}: Trace the filesystem traversal.\n");
- cfprintf(cfile, " %{bld}stat%{rs}: Trace all stat() calls.\n");
- cfprintf(cfile, " %{bld}tree%{rs}: Print the parse tree.\n");
- cfprintf(cfile, " %{bld}all%{rs}: All debug flags at once.\n");
+ cfprintf(cfile, " ${bld}help${rs}: This message.\n");
+ cfprintf(cfile, " ${bld}cost${rs}: Show cost estimates.\n");
+ cfprintf(cfile, " ${bld}exec${rs}: Print executed command details.\n");
+ cfprintf(cfile, " ${bld}opt${rs}: Print optimization details.\n");
+ cfprintf(cfile, " ${bld}rates${rs}: Print predicate success rates.\n");
+ cfprintf(cfile, " ${bld}search${rs}: Trace the filesystem traversal.\n");
+ cfprintf(cfile, " ${bld}stat${rs}: Trace all stat() calls.\n");
+ cfprintf(cfile, " ${bld}tree${rs}: Print the parse tree.\n");
+ cfprintf(cfile, " ${bld}all${rs}: All debug flags at once.\n");
}
/**
@@ -2277,259 +2279,259 @@ static struct expr *parse_warn(struct parser_state *state, int warn, int arg2) {
*/
static struct expr *parse_help(struct parser_state *state, int arg1, int arg2) {
CFILE *cout = state->cmdline->cout;
- cfprintf(cout, "Usage: %{ex}%s%{rs} [%{cyn}flags%{rs}...] [%{mag}paths%{rs}...] [%{blu}expression%{rs}...]\n\n",
+ cfprintf(cout, "Usage: ${ex}%s${rs} [${cyn}flags${rs}...] [${mag}paths${rs}...] [${blu}expression${rs}...]\n\n",
state->command);
- cfprintf(cout, "%{ex}bfs%{rs} is compatible with %{ex}find%{rs}; see %{ex}find%{rs} %{blu}-help%{rs} or"
- " %{ex}man%{rs} %{bld}find%{rs} for help with %{ex}find%{rs}-\n"
+ cfprintf(cout, "${ex}bfs${rs} is compatible with ${ex}find${rs}; see ${ex}find${rs} ${blu}-help${rs} or"
+ " ${ex}man${rs} ${bld}find${rs} for help with ${ex}find${rs}-\n"
"compatible options :)\n\n");
- cfprintf(cout, "%{cyn}flags%{rs} (%{cyn}-H%{rs}/%{cyn}-L%{rs}/%{cyn}-P%{rs} etc.), %{mag}paths%{rs}, and"
- " %{blu}expressions%{rs} may be freely mixed in any order.\n\n");
+ cfprintf(cout, "${cyn}flags${rs} (${cyn}-H${rs}/${cyn}-L${rs}/${cyn}-P${rs} etc.), ${mag}paths${rs}, and"
+ " ${blu}expressions${rs} may be freely mixed in any order.\n\n");
- cfprintf(cout, "%{bld}POSIX find features:%{rs}\n\n");
+ cfprintf(cout, "${bld}POSIX find features:${rs}\n\n");
- cfprintf(cout, " %{red}(%{rs} %{blu}expression%{rs} %{red})%{rs}\n");
- cfprintf(cout, " %{red}!%{rs} %{blu}expression%{rs}\n");
- cfprintf(cout, " %{blu}expression%{rs} [%{red}-a%{rs}] %{blu}expression%{rs}\n");
- cfprintf(cout, " %{blu}expression%{rs} %{red}-o%{rs} %{blu}expression%{rs}\n\n");
+ cfprintf(cout, " ${red}(${rs} ${blu}expression${rs} ${red})${rs}\n");
+ cfprintf(cout, " ${red}!${rs} ${blu}expression${rs}\n");
+ cfprintf(cout, " ${blu}expression${rs} [${red}-a${rs}] ${blu}expression${rs}\n");
+ cfprintf(cout, " ${blu}expression${rs} ${red}-o${rs} ${blu}expression${rs}\n\n");
- cfprintf(cout, " %{cyn}-H%{rs}\n");
+ cfprintf(cout, " ${cyn}-H${rs}\n");
cfprintf(cout, " Follow symbolic links on the command line, but not while searching\n");
- cfprintf(cout, " %{cyn}-L%{rs}\n");
+ cfprintf(cout, " ${cyn}-L${rs}\n");
cfprintf(cout, " Follow all symbolic links\n\n");
- cfprintf(cout, " %{blu}-depth%{rs}\n");
+ cfprintf(cout, " ${blu}-depth${rs}\n");
cfprintf(cout, " Search in post-order (descendents first)\n");
- cfprintf(cout, " %{blu}-xdev%{rs}\n");
+ cfprintf(cout, " ${blu}-xdev${rs}\n");
cfprintf(cout, " Don't descend into other mount points\n\n");
- cfprintf(cout, " %{blu}-atime%{rs} %{bld}[-+]N%{rs}\n");
- cfprintf(cout, " %{blu}-ctime%{rs} %{bld}[-+]N%{rs}\n");
- cfprintf(cout, " %{blu}-mtime%{rs} %{bld}[-+]N%{rs}\n");
- cfprintf(cout, " Find files accessed/changed/modified %{bld}N%{rs} days ago\n");
- cfprintf(cout, " %{blu}-group%{rs} %{bld}NAME%{rs}\n");
- cfprintf(cout, " %{blu}-user%{rs} %{bld}NAME%{rs}\n");
- cfprintf(cout, " Find files owned by the group/user %{bld}NAME%{rs}\n");
- cfprintf(cout, " %{blu}-links%{rs} %{bld}[-+]N%{rs}\n");
- cfprintf(cout, " Find files with %{bld}N%{rs} hard links\n");
- cfprintf(cout, " %{blu}-name%{rs} %{bld}GLOB%{rs}\n");
- cfprintf(cout, " Find files whose name matches the %{bld}GLOB%{rs}\n");
- cfprintf(cout, " %{blu}-path%{rs} %{bld}GLOB%{rs}\n");
- cfprintf(cout, " Find files whose entire path matches the %{bld}GLOB%{rs}\n");
- cfprintf(cout, " %{blu}-newer%{rs} %{bld}FILE%{rs}\n");
- cfprintf(cout, " Find files newer than %{bld}FILE%{rs}\n");
- cfprintf(cout, " %{blu}-perm%{rs} %{bld}[-]MODE%{rs}\n");
+ cfprintf(cout, " ${blu}-atime${rs} ${bld}[-+]N${rs}\n");
+ cfprintf(cout, " ${blu}-ctime${rs} ${bld}[-+]N${rs}\n");
+ cfprintf(cout, " ${blu}-mtime${rs} ${bld}[-+]N${rs}\n");
+ cfprintf(cout, " Find files accessed/changed/modified ${bld}N${rs} days ago\n");
+ cfprintf(cout, " ${blu}-group${rs} ${bld}NAME${rs}\n");
+ cfprintf(cout, " ${blu}-user${rs} ${bld}NAME${rs}\n");
+ cfprintf(cout, " Find files owned by the group/user ${bld}NAME${rs}\n");
+ cfprintf(cout, " ${blu}-links${rs} ${bld}[-+]N${rs}\n");
+ cfprintf(cout, " Find files with ${bld}N${rs} hard links\n");
+ cfprintf(cout, " ${blu}-name${rs} ${bld}GLOB${rs}\n");
+ cfprintf(cout, " Find files whose name matches the ${bld}GLOB${rs}\n");
+ cfprintf(cout, " ${blu}-path${rs} ${bld}GLOB${rs}\n");
+ cfprintf(cout, " Find files whose entire path matches the ${bld}GLOB${rs}\n");
+ cfprintf(cout, " ${blu}-newer${rs} ${bld}FILE${rs}\n");
+ cfprintf(cout, " Find files newer than ${bld}FILE${rs}\n");
+ cfprintf(cout, " ${blu}-perm${rs} ${bld}[-]MODE${rs}\n");
cfprintf(cout, " Find files with a matching mode\n");
- cfprintf(cout, " %{blu}-type%{rs} %{bld}[bcdlpfs]%{rs}\n");
+ cfprintf(cout, " ${blu}-type${rs} ${bld}[bcdlpfs]${rs}\n");
cfprintf(cout, " Find files of the given type\n");
- cfprintf(cout, " %{blu}-size%{rs} %{bld}[-+]N[c]%{rs}\n");
+ cfprintf(cout, " ${blu}-size${rs} ${bld}[-+]N[c]${rs}\n");
cfprintf(cout, " Find files with the given size\n\n");
- cfprintf(cout, " %{blu}-prune%{rs}\n");
+ cfprintf(cout, " ${blu}-prune${rs}\n");
cfprintf(cout, " Don't descend into this directory\n");
- cfprintf(cout, " %{blu}-exec%{rs} %{bld}command ... {} ;%{rs}\n");
+ cfprintf(cout, " ${blu}-exec${rs} ${bld}command ... {} ;${rs}\n");
cfprintf(cout, " Execute a command\n");
- cfprintf(cout, " %{blu}-exec%{rs} %{bld}command ... {} +%{rs}\n");
+ cfprintf(cout, " ${blu}-exec${rs} ${bld}command ... {} +${rs}\n");
cfprintf(cout, " Execute a command with multiple files at once\n");
- cfprintf(cout, " %{blu}-ok%{rs} %{bld}command ... {} ;%{rs}\n");
+ cfprintf(cout, " ${blu}-ok${rs} ${bld}command ... {} ;${rs}\n");
cfprintf(cout, " Prompt the user whether to execute a command\n");
- cfprintf(cout, " %{blu}-print%{rs}\n");
+ cfprintf(cout, " ${blu}-print${rs}\n");
cfprintf(cout, " Print the path to the found file\n\n");
- cfprintf(cout, "%{bld}GNU find features:%{rs}\n\n");
+ cfprintf(cout, "${bld}GNU find features:${rs}\n\n");
- cfprintf(cout, " %{red}-not%{rs} %{blu}expression%{rs}\n");
- cfprintf(cout, " %{blu}expression%{rs} %{red}-and%{rs} %{blu}expression%{rs}\n");
- cfprintf(cout, " %{blu}expression%{rs} %{red}-or%{rs} %{blu}expression%{rs}\n");
- cfprintf(cout, " %{blu}expression%{rs} %{red},%{rs} %{blu}expression%{rs}\n\n");
+ cfprintf(cout, " ${red}-not${rs} ${blu}expression${rs}\n");
+ cfprintf(cout, " ${blu}expression${rs} ${red}-and${rs} ${blu}expression${rs}\n");
+ cfprintf(cout, " ${blu}expression${rs} ${red}-or${rs} ${blu}expression${rs}\n");
+ cfprintf(cout, " ${blu}expression${rs} ${red},${rs} ${blu}expression${rs}\n\n");
- cfprintf(cout, " %{cyn}-P%{rs}\n");
+ cfprintf(cout, " ${cyn}-P${rs}\n");
cfprintf(cout, " Never follow symbolic links (the default)\n");
- cfprintf(cout, " %{cyn}-D%{rs} %{bld}FLAG%{rs}\n");
- cfprintf(cout, " Turn on a debugging flag (see %{cyn}-D%{rs} %{bld}help%{rs})\n");
- cfprintf(cout, " %{cyn}-O%{rs}%{bld}N%{rs}\n");
- cfprintf(cout, " Enable optimization level %{bld}N%{rs} (default: 3; interpreted differently than GNU\n");
+ cfprintf(cout, " ${cyn}-D${rs} ${bld}FLAG${rs}\n");
+ cfprintf(cout, " Turn on a debugging flag (see ${cyn}-D${rs} ${bld}help${rs})\n");
+ cfprintf(cout, " ${cyn}-O${rs}${bld}N${rs}\n");
+ cfprintf(cout, " Enable optimization level ${bld}N${rs} (default: 3; interpreted differently than GNU\n");
cfprintf(cout, " find -- see below)\n\n");
- cfprintf(cout, " %{blu}-d%{rs}\n");
- cfprintf(cout, " Search in post-order (same as %{blu}-depth%{rs})\n");
- cfprintf(cout, " %{blu}-daystart%{rs}\n");
+ cfprintf(cout, " ${blu}-d${rs}\n");
+ cfprintf(cout, " Search in post-order (same as ${blu}-depth${rs})\n");
+ cfprintf(cout, " ${blu}-daystart${rs}\n");
cfprintf(cout, " Measure times relative to the start of today\n");
- cfprintf(cout, " %{blu}-follow%{rs}\n");
- cfprintf(cout, " Follow all symbolic links (same as %{cyn}-L%{rs})\n");
- cfprintf(cout, " %{blu}-ignore_readdir_race%{rs}\n");
- cfprintf(cout, " %{blu}-noignore_readdir_race%{rs}\n");
- cfprintf(cout, " Whether to report an error if %{ex}bfs%{rs} detects that the file tree is modified\n");
- cfprintf(cout, " during the search (default: %{blu}-noignore_readdir_race%{rs})\n");
- cfprintf(cout, " %{blu}-maxdepth%{rs} %{bld}N%{rs}\n");
- cfprintf(cout, " %{blu}-mindepth%{rs} %{bld}N%{rs}\n");
- cfprintf(cout, " Ignore files deeper/shallower than %{bld}N%{rs}\n");
- cfprintf(cout, " %{blu}-mount%{rs}\n");
- cfprintf(cout, " Don't descend into other mount points (same as %{blu}-xdev%{rs})\n");
- cfprintf(cout, " %{blu}-noleaf%{rs}\n");
+ cfprintf(cout, " ${blu}-follow${rs}\n");
+ cfprintf(cout, " Follow all symbolic links (same as ${cyn}-L${rs})\n");
+ cfprintf(cout, " ${blu}-ignore_readdir_race${rs}\n");
+ cfprintf(cout, " ${blu}-noignore_readdir_race${rs}\n");
+ cfprintf(cout, " Whether to report an error if ${ex}bfs${rs} detects that the file tree is modified\n");
+ cfprintf(cout, " during the search (default: ${blu}-noignore_readdir_race${rs})\n");
+ cfprintf(cout, " ${blu}-maxdepth${rs} ${bld}N${rs}\n");
+ cfprintf(cout, " ${blu}-mindepth${rs} ${bld}N${rs}\n");
+ cfprintf(cout, " Ignore files deeper/shallower than ${bld}N${rs}\n");
+ cfprintf(cout, " ${blu}-mount${rs}\n");
+ cfprintf(cout, " Don't descend into other mount points (same as ${blu}-xdev${rs})\n");
+ cfprintf(cout, " ${blu}-noleaf${rs}\n");
cfprintf(cout, " Ignored; for compatibility with GNU find\n");
- cfprintf(cout, " %{blu}-regextype%{rs} %{bld}TYPE%{rs}\n");
- cfprintf(cout, " Use %{bld}TYPE%{rs}-flavored regexes (default: %{bld}posix-basic%{rs}; see %{blu}-regextype%{rs}"
- " %{bld}help%{rs})\n");
- cfprintf(cout, " %{blu}-warn%{rs}\n");
- cfprintf(cout, " %{blu}-nowarn%{rs}\n");
+ cfprintf(cout, " ${blu}-regextype${rs} ${bld}TYPE${rs}\n");
+ cfprintf(cout, " Use ${bld}TYPE${rs}-flavored regexes (default: ${bld}posix-basic${rs}; see ${blu}-regextype${rs}"
+ " ${bld}help${rs})\n");
+ cfprintf(cout, " ${blu}-warn${rs}\n");
+ cfprintf(cout, " ${blu}-nowarn${rs}\n");
cfprintf(cout, " Turn on or off warnings about the command line\n\n");
- cfprintf(cout, " %{blu}-amin%{rs} %{bld}[-+]N%{rs}\n");
- cfprintf(cout, " %{blu}-cmin%{rs} %{bld}[-+]N%{rs}\n");
- cfprintf(cout, " %{blu}-mmin%{rs} %{bld}[-+]N%{rs}\n");
- cfprintf(cout, " Find files accessed/changed/modified %{bld}N%{rs} minutes ago\n");
- cfprintf(cout, " %{blu}-anewer%{rs} %{bld}FILE%{rs}\n");
- cfprintf(cout, " %{blu}-cnewer%{rs} %{bld}FILE%{rs}\n");
- cfprintf(cout, " %{blu}-mnewer%{rs} %{bld}FILE%{rs}\n");
- cfprintf(cout, " Find files accessed/changed/modified more recently than %{bld}FILE%{rs} was modified\n");
- cfprintf(cout, " %{blu}-empty%{rs}\n");
+ cfprintf(cout, " ${blu}-amin${rs} ${bld}[-+]N${rs}\n");
+ cfprintf(cout, " ${blu}-cmin${rs} ${bld}[-+]N${rs}\n");
+ cfprintf(cout, " ${blu}-mmin${rs} ${bld}[-+]N${rs}\n");
+ cfprintf(cout, " Find files accessed/changed/modified ${bld}N${rs} minutes ago\n");
+ cfprintf(cout, " ${blu}-anewer${rs} ${bld}FILE${rs}\n");
+ cfprintf(cout, " ${blu}-cnewer${rs} ${bld}FILE${rs}\n");
+ cfprintf(cout, " ${blu}-mnewer${rs} ${bld}FILE${rs}\n");
+ cfprintf(cout, " Find files accessed/changed/modified more recently than ${bld}FILE${rs} was modified\n");
+ cfprintf(cout, " ${blu}-empty${rs}\n");
cfprintf(cout, " Find empty files/directories\n");
- cfprintf(cout, " %{blu}-executable%{rs}\n");
- cfprintf(cout, " %{blu}-readable%{rs}\n");
- cfprintf(cout, " %{blu}-writable%{rs}\n");
+ cfprintf(cout, " ${blu}-executable${rs}\n");
+ cfprintf(cout, " ${blu}-readable${rs}\n");
+ cfprintf(cout, " ${blu}-writable${rs}\n");
cfprintf(cout, " Find files the current user can execute/read/write\n");
- cfprintf(cout, " %{blu}-false%{rs}\n");
- cfprintf(cout, " %{blu}-true%{rs}\n");
+ cfprintf(cout, " ${blu}-false${rs}\n");
+ cfprintf(cout, " ${blu}-true${rs}\n");
cfprintf(cout, " Always false/true\n");
- cfprintf(cout, " %{blu}-fstype%{rs} %{bld}TYPE%{rs}\n");
- cfprintf(cout, " Find files on file systems with the given %{bld}TYPE%{rs}\n");
- cfprintf(cout, " %{blu}-gid%{rs} %{bld}[-+]N%{rs}\n");
- cfprintf(cout, " %{blu}-uid%{rs} %{bld}[-+]N%{rs}\n");
- cfprintf(cout, " Find files owned by group/user ID %{bld}N%{rs}\n");
- cfprintf(cout, " %{blu}-inum%{rs} %{bld}[-+]N%{rs}\n");
- cfprintf(cout, " Find files with inode number %{bld}N%{rs}\n");
- cfprintf(cout, " %{blu}-lname%{rs} %{bld}GLOB%{rs}\n");
- cfprintf(cout, " Find symbolic links whose target matches the %{bld}GLOB%{rs}\n");
- cfprintf(cout, " %{blu}-newer%{rs}%{bld}XY%{rs} %{bld}REFERENCE%{rs}\n");
- cfprintf(cout, " Find files whose %{bld}X%{rs} time is newer than the %{bld}Y%{rs} time of"
- " %{bld}REFERENCE%{rs}. %{bld}X%{rs} and %{bld}Y%{rs}\n");
+ cfprintf(cout, " ${blu}-fstype${rs} ${bld}TYPE${rs}\n");
+ cfprintf(cout, " Find files on file systems with the given ${bld}TYPE${rs}\n");
+ cfprintf(cout, " ${blu}-gid${rs} ${bld}[-+]N${rs}\n");
+ cfprintf(cout, " ${blu}-uid${rs} ${bld}[-+]N${rs}\n");
+ cfprintf(cout, " Find files owned by group/user ID ${bld}N${rs}\n");
+ cfprintf(cout, " ${blu}-inum${rs} ${bld}[-+]N${rs}\n");
+ cfprintf(cout, " Find files with inode number ${bld}N${rs}\n");
+ cfprintf(cout, " ${blu}-lname${rs} ${bld}GLOB${rs}\n");
+ cfprintf(cout, " Find symbolic links whose target matches the ${bld}GLOB${rs}\n");
+ cfprintf(cout, " ${blu}-newer${rs}${bld}XY${rs} ${bld}REFERENCE${rs}\n");
+ cfprintf(cout, " Find files whose ${bld}X${rs} time is newer than the ${bld}Y${rs} time of"
+ " ${bld}REFERENCE${rs}. ${bld}X${rs} and ${bld}Y${rs}\n");
cfprintf(cout, " can be any of [aBcm].\n");
- cfprintf(cout, " %{blu}-regex%{rs} %{bld}REGEX%{rs}\n");
- cfprintf(cout, " Find files whose entire path matches the regular expression %{bld}REGEX%{rs}\n");
- cfprintf(cout, " %{blu}-samefile%{rs} %{bld}FILE%{rs}\n");
- cfprintf(cout, " Find hard links to %{bld}FILE%{rs}\n");
- cfprintf(cout, " %{blu}-size%{rs} %{bld}[-+]N[cwbkMG]%{rs}\n");
- cfprintf(cout, " 1-byte %{bld}c%{rs}haracters, 2-byte %{bld}w%{rs}ords, 512-byte %{bld}b%{rs}locks, and"
- " %{bld}k%{rs}iB/%{bld}M%{rs}iB/%{bld}G%{rs}iB\n");
- cfprintf(cout, " %{blu}-type%{rs} %{bld}[bcdlpfsD]%{rs}\n");
- cfprintf(cout, " The %{bld}D%{rs}oor file type is also supported on platforms that have it (Solaris)\n");
- cfprintf(cout, " %{blu}-used%{rs} %{bld}[-+]N%{rs}\n");
- cfprintf(cout, " Find files last accessed %{bld}N%{rs} days after they were changed\n");
- cfprintf(cout, " %{blu}-wholename%{rs} %{bld}GLOB%{rs}\n");
- cfprintf(cout, " Find files whose entire path matches the %{bld}GLOB%{rs} (same as %{blu}-path%{rs})\n");
+ cfprintf(cout, " ${blu}-regex${rs} ${bld}REGEX${rs}\n");
+ cfprintf(cout, " Find files whose entire path matches the regular expression ${bld}REGEX${rs}\n");
+ cfprintf(cout, " ${blu}-samefile${rs} ${bld}FILE${rs}\n");
+ cfprintf(cout, " Find hard links to ${bld}FILE${rs}\n");
+ cfprintf(cout, " ${blu}-size${rs} ${bld}[-+]N[cwbkMG]${rs}\n");
+ cfprintf(cout, " 1-byte ${bld}c${rs}haracters, 2-byte ${bld}w${rs}ords, 512-byte ${bld}b${rs}locks, and"
+ " ${bld}k${rs}iB/${bld}M${rs}iB/${bld}G${rs}iB\n");
+ cfprintf(cout, " ${blu}-type${rs} ${bld}[bcdlpfsD]${rs}\n");
+ cfprintf(cout, " The ${bld}D${rs}oor file type is also supported on platforms that have it (Solaris)\n");
+ cfprintf(cout, " ${blu}-used${rs} ${bld}[-+]N${rs}\n");
+ cfprintf(cout, " Find files last accessed ${bld}N${rs} days after they were changed\n");
+ cfprintf(cout, " ${blu}-wholename${rs} ${bld}GLOB${rs}\n");
+ cfprintf(cout, " Find files whose entire path matches the ${bld}GLOB${rs} (same as ${blu}-path${rs})\n");
#ifdef FNM_CASEFOLD
- cfprintf(cout, " %{blu}-ilname%{rs} %{bld}GLOB%{rs}\n");
- cfprintf(cout, " %{blu}-iname%{rs} %{bld}GLOB%{rs}\n");
- cfprintf(cout, " %{blu}-ipath%{rs} %{bld}GLOB%{rs}\n");
- cfprintf(cout, " %{blu}-iregex%{rs} %{bld}REGEX%{rs}\n");
- cfprintf(cout, " %{blu}-iwholename%{rs} %{bld}GLOB%{rs}\n");
- cfprintf(cout, " Case-insensitive versions of %{blu}-lname%{rs}/%{blu}-name%{rs}/%{blu}-path%{rs}"
- "/%{blu}-regex%{rs}/%{blu}-wholename%{rs}\n");
+ cfprintf(cout, " ${blu}-ilname${rs} ${bld}GLOB${rs}\n");
+ cfprintf(cout, " ${blu}-iname${rs} ${bld}GLOB${rs}\n");
+ cfprintf(cout, " ${blu}-ipath${rs} ${bld}GLOB${rs}\n");
+ cfprintf(cout, " ${blu}-iregex${rs} ${bld}REGEX${rs}\n");
+ cfprintf(cout, " ${blu}-iwholename${rs} ${bld}GLOB${rs}\n");
+ cfprintf(cout, " Case-insensitive versions of ${blu}-lname${rs}/${blu}-name${rs}/${blu}-path${rs}"
+ "/${blu}-regex${rs}/${blu}-wholename${rs}\n");
#endif
- cfprintf(cout, " %{blu}-xtype%{rs} %{bld}[bcdlpfsD]%{rs}\n");
- cfprintf(cout, " Find files of the given type, following links when %{blu}-type%{rs} would not, and\n");
+ cfprintf(cout, " ${blu}-xtype${rs} ${bld}[bcdlpfsD]${rs}\n");
+ cfprintf(cout, " Find files of the given type, following links when ${blu}-type${rs} would not, and\n");
cfprintf(cout, " vice versa\n\n");
- cfprintf(cout, " %{blu}-delete%{rs}\n");
- cfprintf(cout, " Delete any found files (implies %{blu}-depth%{rs})\n");
- cfprintf(cout, " %{blu}-execdir%{rs} %{bld}command ... {} ;%{rs}\n");
- cfprintf(cout, " %{blu}-execdir%{rs} %{bld}command ... {} +%{rs}\n");
- cfprintf(cout, " %{blu}-okdir%{rs} %{bld}command ... {} ;%{rs}\n");
- cfprintf(cout, " Like %{blu}-exec%{rs}/%{blu}-ok%{rs}, but run the command in the same directory as the found\n");
+ cfprintf(cout, " ${blu}-delete${rs}\n");
+ cfprintf(cout, " Delete any found files (implies ${blu}-depth${rs})\n");
+ cfprintf(cout, " ${blu}-execdir${rs} ${bld}command ... {} ;${rs}\n");
+ cfprintf(cout, " ${blu}-execdir${rs} ${bld}command ... {} +${rs}\n");
+ cfprintf(cout, " ${blu}-okdir${rs} ${bld}command ... {} ;${rs}\n");
+ cfprintf(cout, " Like ${blu}-exec${rs}/${blu}-ok${rs}, but run the command in the same directory as the found\n");
cfprintf(cout, " file(s)\n");
- cfprintf(cout, " %{blu}-ls%{rs}\n");
- cfprintf(cout, " List files like %{ex}ls%{rs} %{bld}-dils%{rs}\n");
- cfprintf(cout, " %{blu}-print0%{rs}\n");
- cfprintf(cout, " Like %{blu}-print%{rs}, but use the null character ('\\0') as a separator rather than\n");
+ cfprintf(cout, " ${blu}-ls${rs}\n");
+ cfprintf(cout, " List files like ${ex}ls${rs} ${bld}-dils${rs}\n");
+ cfprintf(cout, " ${blu}-print0${rs}\n");
+ cfprintf(cout, " Like ${blu}-print${rs}, but use the null character ('\\0') as a separator rather than\n");
cfprintf(cout, " newlines\n");
- cfprintf(cout, " %{blu}-printf%{rs} %{bld}FORMAT%{rs}\n");
- cfprintf(cout, " Print according to a format string (see %{ex}man%{rs} %{bld}find%{rs})\n");
- cfprintf(cout, " %{blu}-fls%{rs} %{bld}FILE%{rs}\n");
- cfprintf(cout, " %{blu}-fprint%{rs} %{bld}FILE%{rs}\n");
- cfprintf(cout, " %{blu}-fprint0%{rs} %{bld}FILE%{rs}\n");
- cfprintf(cout, " %{blu}-fprintf%{rs} %{bld}FORMAT%{rs} %{bld}FILE%{rs}\n");
- cfprintf(cout, " Like %{blu}-ls%{rs}/%{blu}-print%{rs}/%{blu}-print0%{rs}/%{blu}-printf%{rs}, but write to"
- " %{bld}FILE%{rs} instead of standard output\n");
- cfprintf(cout, " %{blu}-quit%{rs}\n");
+ cfprintf(cout, " ${blu}-printf${rs} ${bld}FORMAT${rs}\n");
+ cfprintf(cout, " Print according to a format string (see ${ex}man${rs} ${bld}find${rs})\n");
+ cfprintf(cout, " ${blu}-fls${rs} ${bld}FILE${rs}\n");
+ cfprintf(cout, " ${blu}-fprint${rs} ${bld}FILE${rs}\n");
+ cfprintf(cout, " ${blu}-fprint0${rs} ${bld}FILE${rs}\n");
+ cfprintf(cout, " ${blu}-fprintf${rs} ${bld}FORMAT${rs} ${bld}FILE${rs}\n");
+ cfprintf(cout, " Like ${blu}-ls${rs}/${blu}-print${rs}/${blu}-print0${rs}/${blu}-printf${rs}, but write to"
+ " ${bld}FILE${rs} instead of standard output\n");
+ cfprintf(cout, " ${blu}-quit${rs}\n");
cfprintf(cout, " Quit immediately\n\n");
- cfprintf(cout, " %{blu}-version%{rs}\n");
+ cfprintf(cout, " ${blu}-version${rs}\n");
cfprintf(cout, " Print version information\n");
- cfprintf(cout, " %{blu}-help%{rs}\n");
+ cfprintf(cout, " ${blu}-help${rs}\n");
cfprintf(cout, " Print this help message\n\n");
- cfprintf(cout, "%{bld}BSD find features:%{rs}\n\n");
+ cfprintf(cout, "${bld}BSD find features:${rs}\n\n");
- cfprintf(cout, " %{cyn}-E%{rs}\n");
- cfprintf(cout, " Use extended regular expressions (same as %{blu}-regextype%{rs} %{bld}posix-extended%{rs})\n");
- cfprintf(cout, " %{cyn}-X%{rs}\n");
- cfprintf(cout, " Filter out files with non-%{ex}xargs%{rs}-safe names\n");
- cfprintf(cout, " %{cyn}-x%{rs}\n");
- cfprintf(cout, " Don't descend into other mount points (same as %{blu}-xdev%{rs})\n\n");
+ cfprintf(cout, " ${cyn}-E${rs}\n");
+ cfprintf(cout, " Use extended regular expressions (same as ${blu}-regextype${rs} ${bld}posix-extended${rs})\n");
+ cfprintf(cout, " ${cyn}-X${rs}\n");
+ cfprintf(cout, " Filter out files with non-${ex}xargs${rs}-safe names\n");
+ cfprintf(cout, " ${cyn}-x${rs}\n");
+ cfprintf(cout, " Don't descend into other mount points (same as ${blu}-xdev${rs})\n\n");
- cfprintf(cout, " %{cyn}-f%{rs} %{mag}PATH%{rs}\n");
- cfprintf(cout, " Treat %{mag}PATH%{rs} as a path to search (useful if begins with a dash)\n\n");
+ cfprintf(cout, " ${cyn}-f${rs} ${mag}PATH${rs}\n");
+ cfprintf(cout, " Treat ${mag}PATH${rs} as a path to search (useful if begins with a dash)\n\n");
#if BFS_HAS_SYS_ACL
- cfprintf(cout, " %{blu}-acl%{rs}\n");
+ cfprintf(cout, " ${blu}-acl${rs}\n");
cfprintf(cout, " Find files with non-trivial Access Control Lists\n");
#endif
- cfprintf(cout, " %{blu}-Bmin%{rs} %{bld}[-+]N%{rs}\n");
- cfprintf(cout, " %{blu}-Btime%{rs} %{bld}[-+]N%{rs}\n");
- cfprintf(cout, " Find files Birthed %{bld}N%{rs} minutes/days ago\n");
- cfprintf(cout, " %{blu}-Bnewer%{rs} %{bld}FILE%{rs}\n");
- cfprintf(cout, " Find files Birthed more recently than %{bld}FILE%{rs} was modified\n");
- cfprintf(cout, " %{blu}-depth%{rs} %{bld}[-+]N%{rs}\n");
- cfprintf(cout, " Find files with depth %{bld}N%{rs}\n");
- cfprintf(cout, " %{blu}-gid%{rs} %{bld}NAME%{rs}\n");
- cfprintf(cout, " %{blu}-uid%{rs} %{bld}NAME%{rs}\n");
+ cfprintf(cout, " ${blu}-Bmin${rs} ${bld}[-+]N${rs}\n");
+ cfprintf(cout, " ${blu}-Btime${rs} ${bld}[-+]N${rs}\n");
+ cfprintf(cout, " Find files Birthed ${bld}N${rs} minutes/days ago\n");
+ cfprintf(cout, " ${blu}-Bnewer${rs} ${bld}FILE${rs}\n");
+ cfprintf(cout, " Find files Birthed more recently than ${bld}FILE${rs} was modified\n");
+ cfprintf(cout, " ${blu}-depth${rs} ${bld}[-+]N${rs}\n");
+ cfprintf(cout, " Find files with depth ${bld}N${rs}\n");
+ cfprintf(cout, " ${blu}-gid${rs} ${bld}NAME${rs}\n");
+ cfprintf(cout, " ${blu}-uid${rs} ${bld}NAME${rs}\n");
cfprintf(cout, " Group/user names are supported in addition to numeric IDs\n");
- cfprintf(cout, " %{blu}-size%{rs} %{bld}[-+]N[cwbkMGTP]%{rs}\n");
- cfprintf(cout, " Units of %{bld}T%{rs}iB/%{bld}P%{rs}iB are additionally supported\n");
- cfprintf(cout, " %{blu}-sparse%{rs}\n");
+ cfprintf(cout, " ${blu}-size${rs} ${bld}[-+]N[cwbkMGTP]${rs}\n");
+ cfprintf(cout, " Units of ${bld}T${rs}iB/${bld}P${rs}iB are additionally supported\n");
+ cfprintf(cout, " ${blu}-sparse${rs}\n");
cfprintf(cout, " Find files that occupy fewer disk blocks than expected\n\n");
- cfprintf(cout, " %{blu}-exit%{rs} %{bld}[STATUS]%{rs}\n");
+ cfprintf(cout, " ${blu}-exit${rs} ${bld}[STATUS]${rs}\n");
cfprintf(cout, " Exit immediately with the given status (%d if unspecified)\n", EXIT_SUCCESS);
- cfprintf(cout, " %{blu}-printx%{rs}\n");
- cfprintf(cout, " Like %{blu}-print%{rs}, but escape whitespace and quotation characters, to make the\n");
- cfprintf(cout, " output safe for %{ex}xargs%{rs}. Consider using %{blu}-print0%{rs} and %{ex}xargs%{rs} %{bld}-0%{rs} instead.\n");
- cfprintf(cout, " %{blu}-rm%{rs}\n");
- cfprintf(cout, " Delete any found files (same as %{blu}-delete%{rs}; implies %{blu}-depth%{rs})\n\n");
+ cfprintf(cout, " ${blu}-printx${rs}\n");
+ cfprintf(cout, " Like ${blu}-print${rs}, but escape whitespace and quotation characters, to make the\n");
+ cfprintf(cout, " output safe for ${ex}xargs${rs}. Consider using ${blu}-print0${rs} and ${ex}xargs${rs} ${bld}-0${rs} instead.\n");
+ cfprintf(cout, " ${blu}-rm${rs}\n");
+ cfprintf(cout, " Delete any found files (same as ${blu}-delete${rs}; implies ${blu}-depth${rs})\n\n");
- cfprintf(cout, "%{ex}bfs%{rs}%{bld}-specific features:%{rs}\n\n");
+ cfprintf(cout, "${ex}bfs${rs}${bld}-specific features:${rs}\n\n");
- cfprintf(cout, " %{cyn}-O%{rs}%{bld}0%{rs}\n");
+ cfprintf(cout, " ${cyn}-O${rs}${bld}0${rs}\n");
cfprintf(cout, " Disable all optimizations\n");
- cfprintf(cout, " %{cyn}-O%{rs}%{bld}1%{rs}\n");
+ cfprintf(cout, " ${cyn}-O${rs}${bld}1${rs}\n");
cfprintf(cout, " Basic logical simplification\n");
- cfprintf(cout, " %{cyn}-O%{rs}%{bld}2%{rs}\n");
- cfprintf(cout, " All %{cyn}-O%{rs}%{bld}1%{rs} optimizations, plus dead code elimination and data flow analysis\n");
- cfprintf(cout, " %{cyn}-O%{rs}%{bld}3%{rs} (default)\n");
- cfprintf(cout, " All %{cyn}-O%{rs}%{bld}2%{rs} optimizations, plus re-order expressions to reduce expected cost\n");
- cfprintf(cout, " %{cyn}-O%{rs}%{bld}4%{rs}/%{cyn}-O%{rs}%{bld}fast%{rs}\n");
+ cfprintf(cout, " ${cyn}-O${rs}${bld}2${rs}\n");
+ cfprintf(cout, " All ${cyn}-O${rs}${bld}1${rs} optimizations, plus dead code elimination and data flow analysis\n");
+ cfprintf(cout, " ${cyn}-O${rs}${bld}3${rs} (default)\n");
+ cfprintf(cout, " All ${cyn}-O${rs}${bld}2${rs} optimizations, plus re-order expressions to reduce expected cost\n");
+ cfprintf(cout, " ${cyn}-O${rs}${bld}4${rs}/${cyn}-O${rs}${bld}fast${rs}\n");
cfprintf(cout, " All optimizations, including aggressive optimizations that may alter the\n");
cfprintf(cout, " observed behavior in corner cases\n\n");
- cfprintf(cout, " %{blu}-color%{rs}\n");
- cfprintf(cout, " %{blu}-nocolor%{rs}\n");
- cfprintf(cout, " Turn colors on or off (default: %{blu}-color%{rs} if outputting to a terminal,\n");
- cfprintf(cout, " %{blu}-nocolor%{rs} otherwise)\n\n");
+ cfprintf(cout, " ${blu}-color${rs}\n");
+ cfprintf(cout, " ${blu}-nocolor${rs}\n");
+ cfprintf(cout, " Turn colors on or off (default: ${blu}-color${rs} if outputting to a terminal,\n");
+ cfprintf(cout, " ${blu}-nocolor${rs} otherwise)\n\n");
#if BFS_HAS_POSIX1E_CAPABILITIES
- cfprintf(cout, " %{blu}-capable%{rs}\n");
+ cfprintf(cout, " ${blu}-capable${rs}\n");
cfprintf(cout, " Match files with POSIX.1e capabilities set\n\n");
#endif
- cfprintf(cout, " %{blu}-hidden%{rs}\n");
- cfprintf(cout, " %{blu}-nohidden%{rs}\n");
+ cfprintf(cout, " ${blu}-hidden${rs}\n");
+ cfprintf(cout, " ${blu}-nohidden${rs}\n");
cfprintf(cout, " Match hidden files, or filter them out\n\n");
- cfprintf(cout, " %{blu}-printf%{rs} %{bld}FORMAT%{rs}\n");
- cfprintf(cout, " %{blu}-fprintf%{rs} %{bld}FORMAT%{rs} %{bld}FILE%{rs}\n");
- cfprintf(cout, " The additional format directives %%w and %%W%{bld}k%{rs} for printing file birth times\n");
+ cfprintf(cout, " ${blu}-printf${rs} ${bld}FORMAT${rs}\n");
+ cfprintf(cout, " ${blu}-fprintf${rs} ${bld}FORMAT${rs} ${bld}FILE${rs}\n");
+ cfprintf(cout, " The additional format directives %%w and %%W${bld}k${rs} for printing file birth times\n");
cfprintf(cout, " are supported.\n\n");
cfprintf(cout, "%s\n", BFS_HOMEPAGE);
@@ -2542,7 +2544,7 @@ static struct expr *parse_help(struct parser_state *state, int arg1, int arg2) {
* "Parse" -version.
*/
static struct expr *parse_version(struct parser_state *state, int arg1, int arg2) {
- cfprintf(state->cmdline->cout, "%{ex}bfs%{rs} %{bld}%s%{rs}\n\n", BFS_VERSION);
+ cfprintf(state->cmdline->cout, "${ex}bfs${rs} ${bld}%s${rs}\n\n", BFS_VERSION);
printf("%s\n", BFS_HOMEPAGE);
@@ -2987,69 +2989,69 @@ fail:
void dump_cmdline(const struct cmdline *cmdline, bool verbose) {
CFILE *cerr = cmdline->cerr;
- cfprintf(cerr, "%{ex}%s%{rs} ", cmdline->argv[0]);
+ cfprintf(cerr, "${ex}%s${rs} ", cmdline->argv[0]);
if (cmdline->flags & BFTW_LOGICAL) {
- cfprintf(cerr, "%{cyn}-L%{rs} ");
+ cfprintf(cerr, "${cyn}-L${rs} ");
} else if (cmdline->flags & BFTW_COMFOLLOW) {
- cfprintf(cerr, "%{cyn}-H%{rs} ");
+ cfprintf(cerr, "${cyn}-H${rs} ");
} else {
- cfprintf(cerr, "%{cyn}-P%{rs} ");
+ cfprintf(cerr, "${cyn}-P${rs} ");
}
if (cmdline->optlevel != 3) {
- cfprintf(cerr, "%{cyn}-O%d%{rs} ", cmdline->optlevel);
+ cfprintf(cerr, "${cyn}-O%d${rs} ", cmdline->optlevel);
}
if (cmdline->debug & DEBUG_COST) {
- cfprintf(cerr, "%{cyn}-D%{rs} %{bld}cost%{rs} ");
+ cfprintf(cerr, "${cyn}-D${rs} ${bld}cost${rs} ");
}
if (cmdline->debug & DEBUG_EXEC) {
- cfprintf(cerr, "%{cyn}-D%{rs} %{bld}exec%{rs} ");
+ cfprintf(cerr, "${cyn}-D${rs} ${bld}exec${rs} ");
}
if (cmdline->debug & DEBUG_OPT) {
- cfprintf(cerr, "%{cyn}-D%{rs} %{bld}opt%{rs} ");
+ cfprintf(cerr, "${cyn}-D${rs} ${bld}opt${rs} ");
}
if (cmdline->debug & DEBUG_RATES) {
- cfprintf(cerr, "%{cyn}-D%{rs} %{bld}rates%{rs} ");
+ cfprintf(cerr, "${cyn}-D${rs} ${bld}rates${rs} ");
}
if (cmdline->debug & DEBUG_SEARCH) {
- cfprintf(cerr, "%{cyn}-D%{rs} %{bld}search%{rs} ");
+ cfprintf(cerr, "${cyn}-D${rs} ${bld}search${rs} ");
}
if (cmdline->debug & DEBUG_STAT) {
- cfprintf(cerr, "%{cyn}-D%{rs} %{bld}stat%{rs} ");
+ cfprintf(cerr, "${cyn}-D${rs} ${bld}stat${rs} ");
}
if (cmdline->debug & DEBUG_TREE) {
- cfprintf(cerr, "%{cyn}-D%{rs} %{bld}tree%{rs} ");
+ cfprintf(cerr, "${cyn}-D${rs} ${bld}tree${rs} ");
}
for (struct root *root = cmdline->roots; root; root = root->next) {
char c = root->path[0];
if (c == '-' || c == '(' || c == ')' || c == '!' || c == ',') {
- cfprintf(cerr, "%{cyn}-f%{rs} ");
+ cfprintf(cerr, "${cyn}-f${rs} ");
}
- cfprintf(cerr, "%{mag}%s%{rs} ", root->path);
+ cfprintf(cerr, "${mag}%s${rs} ", root->path);
}
if (cmdline->cout->colors) {
- cfprintf(cerr, "%{blu}-color%{rs} ");
+ cfprintf(cerr, "${blu}-color${rs} ");
} else {
- cfprintf(cerr, "%{blu}-nocolor%{rs} ");
+ cfprintf(cerr, "${blu}-nocolor${rs} ");
}
if (cmdline->flags & BFTW_DEPTH) {
- cfprintf(cerr, "%{blu}-depth%{rs} ");
+ cfprintf(cerr, "${blu}-depth${rs} ");
}
if (cmdline->ignore_races) {
- cfprintf(cerr, "%{blu}-ignore_readdir_race%{rs} ");
+ cfprintf(cerr, "${blu}-ignore_readdir_race${rs} ");
}
if (cmdline->flags & BFTW_XDEV) {
- cfprintf(cerr, "%{blu}-mount%{rs} ");
+ cfprintf(cerr, "${blu}-mount${rs} ");
}
if (cmdline->mindepth != 0) {
- cfprintf(cerr, "%{blu}-mindepth%{rs} %{bld}%d%{rs} ", cmdline->mindepth);
+ cfprintf(cerr, "${blu}-mindepth${rs} ${bld}%d${rs} ", cmdline->mindepth);
}
if (cmdline->maxdepth != INT_MAX) {
- cfprintf(cerr, "%{blu}-maxdepth%{rs} %{bld}%d%{rs} ", cmdline->maxdepth);
+ cfprintf(cerr, "${blu}-maxdepth${rs} ${bld}%d${rs} ", cmdline->maxdepth);
}
dump_expr(cerr, cmdline->expr, verbose);
@@ -3063,8 +3065,8 @@ void dump_cmdline(const struct cmdline *cmdline, bool verbose) {
static void dump_costs(const struct cmdline *cmdline) {
CFILE *cerr = cmdline->cerr;
const struct expr *expr = cmdline->expr;
- cfprintf(cerr, " Cost: ~%{ylw}%g%{rs}\n", expr->cost);
- cfprintf(cerr, "Probability: ~%{ylw}%g%%%{rs}\n", 100.0*expr->probability);
+ cfprintf(cerr, " Cost: ~${ylw}%g${rs}\n", expr->cost);
+ cfprintf(cerr, "Probability: ~${ylw}%g%%${rs}\n", 100.0*expr->probability);
}
/**
diff --git a/util.h b/util.h
index 836db37..4a9947c 100644
--- a/util.h
+++ b/util.h
@@ -68,6 +68,15 @@
#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);