GNU Octave  4.2.1
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
oct-glob.cc
Go to the documentation of this file.
1 /*
2 
3 Copyright (C) 2010-2017 John W. Eaton
4 
5 This file is part of Octave.
6 
7 Octave is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 3 of the License, or (at your
10 option) any later version.
11 
12 Octave is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with Octave; see the file COPYING. If not, see
19 <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #if defined (HAVE_CONFIG_H)
24 # include "config.h"
25 #endif
26 
27 #include <algorithm>
28 #include <string>
29 
30 #include "glob-wrappers.h"
31 
32 #include "oct-glob.h"
33 #include "file-stat.h"
34 #include "unwind-prot.h"
35 
36 // These functions are defined here and not in glob_match.cc so that we
37 // can include the glob.h file from gnulib, which defines glob to
38 // be rpl_glob. If we include glob.h in glob_match.cc, then it
39 // transforms the glob_match::glob function to be glob_match::rpl_glob,
40 // which is not what we want...
41 
42 static bool
44 {
46 
47  return s.exists ();
48 }
49 
50 namespace octave
51 {
52  namespace sys
53  {
54  bool
55  fnmatch (const string_vector& pat, const std::string& str, int fnm_flags)
56  {
57  int npat = pat.numel ();
58 
59  const char *cstr = str.c_str ();
60 
61  for (int i = 0; i < npat; i++)
62  if (octave_fnmatch_wrapper (pat(i).c_str (), cstr, fnm_flags)
64  return true;
65 
66  return false;
67  }
68 
70  glob (const string_vector& pat)
71  {
73 
74  int npat = pat.numel ();
75 
76  int k = 0;
77 
79 
80  void *glob_info = octave_create_glob_info_struct ();
81 
82  frame.add_fcn (octave_destroy_glob_info_struct, glob_info);
83 
84  for (int i = 0; i < npat; i++)
85  {
86  std::string xpat = pat(i);
87 
88  if (! xpat.empty ())
89  {
90 #if (defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) \
91  && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM))
92  std::replace_if (xpat.begin (), xpat.end (),
93  std::bind2nd (std::equal_to<char> (), '\\'),
94  '/');
95 #endif
96 
97  int err = octave_glob_wrapper (xpat.c_str (),
99  glob_info);
100 
101  if (! err)
102  {
103  int n = octave_glob_num_matches (glob_info);
104 
105  const char * const *matches
106  = octave_glob_match_list (glob_info);
107 
108  // FIXME: we shouldn't have to check to see if
109  // a single match exists, but it seems that glob() won't
110  // check for us unless the pattern contains globbing
111  // characters. Hmm.
112 
113  if (n > 1
114  || (n == 1
115  && single_match_exists (std::string (matches[0]))))
116  {
117  retval.resize (k+n);
118 
119  for (int j = 0; j < n; j++)
120  {
121  std::string tmp = matches[j];
122 
123 #if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) \
124  && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM)
125  std::replace_if (tmp.begin (), tmp.end (),
126  std::bind2nd (std::equal_to<char> (),
127  '/'),
128  '\\');
129 #endif
130 
131  retval[k++] = tmp;
132  }
133  }
134 
135  octave_globfree_wrapper (glob_info);
136  }
137  }
138  }
139 
140  return retval.sort ();
141  }
142 
143  // Glob like Windows "dir". Treat only * and ? as wildcards,
144  // and "*.*" matches filenames even if they do not contain ".".
147  {
149 
150  int npat = pat.numel ();
151 
152  int k = 0;
153 
155 
156  void *glob_info = octave_create_glob_info_struct ();
157 
158  frame.add_fcn (octave_destroy_glob_info_struct, glob_info);
159 
160  for (int i = 0; i < npat; i++)
161  {
162  std::string xpat = pat(i);
163 
164  if (! xpat.empty ())
165  {
166  std::string escaped;
167  escaped.reserve (xpat.length ());
168 
169  for (size_t j = 0; j < xpat.length (); j++)
170  {
171 #if (defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) \
172  && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM))
173  if (xpat[j] == '\\')
174  escaped += '/';
175  else
176 #endif
177  {
178  if (xpat[j] == ']' || xpat[j] == '[')
179  escaped += '\\';
180 
181  escaped += xpat[j];
182  }
183  }
184 
185  // Replace trailing "*.*" by "*".
186  int len = escaped.length ();
187  if (len >= 3 && escaped.substr (len - 3) == "*.*")
188  escaped = escaped.substr (0, len - 2);
189 
190  int err = octave_glob_wrapper (escaped.c_str (),
192  glob_info);
193 
194  if (! err)
195  {
196  int n = octave_glob_num_matches (glob_info);
197 
198  const char * const *matches
199  = octave_glob_match_list (glob_info);
200 
201  // FIXME: we shouldn't have to check to see if
202  // a single match exists, but it seems that glob() won't
203  // check for us unless the pattern contains globbing
204  // characters. Hmm.
205 
206  if (n > 1
207  || (n == 1
208  && single_match_exists (std::string (matches[0]))))
209  {
210  retval.resize (k + n);
211 
212  for (int j = 0; j < n; j++)
213  {
214  std::string tmp = matches[j];
215 
216  std::string unescaped;
217  unescaped.reserve (tmp.length ());
218 
219  for (size_t m = 0; m < tmp.length (); m++)
220  {
221 #if (defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) \
222  && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM))
223  if (tmp[m] == '/')
224  unescaped += '\\';
225  else
226 #endif
227  {
228  if (tmp[m] == '\\'
229  && ++m == tmp.length ())
230  break;
231 
232  unescaped += tmp[m];
233  }
234  }
235 
236  retval[k++] = unescaped;
237  }
238  }
239 
240  octave_globfree_wrapper (glob_info);
241  }
242  }
243  }
244 
245  return retval.sort ();
246  }
247  }
248 }
void octave_globfree_wrapper(void *glob_info)
Definition: glob-wrappers.c:71
bool fnmatch(const string_vector &pat, const std::string &str, int fnm_flags)
Definition: oct-glob.cc:55
Octave interface to the compression and uncompression libraries.
Definition: aepbalance.cc:47
For example cd octave end example noindent changes the current working directory to file
Definition: dirfns.cc:120
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:363
int octave_glob_num_matches(void *glob_info)
Definition: glob-wrappers.c:59
for large enough k
Definition: lu.cc:606
int octave_fnmatch_wrapper(const char *pattern, const char *name, int flags)
Definition: glob-wrappers.c:83
s
Definition: file-io.cc:2682
void resize(octave_idx_type n, const std::string &rfv="")
Definition: str-vec.h:97
int octave_glob_nosort_wrapper(void)
Definition: glob-wrappers.c:77
int octave_glob_wrapper(const char *pattern, int flags, void *glob_info)
Definition: glob-wrappers.c:53
int octave_fnm_nomatch_wrapper(void)
Definition: glob-wrappers.c:89
char ** octave_glob_match_list(void *glob_info)
Definition: glob-wrappers.c:65
string_vector windows_glob(const string_vector &pat)
Definition: oct-glob.cc:146
void add_fcn(void(*fcn)(void))
nd deftypefn *octave_map m
Definition: ov-struct.cc:2058
std::string str
Definition: hash.cc:118
void * octave_create_glob_info_struct(void)
Definition: glob-wrappers.c:40
double tmp
Definition: data.cc:6300
octave_value retval
Definition: data.cc:6294
string_vector & sort(bool make_uniq=false)
Definition: str-vec.cc:74
bool exists(void) const
Definition: file-stat.h:144
void octave_destroy_glob_info_struct(void *glob_info)
Definition: glob-wrappers.c:47
octave::unwind_protect frame
Definition: graphics.cc:11584
=val(i)}if ode{val(i)}occurs in table i
Definition: lookup.cc:239
octave_idx_type length(void) const
Definition: oct-map.h:372
OCTAVE_EXPORT octave_value_list error nd deftypefn *const octave_scalar_map err
Definition: error.cc:1036
If this string is the system will ring the terminal sometimes it is useful to be able to print the original representation of the string
Definition: utils.cc:854
string_vector glob(const string_vector &pat)
Definition: oct-glob.cc:70
static bool single_match_exists(const std::string &file)
Definition: oct-glob.cc:43