Index: extern.h =================================================================== RCS file: /home/ncvs/src/usr.bin/find/extern.h,v retrieving revision 1.11 diff -u -r1.11 extern.h --- extern.h 2001/01/23 11:16:50 1.11 +++ extern.h 2001/02/21 08:40:08 @@ -63,7 +63,10 @@ PLAN *c_fstype __P((char *)); #endif PLAN *c_group __P((char *)); +PLAN *c_iname __P((char *)); PLAN *c_inum __P((char *)); +PLAN *c_ipath __P((char *)); +PLAN *c_iregex __P((char *)); PLAN *c_links __P((char *)); PLAN *c_ls __P((void)); PLAN *c_name __P((char *)); @@ -75,6 +78,7 @@ PLAN *c_print __P((void)); PLAN *c_print0 __P((void)); PLAN *c_prune __P((void)); +PLAN *c_regex __P((char *)); PLAN *c_size __P((char *)); PLAN *c_type __P((char *)); PLAN *c_user __P((char *)); @@ -90,3 +94,4 @@ extern int ftsoptions, isdeprecated, isdepth, isoutput, issort, isxargs; extern int mindepth, maxdepth; +extern int regexp_flags; Index: find.1 =================================================================== RCS file: /home/ncvs/src/usr.bin/find/find.1,v retrieving revision 1.31 diff -u -r1.31 find.1 --- find.1 2001/02/01 16:37:28 1.31 +++ find.1 2001/02/21 08:39:49 @@ -43,7 +43,7 @@ .Sh SYNOPSIS .Nm .Op Fl H | Fl L | Fl P -.Op Fl Xdsx +.Op Fl EXdsx .Op Fl f Ar pathname .Op Ar pathname ...\& .Ar expression @@ -59,6 +59,15 @@ The options are as follows: .Pp .Bl -tag -width Ds +.It Fl E +Interpret regular expressions followed by +.Ic -regex +and +.Ic -iregex +options as extended (modern) regular expressions rather than basic +regular expressions (BRE's). The +.Xr re_format 7 +manual page fully describes both formats. .It Fl H The .Fl H @@ -286,6 +295,20 @@ .Ar pattern . These characters may be matched explicitly by escaping them with a backslash (``\e''). +.It Ic -iname Ar pattern +Like +.Ic -name , +but the match is case insensitive. +.It Ic -regex Ar pattern +True if the whole path of the file matches +.Ar pattern +using regular expression. To match a file named ``./foo/xyzzy'', you +can use the regular expression ``.*/[xyz]*'' or ``.*/foo/.*'', but not +``xyzzy'' or ``/foo/''. +.It Ic -iregex Ar pattern +Like +.Ic -regex , +but the match is case insensitive. .It Ic -newer Ar file True if the current file has a more recent last modification time than .Ar file . @@ -303,6 +326,10 @@ backslash (``\e''). Slashes (``/'') are treated as normal characters and do not have to be matched explicitly. +.It Ic -ipath Ar pattern +Like +.Ic -path , +but the match is case insensitive. .It Xo .Ic -perm .Oo Fl Oc Ns Ar mode @@ -487,6 +514,7 @@ that are newer than ``ttt''. .El .Sh SEE ALSO +.Xr re_format 7, .Xr chflags 1 , .Xr chmod 1 , .Xr locate 1 , @@ -506,11 +534,14 @@ standard. .Pp All the single character options as well as the +.Ic -iname , .Ic -inum , +.Ic -iregex , .Ic -print0 , .Ic -delete , +.Ic -ls , and -.Ic -ls +.Ic -regex primaries are extensions to .St -p1003.2 . .Pp @@ -540,6 +571,13 @@ utility arguments if it had preceding or following non-whitespace characters. This version replaces it no matter where in the utility name or arguments it appears. +.Pp +The +.Fl E +option was implemented on the analogy of +.Xr grep 1 +and +.Xr sed 1 . .Sh BUGS The special characters used by .Nm Index: find.c =================================================================== RCS file: /home/ncvs/src/usr.bin/find/find.c,v retrieving revision 1.8 diff -u -r1.8 find.c --- find.c 2000/06/12 11:12:41 1.8 +++ find.c 2001/02/21 05:14:56 @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include Index: find.h =================================================================== RCS file: /home/ncvs/src/usr.bin/find/find.h,v retrieving revision 1.9 diff -u -r1.9 find.h --- find.h 2001/01/23 11:16:50 1.9 +++ find.h 2001/02/21 08:27:41 @@ -37,14 +37,16 @@ * $FreeBSD: src/usr.bin/find/find.h,v 1.9 2001/01/23 11:16:50 peter Exp $ */ +#include + /* node type */ enum ntype { N_AND = 1, /* must start > 0 */ N_AMIN, N_ATIME, N_CLOSEPAREN, N_CMIN, N_CTIME, N_DEPTH, N_EMPTY, N_EXEC, N_EXECDIR, N_EXPR, N_FLAGS, N_FOLLOW, N_FSTYPE, N_GROUP, N_INUM, N_LINKS, N_LS, N_MMIN, - N_MTIME, N_NAME, - N_NEWER, N_NOGROUP, N_NOT, N_NOUSER, N_OK, N_OPENPAREN, N_OR, N_PATH, + N_MTIME, N_NAME, N_INAME, N_PATH, N_IPATH, N_REGEX, N_IREGEX, + N_NEWER, N_NOGROUP, N_NOT, N_NOUSER, N_OK, N_OPENPAREN, N_OR, N_PERM, N_PRINT, N_PRUNE, N_SIZE, N_TYPE, N_USER, N_XDEV, N_PRINT0, N_DELETE, N_MAXDEPTH, N_MINDEPTH }; @@ -85,6 +87,7 @@ } ex; char *_a_data[2]; /* array of char pointers */ char *_c_data; /* char pointer */ + regex_t *_re_data; /* regex */ } p_un; } PLAN; #define a_data p_un._a_data @@ -100,6 +103,7 @@ #define p_data p_un._p_data #define t_data p_un._t_data #define u_data p_un._u_data +#define re_data p_un._re_data #define e_argv p_un.ex._e_argv #define e_orig p_un.ex._e_orig #define e_len p_un.ex._e_len Index: function.c =================================================================== RCS file: /home/ncvs/src/usr.bin/find/function.c,v retrieving revision 1.28 diff -u -r1.28 function.c --- function.c 2001/01/23 11:16:50 1.28 +++ function.c 2001/02/21 08:37:42 @@ -56,6 +56,7 @@ #include #include #include +#include #include #include #include @@ -76,6 +77,8 @@ } \ } +static int do_f_regex __P((PLAN *, FTSENT *, int)); +static PLAN *do_c_regex __P((char *, int)); static PLAN *palloc __P((enum ntype, int (*) __P((PLAN *, FTSENT *)))); /* @@ -924,7 +927,134 @@ return (new); } + +/* + * -iname functions -- + * + * Like -iname, but the match is case insensitive. + */ +int +f_iname(plan, entry) + PLAN *plan; + FTSENT *entry; +{ + return (!fnmatch(plan->c_data, entry->fts_name, FNM_CASEFOLD)); +} + +PLAN * +c_iname(pattern) + char *pattern; +{ + PLAN *new; + + new = palloc(N_INAME, f_iname); + new->c_data = pattern; + return (new); +} + + +/* + * -regex functions -- + * + * True if the whole path of the file matches pattern using + * regular expression. + */ +int +f_regex(plan, entry) + PLAN *plan; + FTSENT *entry; +{ + return (do_f_regex(plan, entry, 0)); +} + +PLAN * +c_regex(pattern) + char *pattern; +{ + return (do_c_regex(pattern, 0)); +} + /* + * -iregex functions -- + * + * Like -regex, but the match is case insensitive. + */ +int +f_iregex(plan, entry) + PLAN *plan; + FTSENT *entry; +{ + return (do_f_regex(plan, entry, REG_ICASE)); +} + +PLAN * +c_iregex(pattern) + char *pattern; +{ + return (do_c_regex(pattern, REG_ICASE)); +} + +static int +do_f_regex(plan, entry, icase) + PLAN *plan; + FTSENT *entry; + int icase; +{ + char *str; + size_t len; + regex_t *pre; + regmatch_t pmatch; + int errcode; + char errbuf[LINE_MAX]; + int matched; + + pre = plan->re_data; + str = entry->fts_path; + len = strlen(str); + matched = 0; + + pmatch.rm_so = 0; + pmatch.rm_eo = len; + + errcode = regexec(pre, str, 1, &pmatch, REG_STARTEND); + + if (errcode != 0 && errcode != REG_NOMATCH) { + regerror(errcode, pre, errbuf, sizeof errbuf); + errx(1, "%s: %s", + icase == 0 ? "-regex" : "-iregex", errbuf); + } + + if (errcode == 0 && pmatch.rm_so == 0 && pmatch.rm_eo == len) + matched = 1; + + return (matched); +} + +PLAN * +do_c_regex(pattern, icase) + char *pattern; + int icase; +{ + PLAN *new; + regex_t *pre; + int errcode; + char errbuf[LINE_MAX]; + + if ((pre = malloc(sizeof(regex_t))) == NULL) + err(1, NULL); + + if ((errcode = regcomp(pre, pattern, regexp_flags | icase)) != 0) { + regerror(errcode, pre, errbuf, sizeof errbuf); + errx(1, "%s: %s: %s", + icase == 0 ? "-regex" : "-iregex", pattern, errbuf); + } + + new = icase == 0 ? palloc(N_REGEX, f_regex) : palloc(N_IREGEX, f_iregex); + new->re_data = pre; + return (new); +} + +/* * -newer file functions -- * * True if the current file has been modified more recently @@ -1018,8 +1148,32 @@ char *pattern; { PLAN *new; + + new = palloc(N_PATH, f_path); + new->c_data = pattern; + return (new); +} + +/* + * -ipath functions -- + * + * Like -path, but the match is case insensitive. + */ +int +f_ipath(plan, entry) + PLAN *plan; + FTSENT *entry; +{ + return (!fnmatch(plan->c_data, entry->fts_path, FNM_CASEFOLD)); +} + +PLAN * +c_ipath(pattern) + char *pattern; +{ + PLAN *new; - new = palloc(N_NAME, f_path); + new = palloc(N_IPATH, f_ipath); new->c_data = pattern; return (new); } Index: main.c =================================================================== RCS file: /home/ncvs/src/usr.bin/find/main.c,v retrieving revision 1.10 diff -u -r1.10 main.c --- main.c 2000/06/12 11:12:41 1.10 +++ main.c 2001/02/21 08:24:05 @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -73,6 +74,7 @@ int issort; /* do hierarchies in lexicographical order */ int isxargs; /* don't permit xargs delimiting chars */ int mindepth = -1, maxdepth = -1; /* minimum and maximum depth */ +int regexp_flags = REG_BASIC; /* use the "basic" regexp by default*/ static void usage __P((void)); @@ -91,8 +93,11 @@ p = start = argv; Hflag = Lflag = 0; ftsoptions = FTS_NOSTAT | FTS_PHYSICAL; - while ((ch = getopt(argc, argv, "HLPXdf:sx")) != -1) + while ((ch = getopt(argc, argv, "EHLPXdf:sx")) != -1) switch (ch) { + case 'E': + regexp_flags |= REG_EXTENDED; + break; case 'H': Hflag = 1; Lflag = 0; @@ -161,6 +166,6 @@ usage() { (void)fprintf(stderr, -"usage: find [-H | -L | -P] [-Xdsx] [-f file] [file ...] [expression]\n"); +"usage: find [-H | -L | -P] [-EXdsx] [-f file] [file ...] [expression]\n"); exit(1); } Index: option.c =================================================================== RCS file: /home/ncvs/src/usr.bin/find/option.c,v retrieving revision 1.11 diff -u -r1.11 option.c --- option.c 2001/01/23 11:16:50 1.11 +++ option.c 2001/02/21 08:38:26 @@ -47,6 +47,7 @@ #include #include +#include #include #include #include @@ -82,7 +83,10 @@ { "-fstype", N_FSTYPE, c_fstype, O_ARGV }, #endif { "-group", N_GROUP, c_group, O_ARGV }, + { "-iname", N_INAME, c_iname, O_ARGV }, { "-inum", N_INUM, c_inum, O_ARGV }, + { "-ipath", N_IPATH, c_ipath, O_ARGV }, + { "-iregex", N_IREGEX, c_iregex, O_ARGV }, { "-links", N_LINKS, c_links, O_ARGV }, { "-ls", N_LS, c_ls, O_ZERO }, { "-maxdepth", N_MAXDEPTH, c_maxdepth, O_ARGV }, @@ -101,6 +105,7 @@ { "-print", N_PRINT, c_print, O_ZERO }, { "-print0", N_PRINT0, c_print0, O_ZERO }, { "-prune", N_PRUNE, c_prune, O_ZERO }, + { "-regex", N_REGEX, c_regex, O_ARGV }, { "-size", N_SIZE, c_size, O_ARGV }, { "-type", N_TYPE, c_type, O_ARGV }, { "-user", N_USER, c_user, O_ARGV },