oct-glob.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 2010-2012 John W. Eaton
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 #ifdef HAVE_CONFIG_H
00024 #include <config.h>
00025 #endif
00026 
00027 #include <algorithm>
00028 #include <string>
00029 
00030 #include <fnmatch.h>
00031 #include <glob.h>
00032 
00033 #include "oct-glob.h"
00034 #include "file-stat.h"
00035 
00036 // These functions are defined here and not in glob_match.cc so that we
00037 // can include the glob.h file from gnulib, which defines glob to
00038 // be rpl_glob.  If we include glob.h in glob_match.cc, then it
00039 // transforms the glob_match::glob function to be glob_match::rpl_glob,
00040 // which is not what we want...
00041 
00042 static bool
00043 single_match_exists (const std::string& file)
00044 {
00045   file_stat s (file);
00046 
00047   return s.exists ();
00048 }
00049 
00050 bool
00051 octave_fnmatch (const string_vector& pat, const std::string& str,
00052                 int fnmatch_flags)
00053 {
00054   int npat = pat.length ();
00055 
00056   const char *cstr = str.c_str ();
00057 
00058   for (int i = 0; i < npat; i++)
00059     if (fnmatch (pat(i).c_str (), cstr, fnmatch_flags) != FNM_NOMATCH)
00060       return true;
00061 
00062   return false;
00063 }
00064 
00065 string_vector
00066 octave_glob (const string_vector& pat)
00067 {
00068   string_vector retval;
00069 
00070   int npat = pat.length ();
00071 
00072   int k = 0;
00073 
00074   for (int i = 0; i < npat; i++)
00075     {
00076       std::string xpat = pat(i);
00077 
00078       if (! xpat.empty ())
00079         {
00080           glob_t glob_info;
00081 
00082 #if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) \
00083           && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM)
00084               std::replace_if (xpat.begin (), xpat.end (),
00085                                std::bind2nd (std::equal_to<char> (), '\\'),
00086                                '/');
00087 #endif
00088 
00089           int err = gnulib::glob (xpat.c_str (), GLOB_NOSORT, 0, &glob_info);
00090 
00091           if (! err)
00092             {
00093               int n = glob_info.gl_pathc;
00094 
00095               const char * const *matches = glob_info.gl_pathv;
00096 
00097               // FIXME -- we shouldn't have to check to see if
00098               // a single match exists, but it seems that glob() won't
00099               // check for us unless the pattern contains globbing
00100               // characters.  Hmm.
00101 
00102               if (n > 1
00103                   || (n == 1
00104                       && single_match_exists (std::string (matches[0]))))
00105                 {
00106                   retval.resize (k+n);
00107 
00108                   for (int j = 0; j < n; j++)
00109                     {
00110                       std::string tmp = matches[j];
00111 
00112 #if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) \
00113                       && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM)
00114                           std::replace_if (tmp.begin (), tmp.end (),
00115                                            std::bind2nd (std::equal_to<char> (),
00116                                                          '/'),
00117                                            '\\');
00118 #endif
00119 
00120                       retval[k++] = tmp;
00121                     }
00122                 }
00123 
00124               gnulib::globfree (&glob_info);
00125             }
00126         }
00127     }
00128 
00129   return retval.sort ();
00130 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines