GNU Octave  6.2.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
file-ops.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1996-2021 The Octave Project Developers
4 //
5 // See the file COPYRIGHT.md in the top-level directory of this
6 // distribution or <https://octave.org/copyright/>.
7 //
8 // This file is part of Octave.
9 //
10 // Octave is free software: you can redistribute it and/or modify it
11 // under the terms of the GNU General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // Octave is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 //
20 // You should have received a copy of the GNU General Public License
21 // along with Octave; see the file COPYING. If not, see
22 // <https://www.gnu.org/licenses/>.
23 //
24 ////////////////////////////////////////////////////////////////////////
25 
26 #if defined (HAVE_CONFIG_H)
27 # include "config.h"
28 #endif
29 
30 #include <cerrno>
31 #include <cstdio>
32 #include <cstdlib>
33 #include <cstring>
34 
35 #include <vector>
36 
37 #if defined (OCTAVE_USE_WINDOWS_API)
38 # include <windows.h>
39 # include <shlwapi.h>
40 #endif
41 
42 #if (defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM))
43 # include <algorithm>
44 # include "localcharset-wrapper.h"
45 # include "uniconv-wrappers.h"
46 #endif
47 
48 #include "areadlink-wrapper.h"
50 #include "dir-ops.h"
51 #include "file-ops.h"
52 #include "file-stat.h"
53 #include "gen-tempname-wrapper.h"
54 #include "lo-sysdep.h"
55 #include "oct-env.h"
56 #include "oct-locbuf.h"
57 #include "oct-passwd.h"
58 #include "quit.h"
59 #include "stat-wrappers.h"
60 #include "str-vec.h"
61 #include "unistd-wrappers.h"
62 
63 namespace octave
64 {
65  // The following tilde-expansion code was stolen and adapted from
66  // readline.
67 
68  // The default value of tilde_additional_prefixes. This is set to
69  // whitespace preceding a tilde so that simple programs which do not
70  // perform any word separation get desired behavior.
71  static const char *default_prefixes[] = { " ~", "\t~", ":~", nullptr };
72 
73  // The default value of tilde_additional_suffixes. This is set to
74  // whitespace or newline so that simple programs which do not perform
75  // any word separation get desired behavior.
76  static const char *default_suffixes[] = { " ", "\n", ":", nullptr };
77 
78  static size_t
79  tilde_find_prefix (const std::string& s, size_t& len)
80  {
81  len = 0;
82 
83  size_t s_len = s.length ();
84 
85  if (s_len == 0 || s[0] == '~')
86  return 0;
87 
89 
90  if (! prefixes.empty ())
91  {
92  for (size_t i = 0; i < s_len; i++)
93  {
94  for (int j = 0; j < prefixes.numel (); j++)
95  {
96  size_t pfx_len = prefixes[j].length ();
97 
98  if (prefixes[j] == s.substr (i, pfx_len))
99  {
100  len = pfx_len - 1;
101  return i + len;
102  }
103  }
104  }
105  }
106 
107  return s_len;
108  }
109 
110  // Find the end of a tilde expansion in S, and return the index
111  // of the character which ends the tilde definition.
112 
113  static size_t
114  tilde_find_suffix (const std::string& s)
115  {
116  size_t s_len = s.length ();
117 
119 
120  size_t i = 0;
121 
122  for ( ; i < s_len; i++)
123  {
124  if (sys::file_ops::is_dir_sep (s[i]))
125  break;
126 
127  if (! suffixes.empty ())
128  {
129  for (int j = 0; j < suffixes.numel (); j++)
130  {
131  size_t sfx_len = suffixes[j].length ();
132 
133  if (suffixes[j] == s.substr (i, sfx_len))
134  return i;
135  }
136  }
137  }
138 
139  return i;
140  }
141 
142  // Take FNAME and return the tilde prefix we want expanded.
143 
144  static std::string
145  isolate_tilde_prefix (const std::string& fname)
146  {
147  size_t f_len = fname.length ();
148 
149  size_t len = 1;
150 
151  while (len < f_len && ! sys::file_ops::is_dir_sep (fname[len]))
152  len++;
153 
154  return fname.substr (1, len);
155  }
156 
157  // Do the work of tilde expansion on FILENAME. FILENAME starts with a
158  // tilde.
159 
160  static std::string
161  tilde_expand_word (const std::string& filename)
162  {
163  size_t f_len = filename.length ();
164 
165  if (f_len == 0 || filename[0] != '~')
166  return std::string (filename);
167 
168  // A leading '~/' or a bare '~' is *always* translated to the value
169  // of $HOME or the home directory of the current user, regardless of
170  // any preexpansion hook.
171 
172  if (f_len == 1 || sys::file_ops::is_dir_sep (filename[1]))
173  return sys::env::get_home_directory () + filename.substr (1);
174 
175  std::string username = isolate_tilde_prefix (filename);
176 
177  size_t user_len = username.length ();
178 
179  std::string dirname;
180 
182  {
183  std::string expansion
185 
186  if (! expansion.empty ())
187  return expansion + filename.substr (user_len+1);
188  }
189 
190  // No preexpansion hook, or the preexpansion hook failed. Look in the
191  // password database.
192 
193  sys::password pw = sys::password::getpwnam (username);
194 
195  if (! pw)
196  {
197  // If the calling program has a special syntax for expanding tildes,
198  // and we couldn't find a standard expansion, then let them try.
199 
201  {
202  std::string expansion
204 
205  if (! expansion.empty ())
206  dirname = expansion + filename.substr (user_len+1);
207  }
208 
209  // If we don't have a failure hook, or if the failure hook did not
210  // expand the tilde, return a copy of what we were passed.
211 
212  if (dirname.empty ())
213  dirname = filename;
214  }
215  else
216  dirname = pw.dir () + filename.substr (user_len+1);
217 
218  return dirname;
219  }
220 
221  namespace sys
222  {
223  namespace file_ops
224  {
225  char dev_sep_char (void)
226  {
227 #if (defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM))
228  return ':';
229 #else
230  return 0;
231 #endif
232  }
233 
234  char dir_sep_char (void)
235  {
236 #if (defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM))
237  return '\\';
238 #else
239  return '/';
240 #endif
241  }
242 
243  std::string dir_sep_str (void)
244  {
245 #if (defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM))
246  return R"(\)";
247 #else
248  return "/";
249 #endif
250  }
251 
252  std::string dir_sep_chars (void)
253  {
254 #if defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM)
255  return R"(/\)";
256 #else
257  return dir_sep_str ();
258 #endif
259  }
260 
262 
264 
266 
268 
269  bool is_dev_sep (char c)
270  {
271 #if (defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM))
272  return c == dev_sep_char ();
273 #else
274  octave_unused_parameter (c);
275 
276  return false;
277 #endif
278  }
279 
280  bool is_dir_sep (char c)
281  {
282  std::string tmp = dir_sep_chars ();
283  return tmp.find (c) != std::string::npos;
284  }
285 
286  std::string tilde_expand (const std::string& name)
287  {
288  if (name.find ('~') == std::string::npos)
289  return std::string (name);
290  else
291  {
292  std::string result;
293 
294  size_t name_len = name.length ();
295 
296  // Scan through S expanding tildes as we come to them.
297 
298  size_t pos = 0;
299 
300  while (1)
301  {
302  if (pos > name_len)
303  break;
304 
305  size_t len;
306 
307  // Make START point to the tilde which starts the expansion.
308 
309  size_t start = tilde_find_prefix (name.substr (pos), len);
310 
311  result.append (name.substr (pos, start));
312 
313  // Advance STRING to the starting tilde.
314 
315  pos += start;
316 
317  // Make FINI be the index of one after the last character of the
318  // username.
319 
320  size_t fini = tilde_find_suffix (name.substr (pos));
321 
322  // If both START and FINI are zero, we are all done.
323 
324  if (! (start || fini))
325  break;
326 
327  // Expand the entire tilde word, and copy it into RESULT.
328 
329  std::string tilde_word = name.substr (pos, fini);
330 
331  pos += fini;
332 
333  std::string expansion = tilde_expand_word (tilde_word);
334 
335  result.append (expansion);
336  }
337 
338  return result;
339  }
340  }
341 
343  {
344  int n = names.numel ();
345 
347 
348  for (int i = 0; i < n; i++)
349  retval[i] = tilde_expand (names[i]);
350 
351  return retval;
352  }
353 
354  std::string concat (const std::string& dir, const std::string& file)
355  {
356  return dir.empty ()
357  ? file
358  : (is_dir_sep (dir.back ())
359  ? dir + file
360  : dir + dir_sep_char () + file);
361  }
362 
363  std::string dirname (const std::string& path)
364  {
365  size_t ipos = path.find_last_of (dir_sep_chars ());
366 
367  return (ipos != std::string::npos) ? path.substr (0, ipos) : "";
368  }
369 
370  std::string tail (const std::string& path)
371  {
372  size_t ipos = path.find_last_of (dir_sep_chars ());
373 
374  if (ipos != std::string::npos)
375  ipos++;
376  else
377  ipos = 0;
378 
379  return path.substr (ipos);
380  }
381 
382  std::string native_separator_path (const std::string& path)
383  {
384  std::string retval;
385 
386  if (dir_sep_char () == '/')
387  retval = path;
388  else
389  {
390  size_t n = path.length ();
391  for (size_t i = 0; i < n; i++)
392  {
393  if (path[i] == '/')
394  retval += dir_sep_char();
395  else
396  retval += path[i];
397  }
398  }
399 
400  return retval;
401  }
402  }
403 
404  int mkdir (const std::string& nm, mode_t md)
405  {
406  std::string msg;
407  return mkdir (nm, md, msg);
408  }
409 
410  int mkdir (const std::string& name, mode_t mode, std::string& msg)
411  {
412  msg = "";
413 
414  int status = octave_mkdir_wrapper (name.c_str (), mode);
415 
416  if (status < 0)
417  msg = std::strerror (errno);
418 
419  return status;
420  }
421 
422  int mkfifo (const std::string& nm, mode_t md)
423  {
424  std::string msg;
425  return mkfifo (nm, md, msg);
426  }
427 
428  int mkfifo (const std::string& name, mode_t mode, std::string& msg)
429  {
430  msg = "";
431 
432  int status = octave_mkfifo_wrapper (name.c_str (), mode);
433 
434  if (status < 0)
435  msg = std::strerror (errno);
436 
437  return status;
438  }
439 
440  int link (const std::string& old_name, const std::string& new_name)
441  {
442  std::string msg;
443  return link (old_name, new_name, msg);
444  }
445 
446  int link (const std::string& old_name, const std::string& new_name,
447  std::string& msg)
448  {
449  msg = "";
450 
451  int status = -1;
452 
453  status = octave_link_wrapper (old_name.c_str (), new_name.c_str ());
454 
455  if (status < 0)
456  msg = std::strerror (errno);
457 
458  return status;
459  }
460 
461  int symlink (const std::string& old_name, const std::string& new_name)
462  {
463  std::string msg;
464  return symlink (old_name, new_name, msg);
465  }
466 
467  int symlink (const std::string& old_name, const std::string& new_name,
468  std::string& msg)
469  {
470  msg = "";
471 
472  int status = -1;
473 
474  status = octave_symlink_wrapper (old_name.c_str (), new_name.c_str ());
475 
476  if (status < 0)
477  msg = std::strerror (errno);
478 
479  return status;
480  }
481 
482  int readlink (const std::string& path, std::string& result)
483  {
484  std::string msg;
485  return readlink (path, result, msg);
486  }
487 
488  int readlink (const std::string& path, std::string& result, std::string& msg)
489  {
490  int status = -1;
491 
492  msg = "";
493 
494  char *buf = octave_areadlink_wrapper (path.c_str ());
495 
496  if (! buf)
497  msg = std::strerror (errno);
498  else
499  {
500  result = buf;
501  ::free (buf);
502  status = 0;
503  }
504 
505  return status;
506  }
507 
508  int rename (const std::string& from, const std::string& to)
509  {
510  std::string msg;
511  return rename (from, to, msg);
512  }
513 
514  int rename (const std::string& from, const std::string& to,
515  std::string& msg)
516  {
517  int status = -1;
518 
519  msg = "";
520 
521 #if defined (OCTAVE_USE_WINDOWS_API)
522  std::wstring wfrom = u8_to_wstring (from);
523  std::wstring wto = u8_to_wstring (to);
524  status = _wrename (wfrom.c_str (), wto.c_str ());
525 #else
526  status = std::rename (from.c_str (), to.c_str ());
527 #endif
528 
529  if (status < 0)
530  msg = std::strerror (errno);
531 
532  return status;
533  }
534 
535  int rmdir (const std::string& name)
536  {
537  std::string msg;
538  return rmdir (name, msg);
539  }
540 
541  int rmdir (const std::string& name, std::string& msg)
542  {
543  msg = "";
544 
545  int status = -1;
546 
547  status = octave_rmdir_wrapper (name.c_str ());
548 
549  if (status < 0)
550  msg = std::strerror (errno);
551 
552  return status;
553  }
554 
555  // And a version that works recursively.
556 
557  int recursive_rmdir (const std::string& name)
558  {
559  std::string msg;
560  return recursive_rmdir (name, msg);
561  }
562 
563  int recursive_rmdir (const std::string& name, std::string& msg)
564  {
565  msg = "";
566 
567  int status = 0;
568 
569  string_vector dirlist;
570 
571  if (get_dirlist (name, dirlist, msg))
572  {
573  for (octave_idx_type i = 0; i < dirlist.numel (); i++)
574  {
575  octave_quit ();
576 
577  std::string nm = dirlist[i];
578 
579  // Skip current directory and parent.
580  if (nm == "." || nm == "..")
581  continue;
582 
583  std::string fullnm = name + file_ops::dir_sep_str () + nm;
584 
585  // Get info about the file. Don't follow links.
586  file_stat fs (fullnm, false);
587 
588  if (fs)
589  {
590  if (fs.is_dir ())
591  {
592  status = recursive_rmdir (fullnm, msg);
593 
594  if (status < 0)
595  break;
596  }
597  else
598  {
599  status = unlink (fullnm, msg);
600 
601  if (status < 0)
602  break;
603  }
604  }
605  else
606  {
607  msg = fs.error ();
608  break;
609  }
610  }
611 
612  if (status >= 0)
613  status = rmdir (name, msg);
614  }
615  else
616  status = -1;
617 
618  return status;
619  }
620 
621  int umask (mode_t mode)
622  {
623  return octave_umask_wrapper (mode);
624  }
625 
626  int unlink (const std::string& name)
627  {
628  std::string msg;
629  return unlink (name, msg);
630  }
631 
632  int unlink (const std::string& name, std::string& msg)
633  {
634  msg = "";
635 
636  int status = -1;
637 
638  status = octave_unlink_wrapper (name.c_str ());
639 
640  if (status < 0)
641  msg = std::strerror (errno);
642 
643  return status;
644  }
645 
646  std::string tempnam (const std::string& dir, const std::string& pfx)
647  {
648  std::string msg;
649  return tempnam (dir, pfx, msg);
650  }
651 
652  std::string tempnam (const std::string& dir, const std::string& pfx,
653  std::string& msg)
654  {
655  msg = "";
656 
657  std::string retval;
658 
659  // get dir path to use for template
660  std::string templatename;
661  if (dir.empty ())
662  templatename = env::get_temp_directory ();
663  else if (! file_stat (dir, false).is_dir ())
664  templatename = env::get_temp_directory ();
665  else
666  templatename = dir;
667 
668  // add dir sep char if it is not there
669  if (*templatename.rbegin () != file_ops::dir_sep_char ())
670  templatename += file_ops::dir_sep_char ();
671 
672  if (pfx.empty ())
673  templatename += "file";
674  else
675  templatename += pfx;
676 
677  // add the required XXXXXX for the template
678  templatename += "XXXXXX";
679 
680  // create and copy template to char array for call to gen_tempname
681  char tname [templatename.length () + 1];
682 
683  strcpy (tname, templatename.c_str ());
684 
685  if (octave_gen_tempname_wrapper (tname) == -1)
686  msg = std::strerror (errno);
687  else
688  retval = tname;
689 
690  return retval;
691  }
692 
693  std::string canonicalize_file_name (const std::string& name)
694  {
695  std::string msg;
696  return canonicalize_file_name (name, msg);
697  }
698 
699  std::string canonicalize_file_name (const std::string& name, std::string& msg)
700  {
701  msg = "";
702 
703  std::string retval;
704 
705 #if (defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM))
706  // On Windows, convert to locale charset before passing to
707  // canonicalize_file_name, and convert back to UTF-8 after that.
708 
709  // FIXME: This only allows non-ASCII characters in the file or path that
710  // can be encoded in the locale charset.
711  // Consider replacing this with std::filesystem::canonical once we allow
712  // using C++17.
713 
714  const char *locale = octave_locale_charset_wrapper ();
715  const uint8_t *name_u8 = reinterpret_cast<const uint8_t *>
716  (name.c_str ());
717  size_t length = 0;
718  char *name_locale = octave_u8_conv_to_encoding (locale, name_u8,
719  name.length () + 1,
720  &length);
721 
722  if (name_locale)
723  {
724  char *tmp_locale =
726  free (name_locale);
727 
728  if (tmp_locale)
729  {
730  char *tmp = reinterpret_cast<char *>
731  (octave_u8_conv_from_encoding (locale, tmp_locale,
732  strlen (tmp_locale),
733  &length));
734  free (tmp_locale);
735 
736  if (tmp)
737  {
738  retval = std::string (tmp, length);
739  free (tmp);
740  }
741  }
742  }
743 #else
744  char *tmp = octave_canonicalize_file_name_wrapper (name.c_str ());
745 
746  if (tmp)
747  {
748  retval = tmp;
749  free (tmp);
750  }
751 #endif
752 
753 #if (defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM))
754  // Canonical Windows file separator is backslash.
755  std::replace (retval.begin (), retval.end (), '/', '\\');
756 #endif
757 
758 #if defined (OCTAVE_USE_WINDOWS_API)
759  std::wstring w_tmp;
760  bool strip_marker = true;
761  if (retval.empty ())
762  {
763  // For UNC paths, take the input as is.
764  // Also translate forward slashes to backslashes.
765  std::string name_backsl = name;
766  std::replace (name_backsl.begin (), name_backsl.end (), '/', '\\');
767  if (name_backsl.compare (0, 2, "\\\\") == 0)
768  {
769  w_tmp = u8_to_wstring (name_backsl);
770  strip_marker = false;
771  wchar_t canon_path[MAX_PATH];
772  if (PathCanonicalizeW (canon_path, w_tmp.c_str ()))
773  w_tmp = std::wstring (canon_path);
774  }
775  }
776  else
777  w_tmp = L"\\\\?\\" + u8_to_wstring (retval);
778 
779  if (! w_tmp.empty ())
780  {
781  // Get a more canonical name wrt case and full names
782  // FIXME: To make this work on partitions that don't store short file
783  // names, use FindFirstFileW on each component of the path.
784  // Insufficient access permissions on parent folders might make this
785  // tricky.
786 
787  // Parts of the path that wouldn't fit into a short 8.3 file name are
788  // copied as is by GetLongPathNameW. To also get the correct case
789  // for these parts, first convert to short file names and than back
790  // to long.
791  wchar_t buffer[32767] = L"";
792  int w_len = GetShortPathNameW (w_tmp.c_str (), buffer, 32767);
793  w_len = GetLongPathNameW (buffer, buffer, 32767);
794 
795  if (! strip_marker)
796  retval = u8_from_wstring (std::wstring (buffer, w_len));
797  else if (w_len > 4)
798  retval = u8_from_wstring (std::wstring (buffer+4, w_len-4));
799 
800  // If root is a drive, use an upper case letter for the drive letter.
801  if (retval.length () > 1 && retval[1] == ':')
802  retval[0] = toupper (retval[0]);
803  }
804 #endif
805 
806  if (retval.empty ())
807  msg = std::strerror (errno);
808 
809  return retval;
810  }
811  }
812 }
char * octave_canonicalize_file_name_wrapper(const char *name)
std::string error(void) const
Definition: file-stat.h:149
bool is_dir(void) const
Definition: file-stat.cc:65
static std::string get_temp_directory(void)
Definition: oct-env.cc:154
static std::string get_home_directory(void)
Definition: oct-env.cc:147
std::string dir(void) const
Definition: oct-passwd.cc:99
static password getpwnam(const std::string &nm)
Definition: oct-passwd.cc:157
octave_idx_type numel(void) const
Definition: str-vec.h:100
bool empty(void) const
Definition: str-vec.h:77
int octave_gen_tempname_wrapper(char *tmpl)
QString path
QString name
const char * octave_locale_charset_wrapper(void)
octave_idx_type n
Definition: mx-inlines.cc:753
std::string dirname(const std::string &path)
Definition: file-ops.cc:363
string_vector tilde_additional_prefixes
Definition: file-ops.cc:265
string_vector tilde_additional_suffixes
Definition: file-ops.cc:267
char dev_sep_char(void)
Definition: file-ops.cc:225
char dir_sep_char(void)
Definition: file-ops.cc:234
tilde_expansion_hook tilde_expansion_preexpansion_hook
Definition: file-ops.cc:261
std::string(* tilde_expansion_hook)(const std::string &)
Definition: file-ops.h:43
std::string dir_sep_str(void)
Definition: file-ops.cc:243
bool is_dir_sep(char c)
Definition: file-ops.cc:280
std::string native_separator_path(const std::string &path)
Definition: file-ops.cc:382
std::string tilde_expand(const std::string &name)
Definition: file-ops.cc:286
tilde_expansion_hook tilde_expansion_failure_hook
Definition: file-ops.cc:263
std::string concat(const std::string &dir, const std::string &file)
Definition: file-ops.cc:354
bool is_dev_sep(char c)
Definition: file-ops.cc:269
std::string dir_sep_chars(void)
Definition: file-ops.cc:252
std::string tail(const std::string &path)
Definition: file-ops.cc:370
int link(const std::string &old_name, const std::string &new_name)
Definition: file-ops.cc:440
std::string tempnam(const std::string &dir, const std::string &pfx)
Definition: file-ops.cc:646
int readlink(const std::string &path, std::string &result)
Definition: file-ops.cc:482
std::string canonicalize_file_name(const std::string &name)
Definition: file-ops.cc:693
int rename(const std::string &from, const std::string &to)
Definition: file-ops.cc:508
int mkdir(const std::string &nm, mode_t md)
Definition: file-ops.cc:404
std::string u8_from_wstring(const std::wstring &wchar_string)
Definition: lo-sysdep.cc:490
int symlink(const std::string &old_name, const std::string &new_name)
Definition: file-ops.cc:461
int rmdir(const std::string &name)
Definition: file-ops.cc:535
int recursive_rmdir(const std::string &name)
Definition: file-ops.cc:557
int umask(mode_t mode)
Definition: file-ops.cc:621
int unlink(const std::string &name)
Definition: file-ops.cc:626
int mkfifo(const std::string &nm, mode_t md)
Definition: file-ops.cc:422
bool get_dirlist(const std::string &dirname, string_vector &dirlist, std::string &msg)
Definition: lo-sysdep.cc:101
std::wstring u8_to_wstring(const std::string &utf8_string)
Definition: lo-sysdep.cc:468
int rename(const std::string &from, const std::string &to, std::string &msg)
Definition: file-ops.cc:514
static std::string tilde_expand_word(const std::string &filename)
Definition: file-ops.cc:161
static const char * default_suffixes[]
Definition: file-ops.cc:76
static size_t tilde_find_suffix(const std::string &s)
Definition: file-ops.cc:114
static size_t tilde_find_prefix(const std::string &s, size_t &len)
Definition: file-ops.cc:79
static std::string isolate_tilde_prefix(const std::string &fname)
Definition: file-ops.cc:145
static const char * default_prefixes[]
Definition: file-ops.cc:71
T::size_type strlen(const typename T::value_type *str)
Definition: oct-string.cc:85
void free(void *)
octave_value::octave_value(const Array< char > &chm, char type) return retval
Definition: ov.cc:811
int octave_mkdir_wrapper(const char *name, mode_t mode)
Definition: stat-wrappers.c:49
int octave_mkfifo_wrapper(const char *name, mode_t mode)
Definition: stat-wrappers.c:63
int octave_umask_wrapper(mode_t mode)
Definition: stat-wrappers.c:69
uint8_t * octave_u8_conv_from_encoding(const char *fromcode, const char *src, size_t srclen, size_t *lengthp)
char * octave_u8_conv_to_encoding(const char *tocode, const uint8_t *src, size_t srclen, size_t *lengthp)
int octave_rmdir_wrapper(const char *nm)
int octave_unlink_wrapper(const char *nm)
int octave_symlink_wrapper(const char *nm1, const char *nm2)
int octave_link_wrapper(const char *nm1, const char *nm2)
F77_RET_T len
Definition: xerbla.cc:61