]> git.lyx.org Git - features.git/commitdiff
Globbing.
authorAngus Leeming <leeming@lyx.org>
Mon, 5 Jan 2004 16:49:38 +0000 (16:49 +0000)
committerAngus Leeming <leeming@lyx.org>
Mon, 5 Jan 2004 16:49:38 +0000 (16:49 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@8300 a592a061-630c-0410-9148-cb99ea01b6c8

lib/ChangeLog
lib/external_templates
src/frontends/qt2/ChangeLog
src/frontends/qt2/FileDialog_private.C
src/frontends/xforms/ChangeLog
src/frontends/xforms/FormFiledialog.C
src/support/ChangeLog
src/support/Makefile.am
src/support/globbing.C [new file with mode: 0644]
src/support/globbing.h [new file with mode: 0644]

index 4b16454b5f9cf4c603b524bbfad7b1a5580c5c19..3e2e07e2c64a889d4efa510abea19d8bfedfba36 100644 (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>
 
        * layouts/g-brief2.layout: more spelling fixes
index cbc3a755707360cfdbdb90a86fe7277f0c64fedf..211c05b5b2297f45047dc2f4be2fc1cc257d1581 100644 (file)
@@ -38,18 +38,10 @@ Template RasterImage
        GuiName "Bitmap: $$Basename"
        HelpText
                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.
        HelpTextEnd
        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"
        AutomaticProduction true
        Transform Rotate
@@ -188,7 +180,7 @@ TemplateEnd
 Template Date
        GuiName "Date"
        HelpText
-               Todays date.
+               Today's date.
                Read 'info date' for more information.
        HelpTextEnd
        InputFormat date
index 0ee97a65ece008088539eb172916ea8ab55b3f51..0f19da702cb711e926f159896dd7951ed3756237 100644 (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>
 
        * ui/QGraphicsDialogBase.ui: add missing signal/slot (bug 1469).
index 785fe5edc9d3306138e75406c42cb6723dd0f623..01acfdf1fd4086d7f637e51c9d8f31a8b5816c95 100644 (file)
 #include "FileDialog_private.h"
 #include "qt_helpers.h"
 
+#include "support/globbing.h"
 #include "support/lstrings.h"
 
 #include <qapplication.h>
 #include <qtoolbutton.h>
 
+using lyx::support::convert_brace_glob;
 using lyx::support::split;
 
 using std::string;
@@ -45,7 +47,7 @@ string const getLabel(string const & str) {
 LyXFileDialog::LyXFileDialog(string const & p, string const & m,
                             string const & t,
                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),
          b1_(0), b2_(0)
 {
index 5484e682252e2ab2d35d2f2a584a0f05ea4bbbca..39c431c1a37596e4120d04e596c5cbecda6ff704 100644 (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>
 
        * forms/fdfix.sh: no need to assume that the fdfix files are in
index 3dd5faec70aee2af97119932ae77791ca3185f01..4c7b744a588ad41f1db73ece17729d95997b9f37 100644 (file)
 #include "frontends/Dialogs.h"
 
 #include "support/FileInfo.h"
-#include "support/lyxlib.h"
+#include "support/filetools.h"
+#include "support/globbing.h"
 #include "support/lstrings.h"
+#include "support/lyxlib.h"
 #include "support/tostr.h"
-#include "support/filetools.h"
 
 #include "lyx_forms.h"
 
@@ -72,6 +73,7 @@ using std::max;
 using std::sort;
 using std::string;
 using std::map;
+using std::vector;
 
 
 namespace {
@@ -198,32 +200,6 @@ int FileDialog::Private::minw_ = 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
 void FileDialog::Private::Reread()
 {
@@ -263,9 +239,9 @@ void FileDialog::Private::Reread()
                ++depth_;
        }
 
-       // Parses all entries of the given subdirectory
-       boost::regex const mask_regex = glob2regex(mask_);
-
+       vector<string> const glob_matches =
+               lyx::support::expand_globs(mask_, directory_);
+       
        time_t curTime = time(0);
        rewinddir(dir);
        while (dirent * entry = readdir(dir)) {
@@ -331,7 +307,7 @@ void FileDialog::Private::Reread()
                                buffer += Link;
 
                                // 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
                                // as the type of Link (which could again be a
                                // link). Is that intended?
@@ -349,7 +325,10 @@ void FileDialog::Private::Reread()
                    || fileInfo.isChar()
                    || fileInfo.isBlock()
                    || 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;
                } else if (!(isDir = fileInfo.isDir()))
                        continue;
index 0d342db2e95eb9f42d1e9ad804f8b6f845d5b37d..49d71a1316da522285a1a3e4049feadb19cebe32 100644 (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>
 
        * putenv.C: allocate the string before putting it into the
index 575e74faf1c05cf54e8085011cb415b37d7aa539..7098ba6a3a3784edb05dd27d3f233589e196634f 100644 (file)
@@ -39,6 +39,8 @@ libsupport_la_SOURCES = \
        forkedcontr.C \
        forkedcontr.h \
        getcwd.C \
+       globbing.C \
+       globbing.h \
        $(COMPRESSION) kill.C \
        limited_stack.h \
        lstrings.C \
diff --git a/src/support/globbing.C b/src/support/globbing.C
new file mode 100644 (file)
index 0000000..fa6a074
--- /dev/null
@@ -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
diff --git a/src/support/globbing.h b/src/support/globbing.h
new file mode 100644 (file)
index 0000000..809aae6
--- /dev/null
@@ -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