summaryrefslogtreecommitdiffstats
path: root/parse.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2016-06-08 23:26:48 -0400
committerTavian Barnes <tavianator@tavianator.com>2016-06-08 23:26:48 -0400
commitfcd08ee02a660e7c3013b073e7122be5094e8d47 (patch)
tree915bb5c2e1d0ed34d1a45c091f3b8f8972413653 /parse.c
parent593e2135a98b66999f3143c70dd5169701972906 (diff)
downloadbfs-fcd08ee02a660e7c3013b073e7122be5094e8d47.tar.xz
Implement -fprint and -fprint0.
Diffstat (limited to 'parse.c')
-rw-r--r--parse.c88
1 files changed, 86 insertions, 2 deletions
diff --git a/parse.c b/parse.c
index cccdacf..4101c36 100644
--- a/parse.c
+++ b/parse.c
@@ -62,6 +62,12 @@ static struct expr expr_false = {
*/
static void free_expr(struct expr *expr) {
if (expr && expr != &expr_true && expr != &expr_false) {
+ if (expr->file && expr->file != stdout && expr->file != stderr) {
+ if (fclose(expr->file) != 0) {
+ perror("fclose()");
+ }
+ }
+
free_expr(expr->lhs);
free_expr(expr->rhs);
free(expr);
@@ -80,6 +86,7 @@ static struct expr *new_expr(eval_fn *eval, bool pure, size_t argc, char **argv)
expr->pure = pure;
expr->argc = argc;
expr->argv = argv;
+ expr->file = NULL;
}
return expr;
}
@@ -259,7 +266,7 @@ static int stat_arg(const struct parser_state *state, struct expr *expr, struct
int ret = fstatat(AT_FDCWD, expr->sdata, sb, flags);
if (ret != 0) {
pretty_error(cmdline->stderr_colors,
- "'%s': %s\n", expr->sdata, strerror(errno));
+ "error: '%s': %s\n", expr->sdata, strerror(errno));
free_expr(expr);
}
return ret;
@@ -508,6 +515,25 @@ static struct expr *parse_nullary_action(struct parser_state *state, eval_fn *ev
}
/**
+ * Parse an action that takes one argument.
+ */
+static struct expr *parse_unary_action(struct parser_state *state, eval_fn *eval) {
+ const char *arg = state->argv[0];
+ const char *value = state->argv[1];
+ if (!value) {
+ pretty_error(state->cmdline->stderr_colors,
+ "error: %s needs a value.\n", arg);
+ return NULL;
+ }
+
+ struct expr *expr = parse_action(state, eval, 2);
+ if (expr) {
+ expr->sdata = value;
+ }
+ return expr;
+}
+
+/**
* Parse a test expression with integer data and a comparison flag.
*/
static struct expr *parse_test_icmp(struct parser_state *state, eval_fn *eval) {
@@ -703,6 +729,59 @@ static struct expr *parse_exec(struct parser_state *state, enum execflags flags)
}
/**
+ * Open a file for an expression.
+ */
+static int expr_open(struct parser_state *state, struct expr *expr, const char *path) {
+ expr->file = fopen(path, "wb");
+ if (!expr->file) {
+ pretty_error(state->cmdline->stderr_colors,
+ "error: '%s': %s\n", path, strerror(errno));
+ free_expr(expr);
+ return -1;
+ }
+
+ ++state->cmdline->nopen_files;
+ return 0;
+}
+
+/**
+ * Parse -fprint FILE.
+ */
+static struct expr *parse_fprint(struct parser_state *state) {
+ struct expr *expr = parse_unary_action(state, eval_fprint);
+ if (expr) {
+ if (expr_open(state, expr, expr->sdata) != 0) {
+ return NULL;
+ }
+ }
+ return expr;
+}
+
+/**
+ * Parse -fprint0 FILE.
+ */
+static struct expr *parse_fprint0(struct parser_state *state) {
+ struct expr *expr = parse_unary_action(state, eval_print0);
+ if (expr) {
+ if (expr_open(state, expr, expr->sdata) != 0) {
+ return NULL;
+ }
+ }
+ return expr;
+}
+
+/**
+ * Parse -print0.
+ */
+static struct expr *parse_print0(struct parser_state *state) {
+ struct expr *expr = parse_nullary_action(state, eval_print0);
+ if (expr) {
+ expr->file = stdout;
+ }
+ return expr;
+}
+
+/**
* Parse -group.
*/
static struct expr *parse_group(struct parser_state *state) {
@@ -1176,6 +1255,10 @@ static struct expr *parse_literal(struct parser_state *state) {
} else if (strcmp(arg, "-follow") == 0) {
cmdline->flags |= BFTW_FOLLOW | BFTW_DETECT_CYCLES;
return parse_nullary_positional_option(state);
+ } else if (strcmp(arg, "-fprint") == 0) {
+ return parse_fprint(state);
+ } else if (strcmp(arg, "-fprint0") == 0) {
+ return parse_fprint0(state);
}
break;
@@ -1265,7 +1348,7 @@ static struct expr *parse_literal(struct parser_state *state) {
} else if (strcmp(arg, "-print") == 0) {
return parse_nullary_action(state, eval_print);
} else if (strcmp(arg, "-print0") == 0) {
- return parse_nullary_action(state, eval_print0);
+ return parse_print0(state);
} else if (strcmp(arg, "-prune") == 0) {
return parse_nullary_action(state, eval_prune);
}
@@ -1756,6 +1839,7 @@ struct cmdline *parse_cmdline(int argc, char *argv[]) {
cmdline->optlevel = 2;
cmdline->debug = 0;
cmdline->expr = &expr_true;
+ cmdline->nopen_files = 0;
cmdline->colors = parse_colors(getenv("LS_COLORS"));
cmdline->stdout_colors = isatty(STDOUT_FILENO) ? cmdline->colors : NULL;