GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
help.cc
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 1993-2025 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 <cstdlib>
31#include <cstring>
32
33#include <algorithm>
34#include <fstream>
35#include <istream>
36#include <map>
37#include <sstream>
38#include <string>
39
40#include "cmd-edit.h"
41#include "file-ops.h"
42#include "file-stat.h"
43#include "lo-sysdep.h"
44#include "oct-env.h"
45#include "oct-locbuf.h"
46#include "str-vec.h"
47
48#include "Cell.h"
49#include "builtin-defun-decls.h"
50#include "defaults.h"
51#include "defun.h"
52#include "error.h"
53#include "errwarn.h"
54#include "help.h"
55#include "input.h"
56#include "interpreter-private.h"
57#include "interpreter.h"
58#include "load-path.h"
59#include "ov-classdef.h"
60#include "ov-fcn-handle.h"
61#include "ov-usr-fcn.h"
62#include "ovl.h"
63#include "pager.h"
64#include "parse.h"
65#include "pathsearch.h"
66#include "procstream.h"
67#include "quit.h"
68#include "sighandlers.h"
69#include "symtab.h"
70#include "unwind-prot.h"
71#include "utils.h"
72#include "variables.h"
73#include "version.h"
74
75#include "default-defs.h"
76
78
79const static char *const operators[] =
80{
81 "!",
82 "~",
83 "!=",
84 "~=",
85 R"(")",
86 "#",
87 "%",
88 "#{",
89 "%{",
90 "#}",
91 "%}",
92 "...",
93 "&",
94 "&&",
95 "'",
96 "(",
97 ")",
98 "*",
99 "^",
100 "+",
101 "++",
102 ",",
103 "-",
104 "--",
105 ".'",
106 ".*",
107 ".^",
108 "./",
109 "/",
110 R"(.\)",
111 R"(\)",
112 ":",
113 ";",
114 "<",
115 "<=",
116 "=",
117 "==",
118 ">",
119 ">=",
120 "[",
121 "]",
122 "|",
123 "||",
124 nullptr
125};
126
127const static string_vector operator_names (operators);
128
129static bool
130looks_like_html (const std::string& msg)
131{
132 const std::size_t p1 = msg.find ('\n');
133 std::string t = msg.substr (0, p1);
134 // FIXME: this comparison should be case-insensitive
135 const std::size_t p2 = t.find ("<html");
136
137 return (p2 != std::string::npos);
138}
139
140static bool
141looks_like_texinfo (const std::string& msg, std::size_t& p1)
142{
143 p1 = msg.find ('\n');
144
145 std::string t = msg.substr (0, p1);
146
147 if (p1 == std::string::npos)
148 p1 = 0;
149
150 std::size_t p2 = t.find ("-*- texinfo -*-");
151
152 return (p2 != std::string::npos);
153}
154
157 int nargout)
158{
159 return set_internal_variable (m_built_in_docstrings_file, args, nargout,
160 "built_in_docstrings_file", false);
161}
162
164help_system::doc_cache_file (const octave_value_list& args, int nargout)
165{
166 return set_internal_variable (m_doc_cache_file, args, nargout,
167 "doc_cache_file", false);
168}
169
171help_system::info_file (const octave_value_list& args, int nargout)
172{
173 return set_internal_variable (m_info_file, args, nargout,
174 "info_file", false);
175}
176
178help_system::info_program (const octave_value_list& args, int nargout)
179{
180 return set_internal_variable (m_info_program, args, nargout,
181 "info_program", false);
182}
183
185help_system::makeinfo_program (const octave_value_list& args, int nargout)
186{
187 return set_internal_variable (m_makeinfo_program, args, nargout,
188 "makeinfo_program", false);
189}
190
193 int nargout)
194{
195 return set_internal_variable (m_suppress_verbose_help_message, args,
196 nargout, "suppress_verbose_help_message");
197}
198
200help_system::texi_macros_file (const octave_value_list& args, int nargout)
201{
202 return set_internal_variable (m_texi_macros_file, args, nargout,
203 "texi_macros_file", false);
204}
205
206std::string
207help_system::raw_help (const std::string& nm, bool& symbol_found) const
208{
209 std::string h;
210 std::string w;
211 std::string f;
212
213 bool found;
214
215 found = raw_help_from_symbol_table (nm, h, w, symbol_found);
216
217 if (! found)
218 found = raw_help_from_file (nm, h, f, symbol_found);
219
220 bool external_doc = h.compare (0, 12, "external-doc") == 0;
221
222 if (! found || external_doc)
223 {
224 std::string tmp_nm = nm;
225
226 if (external_doc && h.length () > 12 && h[12] == ':')
227 tmp_nm = h.substr (13);
228
229 raw_help_from_docstrings_file (tmp_nm, h, symbol_found);
230 }
231
232 return h;
233}
234
235bool
236help_system::get_which_info_from_fcn (const std::string& name, const octave_value& ov_fcn, std::string& file, std::string& type) const
237{
238 file = "";
239 type = "";
240
241 if (ov_fcn.is_function ())
242 {
243 octave_function *fcn = ov_fcn.function_value ();
244
245 if (fcn)
246 {
247 if (fcn->is_classdef_meta ())
248 {
249 octave_classdef_meta *meta_obj
250 = dynamic_cast<octave_classdef_meta *> (fcn);
251
252 file = meta_obj->file_name ();
253
254 if (meta_obj->is_classdef_constructor ())
255 type = "class constructor";
256 else if (meta_obj->is_classdef_method ())
257 type = "class method";
258 else
259 type = "classdef meta object";
260 }
261 else
262 {
263 file = fcn->fcn_file_name ();
264
265 if (! file.empty ())
266 type = ov_fcn.is_user_script () ? "script" : "function";
267 else
268 {
269 if (fcn->is_user_function ())
270 type = "command-line function";
271 else
272 {
273 file = fcn->src_file_name ();
274 type = "built-in function";
275 }
276 }
277 }
278
279 return true;
280 }
281 else
282 {
283 // We might find a file that contains only a doc string.
284
285 load_path& lp = m_interpreter.get_load_path ();
286
287 file = lp.find_fcn_file (name);
288
289 if (file.empty ())
290 return false;
291 }
292 }
293
294 return false;
295}
296
297// FIXME: There is a lot of duplication between the following function
298// and help_system::raw_help_from_symbol_table. Some refactoring would
299// probably be useful.
300
301std::string
302help_system::which (const std::string& name,
303 std::string& type) const
304{
305 std::string file;
306
307 if (name.empty ())
308 return file;
309
310 type = "";
311
312 symbol_table& symtab = m_interpreter.get_symbol_table ();
313
314 size_t pos = name.find ('.');
315
316 if (pos == std::string::npos)
317 {
318 // Simple name. If not found, continue looking for packages and
319 // classes.
320
321 octave_value ov_fcn = symtab.find_function (name);
322
323 if (get_which_info_from_fcn (name, ov_fcn, file, type))
324 return file;
325 }
326
327 // NAME contains '.' and must match the following pattern:
328 //
329 // (package.)*(package|classname).(property|method)*
330 //
331 // Start by looking up the full name. It could be either a package or
332 // a class and we are done. Otherwise, strip the final component and
333 // lookup that name. If it is a package, look for a function. If it
334 // is a class, look for a property or method.
335
336 cdef_manager& cdm = m_interpreter.get_cdef_manager ();
337
338 // FIXME: In the following search we may load classes. Is that really
339 // what we want, or should we just search the loadpath for
340 // +pkga/+pkgb/classname/file.m, etc. and attempt to extract help text
341 // without actually installing packages and classes into the fcn_info
342 // table?
343
344 // Is NAME a class?
345
346 cdef_class cls = cdm.find_class (name, false, true);
347
348 if (cls.ok ())
349 {
350 // FIXME: Return documentation for the class or the class
351 // constructor?
352
353 file = cls.file_name ();
354 type = "classdef class";
355
356 return file;
357 }
358
359 cdef_package pkg = cdm.find_package (name, false, true);
360
361 if (pkg.ok ())
362 {
363 // FIXME: How to get the fill name of a package?
364 file = pkg.get_name ();
365 type = "package";
366
367 return file;
368 }
369
370 // Strip final component (might be a property or method name).
371
372 pos = name.rfind ('.');
373 std::string prefix = name.substr (0, pos);
374 std::string nm = name.substr (pos+1);
375
376 // Is PREFIX the name of a class?
377
378 cls = cdm.find_class (prefix, false, true);
379
380 if (cls.ok ())
381 {
382 // FIXME: Should we only find public methods here?
383
384 octave_value ov_meth = cls.get_method (nm);
385
386 if (get_which_info_from_fcn (nm, ov_meth, file, type))
387 return file;
388
389 // FIXME: Should we only find public properties here?
390
391 cdef_property prop = cls.find_property (nm);
392
393 if (prop.ok ())
394 {
395 file = cls.file_name ();
396 type = "class property";
397
398 return file;
399 }
400 }
401
402 // Or is PREFIX the name of a package?
403
404 pkg = cdm.find_package (prefix, false, true);
405
406 if (pkg.ok ())
407 {
408 octave_value ov_fcn = pkg.find (nm);
409
410 if (get_which_info_from_fcn (nm, ov_fcn, file, type))
411 return file;
412 }
413
414 // File query.
415
416 load_path& lp = m_interpreter.get_load_path ();
417
418 // For compatibility: "file." queries "file".
419 if (name.size () > 1 && name[name.size () - 1] == '.')
420 file = lp.find_file (name.substr (0, name.size () - 1));
421 else
422 file = lp.find_file (name);
423
424 file = sys::env::make_absolute (file);
425
426 if (! file.empty ())
427 type = "file";
428
429 return file;
430}
431
432std::string
433help_system::which (const std::string& name) const
434{
435 std::string type;
436
437 return which (name, type);
438}
439
442{
443 const static string_vector keywords
444 = Fiskeyword ()(0).string_vector_value ();
445
446 const static int key_len = keywords.numel ();
447
448 symbol_table& symtab = m_interpreter.get_symbol_table ();
449
450 const string_vector bif = symtab.built_in_function_names ();
451 const int bif_len = bif.numel ();
452
453 const string_vector cfl = symtab.cmdline_function_names ();
454 const int cfl_len = cfl.numel ();
455
456 const string_vector lcl = m_interpreter.variable_names ();
457 const int lcl_len = lcl.numel ();
458
459 load_path& lp = m_interpreter.get_load_path ();
460
461 const string_vector ffl = lp.fcn_names ();
462 const int ffl_len = ffl.numel ();
463
464 const string_vector afl = m_interpreter.autoloaded_functions ();
465 const int afl_len = afl.numel ();
466
467 const string_vector lfl = local_functions ();
468 const int lfl_len = lfl.numel ();
469
470 const int total_len
471 = key_len + bif_len + cfl_len + lcl_len + ffl_len + afl_len + lfl_len;
472
473 string_vector list (total_len);
474
475 // Put all the symbols in one big list.
476
477 int j = 0;
478 int i = 0;
479
480 for (i = 0; i < key_len; i++)
481 list[j++] = keywords[i];
482
483 for (i = 0; i < bif_len; i++)
484 list[j++] = bif[i];
485
486 for (i = 0; i < cfl_len; i++)
487 list[j++] = cfl[i];
488
489 for (i = 0; i < lcl_len; i++)
490 list[j++] = lcl[i];
491
492 for (i = 0; i < ffl_len; i++)
493 list[j++] = ffl[i];
494
495 for (i = 0; i < afl_len; i++)
496 list[j++] = afl[i];
497
498 for (i = 0; i < lfl_len; i++)
499 list[j++] = lfl[i];
500
501 return list;
502}
503
504void
505help_system::get_help_text (const std::string& name, std::string& text,
506 std::string& format) const
507{
508 bool symbol_found = false;
509 text = raw_help (name, symbol_found);
510
511 format = "Not found";
512 if (symbol_found)
513 {
514 std::size_t idx = -1;
515 if (text.empty ())
516 {
517 format = "Not documented";
518 }
519 else if (looks_like_texinfo (text, idx))
520 {
521 format = "texinfo";
522 text.erase (0, idx);
523 }
524 else if (looks_like_html (text))
525 {
526 format = "html";
527 }
528 else
529 {
530 format = "plain text";
531 }
532 }
533}
534
535void
536help_system::get_help_text_from_file (const std::string& fname,
537 std::string& text,
538 std::string& format) const
539{
540 bool symbol_found = false;
541
542 std::string f;
543
544 raw_help_from_file (fname, text, f, symbol_found);
545
546 format = "Not found";
547 if (symbol_found)
548 {
549 std::size_t idx = -1;
550 if (text.empty ())
551 {
552 format = "Not documented";
553 }
554 else if (looks_like_texinfo (text, idx))
555 {
556 format = "texinfo";
557 text.erase (0, idx);
558 }
559 else if (looks_like_html (text))
560 {
561 format = "html";
562 }
563 else
564 {
565 format = "plain text";
566 }
567 }
568}
569
570std::string
571help_system::init_built_in_docstrings_file ()
572{
573 std::string df = sys::env::getenv ("OCTAVE_BUILT_IN_DOCSTRINGS_FILE");
574
575 std::string dir_sep = sys::file_ops::dir_sep_str ();
576
577 if (df.empty ())
578 df = config::oct_etc_dir () + dir_sep + "built-in-docstrings";
579
580 return df;
581}
582
583std::string
584help_system::init_doc_cache_file ()
585{
586 std::string def_file = config::prepend_octave_home (OCTAVE_DOC_CACHE_FILE);
587
588 std::string env_file = sys::env::getenv ("OCTAVE_DOC_CACHE_FILE");
589
590 return (env_file.empty () ? def_file : env_file);
591}
592
593std::string
594help_system::init_info_file ()
595{
596 std::string std_info_file = config::prepend_octave_home (OCTAVE_INFOFILE);
597
598 std::string oct_info_file = sys::env::getenv ("OCTAVE_INFO_FILE");
599
600 return (oct_info_file.empty () ? std_info_file : oct_info_file);
601}
602
603std::string
604help_system::init_info_program ()
605{
606 std::string info_prog = sys::env::getenv ("OCTAVE_INFO_PROGRAM");
607
608 if (info_prog.empty ())
609 info_prog = "info";
610
611 return info_prog;
612}
613
614std::string
615help_system::init_texi_macros_file ()
616{
617 std::string def_file
618 = config::prepend_octave_home (OCTAVE_TEXI_MACROS_FILE);
619
620 std::string env_file = sys::env::getenv ("OCTAVE_TEXI_MACROS_FILE");
621
622 return (env_file.empty () ? def_file : env_file);
623}
624
625// Return a vector of all functions from this file,
626// for use in command line auto-completion.
628help_system::local_functions () const
629{
630 string_vector retval;
631
632 tree_evaluator& tw = m_interpreter.get_evaluator ();
633
634 octave_user_code *curr_fcn = tw.current_user_code ();
635
636 if (! curr_fcn)
637 return retval;
638
639 // All subfunctions are listed in the top-level function of this file.
640 // If curr_fcn is a subfunction, then there must be a parent and
641 // curr_fcn will always be valid in and after executing this loop.
642
643 while (curr_fcn->is_subfunction ())
644 {
645 symbol_scope pscope = curr_fcn->parent_fcn_scope ();
646 curr_fcn = pscope.user_code ();
647 }
648
649 // Get subfunctions.
650 const std::list<std::string> names = curr_fcn->subfunction_names ();
651
652 std::size_t sz = names.size ();
653 retval.resize (sz);
654
655 // Loop over them.
656 std::size_t i = 0;
657 for (const auto& nm : names)
658 retval(i++) = nm;
659
660 return retval;
661}
662
663static bool
664get_help_from_fcn (const std::string& fcn_nm, const octave_value& ov_fcn, std::string& help, std::string& what, bool& symbol_found)
665{
666 symbol_found = false;
667
668 help = "";
669 what = "";
670
671 if (ov_fcn.is_function ())
672 {
673 octave_function *fcn = ov_fcn.function_value ();
674
675 help = fcn->doc_string (fcn_nm);
676 what = fcn->fcn_file_name ();
677
678 if (help.empty () && ov_fcn.is_user_function ())
679 {
681
682 if (ufcn->is_classdef_constructor ())
683 help = "undocumented constructor: ";
684 else if (ufcn->is_classdef_method ())
685 help = "undocumented method: ";
686 else
687 help = "undocumented function: ";
688
689 help += ufcn->signature ();
690 }
691
692 if (what.empty ())
693 what = fcn->is_user_function () ? "command-line function" : "built-in function";
694
695 symbol_found = true;
696 }
697
698 return symbol_found;
699}
700
701bool
702help_system::raw_help_for_class (const cdef_class& cls,
703 const std::string& name,
704 std::string& help, std::string& what,
705 bool& symbol_found) const
706{
707 if (cls.ok ())
708 {
709 // Is the class documented?
710 help = cls.doc_string ();
711
712 if (! help.empty ())
713 {
714 what = "class";
715
716 symbol_found = true;
717 return true;
718 }
719
720 // Look for constructor.
721 std::size_t pos = name.rfind ('.');
722
723 if (pos != std::string::npos)
724 {
725 std::string nm = name.substr (pos+1);
726
727 octave_value ov_meth = cls.get_method (nm);
728
729 if (get_help_from_fcn (nm, ov_meth, help, what, symbol_found))
730 {
731 what = "constructor";
732 return true;
733 }
734 }
735
736 // No dot in name and class is undocumented. Look for documented
737 // constructor.
738
739 octave_value ov_meth = cls.get_method (name);
740
741 if (get_help_from_fcn (name, ov_meth, help, what, symbol_found))
742 {
743 what = "constructor";
744 symbol_found = true;
745 return true;
746 }
747
748 // We found a class, but no docstring for it and there is no
749 // constructor explicitly defined.
750
751 help = "default constructor: obj = " + name + " ()";
752 what = "constructor";
753 symbol_found = true;
754 return true;
755 }
756
757 return false;
758}
759
760// FIXME: There is a lot of duplication between the following function
761// and help_system::which. Some refactoring would probably be useful.
762
763bool
764help_system::raw_help_from_symbol_table (const std::string& name, std::string& help, std::string& what, bool& symbol_found) const
765{
766 symbol_table& symtab = m_interpreter.get_symbol_table ();
767
768 size_t pos = name.find ('.');
769
770 if (pos == std::string::npos)
771 {
772 // Simple name. If not found, continue looking for packages and
773 // classes.
774
775 octave_value ov_fcn = symtab.find_function (name);
776
777 // FIXME: it seems like there is a lot of potential for confusion
778 // because is_function can also return true for
779 // octave_classdef_meta objects.
780
781 if (! ov_fcn.is_classdef_meta ()
782 && get_help_from_fcn (name, ov_fcn, help, what, symbol_found))
783 return true;
784 }
785
786 // If NAME does not contain '.', then it should be a package or a
787 // class name.
788 //
789 // If NAME contains '.' it should match the following pattern:
790 //
791 // (package.)*(package|classname).(property|method)*
792 //
793 // Start by looking up the full name. It could be either a package or
794 // a class and we are done. Otherwise, strip the final component and
795 // lookup that name. If it is a package, look for a function. If it
796 // is a class, look for a property or method.
797
798 cdef_manager& cdm = m_interpreter.get_cdef_manager ();
799
800 // FIXME: In the following search we may load classes. Is that really
801 // what we want, or should we just search the loadpath for
802 // +pkga/+pkgb/classname/file.m, etc. and attempt to extract help text
803 // without actually installing packages and classes into the fcn_info
804 // table?
805
806 // Is NAME a class?
807
808 cdef_class cls = cdm.find_class (name, false, true);
809
810 if (raw_help_for_class (cls, name, help, what, symbol_found))
811 return true;
812
813 cdef_package pkg = cdm.find_package (name, false, true);
814
815 if (pkg.ok ())
816 {
817 help = "package " + name;
818 what = "package";
819
820 symbol_found = true;
821 return true;
822 }
823
824 // Strip final component (might be a property or method name).
825
826 pos = name.rfind ('.');
827 std::string prefix = name.substr (0, pos);
828 std::string nm = name.substr (pos+1);
829
830 // Is PREFIX the name of a class?
831
832 cls = cdm.find_class (prefix, false, true);
833
834 bool found_class = cls.ok ();
835
836 if (found_class)
837 {
838 // FIXME: Should we only find public methods here?
839
840 octave_value ov_meth = cls.get_method (nm);
841
842 if (get_help_from_fcn (nm, ov_meth, help, what, symbol_found))
843 {
844 what = "class method";
845 return true;
846 }
847
848 // Found class but no method. If the NM is the same as the name
849 // of the class, then we have a default constructor.
850
851 if (cls.get_name () == nm)
852 {
853 help = "default constructor: obj = " + nm + " ()";
854 what = "constructor";
855 symbol_found = true;
856 return true;
857 }
858
859 // FIXME: Should we only find public properties here?
860
861 cdef_property prop = cls.find_property (nm);
862
863 if (prop.ok ())
864 {
865 // FIXME: is it supposed to be possible to document
866 // properties?
867
868 help = prop.doc_string ();
869 what = "class property";
870
871 symbol_found = true;
872 return true;
873 }
874 }
875
876 // Or is PREFIX the name of a package?
877
878 pkg = cdm.find_package (prefix, false, true);
879
880 if (pkg.ok ())
881 {
882 octave_value ov_fcn = pkg.find (nm);
883
884 if (get_help_from_fcn (nm, ov_fcn, help, what, symbol_found))
885 return true;
886 }
887
888 if (nm == "m" && raw_help_for_class (cls, prefix, help, what, symbol_found))
889 return true;
890
891 return false;
892}
893
894bool
895help_system::raw_help_from_file (const std::string& nm,
896 std::string& h, std::string& file,
897 bool& symbol_found) const
898{
899 bool retval = false;
900
901 h = get_help_from_file (nm, symbol_found, file);
902
903 if (h.length () > 0)
904 retval = true;
905
906 return retval;
907}
908
909bool
910help_system::raw_help_from_docstrings_file (const std::string& nm,
911 std::string& h,
912 bool& symbol_found) const
913{
914 typedef std::pair<std::streampos, std::streamoff> txt_limits_type;
915 typedef std::map<std::string, txt_limits_type> help_txt_map_type;
916
917 static help_txt_map_type help_txt_map;
918 static bool initialized = false;
919
920 h = "";
921 symbol_found = false;
922
923 // FIXME: Should we cache the timestamp of the file and reload the
924 // offsets if it changes? Or just warn about that? Or just ignore
925 // it, and assume it won't change?
926
927 if (! initialized)
928 {
929 std::ifstream file = sys::ifstream (m_built_in_docstrings_file.c_str (),
930 std::ios::in | std::ios::binary);
931
932 if (! file)
933 error ("failed to open docstrings file: %s",
934 m_built_in_docstrings_file.c_str ());
935
936 // Ignore header;
937 file.ignore (std::numeric_limits<std::streamsize>::max(), 0x1d);
938
939 if (file.eof ())
940 error ("invalid built-in-docstrings file!");
941
942 // FIXME: eliminate fixed buffer size.
943 std::size_t bufsize = 1000;
944 OCTAVE_LOCAL_BUFFER (char, buf, bufsize);
945
946 while (! file.eof ())
947 {
948 std::string name;
949 int i = 0;
950 int c;
951 while (file
952 && (c = file.get ()) != std::istream::traits_type::eof ())
953 {
954 if (c == '\n' || c == '\r')
955 {
956 buf[i] = '\0';
957 name = buf;
958 break;
959 }
960 else
961 buf[i++] = c;
962 }
963
964 // Skip @c FILENAME which is part of current DOCSTRINGS
965 // syntax. This may disappear if a specific format for
966 // docstring files is developed.
967 while (file
968 && (c = file.get ()) != std::istream::traits_type::eof ()
969 && c != '\n' && c != '\r')
970 ; // skip text
971
972 // skip newline characters
973 while (file
974 && (c = file.get ()) != std::istream::traits_type::eof ()
975 && (c == '\n' || c == '\r'))
976 ; // skip text
977
978 file.unget ();
979
980 // Position of beginning of help text.
981 std::streampos beg = file.tellg ();
982
983 // Skip help text.
984 file.ignore (std::numeric_limits<std::streamsize>::max(), 0x1d);
985
986 // Position of end of help text.
987 std::streamoff len;
988
989 if (! file.eof ())
990 len = file.tellg () - beg - 1;
991 else
992 {
993 file.seekg (0, file.end);
994 len = file.tellg () - beg - 1;
995 file.setstate (file.eofbit); // reset eof flag
996 }
997
998 help_txt_map[name] = txt_limits_type (beg, len);
999 }
1000
1001 initialized = true;
1002 }
1003
1004 help_txt_map_type::const_iterator it = help_txt_map.find (nm);
1005
1006 if (it != help_txt_map.end ())
1007 {
1008 txt_limits_type txt_limits = it->second;
1009
1010 std::streampos beg = txt_limits.first;
1011 std::streamoff len = txt_limits.second;
1012
1013 std::ifstream file = sys::ifstream (m_built_in_docstrings_file.c_str (),
1014 std::ios::in | std::ios::binary);
1015
1016 if (! file)
1017 error ("failed to open docstrings file: %s",
1018 m_built_in_docstrings_file.c_str ());
1019
1020 file.seekg (beg);
1021
1022 std::size_t txt_len = len;
1023 OCTAVE_LOCAL_BUFFER (char, buf, txt_len + 1);
1024
1025 file.read (buf, txt_len);
1026
1027 buf[txt_len] = '\0';
1028
1029 h = buf;
1030
1031 symbol_found = true;
1032 }
1033
1034 return symbol_found;
1035}
1036
1037// FIXME: It's not likely that this does the right thing now.
1038
1041{
1042 help_system& help_sys = __get_help_system__ ();
1043
1044 return help_sys.make_name_list ();
1045}
1046
1047DEFMETHOD (get_help_text, interp, args, ,
1048 doc: /* -*- texinfo -*-
1049@deftypefn {} {[@var{text}, @var{format}] =} get_help_text (@var{name})
1050Return the raw help text of function @var{name}.
1051
1052The raw help text is returned in @var{text} and the format in @var{format}.
1053The format is a string which is one of @qcode{"texinfo"}, @qcode{"html"}, or
1054@w{@qcode{"plain text"}}.
1055@seealso{get_help_text_from_file}
1056@end deftypefn */)
1057{
1058 if (args.length () != 1)
1059 print_usage ();
1060
1061 const std::string name = args(0).xstring_value ("get_help_text: NAME must be a string");
1062
1063 help_system& help_sys = interp.get_help_system ();
1064
1065 std::string text, format;
1066
1067 help_sys.get_help_text (name, text, format);
1068
1069 return ovl (text, format);
1070}
1071
1072DEFMETHOD (get_help_text_from_file, interp, args, ,
1073 doc: /* -*- texinfo -*-
1074@deftypefn {} {[@var{text}, @var{format}] =} get_help_text_from_file (@var{fname})
1075Return the raw help text from the file @var{fname}.
1076
1077The raw help text is returned in @var{text} and the format in @var{format}.
1078The format is a string which is one of @qcode{"texinfo"}, @qcode{"html"}, or
1079@w{@qcode{"plain text"}}.
1080@seealso{get_help_text}
1081@end deftypefn */)
1082{
1083 if (args.length () != 1)
1084 print_usage ();
1085
1086 const std::string fname = args(0).xstring_value ("get_help_text_from_file: NAME must be a string");
1087
1088 help_system& help_sys = interp.get_help_system ();
1089
1090 std::string text, format;
1091
1092 help_sys.get_help_text_from_file (fname, text, format);
1093
1094 return ovl (text, format);
1095}
1096
1097// Return a cell array of strings containing the names of all operators.
1098
1099DEFUN (__operators__, , ,
1100 doc: /* -*- texinfo -*-
1101@deftypefn {} {@var{cstr} =} __operators__ ()
1102Return a cell array of strings of all possible Octave operators.
1103@end deftypefn */)
1104{
1105 return ovl (Cell (operator_names));
1106}
1107
1108// Return a cell array of strings containing the names of all keywords.
1109// iskeyword() function is located in lex.ll and is based on what the parser
1110// thinks is a keyword.
1111
1112DEFALIAS (__keywords__, iskeyword)
1113
1114// Return a cell array of strings with the names of all builtin functions.
1115
1116DEFMETHOD (__builtins__, interp, , ,
1117 doc: /* -*- texinfo -*-
1118@deftypefn {} {} __builtins__ ()
1119Return a cell array of all builtin (compiled) functions available to Octave.
1120@end deftypefn */)
1121{
1122 symbol_table& symtab = interp.get_symbol_table ();
1123
1124 const string_vector bif = symtab.built_in_function_names ();
1125
1126 return ovl (Cell (bif));
1127}
1128
1129DEFMETHOD (localfunctions, interp, args, ,
1130 doc: /* -*- texinfo -*-
1131@deftypefn {} {@var{subfcn_list} =} localfunctions ()
1132Return a list of all local functions, i.e., subfunctions, within the current
1133file.
1134
1135The return value is a column cell array of function handles to all local
1136functions accessible from the function from which @code{localfunctions} is
1137called. Nested functions are @emph{not} included in the list.
1138
1139If the call is from the command line, an anonymous function, or a script,
1140the return value is an empty cell array.
1141
1142@seealso{functions}
1143@end deftypefn */)
1144{
1145 if (args.length () != 0)
1146 print_usage ();
1147
1148 Cell retval;
1149
1150 // Find the main function we are in.
1151 tree_evaluator& tw = interp.get_evaluator ();
1152 octave_user_code *caller = tw.debug_user_code ();
1153
1154 if (! caller)
1155 return ovl (retval);
1156
1157 symbol_scope scope = caller->scope ();
1158
1159 return ovl (Cell (scope.localfunctions ()));
1160}
1161
1162/*
1163%!test
1164%! f = tempname (tempdir (), "oct_");
1165%! [~, fcn_name] = fileparts (f);
1166%! f = [f ".m"];
1167%! save_path = path ();
1168%! unwind_protect
1169%! addpath (tempdir ());
1170%! fid = fopen (f, "w+");
1171%! fprintf (fid, "function z = %s\n z = localfunctions; end\n", fcn_name);
1172%! fprintf (fid, "function z = b(x)\n z = x+1; end\n");
1173%! fprintf (fid, "function z = c(x)\n z = 2*x; end\n");
1174%! fclose (fid);
1175%! d = eval (fcn_name);
1176%! assert (size (d), [2, 1]);
1177%! assert (d{1} (3), 4);
1178%! assert (d{2} (3), 6);
1179%! unwind_protect_cleanup
1180%! unlink (f);
1181%! path (save_path);
1182%! end_unwind_protect
1183*/
1184
1185DEFMETHOD (__which__, interp, args, ,
1186 doc: /* -*- texinfo -*-
1187@deftypefn {} {@var{var_struct} =} __which__ (@var{name}, @dots{})
1188Undocumented internal function.
1189@end deftypefn */)
1190{
1191 help_system& help_sys = interp.get_help_system ();
1192
1193 string_vector argv = args.make_argv ();
1194
1195 int nargin = argv.numel ();
1196
1197 octave_map m (dim_vector (1, nargin));
1198
1199 Cell names (1, nargin);
1200 Cell files (1, nargin);
1201 Cell types (1, nargin);
1202
1203 for (int i = 0; i < nargin; i++)
1204 {
1205 std::string name = argv[i];
1206
1207 std::string type;
1208
1209 std::string file = help_sys.which (name, type);
1210
1211 names(i) = name;
1212 files(i) = file;
1213 types(i) = type;
1214 }
1215
1216 m.assign ("name", names);
1217 m.assign ("file", files);
1218 m.assign ("type", types);
1219
1220 return ovl (m);
1221}
1222
1223// Return a cell array of strings containing the names of all
1224// functions available in DIRECTORY. If no directory is given, search
1225// the current path.
1226
1227DEFMETHOD (__list_functions__, interp, args, ,
1228 doc: /* -*- texinfo -*-
1229@deftypefn {} {@var{retval} =} __list_functions__ ()
1230@deftypefnx {} {@var{retval} =} __list_functions__ (@var{directory})
1231Return a list of all functions (.m and .oct functions) in the load path.
1232
1233If the optional argument @var{directory} is given then list only the functions
1234in that directory.
1235@seealso{path}
1236@end deftypefn */)
1237{
1238 octave_value retval;
1239
1240 load_path& lp = interp.get_load_path ();
1241
1242 if (args.length () == 0)
1243 {
1244 // Get list of all functions
1245 string_vector ffl = lp.fcn_names ();
1246 string_vector afl = interp.autoloaded_functions ();
1247
1248 retval = Cell (ffl.append (afl));
1249 }
1250 else
1251 {
1252 std::string dir = args(0).xstring_value ("__list_functions__: DIRECTORY argument must be a string");
1253
1254 string_vector fl = lp.files (dir, true);
1255
1256 // Return a sorted list with unique entries (in case of .m and .oct
1257 // versions of the same function in a given directory, for example).
1258 fl.sort (true);
1259
1260 retval = Cell (fl);
1261 }
1262
1263 return retval;
1264}
1265
1266DEFMETHOD (built_in_docstrings_file, interp, args, nargout,
1267 doc: /* -*- texinfo -*-
1268@deftypefn {} {@var{val} =} built_in_docstrings_file ()
1269@deftypefnx {} {@var{old_val} =} built_in_docstrings_file (@var{new_val})
1270@deftypefnx {} {@var{old_val} =} built_in_docstrings_file (@var{new_val}, "local")
1271Query or set the internal variable that specifies the name of the
1272file containing docstrings for built-in Octave functions.
1273
1274The default value is
1275@file{@var{octave-home}/share/octave/@var{version}/etc/built-in-docstrings},
1276in which @var{octave-home} is the root directory of the Octave installation,
1277and @var{version} is the Octave version number. The default value may be
1278overridden by the environment variable
1279@w{@env{OCTAVE_BUILT_IN_DOCSTRINGS_FILE}}, or the command line argument
1280@option{--built-in-docstrings-file FNAME}.
1281
1282Note: This variable is only used when Octave is initializing itself.
1283Modifying it during a running session of Octave will have no effect.
1284@end deftypefn */)
1285{
1286 help_system& help_sys = interp.get_help_system ();
1287
1288 return help_sys.built_in_docstrings_file (args, nargout);
1289}
1290
1291DEFMETHOD (doc_cache_file, interp, args, nargout,
1292 doc: /* -*- texinfo -*-
1293@deftypefn {} {@var{val} =} doc_cache_file ()
1294@deftypefnx {} {@var{old_val} =} doc_cache_file (@var{new_val})
1295@deftypefnx {} {@var{old_val} =} doc_cache_file (@var{new_val}, "local")
1296Query or set the internal variable that specifies the name of the
1297Octave documentation cache file.
1298
1299A cache file significantly improves the performance of the @code{lookfor}
1300command. The default value is
1301@file{@var{octave-home}/share/octave/@var{version}/etc/doc-cache},
1302in which @var{octave-home} is the root directory of the Octave installation,
1303and @var{version} is the Octave version number.
1304The default value may be overridden by the environment variable
1305@w{@env{OCTAVE_DOC_CACHE_FILE}}, or the command line argument
1306@option{--doc-cache-file FNAME}.
1307
1308When called from inside a function with the @qcode{"local"} option, the
1309variable is changed locally for the function and any subroutines it calls.
1310The original variable value is restored when exiting the function.
1311@seealso{doc_cache_create, lookfor, info_program, doc, help, makeinfo_program}
1312@seealso{lookfor}
1313@end deftypefn */)
1314{
1315 help_system& help_sys = interp.get_help_system ();
1316
1317 return help_sys.doc_cache_file (args, nargout);
1318}
1319
1320DEFMETHOD (info_file, interp, args, nargout,
1321 doc: /* -*- texinfo -*-
1322@deftypefn {} {@var{val} =} info_file ()
1323@deftypefnx {} {@var{old_val} =} info_file (@var{new_val})
1324@deftypefnx {} {@var{old_val} =} info_file (@var{new_val}, "local")
1325Query or set the internal variable that specifies the name of the
1326Octave info file.
1327
1328The default value is
1329@file{@var{octave-home}/share/info/octave.info}, in
1330which @var{octave-home} is the root directory of the Octave installation.
1331The default value may be overridden by the environment variable
1332@w{@env{OCTAVE_INFO_FILE}}, or the command line argument
1333@option{--info-file FNAME}.
1334
1335When called from inside a function with the @qcode{"local"} option, the
1336variable is changed locally for the function and any subroutines it calls.
1337The original variable value is restored when exiting the function.
1338@seealso{info_program, doc, help, makeinfo_program}
1339@end deftypefn */)
1340{
1341 help_system& help_sys = interp.get_help_system ();
1342
1343 return help_sys.info_file (args, nargout);
1344}
1345
1346DEFMETHOD (info_program, interp, args, nargout,
1347 doc: /* -*- texinfo -*-
1348@deftypefn {} {@var{val} =} info_program ()
1349@deftypefnx {} {@var{old_val} =} info_program (@var{new_val})
1350@deftypefnx {} {@var{old_val} =} info_program (@var{new_val}, "local")
1351Query or set the internal variable that specifies the name of the
1352info program to run.
1353
1354The default value is @file{info}. The default value may be
1355overridden by the environment variable @w{@env{OCTAVE_INFO_PROGRAM}}, or the
1356command line argument @option{--info-program NAME}.
1357
1358When called from inside a function with the @qcode{"local"} option, the
1359variable is changed locally for the function and any subroutines it calls.
1360The original variable value is restored when exiting the function.
1361@seealso{info_file, doc, help, makeinfo_program}
1362@end deftypefn */)
1363{
1364 help_system& help_sys = interp.get_help_system ();
1365
1366 return help_sys.info_program (args, nargout);
1367}
1368
1369DEFMETHOD (makeinfo_program, interp, args, nargout,
1370 doc: /* -*- texinfo -*-
1371@deftypefn {} {@var{val} =} makeinfo_program ()
1372@deftypefnx {} {@var{old_val} =} makeinfo_program (@var{new_val})
1373@deftypefnx {} {@var{old_val} =} makeinfo_program (@var{new_val}, "local")
1374Query or set the internal variable that specifies the name of the
1375program that Octave runs to format help text containing
1376Texinfo markup commands.
1377
1378The default value is @code{makeinfo}.
1379
1380When called from inside a function with the @qcode{"local"} option, the
1381variable is changed locally for the function and any subroutines it calls.
1382The original variable value is restored when exiting the function.
1383@seealso{texi_macros_file, info_file, info_program, doc, help}
1384@end deftypefn */)
1385{
1386 help_system& help_sys = interp.get_help_system ();
1387
1388 return help_sys.makeinfo_program (args, nargout);
1389}
1390
1391DEFMETHOD (suppress_verbose_help_message, interp, args, nargout,
1392 doc: /* -*- texinfo -*-
1393@deftypefn {} {@var{val} =} suppress_verbose_help_message ()
1394@deftypefnx {} {@var{old_val} =} suppress_verbose_help_message (@var{new_val})
1395@deftypefnx {} {@var{old_val} =} suppress_verbose_help_message (@var{new_val}, "local")
1396Query or set the internal variable that controls whether Octave
1397will add additional help information to the end of the output from
1398the @code{help} command and usage messages for built-in commands.
1399
1400When called from inside a function with the @qcode{"local"} option, the
1401variable is changed locally for the function and any subroutines it calls.
1402The original variable value is restored when exiting the function.
1403@end deftypefn */)
1404{
1405 help_system& help_sys = interp.get_help_system ();
1406
1407 return help_sys.suppress_verbose_help_message (args, nargout);
1408}
1409
1410DEFMETHOD (texi_macros_file, interp, args, nargout,
1411 doc: /* -*- texinfo -*-
1412@deftypefn {} {@var{val} =} texi_macros_file ()
1413@deftypefnx {} {@var{old_val} =} texi_macros_file (@var{new_val})
1414@deftypefnx {} {@var{old_val} =} texi_macros_file (@var{new_val}, "local")
1415Query or set the internal variable that specifies the name of the
1416file containing Texinfo macros that are prepended to documentation strings
1417before they are passed to makeinfo.
1418
1419The default value is
1420@file{@var{octave-home}/share/octave/@var{version}/etc/macros.texi},
1421in which @var{octave-home} is the root directory of the Octave installation,
1422and @var{version} is the Octave version number.
1423The default value may be overridden by the environment variable
1424@w{@env{OCTAVE_TEXI_MACROS_FILE}}, or the command line argument
1425@option{--texi-macros-file FNAME}.
1426
1427When called from inside a function with the @qcode{"local"} option, the
1428variable is changed locally for the function and any subroutines it calls.
1429The original variable value is restored when exiting the function.
1430@seealso{makeinfo_program}
1431@end deftypefn */)
1432{
1433 help_system& help_sys = interp.get_help_system ();
1434
1435 return help_sys.texi_macros_file (args, nargout);
1436}
1437
1438OCTAVE_END_NAMESPACE(octave)
Definition Cell.h:41
octave_value get_method(const std::string &nm) const
Definition cdef-class.h:362
std::string get_name() const
Definition cdef-class.h:329
void file_name(const std::string &nm)
Definition cdef-class.h:413
cdef_property find_property(const std::string &nm)
Definition cdef-class.h:474
cdef_package find_package(const std::string &name, bool error_if_not_found=true, bool load_if_not_found=true)
cdef_class find_class(const std::string &name, bool error_if_not_found=true, bool load_if_not_found=true)
void doc_string(const std::string &txt)
bool ok() const
octave_value find(const std::string &nm)
std::string get_name() const
Vector representing the dimensions (size) of an Array.
Definition dim-vector.h:90
string_vector make_name_list() const
std::string texi_macros_file() const
Definition help.h:121
void get_help_text_from_file(const std::string &fname, std::string &text, std::string &format) const
void get_help_text(const std::string &name, std::string &text, std::string &format) const
octave_value built_in_docstrings_file(const octave_value_list &args, int nargout)
std::string raw_help(const std::string &, bool &) const
std::string info_file() const
Definition help.h:81
std::string info_program() const
Definition help.h:90
bool suppress_verbose_help_message() const
Definition help.h:109
std::string which(const std::string &name) const
octave_value info_file(const octave_value_list &args, int nargout)
octave_value info_program(const octave_value_list &args, int nargout)
std::string built_in_docstrings_file() const
Definition help.h:63
octave_value suppress_verbose_help_message(const octave_value_list &args, int nargout)
std::string doc_cache_file() const
Definition help.h:72
octave_value doc_cache_file(const octave_value_list &args, int nargout)
std::string makeinfo_program() const
Definition help.h:99
octave_value makeinfo_program(const octave_value_list &args, int nargout)
octave_value texi_macros_file(const octave_value_list &args, int nargout)
cdef_manager & get_cdef_manager()
std::list< std::string > autoloaded_functions() const
std::list< std::string > variable_names()
load_path & get_load_path()
tree_evaluator & get_evaluator()
symbol_table & get_symbol_table()
string_vector files(const std::string &dir, bool omit_exts=false) const
Definition load-path.cc:877
string_vector fcn_names() const
Definition load-path.cc:905
std::string find_file(const std::string &file) const
Definition load-path.cc:583
std::string find_fcn_file(const std::string &fcn, const std::string &pack_name="")
Definition load-path.h:127
virtual bool is_classdef_meta() const
Definition ov-base.h:465
virtual bool is_user_function() const
Definition ov-base.h:547
bool is_classdef_method(const std::string &cname="") const
std::string file_name() const
bool is_classdef_constructor(const std::string &cname="") const
virtual bool is_subfunction() const
Definition ov-fcn.h:108
virtual std::list< std::string > subfunction_names() const
Definition ov-fcn.h:201
virtual octave::symbol_scope parent_fcn_scope() const
Definition ov-fcn.h:86
virtual std::string doc_string(const std::string &="") const
Definition ov-fcn.h:221
virtual std::string src_file_name() const
Definition ov-fcn.h:76
virtual std::string fcn_file_name() const
Definition ov-fcn.h:74
octave::symbol_scope scope()
Definition ov-usr-fcn.h:97
bool is_classdef_constructor(const std::string &cname="") const
Definition ov-usr-fcn.h:352
bool is_classdef_method(const std::string &cname="") const
Definition ov-usr-fcn.h:368
std::string signature() const
octave_function * function_value(bool silent=false) const
bool is_classdef_meta() const
Definition ov.h:652
bool is_user_script() const
Definition ov.h:780
bool is_function() const
Definition ov.h:777
bool is_user_function() const
Definition ov.h:783
octave_user_function * user_function_value(bool silent=false) const
string_vector & append(const std::string &s)
Definition str-vec.cc:110
string_vector & sort(bool make_uniq=false)
Definition str-vec.cc:77
void resize(octave_idx_type n, const std::string &rfv="")
Definition str-vec.h:93
octave_idx_type numel() const
Definition str-vec.h:98
std::list< octave_value > localfunctions() const
Definition symscope.cc:383
octave_user_code * user_code() const
Definition symscope.h:613
octave_value find_function(const std::string &name, const symbol_scope &search_scope=symbol_scope::invalid())
Definition symtab.cc:254
std::list< std::string > cmdline_function_names()
Definition symtab.cc:639
std::list< std::string > built_in_function_names()
Definition symtab.cc:620
octave_user_code * current_user_code() const
Definition pt-eval.cc:2595
octave_user_code * debug_user_code() const
Definition pt-eval.cc:2607
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
void print_usage()
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 DEFALIAS(alias, name)
Macro to define an alias for another existing function name.
Definition defun.h:160
void error(const char *fmt,...)
Definition error.cc:1003
string_vector make_name_list()
help_system & __get_help_system__()
bool iskeyword(const std::string &s)
Definition lex.cc:1335
octave_value_list Fiskeyword(const octave_value_list &args, int)
Definition lex.cc:4893
F77_RET_T const F77_DBLE const F77_DBLE * f
std::complex< double > w(std::complex< double > z, double relerr=0)
#define OCTAVE_LOCAL_BUFFER(T, buf, size)
Definition oct-locbuf.h:44
std::string get_help_from_file(const std::string &nm, bool &symbol_found, std::string &full_file)
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition ovl.h:217
std::size_t format(std::ostream &os, const char *fmt,...)
Definition utils.cc:1514
octave_value set_internal_variable(bool &var, const octave_value_list &args, int nargout, const char *nm)
Definition variables.cc:583
F77_RET_T len
Definition xerbla.cc:61