# HG changeset patch # User Rik # Date 1430108093 25200 # Node ID 4c6d70a35192e1abf567a248135a47097ad18e39 # Parent 57b6e06ed811e264fa9b65b4b7afcce78141f8cc lookfor.m: Overhaul function and fix bug #44924. * lookfor.m: Rewrite docstring. Match variable names in function prototype to docstring. Use more meaningful variable names throughout function. Don't continue to process a function if get_first_help_sentence returns an error (bug #44924). Iterate directly over cell list rather than using a for loop with a range to index into cell list. diff -r 57b6e06ed811 -r 4c6d70a35192 scripts/help/lookfor.m --- a/scripts/help/lookfor.m Sun Apr 26 22:36:44 2015 -0400 +++ b/scripts/help/lookfor.m Sun Apr 26 21:14:53 2015 -0700 @@ -19,50 +19,52 @@ ## -*- texinfo -*- ## @deftypefn {Command} {} lookfor @var{str} ## @deftypefnx {Command} {} lookfor -all @var{str} -## @deftypefnx {Function File} {[@var{func}, @var{helpstring}] =} lookfor (@var{str}) -## @deftypefnx {Function File} {[@var{func}, @var{helpstring}] =} lookfor ("-all", @var{str}) -## Search for the string @var{str} in all functions found in the current -## function search path. By default, @code{lookfor} searches for @var{str} -## in the first sentence of the help string of each function found. The entire -## help text of each function can be searched if the @qcode{"-all"} argument is -## supplied. All searches are case insensitive. +## @deftypefnx {Function File} {[@var{fcn}, @var{help1str}] =} lookfor (@var{str}) +## @deftypefnx {Function File} {[@var{fcn}, @var{help1str}] =} lookfor ("-all", @var{str}) +## Search for the string @var{str} in all functions using the current function +## search path. +## +## By default, @code{lookfor} looks for @var{str} in the first sentence of the +## help string for each function found. The entire help text of each function +## can be searched by using the @qcode{"-all"} argument. All searches are case +## insensitive. ## -## Called with no output arguments, @code{lookfor} prints the list of -## matching functions to the terminal. Otherwise, the output arguments -## @var{func} and @var{helpstring} define the matching functions and the -## first sentence of each of their help strings. +## When called with no output arguments, @code{lookfor} prints the list of +## matching functions to the terminal. Otherwise, the output argument +## @var{fcns} contains the function names and @var{help1str} contains the first +## sentence from the help string of each function. ## -## The ability of @code{lookfor} to correctly identify the first -## sentence of the help text is dependent on the format of the -## function's help. All Octave core functions are correctly -## formatted, but the same can not be guaranteed for external packages and -## user-supplied functions. Therefore, the use of the @qcode{"-all"} -## argument may be necessary to find related functions that are not a part of -## Octave. +## Programming Note: The ability of @code{lookfor} to correctly identify the +## first sentence of the help text is dependent on the format of the function's +## help. All Octave core functions are correctly formatted, but the same can +## not be guaranteed for external packages and user-supplied functions. +## Therefore, the use of the @qcode{"-all"} argument may be necessary to find +## related functions that are not a part of Octave. ## @seealso{help, doc, which} ## @end deftypefn -function [out_fun, out_help_text] = lookfor (str, arg2) +function [fcn, help1str] = lookfor (str, arg2) if (strcmpi (str, "-all")) - ## The difference between using '-all' and not, is which part of the caches - ## we search. The cache is organized such that the first column contains - ## the function name, the second column contains the full help text, and - ## the third column contains the first sentence of the help text. + ## The difference between using '-all' and not is which part of the caches + ## we search. The cache is organized such that row + ## 1) contains the function name + ## 2) contains the full help text + ## 3) contains the first sentence of the help text. str = arg2; - search_type = 2; # when using caches, search the second column + search_type = 2; # search the second row (full help text) else - search_type = 3; # when using caches, search the third column + search_type = 3; # search the third column (first help sentence) endif - str = lower (str); # Compare is case insensitive + str = lower (str); # Compare is case insensitive ## Search functions, operators, and keywords that come with Octave cache_file = doc_cache_file (); if (exist (cache_file, "file")) - [fun, help_text] = search_cache (str, cache_file, search_type); + [fcnlist, help_text] = search_cache (str, cache_file, search_type); had_core_cache = true; else - fun = help_text = {}; + fcnlist = help_text = {}; had_core_cache = false; endif @@ -72,37 +74,38 @@ ## ditto for path. new_path = ostrsplit (path (), pathsep ()); - ## scratch out directories already covered by orig_path. + ## remove directories already covered by orig_path. if (had_core_cache) new_path = setdiff (new_path, orig_path); endif for n = 1:numel (new_path) - elt = new_path{n}; - cache_file = fullfile (elt, "doc-cache"); + fcndir = new_path{n}; + cache_file = fullfile (fcndir, "doc-cache"); if (exist (cache_file, "file")) ## We have a cache in the directory, then read it and search it! - [funs, hts] = search_cache (str, cache_file, search_type); - fun(end+1:end+length (funs)) = funs; - help_text(end+1:end+length (hts)) = hts; + [fcns, htext] = search_cache (str, cache_file, search_type); + fcnlist(end+1:end+length (fcns)) = fcns; + help_text(end+1:end+length (htext)) = htext; + else - ## We don't have a cache. Search files - funs_in_f = __list_functions__ (elt); - for m = 1:length (funs_in_f) - fn = funs_in_f{m}; + ## We don't have a cache. Search files. + for fcn_in_fcndir = (__list_functions__ (fcndir)).' + fn = fcn_in_fcndir{1}; - ## Skip files that start with __ - if (length (fn) > 2 && strcmp (fn(1:2), "__")) + ## Skip files that start with "__" + if (strncmp (fn, "__", 2)) continue; endif + status = 0; + ## Extract first sentence try warn_state = warning (); unwind_protect warning ("off"); first_sentence = get_first_help_sentence (fn, 1024); - status = 0; unwind_protect_cleanup warning (warn_state); end_unwind_protect @@ -110,39 +113,39 @@ status = 1; end_try_catch - if (search_type == 2) # search entire help text + if (status) + ## Error getting first help sentence + elseif (search_type == 3) + ## only search the first sentence of the help text + text = first_sentence; + elseif (search_type == 2) + ## search entire help text try warn_state = warning (); unwind_protect warning ("off"); [text, fmt] = get_help_text (fn); - status = 0; + switch (lower (fmt)) + case "plain text" + status = 0; + case "texinfo" + [text, status] = __makeinfo__ (text, "plain text"); + case "html" + [text, status] = strip_html_tags (text); + otherwise + status = 1; + endswitch unwind_protect_cleanup warning (warn_state); end_unwind_protect catch status = 1; end_try_catch - - ## Take action depending on help text fmt - switch (lower (fmt)) - case "plain text" - status = 0; - case "texinfo" - [text, status] = __makeinfo__ (text, "plain text"); - case "html" - [text, status] = strip_html_tags (text); - otherwise - status = 1; - endswitch - - elseif (status == 0) # only search the first sentence of the help text - text = first_sentence; endif - ## Search the help text, if we can - if (status == 0 && ! isempty (strfind (lower (text), str))) - fun(end+1) = fn; + ## Search the help text + if (status == 0 && strfind (lower (text), str)) + fcnlist(end+1) = fn; help_text(end+1) = first_sentence; endif endfor @@ -155,8 +158,8 @@ term_width = (terminal_size ())(2); desc_width = term_width - indent - 2; indent_space = blanks (indent); - for k = 1:length (fun) - f = fun{k}; + for k = 1:length (fcnlist) + f = fcnlist{k}; f(end+1:indent-1) = " "; puts ([f " "]); lf = length (f); @@ -168,25 +171,24 @@ printf ("%s%s\n", indent_space, strtrim (desc (start:stop))); endfor endfor - else ## Return the results instead of displaying them - out_fun = fun; - out_help_text = help_text; + fcn = fcnlist; + help1str = help_text; endif endfunction -function [funs, help_texts] = search_cache (str, cache_file, search_type) +function [fcns, help_texts] = search_cache (str, cache_file, search_type) load (cache_file); if (! isempty (cache)) t1 = strfind (lower (cache (1, :)), str); t2 = strfind (lower (cache (search_type, :)), str); cache_idx = find (! (cellfun ("isempty", t1) & cellfun ("isempty", t2))); - funs = cache(1, cache_idx); + fcns = cache(1, cache_idx); help_texts = cache(3, cache_idx); else - funs = help_texts = {}; + fcns = help_texts = {}; endif endfunction