The --outermost flag culls matches that are within another match, and makes for much cleaner output when looking for directories.
I've reuploaded the patches to fix an off by one error (and before that, to update the db cursor when skipping).
Thanks for the patches. Could you describe for which cases do you need this, and in particular whether -b would work for you?
(locate foo | grep -v 'foo.*foo') is a possible way to do this outside locate - less convenient, sure, but perhaps acceptable if the cases were rare.
(locate foo | grep -v 'foo.*foo')
I haven't reviewed the patches in detail, so just some initial comments (in fairly random order, and I'm really not yet sure that this feature is overall worth including):
At minimum, the test suite needs to keep working, and should also cover all code added for this feature. Notably, the patch doesn't actually work correctly:
{{{ $ (mkdir x; cd x; for i in $(seq 1 5); do mkdir "foo$i"{a,b,c}; cd "foo$i"b;done) $ build/src/updatedb -o db -U . -l 0 $ build/src/locate -d db -o foo2 .../x/foo1b/foo2a .../x/foo1b/foo2b .../x/foo1b/foo2c .../x/foo1b/foo2b/foo3b/foo4a .../x/foo1b/foo2b/foo3b/foo4b .../x/foo1b/foo2b/foo3b/foo4c }}}
Coding style-wise: * Please keep all global variables and functions documented with comments. * The modification of path[dir_name_len - 1] back and forth seems avoidable with some code reorganization, the slash has been added just above. (perhaps a patch that moves things around, and then a patch that adds the feature?) * For static buffers, it's faster to use a single long-term buffer than to allocate and free it all over again. See how check_directory_perms manages "copy", for example, or the use of obstacks throughout.
path[dir_name_len - 1]
Re the example you give, it works with both current patches applied, but the optimisation was broken a bit earlier (you need this line if (! skip && nested_toskip); maybe I'll go back to using a goto skip for this).
if (! skip && nested_toskip)
goto skip
I almost always use -b, but before hacking this I also used a postprocessing script on top of it to sort and remove nested results. The sorting is necessary with the current output order and makes postprocessing slow. grep -v would also work but typing patterns twice and translating the glob syntax is a pain for a command I use frequently.
Typical searches that benefit from this: searching for a program name, I'm looking for either a checkout, a data directory or a configuration directory; unfiltered output tends to gets a large number of results in most categories, making it harder to find the one I'm looking for; filtered output has just the overview. Similar when looking for an artist or album name; the tracks will tend to repeat both names again and not fit into a terminal.
Thanks for the comments on coding style. I'll look into this and the testsuite. The obstacks were a bit frightening, and the performance with -o is currently similar or better than without (in extreme cases, like locate -ob e, ? or lib).
attachment 0003-Add-a-flag-to-return-the-outermost-matches.patch
attachment 0004-Add-an-optimisation-for-the-outermost-flag.patch
attachment 0005-Convert-latest_dir_match-to-an-obstack.patch
attachment 0006-outermost-optimisation-split-out-more-expensive-crit.patch
I've added the missing comments, the first patch now has tests and was refactored a bit (splitting out the subpath check). 0005 converts the extra buffer to an obstack, and 0006 adds another optimisation.
attachment 0007-Imply-basename-when-outermost-is-used-with-simple-pa.patch