summaryrefslogtreecommitdiffstats
path: root/parse.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2017-01-14 16:38:08 -0500
committerTavian Barnes <tavianator@tavianator.com>2017-02-05 19:02:25 -0500
commita6f94c132c425bbab543e98fcd19f4ff7519d1b7 (patch)
tree215135837c0335946b70593877ec5411ba8e6c17 /parse.c
parent9f1863d45fe596e258596a4b4cc9a4064bcb11d3 (diff)
downloadbfs-a6f94c132c425bbab543e98fcd19f4ff7519d1b7.tar.xz
Implement -printf/-fprintf
Based on a patch by Fangrui Song <i@maskray.me>. Closes #16.
Diffstat (limited to 'parse.c')
-rw-r--r--parse.c72
1 files changed, 68 insertions, 4 deletions
diff --git a/parse.c b/parse.c
index d0168a9..b2a4cc3 100644
--- a/parse.c
+++ b/parse.c
@@ -10,6 +10,7 @@
*********************************************************************/
#include "bfs.h"
+#include "printf.h"
#include "typo.h"
#include "util.h"
#include <ctype.h>
@@ -77,6 +78,8 @@ static void free_expr(struct expr *expr) {
free(expr->regex);
}
+ free_bfs_printf(expr->printf);
+
free_expr(expr->lhs);
free_expr(expr->rhs);
free(expr);
@@ -101,6 +104,7 @@ static struct expr *new_expr(eval_fn *eval, bool pure, size_t argc, char **argv)
expr->argv = argv;
expr->file = NULL;
expr->regex = NULL;
+ expr->printf = NULL;
}
return expr;
}
@@ -964,7 +968,7 @@ static struct expr *parse_fprint(struct parser_state *state, int arg1, int arg2)
* Parse -fprint0 FILE.
*/
static struct expr *parse_fprint0(struct parser_state *state, int arg1, int arg2) {
- struct expr *expr = parse_unary_action(state, eval_print0);
+ struct expr *expr = parse_unary_action(state, eval_fprint0);
if (expr) {
if (expr_open(state, expr, expr->sdata) != 0) {
return NULL;
@@ -974,6 +978,44 @@ static struct expr *parse_fprint0(struct parser_state *state, int arg1, int arg2
}
/**
+ * Parse -fprintf FILE FORMAT.
+ */
+static struct expr *parse_fprintf(struct parser_state *state, int arg1, int arg2) {
+ const char *arg = state->argv[0];
+
+ const char *file = state->argv[1];
+ if (!file) {
+ pretty_error(state->cmdline->stderr_colors,
+ "error: %s needs a file.\n", arg);
+ return NULL;
+ }
+
+ const char *format = state->argv[2];
+ if (!format) {
+ pretty_error(state->cmdline->stderr_colors,
+ "error: %s needs a format string.\n", arg);
+ return NULL;
+ }
+
+ struct expr *expr = parse_action(state, eval_fprintf, 3);
+ if (!expr) {
+ return NULL;
+ }
+
+ if (expr_open(state, expr, file) != 0) {
+ return NULL;
+ }
+
+ expr->printf = parse_bfs_printf(format, state->cmdline->stderr_colors);
+ if (!expr->printf) {
+ free_expr(expr);
+ return NULL;
+ }
+
+ return expr;
+}
+
+/**
* Parse -gid/-group.
*/
static struct expr *parse_group(struct parser_state *state, int arg1, int arg2) {
@@ -1495,7 +1537,7 @@ static struct expr *parse_print(struct parser_state *state, int arg1, int arg2)
* Parse -print0.
*/
static struct expr *parse_print0(struct parser_state *state, int arg1, int arg2) {
- struct expr *expr = parse_nullary_action(state, eval_print0);
+ struct expr *expr = parse_nullary_action(state, eval_fprint0);
if (expr) {
expr->file = stdout;
}
@@ -1503,6 +1545,26 @@ static struct expr *parse_print0(struct parser_state *state, int arg1, int arg2)
}
/**
+ * Parse -printf FORMAT.
+ */
+static struct expr *parse_printf(struct parser_state *state, int arg1, int arg2) {
+ struct expr *expr = parse_unary_action(state, eval_fprintf);
+ if (!expr) {
+ return NULL;
+ }
+
+ expr->file = stdout;
+
+ expr->printf = parse_bfs_printf(expr->sdata, state->cmdline->stderr_colors);
+ if (!expr->printf) {
+ free_expr(expr);
+ return NULL;
+ }
+
+ return expr;
+}
+
+/**
* Parse -prune.
*/
static struct expr *parse_prune(struct parser_state *state, int arg1, int arg2) {
@@ -1775,8 +1837,8 @@ static struct expr *parse_help(struct parser_state *state, int arg1, int arg2) {
printf(" -amin, -anewer, -cmin, -cnewer, -mmin, -empty, -false, -gid, -ilname, -iname,\n");
printf(" -inum, -ipath, -iwholename, -iregex, -lname, -newerXY, -wholename, -regex,\n");
printf(" -readable, -writable, -executable, -samefile, -true, -uid, -used, -xtype,\n");
- printf(" -delete, -execdir ... ;, -okdir ... ;, -print0, -fprint, -fprint0, -quit,\n");
- printf(" -help, -version\n\n");
+ printf(" -delete, -execdir ... ;, -okdir ... ;, -print0, -printf, -fprint, -fprint0,\n");
+ printf(" -fprintf, -quit, -help, -version\n\n");
printf("BSD find features:\n");
printf(" -E, -d, -x, -depth N, -gid NAME, -uid NAME, -size N[ckMGTP], -sparse\n\n");
@@ -1848,6 +1910,7 @@ static const struct table_entry parse_table[] = {
{"follow", false, parse_follow, BFTW_LOGICAL | BFTW_DETECT_CYCLES, true},
{"fprint", false, parse_fprint},
{"fprint0", false, parse_fprint0},
+ {"fprintf", false, parse_fprintf},
{"gid", false, parse_group},
{"group", false, parse_group},
{"help", false, parse_help},
@@ -1886,6 +1949,7 @@ static const struct table_entry parse_table[] = {
{"perm", false, parse_perm},
{"print", false, parse_print},
{"print0", false, parse_print0},
+ {"printf", false, parse_printf},
{"prune", false, parse_prune},
{"quit", false, parse_quit},
{"readable", false, parse_access, R_OK},