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

Attachment: 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

Reply via email to