GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
dirfns.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1994-2024 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 <cstddef>
33 #include <cstdlib>
34 #include <cstring>
35 
36 #include <sstream>
37 #include <string>
38 
39 #include "file-ops.h"
40 #include "file-stat.h"
41 #include "glob-match.h"
42 #include "lo-sysdep.h"
43 #include "oct-env.h"
44 #include "oct-glob.h"
45 #include "pathsearch.h"
46 #include "str-vec.h"
47 
48 #include "Cell.h"
49 #include "defun.h"
50 #include "dir-ops.h"
51 #include "error.h"
52 #include "errwarn.h"
53 #include "event-manager.h"
54 #include "input.h"
55 #include "load-path.h"
56 #include "octave.h"
57 #include "ovl.h"
58 #include "pager.h"
59 #include "procstream.h"
60 #include "sysdep.h"
61 #include "interpreter.h"
62 #include "unwind-prot.h"
63 #include "utils.h"
64 #include "variables.h"
65 
67 
68 // TRUE means we ask for confirmation before recursively removing a
69 // directory tree.
70 static bool Vconfirm_recursive_rmdir = true;
71 
72 DEFMETHOD (cd, interp, args, nargout,
73  doc: /* -*- texinfo -*-
74 @deftypefn {} {} cd @var{dir}
75 @deftypefnx {} {} cd
76 @deftypefnx {} {@var{old_dir} =} cd
77 @deftypefnx {} {@var{old_dir} =} cd (@var{dir})
78 @deftypefnx {} {} chdir @dots{}
79 Change the current working directory to @var{dir}.
80 
81 If called with no input or output arguments, the current directory is
82 changed to the user's home directory (@qcode{"~"}).
83 
84 For example,
85 
86 @example
87 cd ~/octave
88 @end example
89 
90 @noindent
91 changes the current working directory to @file{~/octave}. If the
92 directory does not exist, an error message is printed and the working
93 directory is not changed.
94 
95 Programming Note: @code{chdir} is an alias for @code{cd} and can be used with
96 all of the same calling formats.
97 
98 Compatibility Note: When called with no arguments, @sc{matlab} prints the
99 present working directory rather than changing to the user's home directory.
100 @seealso{pwd, mkdir, rmdir, dir, ls}
101 @end deftypefn */)
102 {
103  int nargin = args.length ();
104 
105  if (nargin > 1)
106  print_usage ();
107 
108  octave_value_list retval;
109 
110  if (nargout > 0)
111  retval = octave_value (sys::env::get_current_directory ());
112 
113  if (nargin == 1)
114  {
115  std::string dirname = args(0).xstring_value ("cd: DIR must be a string");
116 
117  if (! dirname.empty ())
118  interp.chdir (dirname);
119  }
120  else if (nargout == 0)
121  {
122  std::string home_dir = sys::env::get_home_directory ();
123 
124  if (! home_dir.empty ())
125  interp.chdir (home_dir);
126  }
127 
128  return retval;
129 }
130 
131 DEFALIAS (chdir, cd);
132 
133 DEFUN (pwd, , ,
134  doc: /* -*- texinfo -*-
135 @deftypefn {} {@var{dir} =} pwd ()
136 Return the current working directory.
137 @seealso{cd, dir, ls, mkdir, rmdir}
138 @end deftypefn */)
139 {
140  return ovl (sys::env::get_current_directory ());
141 }
142 
143 DEFUN (readdir, args, ,
144  doc: /* -*- texinfo -*-
145 @deftypefn {} {@var{files} =} readdir (@var{dir})
146 @deftypefnx {} {[@var{files}, @var{err}, @var{msg}] =} readdir (@var{dir})
147 Return the names of files in the directory @var{dir} as a cell array of
148 strings.
149 
150 If an error occurs, return an empty cell array in @var{files}.
151 If successful, @var{err} is 0 and @var{msg} is an empty string.
152 Otherwise, @var{err} is nonzero and @var{msg} contains a system-dependent
153 error message.
154 @seealso{ls, dir, glob, what}
155 @end deftypefn */)
156 {
157  if (args.length () != 1)
158  print_usage ();
159 
160  std::string dirname = args(0).xstring_value ("readdir: DIR must be a string");
161 
162  octave_value_list retval = ovl (Cell (), -1.0, "");
163 
165 
166  string_vector dirlist;
167  std::string msg;
168 
169  if (sys::get_dirlist (dirname, dirlist, msg))
170  {
171  retval(0) = Cell (dirlist.sort ());
172  retval(1) = 0.0;
173  }
174  else
175  retval(2) = msg;
176 
177  return retval;
178 }
179 
180 // FIXME: should maybe also allow second arg to specify mode?
181 // OTOH, that might cause trouble with compatibility later...
182 
183 DEFUN (__mkdir__, args, ,
184  doc: /* -*- texinfo -*-
185 @deftypefn {} {} __mkdir__ (@var{dir})
186 @deftypefnx {} {} __mkdir__ (@var{parent}, @var{dir})
187 @deftypefnx {} {[@var{status}, @var{msg}, @var{msgid}] =} __mkdir__ (@dots{})
188 Internal function called by mkdir.m.
189 @seealso{mkdir, rmdir, pwd, cd, umask}
190 @end deftypefn */)
191 {
192  int nargin = args.length ();
193 
194  if (nargin < 1 || nargin > 2)
195  print_usage ("mkdir");
196 
197  std::string dirname;
198 
199  if (nargin == 2)
200  {
201  std::string parent = args(0).xstring_value ("mkdir: PARENT must be a string");
202  std::string dir = args(1).xstring_value ("mkdir: DIR must be a string");
203 
204  dirname = sys::file_ops::concat (parent, dir);
205  }
206  else if (nargin == 1)
207  dirname = args(0).xstring_value ("mkdir: DIR must be a string");
208 
210 
211  if (sys::dir_exists (dirname))
212  {
213  // For Matlab compatibility, return true when directory already exists.
214  return ovl (true, "directory exists", "mkdir");
215  }
216  else
217  {
218  std::string msg;
219 
220  int status = sys::mkdir (dirname, 0777, msg);
221 
222  if (status < 0)
223  return ovl (false, msg, "mkdir");
224  else
225  return ovl (true, "", "");
226  }
227 }
228 
229 DEFMETHODX ("rmdir", Frmdir, interp, args, nargout,
230  doc: /* -*- texinfo -*-
231 @deftypefn {} {} rmdir @var{dir}
232 @deftypefnx {} {} rmdir (@var{dir}, "s")
233 @deftypefnx {} {[@var{status}, @var{msg}, @var{msgid}] =} rmdir (@dots{})
234 Remove the directory named @var{dir}.
235 
236 If the optional second parameter is supplied with value @qcode{"s"},
237 recursively remove all subdirectories as well.
238 
239 If successful, @var{status} is logical 1, and @var{msg}, @var{msgid} are empty
240 character strings (""). Otherwise, @var{status} is logical 0, @var{msg}
241 contains a system-dependent error message, and @var{msgid} contains a unique
242 message identifier.
243 
244 @seealso{mkdir, confirm_recursive_rmdir, pwd}
245 @end deftypefn */)
246 {
247  int nargin = args.length ();
248 
249  if (nargin < 1 || nargin > 2)
250  print_usage ();
251 
252  std::string dirname = args(0).xstring_value ("rmdir: DIR must be a string");
253 
254  std::string fulldir = sys::file_ops::tilde_expand (dirname);
255  octave_value_list retval;
256  int status = -1;
257  std::string msg;
258 
259  event_manager& evmgr = interp.get_event_manager ();
260 
261  if (nargin == 2)
262  {
263  if (args(1).string_value () != "s")
264  error (R"(rmdir: second argument must be "s" for recursive removal)");
265 
266  bool doit = true;
267 
268  if (interp.interactive ()
270  && Vconfirm_recursive_rmdir)
271  {
272  input_system& input_sys = interp.get_input_system ();
273 
274  std::string prompt = "remove entire contents of " + fulldir + "? ";
275 
276  doit = input_sys.yes_or_no (prompt);
277  }
278 
279  if (doit)
280  {
281  evmgr.file_remove (fulldir, "");
282  status = sys::recursive_rmdir (fulldir, msg);
283  }
284  }
285  else
286  {
287  evmgr.file_remove (fulldir, "");
288  status = sys::rmdir (fulldir, msg);
289  }
290 
291  evmgr.file_renamed (status >= 0);
292 
293  if (nargout == 0)
294  {
295  if (status < 0)
296  error ("rmdir: operation failed: %s", msg.c_str ());
297  }
298  else
299  {
300  if (status < 0)
301  retval = ovl (false, msg, "rmdir");
302  else
303  retval = ovl (true, "", "");
304  }
305 
306  return retval;
307 }
308 
309 DEFUNX ("link", Flink, args, nargout,
310  doc: /* -*- texinfo -*-
311 @deftypefn {} {} link @var{old} @var{new}
312 @deftypefnx {} {[@var{status}, @var{msg}] =} link (@var{old}, @var{new})
313 Create a new link (also known as a hard link) to an existing file.
314 
315 If successful, @var{status} is 0 and @var{msg} is an empty string.
316 Otherwise, @var{status} is -1 and @var{msg} contains a system-dependent
317 error message.
318 @seealso{symlink, unlink, readlink, lstat}
319 @end deftypefn */)
320 {
321  if (args.length () != 2)
322  print_usage ();
323 
324  std::string from = args(0).xstring_value ("link: OLD must be a string");
325  std::string to = args(1).xstring_value ("link: NEW must be a string");
326 
327  from = sys::file_ops::tilde_expand (from);
328  to = sys::file_ops::tilde_expand (to);
329 
330  octave_value_list retval;
331  std::string msg;
332 
333  int status = sys::link (from, to, msg);
334 
335  if (nargout == 0)
336  {
337  if (status < 0)
338  error ("link: operation failed: %s", msg.c_str ());
339  }
340  else
341  {
342  if (status < 0)
343  retval = ovl (-1.0, msg);
344  else
345  retval = ovl (0.0, "");
346  }
347 
348  return retval;
349 }
350 
351 DEFUNX ("symlink", Fsymlink, args, nargout,
352  doc: /* -*- texinfo -*-
353 @deftypefn {} {} symlink @var{old} @var{new}
354 @deftypefnx {} {[@var{status}, @var{msg}] =} symlink (@var{old}, @var{new})
355 Create a symbolic link @var{new} which contains the string @var{old}.
356 
357 If successful, @var{status} is 0 and @var{msg} is an empty string.
358 Otherwise, @var{status} is -1 and @var{msg} contains a system-dependent
359 error message.
360 @seealso{link, unlink, readlink, lstat}
361 @end deftypefn */)
362 {
363  if (args.length () != 2)
364  print_usage ();
365 
366  std::string from = args(0).xstring_value ("symlink: OLD must be a string");
367  std::string to = args(1).xstring_value ("symlink: NEW must be a string");
368 
369  from = sys::file_ops::tilde_expand (from);
370  to = sys::file_ops::tilde_expand (to);
371 
372  octave_value_list retval;
373  std::string msg;
374 
375  int status = sys::symlink (from, to, msg);
376 
377  if (nargout == 0)
378  {
379  if (status < 0)
380  error ("symlink: operation failed: %s", msg.c_str ());
381  }
382  else
383  {
384  if (status < 0)
385  retval = ovl (-1.0, msg);
386  else
387  retval = ovl (0.0, "");
388  }
389 
390  return retval;
391 }
392 
393 DEFUNX ("readlink", Freadlink, args, ,
394  doc: /* -*- texinfo -*-
395 @deftypefn {} {@var{result} =} readlink @var{symlink}
396 @deftypefnx {} {[@var{result}, @var{err}, @var{msg}] =} readlink (@var{symlink})
397 Read the value of the symbolic link @var{symlink}.
398 
399 If successful, @var{result} contains the contents of the symbolic link
400 @var{symlink}, @var{err} is 0, and @var{msg} is an empty string.
401 Otherwise, @var{err} is nonzero and @var{msg} contains a system-dependent
402 error message.
403 @seealso{lstat, symlink, link, unlink, delete}
404 @end deftypefn */)
405 {
406  if (args.length () != 1)
407  print_usage ();
408 
409  std::string symlink = args(0).xstring_value ("readlink: SYMLINK must be a string");
410 
412 
413  std::string result, msg;
414 
415  int status = sys::readlink (symlink, result, msg);
416 
417  if (status < 0)
418  return ovl ("", -1.0, msg);
419  else
420  return ovl (result, status, "");
421 }
422 
423 DEFMETHODX ("rename", Frename, interp, args, nargout,
424  doc: /* -*- texinfo -*-
425 @deftypefn {} {} rename @var{old} @var{new}
426 @deftypefnx {} {[@var{status}, @var{msg}] =} rename (@var{old}, @var{new})
427 Change the name of file @var{old} to @var{new}.
428 
429 If successful, @var{status} is 0 and @var{msg} is an empty string.
430 Otherwise, @var{status} is -1 and @var{msg} contains a system-dependent
431 error message.
432 @seealso{movefile, copyfile, ls, dir}
433 @end deftypefn */)
434 {
435  if (args.length () != 2)
436  print_usage ();
437 
438  std::string from = args(0).xstring_value ("rename: OLD must be a string");
439  std::string to = args(1).xstring_value ("rename: NEW must be a string");
440 
441  from = sys::file_ops::tilde_expand (from);
442  to = sys::file_ops::tilde_expand (to);
443 
444  octave_value_list retval;
445  std::string msg;
446 
447  event_manager& evmgr = interp.get_event_manager ();
448 
449  evmgr.file_remove (from, to);
450 
451  int status = sys::rename (from, to, msg);
452 
453  evmgr.file_renamed (status >= 0);
454 
455  if (nargout == 0)
456  {
457  if (status < 0)
458  error ("rename: operation failed: %s", msg.c_str ());
459  }
460  else
461  {
462  if (status < 0)
463  retval = ovl (-1.0, msg);
464  else
465  retval = ovl (0.0, "");
466  }
467 
468  return retval;
469 }
470 
471 DEFUN (glob, args, ,
472  doc: /* -*- texinfo -*-
473 @deftypefn {} {@var{cstr} =} glob (@var{pattern})
474 Given an array of pattern strings (as a char array or a cell array) in
475 @var{pattern}, return a cell array of filenames that match any of
476 them, or an empty cell array if no patterns match.
477 
478 The pattern strings are interpreted as filename globbing patterns (as they
479 are used by Unix shells).
480 
481 Within a pattern
482 
483 @table @code
484 @item *
485 matches any string, including the null string,
486 
487 @item ?
488 matches any single character, and
489 
490 @item [@dots{}]
491 matches any of the enclosed characters.
492 @end table
493 
494 Tilde expansion is performed on each of the patterns before looking for
495 matching filenames. For example:
496 
497 @example
498 ls
499  @result{}
500  file1 file2 file3 myfile1 myfile1b
501 glob ("*file1")
502  @result{}
503  @{
504  [1,1] = file1
505  [2,1] = myfile1
506  @}
507 glob ("myfile?")
508  @result{}
509  @{
510  [1,1] = myfile1
511  @}
512 glob ("file[12]")
513  @result{}
514  @{
515  [1,1] = file1
516  [2,1] = file2
517  @}
518 @end example
519 
520 Note: On Windows, patterns that contain non-ASCII characters are not
521 supported.
522 
523 @seealso{ls, dir, readdir, what}
524 @end deftypefn */)
525 {
526  if (args.length () != 1)
527  print_usage ();
528 
529  string_vector pat
530  = args(0).xstring_vector_value ("glob: PATTERN must be a string");
531 
532  glob_match pattern (sys::file_ops::tilde_expand (pat));
533 
534  return ovl (Cell (pattern.glob ()));
535 }
536 
537 /*
538 %!test
539 %! tmpdir = tempname ();
540 %! filename = {"file1", "file2", "file3", "myfile1", "myfile1b"};
541 %! if (mkdir (tmpdir))
542 %! cwd = pwd ();
543 %! cd (tmpdir);
544 %! if (strcmp (canonicalize_file_name (pwd), canonicalize_file_name (tmpdir)))
545 %! a = 0;
546 %! for n = 1:5
547 %! save (filename{n}, "a");
548 %! endfor
549 %! else
550 %! sts = rmdir (tmpdir);
551 %! error ("Couldn't change to temporary directory");
552 %! endif
553 %! else
554 %! error ("Couldn't create temporary directory");
555 %! endif
556 %! result1 = glob ("*file1");
557 %! result2 = glob ("myfile?");
558 %! result3 = glob ("file[12]");
559 %! for n = 1:5
560 %! delete (filename{n});
561 %! endfor
562 %! cd (cwd);
563 %! sts = rmdir (tmpdir);
564 %! assert (result1, {"file1"; "myfile1"});
565 %! assert (result2, {"myfile1"});
566 %! assert (result3, {"file1"; "file2"});
567 
568 ## Check backslash handling on Windows
569 %!testif ; ispc ()
570 %! win_dir = getenv ("WINDIR");
571 %! assert (glob (win_dir), {win_dir});
572 %! assert (glob ([win_dir, filesep]), {[win_dir, filesep]});
573 %! win_dir2 = strrep(win_dir, filesep, '/');
574 %! assert (glob (win_dir2), {win_dir});
575 %! assert (glob ([win_dir2, '/']), {[win_dir, filesep]});
576 */
577 
578 DEFUN (__wglob__, args, ,
579  doc: /* -*- texinfo -*-
580 @deftypefn {} {@var{cstr} =} __wglob__ (@var{pattern})
581 Windows-like glob for dir.
582 
583 Given an array of pattern strings (as a char array or a cell array) in
584 @var{pattern}, return a cell array of filenames that match any of
585 them, or an empty cell array if no patterns match.
586 
587 The pattern strings are interpreted as filename globbing patterns
588 (roughly as they are used by Windows dir).
589 
590 Within a pattern
591 
592 @table @code
593 @item *
594 matches any string, including the null string,
595 
596 @item ?
597 matches any single character, and
598 
599 @item *.*
600 matches any string, even if no . is present.
601 @end table
602 
603 Tilde expansion is performed on each of the patterns before looking for
604 matching filenames. For example:
605 
606 @example
607 ls
608  @result{}
609  file1 file2 file3 myfile1 myfile1b
610 glob ("*file1")
611  @result{}
612  @{
613  [1,1] = file1
614  [2,1] = myfile1
615  @}
616 glob ("myfile?")
617  @result{}
618  @{
619  [1,1] = myfile1
620  @}
621 glob ("*.*")
622  @result{}
623  @{
624  [1,1] = file1
625  [2,1] = file2
626  [3,1] = file3
627  [4,1] = myfile1
628  [5,1] = myfile1b
629  @}
630 @end example
631 @seealso{glob, dir}
632 @end deftypefn */)
633 {
634  if (args.length () == 0)
635  return ovl ();
636 
637  string_vector pat = args(0).string_vector_value ();
638 
640 
641  return ovl (Cell (sys::windows_glob (pattern)));
642 }
643 
644 /*
645 %!test <*62414>
646 %! ## get name of current directory and one file in it
647 %! [~, curr_dir, ext] = fileparts (pwd ());
648 %! curr_dir = [curr_dir, ext];
649 %! files = dir ();
650 %! if (numel (files) < 3)
651 %! return;
652 %! endif
653 %! ## check some patterns including "." and ".."
654 %! file_in_pwd = files(3).name;
655 %! assert (__wglob__ (file_in_pwd), {file_in_pwd});
656 %! glob_pattern = fullfile (".", file_in_pwd);
657 %! assert (__wglob__ (glob_pattern), {glob_pattern});
658 %! glob_pattern = fullfile ("..", curr_dir, file_in_pwd);
659 %! assert (__wglob__ (glob_pattern), {glob_pattern});
660 %! glob_pattern = fullfile ("..", curr_dir, "..", ".", curr_dir, ".", file_in_pwd);
661 %! assert (__wglob__ (glob_pattern), {glob_pattern});
662 
663 %!test <*62414>
664 %! old_dir = cd (fileparts (which ("plot.m")));
665 %! unwind_protect
666 %! assert (__wglob__ (fullfile (".", "*.m")), ...
667 %! fullfile (".", __wglob__ ("*.m")));
668 %! unwind_protect_cleanup
669 %! cd (old_dir);
670 %! end_unwind_protect
671 
672 ## retain trailing file separator
673 %!test <*62414>
674 %! old_dir = cd (fileparts (which ("plot.m")));
675 %! unwind_protect
676 %! assert (__wglob__ ("private"), {"private"});
677 %! assert (__wglob__ ("private/"), {["private", filesep()]});
678 %! assert (__wglob__ ("private///"), {["private", filesep()]});
679 %! assert (__wglob__ ("./private"), {fullfile(".", "private")});
680 %! assert (__wglob__ ("./private/"), ...
681 %! {[fullfile(".", "private"), filesep()]});
682 %! assert (__wglob__ ("./private///"), ...
683 %! {[fullfile(".", "private"), filesep()]});
684 %! assert (__wglob__ (["./p*","/"]), ...
685 %! {[fullfile(".", "private"), filesep()]});
686 %! unwind_protect_cleanup
687 %! cd (old_dir);
688 %! end_unwind_protect
689 */
690 
691 DEFUN (__fnmatch__, args, ,
692  doc: /* -*- texinfo -*-
693 @deftypefn {} {@var{TF} =} fnmatch (@var{pattern}, @var{string})
694 Return true or false for each element of @var{string} that matches any of
695 the elements of the string array @var{pattern}, using the rules of
696 filename pattern matching.
697 
698 For example:
699 
700 @example
701 @group
702 fnmatch ("a*b", @{"ab"; "axyzb"; "xyzab"@})
703  @result{} [ 1; 1; 0 ]
704 @end group
705 @end example
706 @seealso{glob, regexp}
707 @end deftypefn */)
708 {
709  if (args.length () != 2)
710  print_usage ();
711 
712  string_vector pat = args(0).string_vector_value ();
713  string_vector str = args(1).string_vector_value ();
714 
715  glob_match pattern (sys::file_ops::tilde_expand (pat));
716 
717  return ovl (pattern.match (str));
718 }
719 
720 DEFUN (filesep, args, ,
721  doc: /* -*- texinfo -*-
722 @deftypefn {} {@var{sep} =} filesep ()
723 @deftypefnx {} {} filesep ("all")
724 Return the system-dependent character used to separate directory names.
725 
726 If @qcode{"all"} is given, the function returns all valid file separators
727 in the form of a string. The list of file separators is system-dependent.
728 It is @samp{/} (forward slash) under UNIX or @w{Mac OS X}, @samp{/} and
729 @samp{\} (forward and backward slashes) under Windows.
730 @seealso{pathsep}
731 @end deftypefn */)
732 {
733  int nargin = args.length ();
734 
735  if (nargin > 1)
736  print_usage ();
737 
738  octave_value retval;
739 
740  if (nargin == 0)
741  retval = sys::file_ops::dir_sep_str ();
742  else
743  {
744  std::string s = args(0).xstring_value ("filesep: argument must be a string");
745  if (s != "all")
746  error (R"(filesep: argument must be "all")");
747 
748  retval = sys::file_ops::dir_sep_chars ();
749  }
750 
751  return retval;
752 }
753 
754 DEFUN (pathsep, args, ,
755  doc: /* -*- texinfo -*-
756 @deftypefn {} {@var{val} =} pathsep ()
757 Query the character used to separate directories in a path.
758 @seealso{filesep}
759 @end deftypefn */)
760 {
761  if (args.length () > 0)
762  print_usage ();
763 
764  return ovl (directory_path::path_sep_str ());
765 }
766 
767 DEFUN (confirm_recursive_rmdir, args, nargout,
768  doc: /* -*- texinfo -*-
769 @deftypefn {} {@var{val} =} confirm_recursive_rmdir ()
770 @deftypefnx {} {@var{old_val} =} confirm_recursive_rmdir (@var{new_val})
771 @deftypefnx {} {@var{old_val} =} confirm_recursive_rmdir (@var{new_val}, "local")
772 Query or set the internal variable that controls whether Octave
773 will ask for confirmation before recursively removing a directory tree.
774 
775 When called from inside a function with the @qcode{"local"} option, the
776 variable is changed locally for the function and any subroutines it calls.
777 The original variable value is restored when exiting the function.
778 @seealso{rmdir}
779 @end deftypefn */)
780 {
781  return set_internal_variable (Vconfirm_recursive_rmdir, args, nargout,
782  "confirm_recursive_rmdir");
783 }
784 
785 OCTAVE_END_NAMESPACE(octave)
ComplexNDArray concat(NDArray &ra, ComplexNDArray &rb, const Array< octave_idx_type > &ra_idx)
Definition: CNDArray.cc:418
octave_value_list Freadlink(const octave_value_list &=octave_value_list(), int=0)
octave_value_list Frename(octave::interpreter &, const octave_value_list &=octave_value_list(), int=0)
octave_value_list Frmdir(octave::interpreter &, const octave_value_list &=octave_value_list(), int=0)
octave_value_list Flink(const octave_value_list &=octave_value_list(), int=0)
octave_value_list Fsymlink(const octave_value_list &=octave_value_list(), int=0)
Definition: Cell.h:43
static bool forced_interactive()
Definition: octave.cc:329
static std::string path_sep_str()
Definition: pathsearch.cc:134
Provides threadsafe access to octave.
void file_renamed(bool load_new)
void file_remove(const std::string &old_name, const std::string &new_name)
string_vector glob() const
Definition: glob-match.cc:41
bool match(const std::string &str) const
Definition: glob-match.cc:35
bool yes_or_no(const std::string &prompt)
string_vector & sort(bool make_uniq=false)
Definition: str-vec.cc:77
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
void print_usage(void)
Definition: defun-int.h:72
#define DEFMETHOD(name, interp_name, args_name, nargout_name, doc)
Macro to define a builtin method.
Definition: defun.h:111
#define DEFUN(name, args_name, nargout_name, doc)
Macro to define a builtin function.
Definition: defun.h:56
#define DEFUNX(name, fname, args_name, nargout_name, doc)
Macro to define a builtin function with certain internal name.
Definition: defun.h:85
#define DEFALIAS(alias, name)
Macro to define an alias for another existing function name.
Definition: defun.h:160
void() error(const char *fmt,...)
Definition: error.cc:988
std::string dir_sep_str()
std::string dir_sep_chars()
std::string dirname(const std::string &path)
bool dir_exists(const std::string &dirname)
Definition: lo-sysdep.cc:389
int chdir(const std::string &path_arg)
Definition: lo-sysdep.cc:107
bool get_dirlist(const std::string &dirname, string_vector &dirlist, std::string &msg)
Definition: lo-sysdep.cc:120
std::string tilde_expand(const std::string &name)
Definition: file-ops.cc:289
int symlink(const std::string &old_name, const std::string &new_name)
Definition: file-ops.cc:531
int mkdir(const std::string &nm, mode_t md)
Definition: file-ops.cc:413
int readlink(const std::string &path, std::string &result)
Definition: file-ops.cc:554
int link(const std::string &old_name, const std::string &new_name)
Definition: file-ops.cc:508
int recursive_rmdir(const std::string &name)
Definition: file-ops.cc:655
int rename(const std::string &from, const std::string &to)
Definition: file-ops.cc:582
int rmdir(const std::string &name)
Definition: file-ops.cc:631
octave_value set_internal_variable(bool &var, const octave_value_list &args, int nargout, const char *nm)
Definition: variables.cc:583
string_vector windows_glob(const string_vector &pat)
Definition: oct-glob.cc:231
string_vector glob(const string_vector &pat)
Definition: oct-glob.cc:73
return octave_value(v1.char_array_value() . concat(v2.char_array_value(), ra_idx),((a1.is_sq_string()||a2.is_sq_string()) ? '\'' :'"'))
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:219
DEFMETHODX("quad", Fquad, interp, args,, doc:)
Definition: quad.cc:136