diff liboctave/oct-glob.cc @ 10138:805a83ecd3da

avoid conflict between glob.h definition of glob and glob_match::glob function
author John W. Eaton <jwe@octave.org>
date Wed, 20 Jan 2010 01:57:41 -0500
parents
children 07ebe522dac2
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/liboctave/oct-glob.cc	Wed Jan 20 01:57:41 2010 -0500
@@ -0,0 +1,110 @@
+/*
+
+Copyright (C) 2010 John W. Eaton
+
+This file is part of Octave.
+
+Octave is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3 of the License, or (at your
+option) any later version.
+
+Octave is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string>
+
+#include <fnmatch.h>
+#include <glob.h>
+
+#include "oct-glob.h"
+#include "file-stat.h"
+
+// These functions are defined here and not in glob_match.cc so that we
+// can include the glob.h file from gnulib, which defines glob to
+// be rpl_glob.  If we include glob.h in glob_match.cc, then it
+// transforms the glob_match::glob function to be glob_match::rpl_glob,
+// which is not what we want...
+
+static bool
+single_match_exists (const std::string& file)
+{
+  file_stat s (file);
+
+  return s.exists ();
+}
+
+bool
+octave_fnmatch (const string_vector& pat, const std::string& str,
+                int fnmatch_flags)
+{
+  int npat = pat.length ();
+
+  const char *cstr = str.c_str ();
+
+  for (int i = 0; i < npat; i++)
+    if (fnmatch (pat(i).c_str (), cstr, fnmatch_flags) != FNM_NOMATCH)
+      return true;
+
+  return false;
+}
+
+string_vector
+octave_glob (const string_vector& pat)
+{
+  string_vector retval;
+
+  int npat = pat.length ();
+
+  int k = 0;
+
+  for (int i = 0; i < npat; i++)
+    {
+      std::string xpat = pat(i);
+
+      if (! xpat.empty ())
+	{
+	  glob_t glob_info;
+
+	  int err = ::glob (xpat.c_str (), GLOB_NOSORT, 0, &glob_info);
+
+	  if (! err)
+	    {
+	      int n = glob_info.gl_pathc;
+
+	      const char * const *matches = glob_info.gl_pathv;
+
+	      // FIXME -- we shouldn't have to check to see if
+	      // a single match exists, but it seems that glob() won't
+	      // check for us unless the pattern contains globbing
+	      // characters.  Hmm.
+
+	      if (n > 1
+		  || (n == 1
+		      && single_match_exists (std::string (matches[0]))))
+		{
+		  retval.resize (k+n);
+
+		  for (int j = 0; j < n; j++)
+		    retval[k++] = matches[j];
+		}
+
+	      globfree (&glob_info);
+	    }
+	}
+    }
+
+  return retval.sort ();
+}