input.cc

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1993-2012 John W. Eaton
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 // Get command input interactively or from files.
00024 
00025 #ifdef HAVE_CONFIG_H
00026 #include <config.h>
00027 #endif
00028 
00029 #include <cstdio>
00030 #include <cstdlib>
00031 #include <cstring>
00032 #include <cassert>
00033 
00034 #include <iostream>
00035 #include <sstream>
00036 #include <string>
00037 
00038 #include <sys/types.h>
00039 #include <unistd.h>
00040 
00041 #include "cmd-edit.h"
00042 #include "file-ops.h"
00043 #include "quit.h"
00044 #include "str-vec.h"
00045 
00046 #include "debug.h"
00047 #include "defun.h"
00048 #include "dirfns.h"
00049 #include "error.h"
00050 #include "gripes.h"
00051 #include "help.h"
00052 #include "input.h"
00053 #include "lex.h"
00054 #include "load-path.h"
00055 #include "oct-map.h"
00056 #include "oct-hist.h"
00057 #include "toplev.h"
00058 #include "oct-obj.h"
00059 #include "pager.h"
00060 #include "parse.h"
00061 #include "pathlen.h"
00062 #include "pt.h"
00063 #include "pt-const.h"
00064 #include "pt-eval.h"
00065 #include "pt-stmt.h"
00066 #include "sighandlers.h"
00067 #include "sysdep.h"
00068 #include "toplev.h"
00069 #include "unwind-prot.h"
00070 #include "utils.h"
00071 #include "variables.h"
00072 
00073 // Primary prompt string.
00074 static std::string VPS1 = "\\s:\\#> ";
00075 
00076 // Secondary prompt string.
00077 static std::string VPS2 = "> ";
00078 
00079 // String printed before echoed input (enabled by --echo-input).
00080 std::string VPS4 = "+ ";
00081 
00082 // Echo commands as they are executed?
00083 //
00084 //   1  ==>  echo commands read from script files
00085 //   2  ==>  echo commands from functions
00086 //   4  ==>  echo commands read from command line
00087 //
00088 // more than one state can be active at once.
00089 int Vecho_executing_commands = ECHO_OFF;
00090 
00091 // The time we last printed a prompt.
00092 octave_time Vlast_prompt_time = 0.0;
00093 
00094 // Character to append after successful command-line completion attempts.
00095 static char Vcompletion_append_char = ' ';
00096 
00097 // Global pointer for eval().
00098 std::string current_eval_string;
00099 
00100 // TRUE means get input from current_eval_string.
00101 bool get_input_from_eval_string = false;
00102 
00103 // TRUE means we haven't been asked for the input from
00104 // current_eval_string yet.
00105 bool input_from_eval_string_pending = false;
00106 
00107 // TRUE means that input is coming from a file that was named on
00108 // the command line.
00109 bool input_from_command_line_file = false;
00110 
00111 // TRUE means that stdin is a terminal, not a pipe or redirected file.
00112 bool stdin_is_tty = false;
00113 
00114 // TRUE means we're parsing a function file.
00115 bool reading_fcn_file = false;
00116 
00117 // TRUE means we're parsing a classdef file.
00118 bool reading_classdef_file = false;
00119 
00120 // Simple name of function file we are reading.
00121 std::string curr_fcn_file_name;
00122 
00123 // Full name of file we are reading.
00124 std::string curr_fcn_file_full_name;
00125 
00126 // TRUE means we're parsing a script file.
00127 bool reading_script_file = false;
00128 
00129 // If we are reading from an M-file, this is it.
00130 FILE *ff_instream = 0;
00131 
00132 // TRUE means this is an interactive shell.
00133 bool interactive = false;
00134 
00135 // TRUE means the user forced this shell to be interactive (-i).
00136 bool forced_interactive = false;
00137 
00138 // Should we issue a prompt?
00139 int promptflag = 1;
00140 
00141 // The current line of input, from wherever.
00142 std::string current_input_line;
00143 
00144 // TRUE after a call to completion_matches.
00145 bool octave_completion_matches_called = false;
00146 
00147 // TRUE if the plotting system has requested a call to drawnow at
00148 // the next user prompt.
00149 bool Vdrawnow_requested = false;
00150 
00151 // TRUE if we are in debugging mode.
00152 bool Vdebugging = false;
00153 
00154 // If we are in debugging mode, this is the last command entered, so
00155 // that we can repeat the previous command if the user just types RET.
00156 static std::string last_debugging_command;
00157 
00158 // TRUE if we are running in the Emacs GUD mode.
00159 static bool Vgud_mode = false;
00160 
00161 // The filemarker used to separate filenames from subfunction names
00162 char Vfilemarker = '>';
00163 
00164 static void
00165 do_input_echo (const std::string& input_string)
00166 {
00167   int do_echo = reading_script_file ?
00168     (Vecho_executing_commands & ECHO_SCRIPTS)
00169       : (Vecho_executing_commands & ECHO_CMD_LINE) && ! forced_interactive;
00170 
00171   if (do_echo)
00172     {
00173       if (forced_interactive)
00174         {
00175           if (promptflag > 0)
00176             octave_stdout << command_editor::decode_prompt_string (VPS1);
00177           else
00178             octave_stdout << command_editor::decode_prompt_string (VPS2);
00179         }
00180       else
00181         octave_stdout << command_editor::decode_prompt_string (VPS4);
00182 
00183       if (! input_string.empty ())
00184         {
00185           octave_stdout << input_string;
00186 
00187           if (input_string[input_string.length () - 1] != '\n')
00188             octave_stdout << "\n";
00189         }
00190     }
00191 }
00192 
00193 std::string
00194 gnu_readline (const std::string& s, bool force_readline)
00195 {
00196   octave_quit ();
00197 
00198   std::string retval;
00199 
00200   if (line_editing || force_readline)
00201     {
00202       bool eof;
00203 
00204       retval = command_editor::readline (s, eof);
00205 
00206       if (! eof && retval.empty ())
00207         retval = "\n";
00208     }
00209   else
00210     {
00211       if (! s.empty () && (interactive || forced_interactive))
00212         {
00213           FILE *stream = command_editor::get_output_stream ();
00214 
00215           gnulib::fputs (s.c_str (), stream);
00216           gnulib::fflush (stream);
00217         }
00218 
00219       FILE *curr_stream = command_editor::get_input_stream ();
00220 
00221       if (reading_fcn_file || reading_script_file || reading_classdef_file)
00222         curr_stream = ff_instream;
00223 
00224       retval = octave_fgets (curr_stream);
00225     }
00226 
00227   return retval;
00228 }
00229 
00230 static inline std::string
00231 interactive_input (const std::string& s, bool force_readline = false)
00232 {
00233   Vlast_prompt_time.stamp ();
00234 
00235   if (Vdrawnow_requested && (interactive || forced_interactive))
00236     {
00237       feval ("drawnow");
00238 
00239       flush_octave_stdout ();
00240 
00241       // We set Vdrawnow_requested to false even if there is an error
00242       // in drawnow so that the error doesn't reappear at every prompt.
00243 
00244       Vdrawnow_requested = false;
00245 
00246       if (error_state)
00247         return "\n";
00248     }
00249 
00250   return gnu_readline (s, force_readline);
00251 }
00252 
00253 static std::string
00254 octave_gets (void)
00255 {
00256   octave_quit ();
00257 
00258   std::string retval;
00259 
00260   bool history_skip_auto_repeated_debugging_command = false;
00261 
00262   if ((interactive || forced_interactive)
00263       && (! (reading_fcn_file
00264              || reading_classdef_file
00265              || reading_script_file
00266              || get_input_from_eval_string
00267              || input_from_startup_file
00268              || input_from_command_line_file)))
00269     {
00270       std::string ps = (promptflag > 0) ? VPS1 : VPS2;
00271 
00272       std::string prompt = command_editor::decode_prompt_string (ps);
00273 
00274       pipe_handler_error_count = 0;
00275 
00276       flush_octave_stdout ();
00277 
00278       octave_pager_stream::reset ();
00279       octave_diary_stream::reset ();
00280 
00281       octave_diary << prompt;
00282 
00283       retval = interactive_input (prompt);
00284 
00285       // There is no need to update the load_path cache if there is no
00286       // user input.
00287       if (! retval.empty ()
00288           && retval.find_first_not_of (" \t\n\r") != std::string::npos)
00289         {
00290           load_path::update ();
00291 
00292           if (Vdebugging)
00293             last_debugging_command = retval;
00294           else
00295             last_debugging_command = std::string ();
00296         }
00297       else if (Vdebugging)
00298         {
00299           retval = last_debugging_command;
00300           history_skip_auto_repeated_debugging_command = true;
00301         }
00302     }
00303   else
00304     retval = gnu_readline ("");
00305 
00306   current_input_line = retval;
00307 
00308   if (! current_input_line.empty ())
00309     {
00310       if (! (input_from_startup_file || input_from_command_line_file
00311              || history_skip_auto_repeated_debugging_command))
00312         command_history::add (current_input_line);
00313 
00314       if (! (reading_fcn_file || reading_script_file || reading_classdef_file))
00315         {
00316           octave_diary << current_input_line;
00317 
00318           if (current_input_line[current_input_line.length () - 1] != '\n')
00319             octave_diary << "\n";
00320         }
00321 
00322       do_input_echo (current_input_line);
00323     }
00324   else if (! (reading_fcn_file || reading_script_file || reading_classdef_file))
00325     octave_diary << "\n";
00326 
00327   return retval;
00328 }
00329 
00330 // Read a line from the input stream.
00331 
00332 static std::string
00333 get_user_input (void)
00334 {
00335   octave_quit ();
00336 
00337   std::string retval;
00338 
00339   if (get_input_from_eval_string)
00340     {
00341       if (input_from_eval_string_pending)
00342         {
00343           input_from_eval_string_pending = false;
00344 
00345           retval = current_eval_string;
00346 
00347           size_t len = retval.length ();
00348 
00349           if (len > 0 && retval[len-1] != '\n')
00350             retval.append ("\n");
00351         }
00352     }
00353   else
00354     retval = octave_gets ();
00355 
00356   current_input_line = retval;
00357 
00358   return retval;
00359 }
00360 
00361 int
00362 octave_read (char *buf, unsigned max_size)
00363 {
00364   // FIXME -- is this a safe way to buffer the input?
00365 
00366   static const char * const eol = "\n";
00367   static std::string input_buf;
00368   static const char *pos = 0;
00369   static size_t chars_left = 0;
00370 
00371   int status = 0;
00372   if (chars_left == 0)
00373     {
00374       pos = 0;
00375 
00376       input_buf = get_user_input ();
00377 
00378       chars_left = input_buf.length ();
00379 
00380       pos = input_buf.c_str ();
00381     }
00382 
00383   if (chars_left > 0)
00384     {
00385       size_t len = max_size > chars_left ? chars_left : max_size;
00386       assert (len > 0);
00387 
00388       memcpy (buf, pos, len);
00389 
00390       chars_left -= len;
00391       pos += len;
00392 
00393       // Make sure input ends with a new line character.
00394       if (chars_left == 0 && buf[len-1] != '\n')
00395         {
00396           if (len < max_size)
00397             {
00398               // There is enough room to plug the newline character in
00399               // the buffer.
00400               buf[len++] = '\n';
00401             }
00402           else
00403             {
00404               // There isn't enough room to plug the newline character
00405               // in the buffer so make sure it is returned on the next
00406               // octave_read call.
00407               pos = eol;
00408               chars_left = 1;
00409             }
00410         }
00411 
00412       status = len;
00413 
00414     }
00415   else if (chars_left == 0)
00416     {
00417       status = 0;
00418     }
00419   else
00420     status = -1;
00421 
00422   return status;
00423 }
00424 
00425 // Fix things up so that input can come from file 'name', printing a
00426 // warning if the file doesn't exist.
00427 
00428 FILE *
00429 get_input_from_file (const std::string& name, int warn)
00430 {
00431   FILE *instream = 0;
00432 
00433   if (name.length () > 0)
00434     instream = gnulib::fopen (name.c_str (), "rb");
00435 
00436   if (! instream && warn)
00437     warning ("%s: no such file or directory", name.c_str ());
00438 
00439   if (reading_fcn_file || reading_script_file || reading_classdef_file)
00440     ff_instream = instream;
00441   else
00442     command_editor::set_input_stream (instream);
00443 
00444   return instream;
00445 }
00446 
00447 // Fix things up so that input can come from the standard input.  This
00448 // may need to become much more complicated, which is why it's in a
00449 // separate function.
00450 
00451 FILE *
00452 get_input_from_stdin (void)
00453 {
00454   command_editor::set_input_stream (stdin);
00455   return command_editor::get_input_stream ();
00456 }
00457 
00458 // FIXME -- make this generate file names when appropriate.
00459 
00460 static string_vector
00461 generate_possible_completions (const std::string& text, std::string& prefix,
00462                                std::string& hint)
00463 {
00464   string_vector names;
00465 
00466   prefix = "";
00467 
00468   if (looks_like_struct (text))
00469     names = generate_struct_completions (text, prefix, hint);
00470   else
00471     names = make_name_list ();
00472 
00473   // Sort and remove duplicates.
00474 
00475   names.sort (true);
00476 
00477   return names;
00478 }
00479 
00480 static bool
00481 is_completing_dirfns (void)
00482 {
00483   static std::string dirfns_commands[] = {"cd", "ls"};
00484   static const size_t dirfns_commands_length = 2;
00485 
00486   bool retval = false;
00487 
00488   std::string line = command_editor::get_line_buffer ();
00489 
00490   for (size_t i = 0; i < dirfns_commands_length; i++)
00491     {
00492       int index = line.find (dirfns_commands[i] + " ");
00493 
00494       if (index == 0)
00495         {
00496           retval = true;
00497           break;
00498         }
00499     }
00500 
00501   return retval;
00502 }
00503 
00504 static std::string
00505 generate_completion (const std::string& text, int state)
00506 {
00507   std::string retval;
00508 
00509   static std::string prefix;
00510   static std::string hint;
00511 
00512   static size_t hint_len = 0;
00513 
00514   static int list_index = 0;
00515   static int name_list_len = 0;
00516   static int name_list_total_len = 0;
00517   static string_vector name_list;
00518   static string_vector file_name_list;
00519 
00520   static int matches = 0;
00521 
00522   if (state == 0)
00523     {
00524       list_index = 0;
00525 
00526       prefix = "";
00527 
00528       hint = text;
00529 
00530       // No reason to display symbols while completing a
00531       // file/directory operation.
00532 
00533       if (is_completing_dirfns ())
00534         name_list = string_vector ();
00535       else
00536         name_list = generate_possible_completions (text, prefix, hint);
00537 
00538       name_list_len = name_list.length ();
00539 
00540       file_name_list = command_editor::generate_filename_completions (text);
00541 
00542       name_list.append (file_name_list);
00543 
00544       name_list_total_len = name_list.length ();
00545 
00546       hint_len = hint.length ();
00547 
00548       matches = 0;
00549 
00550       for (int i = 0; i < name_list_len; i++)
00551         if (hint == name_list[i].substr (0, hint_len))
00552           matches++;
00553     }
00554 
00555   if (name_list_total_len > 0 && matches > 0)
00556     {
00557       while (list_index < name_list_total_len)
00558         {
00559           std::string name = name_list[list_index];
00560 
00561           list_index++;
00562 
00563           if (hint == name.substr (0, hint_len))
00564             {
00565               if (list_index <= name_list_len && ! prefix.empty ())
00566                 retval = prefix + "." + name;
00567               else
00568                 retval = name;
00569 
00570               // FIXME -- looks_like_struct is broken for now,
00571               // so it always returns false.
00572 
00573               if (matches == 1 && looks_like_struct (retval))
00574                 {
00575                   // Don't append anything, since we don't know
00576                   // whether it should be '(' or '.'.
00577 
00578                   command_editor::set_completion_append_character ('\0');
00579                 }
00580               else
00581                 command_editor::set_completion_append_character
00582                   (Vcompletion_append_char);
00583 
00584               break;
00585             }
00586         }
00587     }
00588 
00589   return retval;
00590 }
00591 
00592 static std::string
00593 quoting_filename (const std::string &text, int, char quote)
00594 {
00595   if (quote)
00596     return text;
00597   else
00598     return (std::string ("'") + text);
00599 }
00600 
00601 void
00602 initialize_command_input (void)
00603 {
00604   // If we are using readline, this allows conditional parsing of the
00605   // .inputrc file.
00606 
00607   command_editor::set_name ("Octave");
00608 
00609   // FIXME -- this needs to include a comma too, but that
00610   // causes trouble for the new struct element completion code.
00611 
00612   static const char *s = "\t\n !\"\'*+-/:;<=>(){}[\\]^`~";
00613 
00614   command_editor::set_basic_word_break_characters (s);
00615 
00616   command_editor::set_completer_word_break_characters (s);
00617 
00618   command_editor::set_basic_quote_characters ("\"");
00619 
00620   command_editor::set_filename_quote_characters (" \t\n\\\"'@<>=;|&()#$`?*[!:{");
00621   command_editor::set_completer_quote_characters ("'\"");
00622 
00623   command_editor::set_completion_function (generate_completion);
00624 
00625   command_editor::set_quoting_function (quoting_filename);
00626 }
00627 
00628 static void
00629 get_debug_input (const std::string& prompt)
00630 {
00631   octave_user_code *caller = octave_call_stack::caller_user_code ();
00632   std::string nm;
00633 
00634   int curr_debug_line = octave_call_stack::current_line ();
00635 
00636   bool have_file = false;
00637 
00638   if (caller)
00639     {
00640       nm = caller->fcn_file_name ();
00641 
00642       if (nm.empty ())
00643         nm = caller->name ();
00644       else
00645         have_file = true;
00646     }
00647   else
00648     curr_debug_line = -1;
00649 
00650   std::ostringstream buf;
00651 
00652   if (! nm.empty ())
00653     {
00654       if (Vgud_mode)
00655         {
00656           static char ctrl_z = 'Z' & 0x1f;
00657 
00658           buf << ctrl_z << ctrl_z << nm << ":" << curr_debug_line;
00659         }
00660       else
00661         {
00662           // FIXME -- we should come up with a clean way to detect
00663           // that we are stopped on the no-op command that marks the
00664           // end of a function or script.
00665 
00666           buf << "stopped in " << nm;
00667 
00668           if (curr_debug_line > 0)
00669             buf << " at line " << curr_debug_line;
00670 
00671           if (have_file)
00672             {
00673               std::string line_buf
00674                 = get_file_line (nm, curr_debug_line);
00675 
00676               if (! line_buf.empty ())
00677                 buf << "\n" << curr_debug_line << ": " << line_buf;
00678             }
00679         }
00680     }
00681 
00682   std::string msg = buf.str ();
00683 
00684   if (! msg.empty ())
00685     std::cerr << msg << std::endl;
00686 
00687   unwind_protect frame;
00688 
00689   frame.protect_var (VPS1);
00690   VPS1 = prompt;
00691 
00692   if (! (interactive || forced_interactive)
00693       || (reading_fcn_file
00694           || reading_classdef_file
00695           || reading_script_file
00696           || get_input_from_eval_string
00697           || input_from_startup_file
00698           || input_from_command_line_file))
00699     {
00700       frame.protect_var (forced_interactive);
00701       forced_interactive = true;
00702 
00703       frame.protect_var (reading_fcn_file);
00704       reading_fcn_file = false;
00705 
00706       frame.protect_var (reading_classdef_file);
00707       reading_classdef_file = false;
00708 
00709       frame.protect_var (reading_script_file);
00710       reading_script_file = false;
00711 
00712       frame.protect_var (input_from_startup_file);
00713       input_from_startup_file = false;
00714 
00715       frame.protect_var (input_from_command_line_file);
00716       input_from_command_line_file = false;
00717 
00718       frame.protect_var (get_input_from_eval_string);
00719       get_input_from_eval_string = false;
00720 
00721       YY_BUFFER_STATE old_buf = current_buffer ();
00722       YY_BUFFER_STATE new_buf = create_buffer (get_input_from_stdin ());
00723 
00724       // FIXME: are these safe?
00725       frame.add_fcn (switch_to_buffer, old_buf);
00726       frame.add_fcn (delete_buffer, new_buf);
00727 
00728       switch_to_buffer (new_buf);
00729     }
00730 
00731   while (Vdebugging)
00732     {
00733       reset_error_handler ();
00734 
00735       reset_parser ();
00736 
00737       // Save current value of global_command.
00738       frame.protect_var (global_command);
00739 
00740       global_command = 0;
00741 
00742       // Do this with an unwind-protect cleanup function so that the
00743       // forced variables will be unmarked in the event of an interrupt.
00744       symbol_table::scope_id scope = symbol_table::top_scope ();
00745       frame.add_fcn (symbol_table::unmark_forced_variables, scope);
00746 
00747       // This is the same as yyparse in parse.y.
00748       int retval = octave_parse ();
00749 
00750       if (retval == 0 && global_command)
00751         {
00752           unwind_protect inner_frame;
00753 
00754           // Use an unwind-protect cleanup function so that the
00755           // global_command list will be deleted in the event of an
00756           // interrupt.
00757 
00758           inner_frame.add_fcn (cleanup_statement_list, &global_command);
00759 
00760           global_command->accept (*current_evaluator);
00761 
00762           if (octave_completion_matches_called)
00763             octave_completion_matches_called = false;
00764         }
00765 
00766       // Unmark forced variables.
00767       // Restore previous value of global_command.
00768       frame.run_top (2);
00769 
00770       octave_quit ();
00771     }
00772 }
00773 
00774 // If the user simply hits return, this will produce an empty matrix.
00775 
00776 static octave_value_list
00777 get_user_input (const octave_value_list& args, int nargout)
00778 {
00779   octave_value_list retval;
00780 
00781   int nargin = args.length ();
00782 
00783   int read_as_string = 0;
00784 
00785   if (nargin == 2)
00786     read_as_string++;
00787 
00788   std::string prompt = args(0).string_value ();
00789 
00790   if (error_state)
00791     {
00792       error ("input: unrecognized argument");
00793       return retval;
00794     }
00795 
00796   flush_octave_stdout ();
00797 
00798   octave_pager_stream::reset ();
00799   octave_diary_stream::reset ();
00800 
00801   octave_diary << prompt;
00802 
00803   std::string input_buf = interactive_input (prompt.c_str (), true);
00804 
00805   if (! (error_state || input_buf.empty ()))
00806     {
00807       if (! input_from_startup_file)
00808         command_history::add (input_buf);
00809 
00810       size_t len = input_buf.length ();
00811 
00812       octave_diary << input_buf;
00813 
00814       if (input_buf[len - 1] != '\n')
00815         octave_diary << "\n";
00816 
00817       if (len < 1)
00818         return read_as_string ? octave_value ("") : octave_value (Matrix ());
00819 
00820       if (read_as_string)
00821         {
00822           // FIXME -- fix gnu_readline and octave_gets instead!
00823           if (input_buf.length () == 1 && input_buf[0] == '\n')
00824             retval(0) = "";
00825           else
00826             retval(0) = input_buf;
00827         }
00828       else
00829         {
00830           int parse_status = 0;
00831 
00832           retval = eval_string (input_buf, true, parse_status, nargout);
00833 
00834           if (! Vdebugging && retval.length () == 0)
00835             retval(0) = Matrix ();
00836         }
00837     }
00838   else
00839     error ("input: reading user-input failed!");
00840 
00841   return retval;
00842 }
00843 
00844 DEFUN (input, args, nargout,
00845   "-*- texinfo -*-\n\
00846 @deftypefn  {Built-in Function} {} input (@var{prompt})\n\
00847 @deftypefnx {Built-in Function} {} input (@var{prompt}, \"s\")\n\
00848 Print a prompt and wait for user input.  For example,\n\
00849 \n\
00850 @example\n\
00851 input (\"Pick a number, any number! \")\n\
00852 @end example\n\
00853 \n\
00854 @noindent\n\
00855 prints the prompt\n\
00856 \n\
00857 @example\n\
00858 Pick a number, any number!\n\
00859 @end example\n\
00860 \n\
00861 @noindent\n\
00862 and waits for the user to enter a value.  The string entered by the user\n\
00863 is evaluated as an expression, so it may be a literal constant, a\n\
00864 variable name, or any other valid expression.\n\
00865 \n\
00866 Currently, @code{input} only returns one value, regardless of the number\n\
00867 of values produced by the evaluation of the expression.\n\
00868 \n\
00869 If you are only interested in getting a literal string value, you can\n\
00870 call @code{input} with the character string @code{\"s\"} as the second\n\
00871 argument.  This tells Octave to return the string entered by the user\n\
00872 directly, without evaluating it first.\n\
00873 \n\
00874 Because there may be output waiting to be displayed by the pager, it is\n\
00875 a good idea to always call @code{fflush (stdout)} before calling\n\
00876 @code{input}.  This will ensure that all pending output is written to\n\
00877 the screen before your prompt.  @xref{Input and Output}.\n\
00878 @end deftypefn")
00879 {
00880   octave_value_list retval;
00881 
00882   int nargin = args.length ();
00883 
00884   if (nargin == 1 || nargin == 2)
00885     retval = get_user_input (args, nargout);
00886   else
00887     print_usage ();
00888 
00889   return retval;
00890 }
00891 
00892 bool
00893 octave_yes_or_no (const std::string& prompt)
00894 {
00895   std::string prompt_string = prompt + "(yes or no) ";
00896 
00897   while (1)
00898     {
00899       std::string input_buf = interactive_input (prompt_string, true);
00900 
00901       if (input_buf == "yes")
00902         return true;
00903       else if (input_buf == "no")
00904         return false;
00905       else
00906         message (0, "Please answer yes or no.");
00907     }
00908 }
00909 
00910 DEFUN (yes_or_no, args, ,
00911   "-*- texinfo -*-\n\
00912 @deftypefn {Built-in Function} {} yes_or_no (@var{prompt})\n\
00913 Ask the user a yes-or-no question.  Return 1 if the answer is yes.\n\
00914 Takes one argument, which is the string to display to ask the\n\
00915 question.  It should end in a space; @samp{yes-or-no-p} adds\n\
00916 @samp{(yes or no) } to it.  The user must confirm the answer with\n\
00917 RET and can edit it until it has been confirmed.\n\
00918 @end deftypefn")
00919 {
00920   octave_value retval;
00921 
00922   int nargin = args.length ();
00923 
00924   if (nargin == 0 || nargin == 1)
00925     {
00926       std::string prompt;
00927 
00928       if (nargin == 1)
00929         {
00930           prompt = args(0).string_value ();
00931 
00932           if (error_state)
00933             {
00934               error ("yes_or_no: PROMPT must be a character string");
00935               return retval;
00936             }
00937         }
00938 
00939       retval = octave_yes_or_no (prompt);
00940     }
00941   else
00942     print_usage ();
00943 
00944   return retval;
00945 }
00946 
00947 octave_value
00948 do_keyboard (const octave_value_list& args)
00949 {
00950   octave_value retval;
00951 
00952   int nargin = args.length ();
00953 
00954   assert (nargin == 0 || nargin == 1);
00955 
00956   unwind_protect frame;
00957 
00958   frame.add_fcn (command_history::ignore_entries,
00959                  command_history::ignoring_entries ());
00960 
00961   command_history::ignore_entries (false);
00962 
00963   frame.protect_var (Vdebugging);
00964 
00965   frame.add_fcn (octave_call_stack::restore_frame,
00966                  octave_call_stack::current_frame ());
00967 
00968   // FIXME -- probably we just want to print one line, not the
00969   // entire statement, which might span many lines...
00970   //
00971   // tree_print_code tpc (octave_stdout);
00972   // stmt.accept (tpc);
00973 
00974   Vdebugging = true;
00975 
00976   std::string prompt = "debug> ";
00977   if (nargin > 0)
00978     prompt = args(0).string_value ();
00979 
00980   if (! error_state)
00981     get_debug_input (prompt);
00982 
00983   return retval;
00984 }
00985 
00986 DEFUN (keyboard, args, ,
00987   "-*- texinfo -*-\n\
00988 @deftypefn  {Built-in Function} {} keyboard ()\n\
00989 @deftypefnx {Built-in Function} {} keyboard (@var{prompt})\n\
00990 This function is normally used for simple debugging.  When the\n\
00991 @code{keyboard} function is executed, Octave prints a prompt and waits\n\
00992 for user input.  The input strings are then evaluated and the results\n\
00993 are printed.  This makes it possible to examine the values of variables\n\
00994 within a function, and to assign new values if necessary.  To leave the\n\
00995 prompt and return to normal execution type @samp{return} or @samp{dbcont}.\n\
00996 The @code{keyboard} function does not return an exit status.\n\
00997 \n\
00998 If @code{keyboard} is invoked without arguments, a default prompt of\n\
00999 @samp{debug> } is used.\n\
01000 @seealso{dbcont, dbquit}\n\
01001 @end deftypefn")
01002 {
01003   octave_value_list retval;
01004 
01005   int nargin = args.length ();
01006 
01007   if (nargin == 0 || nargin == 1)
01008     {
01009       unwind_protect frame;
01010 
01011       frame.add_fcn (octave_call_stack::restore_frame,
01012                      octave_call_stack::current_frame ());
01013 
01014       // Skip the frame assigned to the keyboard function.
01015       octave_call_stack::goto_frame_relative (0);
01016 
01017       tree_evaluator::debug_mode = true;
01018 
01019       tree_evaluator::current_frame = octave_call_stack::current_frame ();
01020 
01021       do_keyboard (args);
01022     }
01023   else
01024     print_usage ();
01025 
01026   return retval;
01027 }
01028 
01029 DEFUN (echo, args, ,
01030   "-*- texinfo -*-\n\
01031 @deftypefn {Command} {} echo options\n\
01032 Control whether commands are displayed as they are executed.  Valid\n\
01033 options are:\n\
01034 \n\
01035 @table @code\n\
01036 @item on\n\
01037 Enable echoing of commands as they are executed in script files.\n\
01038 \n\
01039 @item off\n\
01040 Disable echoing of commands as they are executed in script files.\n\
01041 \n\
01042 @item on all\n\
01043 Enable echoing of commands as they are executed in script files and\n\
01044 functions.\n\
01045 \n\
01046 @item off all\n\
01047 Disable echoing of commands as they are executed in script files and\n\
01048 functions.\n\
01049 @end table\n\
01050 \n\
01051 @noindent\n\
01052 With no arguments, @code{echo} toggles the current echo state.\n\
01053 @end deftypefn")
01054 {
01055   octave_value_list retval;
01056 
01057   int argc = args.length () + 1;
01058 
01059   string_vector argv = args.make_argv ("echo");
01060 
01061   if (error_state)
01062     return retval;
01063 
01064   switch (argc)
01065     {
01066     case 1:
01067       {
01068         if ((Vecho_executing_commands & ECHO_SCRIPTS)
01069             || (Vecho_executing_commands & ECHO_FUNCTIONS))
01070           Vecho_executing_commands = ECHO_OFF;
01071         else
01072           Vecho_executing_commands = ECHO_SCRIPTS;
01073       }
01074       break;
01075 
01076     case 2:
01077       {
01078         std::string arg = argv[1];
01079 
01080         if (arg == "on")
01081           Vecho_executing_commands = ECHO_SCRIPTS;
01082         else if (arg == "off")
01083           Vecho_executing_commands = ECHO_OFF;
01084         else
01085           print_usage ();
01086       }
01087       break;
01088 
01089     case 3:
01090       {
01091         std::string arg = argv[1];
01092 
01093         if (arg == "on" && argv[2] == "all")
01094           {
01095             int tmp = (ECHO_SCRIPTS | ECHO_FUNCTIONS);
01096             Vecho_executing_commands = tmp;
01097           }
01098         else if (arg == "off" && argv[2] == "all")
01099           Vecho_executing_commands = ECHO_OFF;
01100         else
01101           print_usage ();
01102       }
01103       break;
01104 
01105     default:
01106       print_usage ();
01107       break;
01108     }
01109 
01110   return retval;
01111 }
01112 
01113 DEFUN (completion_matches, args, nargout,
01114   "-*- texinfo -*-\n\
01115 @deftypefn {Built-in Function} {} completion_matches (@var{hint})\n\
01116 Generate possible completions given @var{hint}.\n\
01117 \n\
01118 This function is provided for the benefit of programs like Emacs which\n\
01119 might be controlling Octave and handling user input.  The current\n\
01120 command number is not incremented when this function is called.  This is\n\
01121 a feature, not a bug.\n\
01122 @end deftypefn")
01123 {
01124   octave_value retval;
01125 
01126   int nargin = args.length ();
01127 
01128   if (nargin == 1)
01129     {
01130       std::string hint = args(0).string_value ();
01131 
01132       if (! error_state)
01133         {
01134           int n = 32;
01135 
01136           string_vector list (n);
01137 
01138           int k = 0;
01139 
01140           for (;;)
01141             {
01142               std::string cmd = generate_completion (hint, k);
01143 
01144               if (! cmd.empty ())
01145                 {
01146                   if (k == n)
01147                     {
01148                       n *= 2;
01149                       list.resize (n);
01150                     }
01151 
01152                   list[k++] = cmd;
01153                 }
01154               else
01155                 {
01156                   list.resize (k);
01157                   break;
01158                 }
01159             }
01160 
01161           if (nargout > 0)
01162             {
01163               if (! list.empty ())
01164                 retval = list;
01165               else
01166                 retval = "";
01167             }
01168           else
01169             {
01170               // We don't use string_vector::list_in_columns here
01171               // because it will be easier for Emacs if the names
01172               // appear in a single column.
01173 
01174               int len = list.length ();
01175 
01176               for (int i = 0; i < len; i++)
01177                 octave_stdout << list[i] << "\n";
01178             }
01179 
01180           octave_completion_matches_called = true;
01181         }
01182     }
01183   else
01184     print_usage ();
01185 
01186   return retval;
01187 }
01188 
01189 DEFUN (read_readline_init_file, args, ,
01190   "-*- texinfo -*-\n\
01191 @deftypefn {Built-in Function} {} read_readline_init_file (@var{file})\n\
01192 Read the readline library initialization file @var{file}.  If\n\
01193 @var{file} is omitted, read the default initialization file (normally\n\
01194 @file{~/.inputrc}).\n\
01195 \n\
01196 @xref{Readline Init File, , , readline, GNU Readline Library},\n\
01197 for details.\n\
01198 @end deftypefn")
01199 {
01200   octave_value_list retval;
01201 
01202   int nargin = args.length ();
01203 
01204   if (nargin == 0)
01205     command_editor::read_init_file ();
01206   else if (nargin == 1)
01207     {
01208       std::string file = args(0).string_value ();
01209 
01210       if (! error_state)
01211         command_editor::read_init_file (file);
01212     }
01213   else
01214     print_usage ();
01215 
01216   return retval;
01217 }
01218 
01219 DEFUN (re_read_readline_init_file, args, ,
01220   "-*- texinfo -*-\n\
01221 @deftypefn {Built-in Function} {} re_read_readline_init_file ()\n\
01222 Re-read the last readline library initialization file that was read.\n\
01223 @xref{Readline Init File, , , readline, GNU Readline Library},\n\
01224 for details.\n\
01225 @end deftypefn")
01226 {
01227   octave_value_list retval;
01228 
01229   if (args.length () == 0)
01230     command_editor::re_read_init_file ();
01231   else
01232     print_usage ();
01233 
01234   return retval;
01235 }
01236 
01237 typedef std::map<std::string, octave_value> hook_fcn_map_type;
01238 
01239 static hook_fcn_map_type hook_fcn_map;
01240 
01241 static int
01242 input_event_hook (void)
01243 {
01244   if (! lexer_flags.defining_func)
01245     {
01246       hook_fcn_map_type::iterator p = hook_fcn_map.begin ();
01247 
01248       while (p != hook_fcn_map.end ())
01249         {
01250           std::string hook_fcn = p->first;
01251           octave_value user_data = p->second;
01252 
01253           hook_fcn_map_type::iterator q = p++;
01254 
01255           if (is_valid_function (hook_fcn))
01256             {
01257               if (user_data.is_defined ())
01258                 feval (hook_fcn, user_data, 0);
01259               else
01260                 feval (hook_fcn, octave_value_list (), 0);
01261             }
01262           else
01263             hook_fcn_map.erase (q);
01264         }
01265 
01266       if (hook_fcn_map.empty ())
01267         command_editor::remove_event_hook (input_event_hook);
01268     }
01269 
01270   return 0;
01271 }
01272 
01273 DEFUN (add_input_event_hook, args, ,
01274   "-*- texinfo -*-\n\
01275 @deftypefn  {Built-in Function} {} add_input_event_hook (@var{fcn})\n\
01276 @deftypefnx {Built-in Function} {} add_input_event_hook (@var{fcn}, @var{data})\n\
01277 Add the named function @var{fcn} to the list of functions to call\n\
01278 periodically when Octave is waiting for input.  The function should\n\
01279 have the form\n\
01280 \n\
01281 @example\n\
01282 @var{fcn} (@var{data})\n\
01283 @end example\n\
01284 \n\
01285 If @var{data} is omitted, Octave calls the function without any\n\
01286 arguments.\n\
01287 @seealso{remove_input_event_hook}\n\
01288 @end deftypefn")
01289 {
01290   octave_value_list retval;
01291 
01292   int nargin = args.length ();
01293 
01294   if (nargin == 1 || nargin == 2)
01295     {
01296       octave_value user_data;
01297 
01298       if (nargin == 2)
01299         user_data = args(1);
01300 
01301       std::string hook_fcn = args(0).string_value ();
01302 
01303       if (! error_state)
01304         {
01305           if (hook_fcn_map.empty ())
01306             command_editor::add_event_hook (input_event_hook);
01307 
01308           hook_fcn_map[hook_fcn] = user_data;
01309         }
01310       else
01311         error ("add_input_event_hook: expecting string as first arg");
01312     }
01313   else
01314     print_usage ();
01315 
01316   return retval;
01317 }
01318 
01319 DEFUN (remove_input_event_hook, args, ,
01320   "-*- texinfo -*-\n\
01321 @deftypefn {Built-in Function} {} remove_input_event_hook (@var{fcn})\n\
01322 Remove the named function @var{fcn} from the list of functions to call\n\
01323 periodically when Octave is waiting for input.\n\
01324 @seealso{add_input_event_hook}\n\
01325 @end deftypefn")
01326 {
01327   octave_value_list retval;
01328 
01329   int nargin = args.length ();
01330 
01331   if (nargin == 1)
01332     {
01333       std::string hook_fcn = args(0).string_value ();
01334 
01335       if (! error_state)
01336         {
01337           hook_fcn_map_type::iterator p = hook_fcn_map.find (hook_fcn);
01338 
01339           if (p != hook_fcn_map.end ())
01340             hook_fcn_map.erase (p);
01341           else
01342             error ("remove_input_event_hook: %s not found in list",
01343                    hook_fcn.c_str ());
01344 
01345           if (hook_fcn_map.empty ())
01346             command_editor::remove_event_hook (input_event_hook);
01347         }
01348       else
01349         error ("remove_input_event_hook: expecting string as first arg");
01350     }
01351   else
01352     print_usage ();
01353 
01354   return retval;
01355 }
01356 
01357 DEFUN (PS1, args, nargout,
01358   "-*- texinfo -*-\n\
01359 @deftypefn  {Built-in Function} {@var{val} =} PS1 ()\n\
01360 @deftypefnx {Built-in Function} {@var{old_val} =} PS1 (@var{new_val})\n\
01361 @deftypefnx {Built-in Function} {} PS1 (@var{new_val}, \"local\")\n\
01362 Query or set the primary prompt string.  When executing interactively,\n\
01363 Octave displays the primary prompt when it is ready to read a command.\n\
01364 \n\
01365 The default value of the primary prompt string is @code{\"\\s:\\#> \"}.\n\
01366 To change it, use a command like\n\
01367 \n\
01368 @example\n\
01369 PS1 (\"\\\\u@@\\\\H> \")\n\
01370 @end example\n\
01371 \n\
01372 @noindent\n\
01373 which will result in the prompt @samp{boris@@kremvax> } for the user\n\
01374 @samp{boris} logged in on the host @samp{kremvax.kgb.su}.  Note that two\n\
01375 backslashes are required to enter a backslash into a double-quoted\n\
01376 character string.  @xref{Strings}.\n\
01377 \n\
01378 You can also use ANSI escape sequences if your terminal supports them.\n\
01379 This can be useful for coloring the prompt.  For example,\n\
01380 \n\
01381 @example\n\
01382 PS1 (\"\\\\[\\\\033[01;31m\\\\]\\\\s:\\\\#> \\\\[\\\\033[0m\\\\]\")\n\
01383 @end example\n\
01384 \n\
01385 @noindent\n\
01386 will give the default Octave prompt a red coloring.\n\
01387 \n\
01388 When called from inside a function with the \"local\" option, the variable is\n\
01389 changed locally for the function and any subroutines it calls.  The original\n\
01390 variable value is restored when exiting the function.\n\
01391 @seealso{PS2, PS4}\n\
01392 @end deftypefn")
01393 {
01394   return SET_INTERNAL_VARIABLE (PS1);
01395 }
01396 
01397 DEFUN (PS2, args, nargout,
01398   "-*- texinfo -*-\n\
01399 @deftypefn  {Built-in Function} {@var{val} =} PS2 ()\n\
01400 @deftypefnx {Built-in Function} {@var{old_val} =} PS2 (@var{new_val})\n\
01401 @deftypefnx {Built-in Function} {} PS2 (@var{new_val}, \"local\")\n\
01402 Query or set the secondary prompt string.  The secondary prompt is\n\
01403 printed when Octave is expecting additional input to complete a\n\
01404 command.  For example, if you are typing a @code{for} loop that spans several\n\
01405 lines, Octave will print the secondary prompt at the beginning of\n\
01406 each line after the first.  The default value of the secondary prompt\n\
01407 string is @code{\"> \"}.\n\
01408 \n\
01409 When called from inside a function with the \"local\" option, the variable is\n\
01410 changed locally for the function and any subroutines it calls.  The original\n\
01411 variable value is restored when exiting the function.\n\
01412 @seealso{PS1, PS4}\n\
01413 @end deftypefn")
01414 {
01415   return SET_INTERNAL_VARIABLE (PS2);
01416 }
01417 
01418 DEFUN (PS4, args, nargout,
01419   "-*- texinfo -*-\n\
01420 @deftypefn  {Built-in Function} {@var{val} =} PS4 ()\n\
01421 @deftypefnx {Built-in Function} {@var{old_val} =} PS4 (@var{new_val})\n\
01422 @deftypefnx {Built-in Function} {} PS4 (@var{new_val}, \"local\")\n\
01423 Query or set the character string used to prefix output produced\n\
01424 when echoing commands is enabled.\n\
01425 The default value is @code{\"+ \"}.\n\
01426 @xref{Diary and Echo Commands}, for a description of echoing commands.\n\
01427 \n\
01428 When called from inside a function with the \"local\" option, the variable is\n\
01429 changed locally for the function and any subroutines it calls.  The original\n\
01430 variable value is restored when exiting the function.\n\
01431 @seealso{echo, echo_executing_commands, PS1, PS2}\n\
01432 @end deftypefn")
01433 {
01434   return SET_INTERNAL_VARIABLE (PS4);
01435 }
01436 
01437 DEFUN (completion_append_char, args, nargout,
01438   "-*- texinfo -*-\n\
01439 @deftypefn  {Built-in Function} {@var{val} =} completion_append_char ()\n\
01440 @deftypefnx {Built-in Function} {@var{old_val} =} completion_append_char (@var{new_val})\n\
01441 @deftypefnx {Built-in Function} {} completion_append_char (@var{new_val}, \"local\")\n\
01442 Query or set the internal character variable that is appended to\n\
01443 successful command-line completion attempts.  The default\n\
01444 value is @code{\" \"} (a single space).\n\
01445 \n\
01446 When called from inside a function with the \"local\" option, the variable is\n\
01447 changed locally for the function and any subroutines it calls.  The original\n\
01448 variable value is restored when exiting the function.\n\
01449 @end deftypefn")
01450 {
01451   return SET_INTERNAL_VARIABLE (completion_append_char);
01452 }
01453 
01454 DEFUN (echo_executing_commands, args, nargout,
01455   "-*- texinfo -*-\n\
01456 @deftypefn  {Built-in Function} {@var{val} =} echo_executing_commands ()\n\
01457 @deftypefnx {Built-in Function} {@var{old_val} =} echo_executing_commands (@var{new_val})\n\
01458 @deftypefnx {Built-in Function} {} echo_executing_commands (@var{new_val}, \"local\")\n\
01459 Query or set the internal variable that controls the echo state.\n\
01460 It may be the sum of the following values:\n\
01461 \n\
01462 @table @asis\n\
01463 @item 1\n\
01464 Echo commands read from script files.\n\
01465 \n\
01466 @item 2\n\
01467 Echo commands from functions.\n\
01468 \n\
01469 @item 4\n\
01470 Echo commands read from command line.\n\
01471 @end table\n\
01472 \n\
01473 More than one state can be active at once.  For example, a value of 3 is\n\
01474 equivalent to the command @kbd{echo on all}.\n\
01475 \n\
01476 The value of @code{echo_executing_commands} may be set by the @kbd{echo}\n\
01477 command or the command line option @option{--echo-commands}.\n\
01478 \n\
01479 When called from inside a function with the \"local\" option, the variable is\n\
01480 changed locally for the function and any subroutines it calls.  The original\n\
01481 variable value is restored when exiting the function.\n\
01482 @end deftypefn")
01483 {
01484   return SET_INTERNAL_VARIABLE (echo_executing_commands);
01485 }
01486 
01487 DEFUN (__request_drawnow__, args, ,
01488   "-*- texinfo -*-\n\
01489 @deftypefn  {Built-in Function} {} __request_drawnow__ ()\n\
01490 @deftypefnx {Built-in Function} {} __request_drawnow__ (@var{flag})\n\
01491 Undocumented internal function.\n\
01492 @end deftypefn")
01493 {
01494   octave_value retval;
01495 
01496   int nargin = args.length ();
01497 
01498   if (nargin == 0)
01499     Vdrawnow_requested = true;
01500   else if (nargin == 1)
01501     Vdrawnow_requested = args(0).bool_value ();
01502   else
01503     print_usage ();
01504 
01505   return retval;
01506 }
01507 
01508 DEFUN (__gud_mode__, args, ,
01509   "-*- texinfo -*-\n\
01510 @deftypefn {Built-in Function} {} __gud_mode__ ()\n\
01511 Undocumented internal function.\n\
01512 @end deftypefn")
01513 {
01514   octave_value retval;
01515 
01516   int nargin = args.length ();
01517 
01518   if (nargin == 0)
01519     retval = Vgud_mode;
01520   else if (nargin == 1)
01521     Vgud_mode = args(0).bool_value ();
01522   else
01523     print_usage ();
01524 
01525   return retval;
01526 }
01527 
01528 DEFUN (filemarker, args, nargout,
01529   "-*- texinfo -*-\n\
01530 @deftypefn  {Built-in Function} {@var{val} =} filemarker ()\n\
01531 @deftypefnx {Built-in Function} {} filemarker (@var{new_val})\n\
01532 @deftypefnx {Built-in Function} {} filemarker (@var{new_val}, \"local\")\n\
01533 Query or set the character used to separate filename from the\n\
01534 the subfunction names contained within the file.  This can be used in\n\
01535 a generic manner to interact with subfunctions.  For example,\n\
01536 \n\
01537 @example\n\
01538 help ([\"myfunc\", filemarker, \"mysubfunc\"])\n\
01539 @end example\n\
01540 \n\
01541 @noindent\n\
01542 returns the help string associated with the sub-function @code{mysubfunc}\n\
01543 of the function @code{myfunc}.  Another use of @code{filemarker} is when\n\
01544 debugging it allows easier placement of breakpoints within sub-functions.\n\
01545 For example,\n\
01546 \n\
01547 @example\n\
01548 dbstop ([\"myfunc\", filemarker, \"mysubfunc\"])\n\
01549 @end example\n\
01550 \n\
01551 @noindent\n\
01552 will set a breakpoint at the first line of the subfunction @code{mysubfunc}.\n\
01553 \n\
01554 When called from inside a function with the \"local\" option, the variable is\n\
01555 changed locally for the function and any subroutines it calls.  The original\n\
01556 variable value is restored when exiting the function.\n\
01557 @end deftypefn")
01558 {
01559   char tmp = Vfilemarker;
01560   octave_value retval = SET_INTERNAL_VARIABLE (filemarker);
01561 
01562   // The character passed must not be a legal character for a function name
01563   if (! error_state && (::isalnum (Vfilemarker) || Vfilemarker == '_'))
01564     {
01565       Vfilemarker = tmp;
01566       error ("filemarker: character can not be a valid character for a function name");
01567     }
01568 
01569   return retval;
01570 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines