Globbing.

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8300 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Angus Leeming 2004-01-05 16:49:38 +00:00
parent 36fda753fc
commit 9387970e7d
10 changed files with 199 additions and 45 deletions

View File

@ -1,3 +1,10 @@
2004-01-05 Angus Leeming <leeming@lyx.org>
* external_templates: use the valid csh-style glob
"*.{gif,png,jpg,bmp,pbm,ppm,tga,tif,xpm,xbm}" to define the
RasterImage file filter, rather than the current psuedo-glob,
psuedo-regex .
2003-12-22 Michael Schmitt <michael.schmitt@teststep.org> 2003-12-22 Michael Schmitt <michael.schmitt@teststep.org>
* layouts/g-brief2.layout: more spelling fixes * layouts/g-brief2.layout: more spelling fixes

View File

@ -38,18 +38,10 @@ Template RasterImage
GuiName "Bitmap: $$Basename" GuiName "Bitmap: $$Basename"
HelpText HelpText
A bitmap file. A bitmap file.
In the parameters box, you can provide optional
parameters for the ImageMagick convert program.
E.g., use `-border 10x10 -bordercolor black'
to surround the picture with a black border
when you export to LaTeX.
When you export to Ascii, you can provide a
number describing how many columns the picture
should expand to.
This template uses Gimp for editing. This template uses Gimp for editing.
HelpTextEnd HelpTextEnd
InputFormat "*" InputFormat "*"
FileFilter "*.(gif|png|jpg|bmp|pbm|ppm|tga|tif|xpm|xbm)" FileFilter "*.{gif,png,jpg,bmp,pbm,ppm,tga,tif,xpm,xbm}"
EditCommand "gimp $$FName" EditCommand "gimp $$FName"
AutomaticProduction true AutomaticProduction true
Transform Rotate Transform Rotate
@ -188,7 +180,7 @@ TemplateEnd
Template Date Template Date
GuiName "Date" GuiName "Date"
HelpText HelpText
Todays date. Today's date.
Read 'info date' for more information. Read 'info date' for more information.
HelpTextEnd HelpTextEnd
InputFormat date InputFormat date

View File

@ -1,3 +1,9 @@
2004-01-05 Angus Leeming <leeming@lyx.org>
* FileDialog_private.C (c-tor): invoke convert_brace_glob to convert
a csh-style glob like "*.{abc,def}" to something that
Qt can understand.
2003-12-30 Juergen Spitzmueller <j.spitzmueller@gmx.de> 2003-12-30 Juergen Spitzmueller <j.spitzmueller@gmx.de>
* ui/QGraphicsDialogBase.ui: add missing signal/slot (bug 1469). * ui/QGraphicsDialogBase.ui: add missing signal/slot (bug 1469).

View File

@ -14,11 +14,13 @@
#include "FileDialog_private.h" #include "FileDialog_private.h"
#include "qt_helpers.h" #include "qt_helpers.h"
#include "support/globbing.h"
#include "support/lstrings.h" #include "support/lstrings.h"
#include <qapplication.h> #include <qapplication.h>
#include <qtoolbutton.h> #include <qtoolbutton.h>
using lyx::support::convert_brace_glob;
using lyx::support::split; using lyx::support::split;
using std::string; using std::string;
@ -45,7 +47,7 @@ string const getLabel(string const & str) {
LyXFileDialog::LyXFileDialog(string const & p, string const & m, LyXFileDialog::LyXFileDialog(string const & p, string const & m,
string const & t, string const & t,
FileDialog::Button const & b1, FileDialog::Button const & b2) FileDialog::Button const & b1, FileDialog::Button const & b2)
: QFileDialog(toqstr(p), toqstr(m), : QFileDialog(toqstr(p), toqstr(convert_brace_glob(m)),
qApp->focusWidget() ? qApp->focusWidget() : qApp->mainWidget(), toqstr(t), true), qApp->focusWidget() ? qApp->focusWidget() : qApp->mainWidget(), toqstr(t), true),
b1_(0), b2_(0) b1_(0), b2_(0)
{ {

View File

@ -1,3 +1,8 @@
2004-01-05 Angus Leeming <leeming@lyx.org>
* FormFiledialog.C (glob2regex, globMatch): removed.
(Reread): use lyx::support::expand_globs instead.
2004-01-02 Angus Leeming <leeming@lyx.org> 2004-01-02 Angus Leeming <leeming@lyx.org>
* forms/fdfix.sh: no need to assume that the fdfix files are in * forms/fdfix.sh: no need to assume that the fdfix files are in

View File

@ -20,10 +20,11 @@
#include "frontends/Dialogs.h" #include "frontends/Dialogs.h"
#include "support/FileInfo.h" #include "support/FileInfo.h"
#include "support/lyxlib.h"
#include "support/lstrings.h"
#include "support/tostr.h"
#include "support/filetools.h" #include "support/filetools.h"
#include "support/globbing.h"
#include "support/lstrings.h"
#include "support/lyxlib.h"
#include "support/tostr.h"
#include "lyx_forms.h" #include "lyx_forms.h"
@ -72,6 +73,7 @@ using std::max;
using std::sort; using std::sort;
using std::string; using std::string;
using std::map; using std::map;
using std::vector;
namespace { namespace {
@ -198,32 +200,6 @@ int FileDialog::Private::minw_ = 0;
int FileDialog::Private::minh_ = 0; int FileDialog::Private::minh_ = 0;
namespace {
boost::regex glob2regex(string const & pat)
{
// We massage the pattern a bit so that the usual
// shell pattern we all are used to will work.
// One nice thing about using a real regex is that
// things like "*.*[^~]" will work also.
// build the regex string.
string pattern = subst(pat, ".", "\\.");
pattern = subst(pattern, "*", ".*");
boost::regex reg(pattern);
return reg;
}
bool globMatch(string const & a, boost::regex const & reg)
{
// If the glob is invalid then match everything.
return reg.empty() ? true : boost::regex_match(a, reg);
}
} // namespace anon
// Reread: updates dialog list to match class directory // Reread: updates dialog list to match class directory
void FileDialog::Private::Reread() void FileDialog::Private::Reread()
{ {
@ -263,8 +239,8 @@ void FileDialog::Private::Reread()
++depth_; ++depth_;
} }
// Parses all entries of the given subdirectory vector<string> const glob_matches =
boost::regex const mask_regex = glob2regex(mask_); lyx::support::expand_globs(mask_, directory_);
time_t curTime = time(0); time_t curTime = time(0);
rewinddir(dir); rewinddir(dir);
@ -331,7 +307,7 @@ void FileDialog::Private::Reread()
buffer += Link; buffer += Link;
// This gives the FileType of the file that // This gives the FileType of the file that
// is really pointed too after resolving all // is really pointed to after resolving all
// symlinks. This is not necessarily the same // symlinks. This is not necessarily the same
// as the type of Link (which could again be a // as the type of Link (which could again be a
// link). Is that intended? // link). Is that intended?
@ -349,7 +325,10 @@ void FileDialog::Private::Reread()
|| fileInfo.isChar() || fileInfo.isChar()
|| fileInfo.isBlock() || fileInfo.isBlock()
|| fileInfo.isFifo()) { || fileInfo.isFifo()) {
if (!globMatch(fname, mask_regex)) typedef vector<string>::const_iterator viterator;
viterator gbegin = glob_matches.begin();
viterator const gend = glob_matches.end();
if (std::find(gbegin, gend, fname) == gend)
continue; continue;
} else if (!(isDir = fileInfo.isDir())) } else if (!(isDir = fileInfo.isDir()))
continue; continue;

View File

@ -1,3 +1,7 @@
2004-01-05 Angus Leeming <leeming@lyx.org>
* globbing.[Ch]: new files containing some globbing utilities.
2003-11-05 João Luis M. Assirati <assirati@fma.if.usp.br> 2003-11-05 João Luis M. Assirati <assirati@fma.if.usp.br>
* putenv.C: allocate the string before putting it into the * putenv.C: allocate the string before putting it into the

View File

@ -39,6 +39,8 @@ libsupport_la_SOURCES = \
forkedcontr.C \ forkedcontr.C \
forkedcontr.h \ forkedcontr.h \
getcwd.C \ getcwd.C \
globbing.C \
globbing.h \
$(COMPRESSION) kill.C \ $(COMPRESSION) kill.C \
limited_stack.h \ limited_stack.h \
lstrings.C \ lstrings.C \

105
src/support/globbing.C Normal file
View File

@ -0,0 +1,105 @@
/**
* \file globbing.C
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Angus Leeming
*
* Full author contact details are available in file CREDITS.
*/
#include "globbing.h"
#include "path.h"
#include <boost/regex.hpp>
#include <boost/tokenizer.hpp>
#include "glob.h"
using std::string;
using std::vector;
namespace lyx {
namespace support {
string const convert_brace_glob(string const & glob)
{
// Matches " *.{abc,def,ghi}", storing "*." as group 1 and
// "abc,def,ghi" as group 2.
static boost::regex const glob_re(" *([^ {]*)\\{([^ }]+)\\}");
// Matches "abc" and "abc,", storing "abc" as group 1.
static boost::regex const block_re("([^,}]+),?");
string pattern;
string::const_iterator it = glob.begin();
string::const_iterator const end = glob.end();
while (true) {
boost::match_results<string::const_iterator> what;
if (!boost::regex_search(it, end, what, glob_re)) {
// Ensure that no information is lost.
pattern += string(it, end);
break;
}
// Everything from the start of the input to
// the start of the match.
pattern += string(what[-1].first, what[-1].second);
// Given " *.{abc,def}", head == "*." and tail == "abc,def".
string const head = string(what[1].first, what[1].second);
string const tail = string(what[2].first, what[2].second);
// Split the ','-separated chunks of tail so that
// $head{$chunk1,$chunk2} becomes "$head$chunk1 $head$chunk2".
string const fmt = " " + head + "$1";
pattern += boost::regex_merge(tail, block_re, fmt);
// Increment the iterator to the end of the match.
it += std::distance(it, what[0].second);
}
return pattern;
}
vector<string> const glob(string const & pattern, int flags)
{
glob_t glob_buffer = {0, 0, 0, 0, 0, 0, 0, 0, 0};
glob(pattern.c_str(), flags, 0, &glob_buffer);
vector<string> const matches(glob_buffer.gl_pathv,
glob_buffer.gl_pathv +
glob_buffer.gl_pathc);
globfree(&glob_buffer);
return matches;
}
vector<string> const expand_globs(string const & mask,
std::string const & directory)
{
typedef boost::tokenizer<boost::char_separator<char> > Tokenizer;
boost::char_separator<char> const separator(" ");
// Given "<glob> <glob> ... *.{abc,def} <glob>", expand to
// "<glob> <glob> ... *.abc *.def <glob>"
string const expanded_glob = convert_brace_glob(mask);
Path p(directory);
// Split into individual globs and then call 'glob' on each one.
vector<string> matches;
Tokenizer const tokens(expanded_glob, separator);
Tokenizer::const_iterator it = tokens.begin();
Tokenizer::const_iterator const end = tokens.end();
for (; it != end; ++it) {
vector<string> const tmp = glob(*it);
matches.insert(matches.end(), tmp.begin(), tmp.end());
}
return matches;
}
} // namespace support
} // namespace lyx

52
src/support/globbing.h Normal file
View File

@ -0,0 +1,52 @@
// -*- C++ -*-
/**
* \file globbing.h
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Angus Leeming
*
* Full author contact details are available in file CREDITS.
*/
#ifndef GLOBBING_H
#define GLOBBING_H
#include <string>
#include <vector>
namespace lyx {
namespace support {
/** Given a string such as
* "<glob> <glob> ... *.{abc,def} <glob>",
* convert the csh-style brace expresions:
* "<glob> <glob> ... *.abc *.def <glob>".
* Requires no system support, so should work equally on Unix, Mac, Win32.
*/
std::string const convert_brace_glob(std::string const & glob);
/** A wrapper for the Posix function 'glob'.
* \param pattern the glob to be expanded. Eg "*.[Ch]".
* \param flags flags to be passed to the system function. See 'man glob'.
* \returns a vector of the files found to match \c pattern.
*/
std::vector<std::string> const glob(std::string const & pattern, int flags = 0);
/** Given a string "<glob> <glob> <glob>", expand each glob in turn.
* Any glob that cannot be expanded is ignored silently.
* Invokes \c expand_brace_glob and \c glob internally, so use only
* on systems supporting the Posix function 'glob'.
* \param mask the string "<glob> <glob> <glob>".
* \param directory (if not empty) the current working directory from
* which \c glob is invoked.
* \returns a vector of all matching file names.
*/
std::vector<std::string> const
expand_globs(std::string const & mask,
std::string const & directory = std::string());
} // namespace support
} // namespace lyx
#endif // NOT GLOBBING_H