This adds -fprint function. The primary name "-fprint" (but not the

code) comes from findutils; it behaves the same.

From my manpage addition:

 -fprint filename
	This primary always evaluates to true.  This creates filename or
	overwrites the file if it already exists.  The file is created at
	startup.  It writes the pathname of the current file to this
	file, followed by a newline character.  The file will be empty if
	no files are matched.

Here is an example usage:

find /etc \( -name "*pass*" -fprint file1 \) -o \( -group operator -fprint file2 \) -o -name "w*"

Note that this example will NOT include entry in file2 if it is
matched in first expression. (This also is same behaviour as
findutils, and I have implemented a -false primary to handle that.
I will commit it later.)

This creates the file as command line argument parsing time.
If there is an error somewhere on that line, such as missing values
or mismatched parenthesis, then a file may still be created.
(Even if a later -fprint filename is unwritable.) This is similar
behaviour to findutils. (It has been suggested that this find could
be code to create the files in an extra stage after the command-line
argument parsing and before the actual function processing.)

I will add -fprintx and -fprint0 soon.

This was discussed on tech-userlevel.
This commit is contained in:
reed 2005-10-12 20:03:59 +00:00
parent 90eafdf511
commit 4129c05469
6 changed files with 65 additions and 13 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: extern.h,v 1.20 2003/08/07 11:13:40 agc Exp $ */
/* $NetBSD: extern.h,v 1.21 2005/10/12 20:03:59 reed Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
@ -58,6 +58,7 @@ PLAN *c_exec __P((char ***, int));
PLAN *c_execdir __P((char ***, int));
PLAN *c_flags __P((char ***, int));
PLAN *c_follow __P((char ***, int));
PLAN *c_fprint __P((char ***, int));
PLAN *c_fstype __P((char ***, int));
PLAN *c_group __P((char ***, int));
PLAN *c_iname __P((char ***, int));

View File

@ -1,4 +1,4 @@
.\" $NetBSD: find.1,v 1.52 2005/08/10 06:51:24 mrg Exp $
.\" $NetBSD: find.1,v 1.53 2005/10/12 20:03:59 reed Exp $
.\"
.\" Copyright (c) 1990, 1993
.\" The Regents of the University of California. All rights reserved.
@ -260,6 +260,15 @@ files with no flags bits set are matched.
for more information about file flags.)
.It Ic -follow
Follow symbolic links.
.It Ic -fprint Ar filename
This primary always evaluates to true.
This creates
.Ar filename
or overwrites the file if it already exists.
The file is created at startup.
It writes the pathname of the current file to this file, followed
by a newline character.
The file will be empty if no files are matched.
.It Ic -fstype Ar type
True if the file is contained in a file system of type
.Ar type .
@ -436,6 +445,7 @@ It prints the pathname of the current file to standard output, followed
by a newline character.
If none of
.Ic -exec ,
.Ic -fprint ,
.Ic -ls ,
.Ic -ok ,
.Ic -print0 ,

View File

@ -1,4 +1,4 @@
/* $NetBSD: find.c,v 1.19 2004/03/30 22:51:13 heas Exp $ */
/* $NetBSD: find.c,v 1.20 2005/10/12 20:03:59 reed Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "from: @(#)find.c 8.5 (Berkeley) 8/5/94";
#else
__RCSID("$NetBSD: find.c,v 1.19 2004/03/30 22:51:13 heas Exp $");
__RCSID("$NetBSD: find.c,v 1.20 2005/10/12 20:03:59 reed Exp $");
#endif
#endif /* not lint */
@ -98,9 +98,9 @@ find_formplan(argv)
}
/*
* if the user didn't specify one of -print, -ok or -exec, then -print
* is assumed so we bracket the current expression with parens, if
* necessary, and add a -print node on the end.
* if the user didn't specify one of -print, -ok, -fprint, or -exec,
* then -print is assumed so we bracket the current expression with
* parens, if necessary, and add a -print node on the end.
*/
if (!isoutput) {
if (plan == NULL) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: find.h,v 1.18 2003/08/07 11:13:41 agc Exp $ */
/* $NetBSD: find.h,v 1.19 2005/10/12 20:03:59 reed Exp $ */
/*-
* Copyright (c) 1990, 1993
@ -41,7 +41,7 @@ enum ntype {
N_AND = 1, /* must start > 0 */
N_AMIN, N_ANEWER, N_ATIME, N_CLOSEPAREN, N_CMIN, N_CNEWER, N_CTIME,
N_DEPTH, N_EMPTY,
N_EXEC, N_EXECDIR, N_EXPR, N_FLAGS, N_FOLLOW, N_FSTYPE, N_GROUP,
N_EXEC, N_EXECDIR, N_EXPR, N_FLAGS, N_FOLLOW, N_FPRINT, N_FSTYPE, N_GROUP,
N_INAME, N_INUM, N_IREGEX, N_LINKS, N_LS, N_MINDEPTH, N_MAXDEPTH,
N_MMIN, N_MTIME, N_NAME, N_NEWER, N_NOGROUP, N_NOT, N_NOUSER, N_OK,
N_OPENPAREN, N_OR, N_PATH, N_PERM, N_PRINT, N_PRINT0, N_PRINTX,
@ -83,6 +83,7 @@ typedef struct _plandata {
int _max_data; /* tree depth */
int _min_data; /* tree depth */
regex_t _regexp_data; /* compiled regexp */
FILE *_fprint_file; /* file stream for -fprint */
} p_un;
} PLAN;
#define a_data p_un._a_data
@ -103,6 +104,7 @@ typedef struct _plandata {
#define max_data p_un._max_data
#define min_data p_un._min_data
#define regexp_data p_un._regexp_data
#define fprint_file p_un._fprint_file
typedef struct _option {
char *name; /* option name */

View File

@ -1,4 +1,4 @@
/* $NetBSD: function.c,v 1.50 2005/10/01 20:27:17 christos Exp $ */
/* $NetBSD: function.c,v 1.51 2005/10/12 20:03:59 reed Exp $ */
/*-
* Copyright (c) 1990, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "from: @(#)function.c 8.10 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: function.c,v 1.50 2005/10/01 20:27:17 christos Exp $");
__RCSID("$NetBSD: function.c,v 1.51 2005/10/12 20:03:59 reed Exp $");
#endif
#endif /* not lint */
@ -88,6 +88,7 @@ static int64_t find_parsenum __P((PLAN *, char *, char *, char *));
int f_exec __P((PLAN *, FTSENT *));
int f_execdir __P((PLAN *, FTSENT *));
int f_flags __P((PLAN *, FTSENT *));
int f_fprint __P((PLAN *, FTSENT *));
int f_fstype __P((PLAN *, FTSENT *));
int f_group __P((PLAN *, FTSENT *));
int f_iname __P((PLAN *, FTSENT *));
@ -708,6 +709,43 @@ c_follow(argvp, isok)
return (palloc(N_FOLLOW, f_always_true));
}
/* -fprint functions --
*
* Causes the current pathame to be written to the defined output file.
*/
int
f_fprint(plan, entry)
PLAN *plan;
FTSENT *entry;
{
if (-1 == fprintf(plan->fprint_file, "%s\n", entry->fts_path))
warn("fprintf");
return(1);
/* no descriptors are closed; they will be closed by
operating system when this find command exits. */
}
PLAN *
c_fprint(argvp, isok)
char ***argvp;
int isok;
{
PLAN *new;
isoutput = 1; /* do not assume -print */
new = palloc(N_FPRINT, f_fprint);
if (NULL == (new->fprint_file = fopen(**argvp, "w")))
err(1, "-fprint: %s: cannot create file", **argvp);
(*argvp)++;
return (new);
}
/*
* -fstype functions --
*

View File

@ -1,4 +1,4 @@
/* $NetBSD: option.c,v 1.20 2003/08/07 11:13:43 agc Exp $ */
/* $NetBSD: option.c,v 1.21 2005/10/12 20:03:59 reed Exp $ */
/*-
* Copyright (c) 1990, 1993, 1994
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "from: @(#)option.c 8.2 (Berkeley) 4/16/94";
#else
__RCSID("$NetBSD: option.c,v 1.20 2003/08/07 11:13:43 agc Exp $");
__RCSID("$NetBSD: option.c,v 1.21 2005/10/12 20:03:59 reed Exp $");
#endif
#endif /* not lint */
@ -74,6 +74,7 @@ static OPTION const options[] = {
{ "-execdir", N_EXECDIR, c_execdir, 1 },
{ "-flags", N_FLAGS, c_flags, 1 },
{ "-follow", N_FOLLOW, c_follow, 0 },
{ "-fprint", N_FPRINT, c_fprint, 1 },
{ "-fstype", N_FSTYPE, c_fstype, 1 },
{ "-group", N_GROUP, c_group, 1 },
{ "-iname", N_INAME, c_iname, 1 },