I've been working on $SUBJECT for the past few hours, and have managed to implement a very crude subset of GNU find's features:
http://www.gnu.org/software/findutils/manual/html_node/find_html/Format-Directives.html#Format-Directives I've implemented %f and %p (which appear identical to GNU find), and some escaped characters. Things I need help with, as string parsing in C has never been my forte (which will become quite obvious): 1) Getting %h to behave like GNU find. The GNU find code is significantly different than ours. As it stands, %h is broken. 2) find . -printf '\' results in odd output (SHELL=/usr/local/bin/bash on my box). Not sure why this is happening, but it's a big concern. 3) Security issues. I believe use of a large number of formatting variables could exceed the calloc()'d buffer (of MAXPATHLEN), causing a segfault at bare minimum. I'm not sure how to work around this. Also, some folks on #bsdports asked why I was bothering with this in the first place: mutt supports backticks to run shell commands inside of a muttrc file. See "Building a list of mailboxes on the fly" below: http://wiki.mutt.org/?ConfigTricks Note the find ... -printf '%h ' method. I can accomplish (just about) the same using `echo $HOME/Maildir/*`, but if I want to exclude an entry, I can't use | grep -v, because mutt doesn't support pipes within backticks. :-) -- | Jeremy Chadwick jdc at parodius.com | | Parodius Networking http://www.parodius.com/ | | UNIX Systems Administrator Mountain View, CA, USA | | Making life hard for others since 1977. PGP: 4BD6C0CB | diff -ruN find.orig/extern.h find/extern.h --- find.orig/extern.h 2006-05-14 13:23:00.000000000 -0700 +++ find/extern.h 2008-09-04 20:55:17.000000000 -0700 @@ -73,6 +73,7 @@ creat_f c_nouser; creat_f c_perm; creat_f c_print; +creat_f c_printf; creat_f c_regex; creat_f c_simple; creat_f c_size; @@ -107,6 +108,7 @@ exec_f f_perm; exec_f f_print; exec_f f_print0; +exec_f f_printf; exec_f f_prune; exec_f f_regex; exec_f f_size; diff -ruN find.orig/function.c find/function.c --- find.orig/function.c 2006-05-27 11:27:41.000000000 -0700 +++ find/function.c 2008-09-05 03:01:36.000000000 -0700 @@ -1272,6 +1272,86 @@ /* c_print0 is the same as c_print */ /* + * -printf functions -- + * + * Always true, manipulates output based on printf()-like + * formatting characters. + */ +int +f_printf(PLAN *plan, FTSENT *entry) +{ + char *scan; + char *outptr; + char *outidx; + + if ((outptr = calloc(MAXPATHLEN, 1)) == NULL) + err(1, NULL); + + outidx = outptr; + + for (scan = plan->c_data; *scan; scan++) { + if (*scan == '%') { + if (scan[1] == 0) { + errx(1, "missing format character"); + } + else if (scan[1] == '%') { + *outidx++ = '%'; + } + else if (scan[1] == 'f') { + strcpy(outidx, entry->fts_name); + outidx += entry->fts_namelen; + } + /* XXX - needs to behave like GNU find %h */ + /* + else if (scan[1] == 'h') { + strcpy(outidx, entry->fts_path); + outidx += entry->fts_pathlen; + } + */ + else if (scan[1] == 'p') { + strcpy(outidx, entry->fts_path); + outidx += entry->fts_pathlen; + } + scan++; + } + else if (*scan == '\\') { + if (scan[1] == '\\') { + *outidx++ = '\\'; + } + else if (scan[1] == 'n') { + *outidx++ = '\n'; + } + else if (scan[1] == 't') { + *outidx++ = '\t'; + } + scan++; + } + else { + *outidx++ = *scan; + } + } + + (void)printf(outptr); + free(outptr); + return 1; +} + +PLAN * +c_printf(OPTION *option, char ***argvp) +{ + char *argstring; + PLAN *new; + + argstring = nextarg(option, argvp); + ftsoptions &= ~FTS_NOSTAT; + isoutput = 1; + + new = palloc(option); + new->c_data = argstring; + return new; +} + +/* * -prune functions -- * * Prune a portion of the hierarchy. diff -ruN find.orig/option.c find/option.c --- find.orig/option.c 2006-04-05 16:06:11.000000000 -0700 +++ find/option.c 2008-09-04 20:48:18.000000000 -0700 @@ -128,6 +128,7 @@ { "-perm", c_perm, f_perm, 0 }, { "-print", c_print, f_print, 0 }, { "-print0", c_print, f_print0, 0 }, + { "-printf", c_printf, f_printf, 0 }, { "-prune", c_simple, f_prune, 0 }, { "-regex", c_regex, f_regex, 0 }, { "-size", c_size, f_size, 0 }, _______________________________________________ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "[EMAIL PROTECTED]"