Lars, can I get you to add boost/spirit to the boost tree please? The attached patch gives us a platform-independent glob function. It's the necessary first step towards a command-line parser.
Lars' requirement that I do not use exceptions means that I've had to jump through a few hoops. I have still to add some further code to ensure that Boost.Regex doesn't assert if it receives a pattern like '[z-a]', but otherwise all seems well. If there are no objections, I'll commit this and continue to improve it from within the LyX tree. As yet, nothing uses it, so impact will be zero. (Excuse the hacked #include in globbing.C. globbing.[Ch] will become redundant and will be removed once I'm happy with this.) I also enclose a main() so that you can try it out --- but you'll need to have Boost.Spirit in you boost src tree. $ ./glob_function Usage: glob_function <globbing pattern> <working directory> <working directory> is used only if <globbing pattern> describes a relative path. If it is omitted, the current working directory is used. $ ./glob_function 'src/*.h' $ ./glob_function '*.h' 'src' Here, I build it from the top level dir with: $ g++ -DHAVE_CONFIG_H -Isrc/support -Isrc -Iboost \ -g -O -fno-exceptions -W -Wall -c glob_function.cpp $ g++ -o glob_function glob_function.o \ -Lbuild/src/support/.libs -lsupport \ -Lbuild/boost/libs/filesystem/src/.libs/ -lboostfilesystem \ -Lbuild/boost/libs/regex/src/.libs/ -lboostregex When using a std::vector to hold the matches, timings are comparable to the system glob on a *nix machine. -- Angus
glob.diff.bz2
Description: BZip2 compressed data
// Copyright Angus Leeming 2004. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) #include "support/glob.h" #include "debug.h" #include "support/lyxlib.h" #include <iostream> namespace fs = boost::filesystem; LyXErr lyxerr(std::cerr.rdbuf()); template <typename ContainerT> void print(std::ostream & os, char const * title, ContainerT const & matches) { typedef ContainerT container_type; os << title << ":\n"; typename container_type::const_iterator it = matches.begin(); typename container_type::const_iterator const end = matches.end(); for (; it != end; ++it) os << '\t' << it->native_file_string() << '\n'; } int main(int argc, char * argv[]) { if (argc < 2 || argc > 3) { fs::path const exe(argv[0], fs::native); std::cerr << "Usage:\n\t" << exe.leaf() << " <globbing pattern> <working directory>\n\n" "\t<working directory> is used only if " "<globbing pattern> describes\n\ta relative path. " "If it is omitted, the current working directory\n" "\tis used.\n"; return 1; } std::string const pattern = argv[1]; fs::path const start_dir(argc == 3 ? argv[2] : "."); lyx::glob_flags const flags = lyx::glob_brace; std::vector<fs::path> matches; lyx::glob(matches, pattern, start_dir, flags); print(std::cout, "Boost glob", matches); std::cout << std::endl; return 0; } namespace boost { void assertion_failed(char const * expr, char const * function, char const * file, long line) { lyxerr << "Assertion triggered in " << function << " by failing check \"" << expr << "\"" << " in file " << file << ":" << line << std::endl; lyx::support::abort(); } } // namespace boost