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