GNU Octave  9.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
oct-hist.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (C) 1993-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 /*
27 
28 The functions listed below were adapted from similar functions from
29 GNU Bash, the Bourne Again SHell, copyright (C) 1987, 1989, 1991 Free
30 Software Foundation, Inc.
31 
32  do_history edit_history_readline
33  do_edit_history edit_history_add_hist
34 
35 */
36 
37 #if defined (HAVE_CONFIG_H)
38 # include "config.h"
39 #endif
40 
41 #include <cstdlib>
42 #include <cstring>
43 
44 #include <fstream>
45 #include <string>
46 
47 #include "cmd-hist.h"
48 #include "file-ops.h"
49 #include "lo-mappers.h"
50 #include "lo-sysdep.h"
51 #include "oct-env.h"
52 #include "oct-time.h"
53 #include "str-vec.h"
54 #include "unistd-wrappers.h"
55 
56 #include "defun.h"
57 #include "error.h"
58 #include "errwarn.h"
59 #include "event-manager.h"
60 #include "input.h"
61 #include "oct-hist.h"
62 #include "ovl.h"
63 #include "pager.h"
64 #include "parse.h"
65 #include "sighandlers.h"
66 #include "sysdep.h"
67 #include "interpreter.h"
68 #include "interpreter-private.h"
69 #include "unwind-prot.h"
70 #include "utils.h"
71 #include "variables.h"
72 
74 
75 // Read the edited history lines from STREAM and return them
76 // one at a time. This can read unlimited length lines. The
77 // caller should free the storage.
78 
79 static char *
80 edit_history_readline (std::fstream& stream)
81 {
82  char c;
83  int line_len = 128;
84  int lindex = 0;
85  char *line = new char [line_len];
86  line[0] = '\0';
87 
88  while (stream.get (c))
89  {
90  if (lindex + 2 >= line_len)
91  {
92  char *tmp_line = new char [line_len += 128];
93  strcpy (tmp_line, line);
94  delete [] line;
95  line = tmp_line;
96  }
97 
98  if (c == '\n')
99  {
100  line[lindex++] = '\n';
101  line[lindex++] = '\0';
102  return line;
103  }
104  else
105  line[lindex++] = c;
106  }
107 
108  if (! lindex)
109  {
110  delete [] line;
111  return nullptr;
112  }
113 
114  if (lindex + 2 >= line_len)
115  {
116  char *tmp_line = new char [lindex+3];
117  strcpy (tmp_line, line);
118  delete [] line;
119  line = tmp_line;
120  }
121 
122  // Finish with newline if none in file.
123 
124  line[lindex++] = '\n';
125  line[lindex++] = '\0';
126  return line;
127 }
128 
129 static void
130 edit_history_add_hist (const std::string& line)
131 {
132  if (! line.empty ())
133  {
134  std::string tmp = line;
135 
136  int len = tmp.length ();
137 
138  if (len > 0 && tmp[len-1] == '\n')
139  tmp.resize (len - 1);
140 
141  if (! tmp.empty ())
142  {
143  if (command_history::add (tmp))
144  {
146 
147  evmgr.append_history (tmp);
148  }
149  }
150  }
151 }
152 
153 static bool
154 get_int_arg (const octave_value& arg, int& val)
155 {
156  bool ok = true;
157 
158  if (arg.is_string ())
159  {
160  std::string tmp = arg.string_value ();
161 
162  ok = sscanf (tmp.c_str (), "%d", &val) == 1;
163  }
164  else if (arg.isnumeric ())
165  val = arg.int_value ();
166  else
167  ok = false;
168 
169  return ok;
170 }
171 
172 static std::string
173 mk_tmp_hist_file (const octave_value_list& args,
174  bool insert_curr, const char *warn_for)
175 {
177 
178  int hist_count = hlist.numel () - 1; // switch to zero-based indexing
179 
180  // The current command line is already part of the history list by
181  // the time we get to this point. Delete the cmd from the list when
182  // executing 'edit_history' so that it doesn't show up in the history
183  // but the actual commands performed will.
184 
185  if (! insert_curr)
186  command_history::remove (hist_count);
187 
188  hist_count--; // skip last entry in history list
189 
190  // If no numbers have been specified, the default is to edit the
191  // last command in the history list.
192 
193  int hist_beg = hist_count;
194  int hist_end = hist_count;
195 
196  bool reverse = false;
197 
198  // Process options.
199 
200  int nargin = args.length ();
201 
202  if (nargin == 2)
203  {
204  if (! get_int_arg (args(0), hist_beg)
205  || ! get_int_arg (args(1), hist_end))
206  error ("%s: arguments must be integers", warn_for);
207 
208  if (hist_beg < 0)
209  hist_beg += (hist_count + 1);
210  else
211  hist_beg--;
212  if (hist_end < 0)
213  hist_end += (hist_count + 1);
214  else
215  hist_end--;
216  }
217  else if (nargin == 1)
218  {
219  if (! get_int_arg (args(0), hist_beg))
220  error ("%s: argument must be an integer", warn_for);
221 
222  if (hist_beg < 0)
223  hist_beg += (hist_count + 1);
224  else
225  hist_beg--;
226 
227  hist_end = hist_beg;
228  }
229 
230  if (hist_beg > hist_count || hist_end > hist_count)
231  error ("%s: history specification out of range", warn_for);
232 
233  if (hist_end < hist_beg)
234  {
235  std::swap (hist_end, hist_beg);
236  reverse = true;
237  }
238 
239  std::string name = sys::tempnam ("", "oct-");
240 
241  std::ofstream file = sys::ofstream (name.c_str (), std::ios::out);
242 
243  if (! file)
244  error ("%s: couldn't open temporary file '%s'", warn_for,
245  name.c_str ());
246 
247  if (reverse)
248  {
249  for (int i = hist_end; i >= hist_beg; i--)
250  file << hlist[i] << "\n";
251  }
252  else
253  {
254  for (int i = hist_beg; i <= hist_end; i++)
255  file << hlist[i] << "\n";
256  }
257 
258  file.close ();
259 
260  return name;
261 }
262 
264  : m_interpreter (interp), m_input_from_tmp_file (false),
265  m_timestamp_format_string (default_timestamp_format ())
266 { }
267 
268 void
269 history_system::initialize (bool read_history_file)
270 {
271  command_history::initialize (read_history_file, default_file (),
272  default_size (),
273  sys::env::getenv ("OCTAVE_HISTCONTROL"));
274 
275  event_manager& evmgr = m_interpreter.get_event_manager ();
276 
278 }
279 
280 void
282 {
283  sys::localtime now;
284 
285  std::string timestamp = now.strftime (m_timestamp_format_string);
286 
287  if (! timestamp.empty ())
288  {
289  if (command_history::add (timestamp))
290  {
291  event_manager& evmgr = m_interpreter.get_event_manager ();
292 
293  evmgr.append_history (timestamp);
294  }
295  }
296 }
297 
300  int nargout)
301 {
302  return set_internal_variable (m_input_from_tmp_file, args, nargout,
303  "input_from_tmp_file");
304 }
305 
308  int nargout)
309 {
310  return set_internal_variable (m_timestamp_format_string, args, nargout,
311  "timestamp_format_string");
312 }
313 
314 // Display, save, or load history. Stolen and modified from bash.
315 //
316 // Arg of -w FILENAME means write file, arg of -r FILENAME
317 // means read file, arg of -q means don't number lines. Arg of N
318 // means only display that many items.
319 
322  int nargout)
323 {
324  bool numbered_output = nargout == 0;
325 
326  unwind_action restore_history_filename
327  ([] (const std::string& old_filename)
328  {
329  command_history::set_file (old_filename);
330  }, command_history::file ());
331 
332  string_vector hlist;
333 
334  int nargin = args.length ();
335 
336  // Number of history lines to show (-1 = all)
337  int limit = -1;
338 
339  for (octave_idx_type i = 0; i < nargin; i++)
340  {
341  octave_value arg = args(i);
342 
343  std::string option;
344 
345  if (arg.is_string ())
346  option = arg.string_value ();
347  else if (arg.isnumeric ())
348  {
349  limit = arg.int_value ();
350  if (limit < 0)
351  limit = -limit;
352  continue;
353  }
354  else
355  err_wrong_type_arg ("history", arg);
356 
357  event_manager& evmgr = m_interpreter.get_event_manager ();
358 
359  if (option == "-r" || option == "-w" || option == "-a"
360  || option == "-n")
361  {
362  if (i < nargin - 1)
363  {
364  std::string fname
365  = args(++i).xstring_value ("history: filename must be a string for %s option",
366  option.c_str ());
367 
369  }
370  else
371  command_history::set_file (default_file ());
372 
373  if (option == "-a")
374  // Append 'new' lines to file.
376 
377  else if (option == "-w")
378  // Write entire history.
380 
381  else if (option == "-r")
382  {
383  // Read entire file.
386  }
387 
388  else if (option == "-n")
389  {
390  // Read 'new' history from file.
393  }
394 
395  else
396  panic_impossible ();
397 
398  return hlist;
399  }
400  else if (option == "-c")
401  {
403  evmgr.clear_history ();
404  }
405  else if (option == "-q")
406  numbered_output = false;
407  else if (option == "--")
408  {
409  i++;
410  break;
411  }
412  else
413  {
414  // The last argument found in the command list that looks like
415  // an integer will be used
416  int tmp;
417 
418  if (sscanf (option.c_str (), "%d", &tmp) == 1)
419  {
420  if (tmp > 0)
421  limit = tmp;
422  else
423  limit = -tmp;
424  }
425 
426  else
427  {
428  if (option.length () > 0 && option[0] == '-')
429  error ("history: unrecognized option '%s'", option.c_str ());
430  else
431  error ("history: bad non-numeric arg '%s'", option.c_str ());
432  }
433  }
434  }
435 
436  hlist = command_history::list (limit, numbered_output);
437 
438  int len = hlist.numel ();
439 
440  if (nargout == 0)
441  {
442  for (octave_idx_type i = 0; i < len; i++)
443  octave_stdout << hlist[i] << "\n";
444  }
445 
446  return hlist;
447 }
448 
449 void
451 {
452  std::string name = mk_tmp_hist_file (args, false, "edit_history");
453 
454  if (name.empty ())
455  return;
456 
457  // Call up our favorite editor on the file of commands.
458 
459  environment& env = m_interpreter.get_environment ();
460  std::string cmd = env.editor ();
461  cmd.append (R"( ")" + name + '"');
462 
463  // Ignore interrupts while we are off editing commands. Should we
464  // maybe avoid using system()?
465 
466  volatile interrupt_handler old_interrupt_handler
467  = ignore_interrupts ();
468 
469  int status = sys::system (cmd);
470 
471  set_interrupt_handler (old_interrupt_handler);
472 
473  // Check if text edition was successful. Abort the operation
474  // in case of failure.
475  if (status != EXIT_SUCCESS)
476  error ("edit_history: text editor command failed");
477 
478  // Write the commands to the history file since source_file
479  // disables command line history while it executes.
480 
481  std::fstream file = sys::fstream (name.c_str (), std::ios::in);
482 
483  char *line;
484  //int first = 1;
485  while ((line = edit_history_readline (file)) != nullptr)
486  {
487  // Skip blank lines.
488 
489  if (line[0] == '\n')
490  {
491  delete [] line;
492  continue;
493  }
494 
495  edit_history_add_hist (line);
496 
497  delete [] line;
498  }
499 
500  file.close ();
501 
502  int(*unlink_fptr)(const std::string&) = sys::unlink;
503  unwind_action unlink_action (unlink_fptr, name);
504  unwind_protect_var<bool> upv (m_input_from_tmp_file, true);
505 
506  // FIXME: instead of sourcing a file, we should just iterate through
507  // the list of commands, parsing and executing them one at a time as
508  // if they were entered interactively.
509 
510  source_file (name);
511 }
512 
513 void
515 {
516  std::string name = mk_tmp_hist_file (args, false, "run_history");
517 
518  if (name.empty ())
519  return;
520 
521  int(*unlink_fptr)(const std::string&) = sys::unlink;
522  unwind_action unlink_action (unlink_fptr, name);
523  unwind_protect_var<bool> upv (m_input_from_tmp_file, true);
524 
525  // FIXME: instead of sourcing a file, we should just iterate through
526  // the list of commands, parsing and executing them one at a time as
527  // if they were entered interactively.
528 
529  source_file (name);
530 }
531 
532 std::string
533 history_system::default_file ()
534 {
535  std::string file;
536 
537  std::string env_file = sys::env::getenv ("OCTAVE_HISTFILE");
538 
539  if (! env_file.empty ())
540  file = env_file;
541 
542  if (file.empty ())
543  {
544  // Default to $DATA/octave/history, where $DATA is the platform-
545  // dependent location for (roaming) user data files.
546 
547  std::string user_data_dir = sys::env::get_user_data_directory ();
548 
549  std::string hist_dir = user_data_dir + sys::file_ops::dir_sep_str ()
550  + "octave";
551 
552  file = sys::env::make_absolute ("history", hist_dir);
553  }
554 
555 
556  return file;
557 }
558 
559 int
560 history_system::default_size ()
561 {
562  int size = 1000;
563 
564  std::string env_size = sys::env::getenv ("OCTAVE_HISTSIZE");
565 
566  if (! env_size.empty ())
567  {
568  int val;
569 
570  if (sscanf (env_size.c_str (), "%d", &val) == 1)
571  size = (val > 0 ? val : 0);
572  }
573 
574  return size;
575 }
576 
577 std::string
578 history_system::default_timestamp_format ()
579 {
580  return
581  "# Octave " OCTAVE_VERSION ", %a %b %d %H:%M:%S %Y %Z <"
582  + sys::env::get_user_name ()
583  + '@'
584  + sys::env::get_host_name ()
585  + '>';
586 }
587 
588 DEFMETHOD (edit_history, interp, args, ,
589  doc: /* -*- texinfo -*-
590 @deftypefn {} {} edit_history
591 @deftypefnx {} {} edit_history @var{cmd_number}
592 @deftypefnx {} {} edit_history @var{first} @var{last}
593 Edit the history list using the editor named by the variable @env{EDITOR}.
594 
595 The commands to be edited are first copied to a temporary file. When you
596 exit the editor, Octave executes the commands that remain in the file. It
597 is often more convenient to use @code{edit_history} to define functions
598 rather than attempting to enter them directly on the command line.
599 The block of commands is executed as soon as you exit the editor.
600 To avoid executing any commands, simply delete all the lines from the buffer
601 before leaving the editor.
602 
603 When invoked with no arguments, edit the previously executed command;
604 With one argument, edit the specified command @var{cmd_number};
605 With two arguments, edit the list of commands between @var{first} and
606 @var{last}. Command number specifiers may also be negative where -1
607 refers to the most recently executed command.
608 The following are equivalent and edit the most recently executed command.
609 
610 @example
611 @group
612 edit_history
613 edit_history -1
614 @end group
615 @end example
616 
617 When using ranges, specifying a larger number for the first command than the
618 last command reverses the list of commands before they are placed in the
619 buffer to be edited.
620 @seealso{run_history, history}
621 @end deftypefn */)
622 {
623  // FIXME: should this be limited to the top-level context?
624  if (args.length () > 2)
625  print_usage ();
626 
627  history_system& history_sys = interp.get_history_system ();
628 
629  history_sys.do_edit_history (args);
630 
631  return ovl ();
632 }
633 
634 DEFMETHOD (history, interp, args, nargout,
635  doc: /* -*- texinfo -*-
636 @deftypefn {} {} history
637 @deftypefnx {} {} history @var{opt1} @dots{}
638 @deftypefnx {} {@var{H} =} history ()
639 @deftypefnx {} {@var{H} =} history (@var{opt1}, @dots{})
640 If invoked with no arguments, @code{history} displays a list of commands
641 that you have executed.
642 
643 Valid options are:
644 
645 @table @code
646 @item @var{n}
647 @itemx -@var{n}
648 Display only the most recent @var{n} lines of history.
649 
650 @item -c
651 Clear the history list.
652 
653 @item -q
654 Don't number the displayed lines of history. This is useful for cutting
655 and pasting commands using the X Window System.
656 
657 @item -r @var{file}
658 Read the file @var{file}, appending its contents to the current
659 history list. If the name is omitted, use the default history file
660 (normally @file{~/.octave_hist}).
661 
662 @item -w @var{file}
663 Write the current history to the file @var{file}. If the name is
664 omitted, use the default history file (normally @file{~/.octave_hist}).
665 @end table
666 
667 For example, to display the five most recent commands that you have
668 typed without displaying line numbers, use the command
669 @kbd{history -q 5}.
670 
671 If invoked with a single output argument, the history will be saved to that
672 argument as a cell string and will not be output to screen.
673 @seealso{edit_history, run_history}
674 @end deftypefn */)
675 {
676  // FIXME: should this be limited to the top-level context?
677 
678  history_system& history_sys = interp.get_history_system ();
679 
680  // Call do_history even if nargout is zero to display history list.
681 
682  string_vector hlist = history_sys.do_history (args, nargout);
683 
684  return nargout > 0 ? ovl (Cell (hlist)) : ovl ();
685 }
686 
687 DEFMETHOD (run_history, interp, args, ,
688  doc: /* -*- texinfo -*-
689 @deftypefn {} {} run_history
690 @deftypefnx {} {} run_history @var{cmd_number}
691 @deftypefnx {} {} run_history @var{first} @var{last}
692 Run commands from the history list.
693 
694 When invoked with no arguments, run the previously executed command;
695 
696 With one argument, run the specified command @var{cmd_number};
697 
698 With two arguments, run the list of commands between @var{first} and
699 @var{last}. Command number specifiers may also be negative where -1
700 refers to the most recently executed command. For example, the command
701 
702 @example
703 @group
704 run_history
705  OR
706 run_history -1
707 @end group
708 @end example
709 
710 @noindent
711 executes the most recent command again.
712 The command
713 
714 @example
715 run_history 13 169
716 @end example
717 
718 @noindent
719 executes commands 13 through 169.
720 
721 Specifying a larger number for the first command than the last command
722 reverses the list of commands before executing them.
723 For example:
724 
725 @example
726 @group
727 disp (1)
728 disp (2)
729 run_history -1 -2
730 @result{}
731  2
732  1
733 @end group
734 @end example
735 
736 @seealso{edit_history, history}
737 @end deftypefn */)
738 {
739  // FIXME: should this be limited to the top-level context?
740 
741  history_system& history_sys = interp.get_history_system ();
742 
743  if (args.length () > 2)
744  print_usage ();
745 
746  history_sys.do_run_history (args);
747 
748  return ovl ();
749 }
750 
751 DEFUN (history_control, args, nargout,
752  doc: /* -*- texinfo -*-
753 @deftypefn {} {@var{val} =} history_control ()
754 @deftypefnx {} {@var{old_val} =} history_control (@var{new_val})
755 Query or set the internal variable that specifies how commands are saved
756 to the history list.
757 
758 The default value is an empty character string, but may be overridden by the
759 environment variable @w{@env{OCTAVE_HISTCONTROL}}.
760 
761 The value of @code{history_control} is a colon-separated list of values
762 controlling how commands are saved on the history list. If the list
763 of values includes @code{ignorespace}, lines which begin with a space
764 character are not saved in the history list. A value of @code{ignoredups}
765 causes lines matching the previous history entry to not be saved.
766 A value of @code{ignoreboth} is shorthand for @code{ignorespace} and
767 @code{ignoredups}. A value of @code{erasedups} causes all previous lines
768 matching the current line to be removed from the history list before that
769 line is saved. Any value not in the above list is ignored. If
770 @code{history_control} is the empty string, all commands are saved on
771 the history list, subject to the value of @code{history_save}.
772 @seealso{history_file, history_size, history_timestamp_format_string,
773 history_save}
774 @end deftypefn */)
775 {
776  octave_value retval;
777 
778  std::string old_history_control = command_history::histcontrol ();
779 
780  std::string tmp = old_history_control;
781 
782  retval = set_internal_variable (tmp, args, nargout, "history_control");
783 
784  if (tmp != old_history_control)
786 
787  return retval;
788 }
789 
790 DEFUN (history_size, args, nargout,
791  doc: /* -*- texinfo -*-
792 @deftypefn {} {@var{val} =} history_size ()
793 @deftypefnx {} {@var{old_val} =} history_size (@var{new_val})
794 Query or set the internal variable that specifies how many entries
795 to store in the history file.
796 
797 The default value is @code{1000}, but may be overridden by the environment
798 variable @w{@env{OCTAVE_HISTSIZE}}.
799 @seealso{history_file, history_timestamp_format_string, history_save}
800 @end deftypefn */)
801 {
802  octave_value retval;
803 
804  int old_history_size = command_history::size ();
805 
806  int tmp = old_history_size;
807 
808  retval = set_internal_variable (tmp, args, nargout,
809  "history_size", -1,
811 
812  if (tmp != old_history_size)
814 
815  return retval;
816 }
817 
818 DEFUN (history_file, args, nargout,
819  doc: /* -*- texinfo -*-
820 @deftypefn {} {@var{val} =} history_file ()
821 @deftypefnx {} {@var{old_val} =} history_file (@var{new_val})
822 Query or set the internal variable that specifies the name of the file used to
823 store command history.
824 
825 All future commands issued during the current Octave session will be written to
826 this new file (if the current setting of @code{history_save} allows for this).
827 
828 The default value is @file{@w{@env{$DATA}}/octave/history}, where
829 @w{@env{$DATA}} is the platform-specific location for (roaming) user data files
830 (e.g., @w{@env{$XDG_DATA_HOME}} or, if that is not set, @file{~/.local/share}
831 on Unix-like operating systems or @w{@env{%APPDATA%}} on Windows). The default
832 value may be overridden by the environment variable @w{@env{OCTAVE_HISTFILE}}.
833 
834 Programming Notes:
835 
836 If you want to permanently change the location of Octave's history file you
837 need to issue the @code{history_file} command in every new Octave session.
838 This can be achieved by using Octave's @file{.octaverc} startup file.
839 
840 If you also want to read the saved history commands of past Octave sessions
841 from this different history file, then you need to use the additional command
842 @code{history -r} after setting the new value of the history file. Example
843 code in Octave's startup file to do this might look like this:
844 
845 @example
846 @group
847 history_file ("~/new/.octave_hist");
848 if (exist (history_file ()))
849  history ("-r", history_file());
850 endif
851 @end group
852 @end example
853 
854 @seealso{history, history_control, history_save, history_size,
855 history_timestamp_format_string}
856 @end deftypefn */)
857 {
858  octave_value retval;
859 
860  std::string old_history_file = command_history::file ();
861 
862  std::string tmp = old_history_file;
863 
864  retval = set_internal_variable (tmp, args, nargout, "history_file");
865 
866  if (tmp != old_history_file)
868 
869  return retval;
870 }
871 
872 DEFMETHOD (history_timestamp_format_string, interp, args, nargout,
873  doc: /* -*- texinfo -*-
874 @deftypefn {} {@var{val} =} history_timestamp_format_string ()
875 @deftypefnx {} {@var{old_val} =} history_timestamp_format_string (@var{new_val})
876 @deftypefnx {} {@var{old_val} =} history_timestamp_format_string (@var{new_val}, "local")
877 Query or set the internal variable that specifies the format string
878 for the comment line that is written to the history file when Octave
879 exits.
880 
881 The format string is passed to @code{strftime}. The default value is
882 
883 @example
884 "# Octave VERSION, %a %b %d %H:%M:%S %Y %Z <USER@@HOST>"
885 @end example
886 
887 When called from inside a function with the @qcode{"local"} option, the
888 variable is changed locally for the function and any subroutines it calls.
889 The original variable value is restored when exiting the function.
890 @seealso{strftime, history_file, history_size, history_save}
891 @end deftypefn */)
892 {
893  history_system& history_sys = interp.get_history_system ();
894 
895  return history_sys.timestamp_format_string (args, nargout);
896 }
897 
898 /*
899 %!test
900 %! history_timestamp_format_string ("# Example history marker", "local");
901 %! assert (history_timestamp_format_string (), "# Example history marker")
902 %!test <*57843>
903 %! history_timestamp_format_string ("", "local");
904 %! assert (history_timestamp_format_string (), "")
905 */
906 
907 DEFUN (history_save, args, nargout,
908  doc: /* -*- texinfo -*-
909 @deftypefn {} {@var{val} =} history_save ()
910 @deftypefnx {} {@var{old_val} =} history_save (@var{new_val})
911 @deftypefnx {} {@var{old_val} =} history_save (@var{new_val}, "local")
912 Query or set the internal variable that controls whether commands entered
913 on the command line are saved in the history file.
914 
915 When called from inside a function with the @qcode{"local"} option, the
916 variable is changed locally for the function and any subroutines it calls.
917 The original variable value is restored when exiting the function.
918 @seealso{history_control, history_file, history_size,
919 history_timestamp_format_string}
920 @end deftypefn */)
921 {
922  octave_value retval;
923 
924  bool old_history_save = ! command_history::ignoring_entries ();
925 
926  bool tmp = old_history_save;
927 
928  retval = set_internal_variable (tmp, args, nargout, "history_save");
929 
930  if (tmp != old_history_save)
932 
933  return retval;
934 }
935 
936 OCTAVE_END_NAMESPACE(octave)
charNDArray max(char d, const charNDArray &m)
Definition: chNDArray.cc:230
Definition: Cell.h:43
static bool ignoring_entries()
Definition: cmd-hist.cc:611
static void read(bool=true)
Definition: cmd-hist.cc:701
static void clear()
Definition: cmd-hist.cc:632
static int size()
Definition: cmd-hist.cc:598
static void initialize(bool, const std::string &, int, const std::string &)
Definition: cmd-hist.cc:544
static void append(const std::string &="")
Definition: cmd-hist.cc:735
static std::string file()
Definition: cmd-hist.cc:572
static void set_file(const std::string &)
Definition: cmd-hist.cc:561
static std::string histcontrol()
Definition: cmd-hist.cc:585
static bool add(const std::string &)
Definition: cmd-hist.cc:617
static void set_size(int)
Definition: cmd-hist.cc:591
static void remove(int)
Definition: cmd-hist.cc:625
static void ignore_entries(bool=true)
Definition: cmd-hist.cc:604
static void process_histcontrol(const std::string &)
Definition: cmd-hist.cc:578
static void read_range(int=-1, int=-1, bool=true)
Definition: cmd-hist.cc:714
static string_vector list(int=-1, bool=false)
Definition: cmd-hist.cc:749
static void write(const std::string &="")
Definition: cmd-hist.cc:728
Definition: oct-env.h:40
Provides threadsafe access to octave.
void append_history(const std::string &hist_entry)
void clear_history()
void write_timestamp()
Definition: oct-hist.cc:281
void do_edit_history(const octave_value_list &args=octave_value_list())
Definition: oct-hist.cc:450
bool input_from_tmp_file() const
Definition: oct-hist.h:58
history_system(interpreter &interp)
Definition: oct-hist.cc:263
void do_run_history(const octave_value_list &args=octave_value_list())
Definition: oct-hist.cc:514
octave_value timestamp_format_string(const octave_value_list &args, int nargout)
Definition: oct-hist.cc:307
void initialize(bool read_history_file=false)
Definition: oct-hist.cc:269
std::string timestamp_format_string() const
Definition: oct-hist.h:71
string_vector do_history(const octave_value_list &args=octave_value_list(), int nargout=0)
Definition: oct-hist.cc:321
environment & get_environment()
Definition: interpreter.h:241
event_manager & get_event_manager()
Definition: interpreter.h:328
octave_idx_type length() const
Definition: ovl.h:113
int int_value(bool req_int=false, bool frc_str_conv=false) const
Definition: ov.h:812
bool is_string() const
Definition: ov.h:637
bool isnumeric() const
Definition: ov.h:750
std::string string_value(bool force=false) const
Definition: ov.h:974
octave_idx_type numel() const
Definition: str-vec.h:100
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
void() error(const char *fmt,...)
Definition: error.cc:988
#define panic_impossible()
Definition: error.h:503
void err_wrong_type_arg(const char *name, const char *s)
Definition: errwarn.cc:166
std::string dir_sep_str()
event_manager & __get_event_manager__()
int system(const std::string &cmd_str)
Definition: lo-sysdep.cc:60
std::fstream fstream(const std::string &filename, const std::ios::openmode mode)
Definition: lo-sysdep.cc:607
std::ofstream ofstream(const std::string &filename, const std::ios::openmode mode)
Definition: lo-sysdep.cc:635
#define OCTAVE_VERSION
Definition: main.cc:63
std::string tempnam(const std::string &dir, const std::string &pfx)
Definition: file-ops.cc:749
int unlink(const std::string &name)
Definition: file-ops.cc:727
octave_value set_internal_variable(bool &var, const octave_value_list &args, int nargout, const char *nm)
Definition: variables.cc:583
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:219
#define octave_stdout
Definition: pager.h:309
void source_file(const std::string &file_name, const std::string &context="", bool verbose=false, bool require_file=true)
interrupt_handler ignore_interrupts()
Definition: sighandlers.cc:338
interrupt_handler set_interrupt_handler(const volatile interrupt_handler &h, bool restart_syscalls)
Definition: sighandlers.cc:349
F77_RET_T len
Definition: xerbla.cc:61