comparison scripts/help/type.m @ 17399:a1fa416c7c4a

type.m: Fix function for filenames without extension (bug #39922). * scripts/help/type.m: Redo docstring to describe that 'type' works on ordinary files and variables, as well as functions. Display file even if name does not have an extension. Add more %!tests.
author Rik <rik@octave.org>
date Mon, 09 Sep 2013 20:20:14 -0700
parents 1c89599167a6
children fedcd3717ebc
comparison
equal deleted inserted replaced
17398:67c6fc2b9f63 17399:a1fa416c7c4a
17 ## <http://www.gnu.org/licenses/>. 17 ## <http://www.gnu.org/licenses/>.
18 18
19 ## -*- texinfo -*- 19 ## -*- texinfo -*-
20 ## @deftypefn {Command} {} type @var{name} @dots{} 20 ## @deftypefn {Command} {} type @var{name} @dots{}
21 ## @deftypefnx {Command} {} type -q @var{name} @dots{} 21 ## @deftypefnx {Command} {} type -q @var{name} @dots{}
22 ## @deftypefnx {Function File} {dfns =} type ("@var{name}", @dots{}) 22 ## @deftypefnx {Function File} {text =} type ("@var{name}", @dots{})
23 ## Display the definition of each @var{name} that refers to a function. 23 ## Display the contents of @var{name} which may be a file, function (m-file),
24 ## variable, operator, or keyword.
24 ## 25 ##
25 ## Normally also displays whether each @var{name} is user-defined or built-in; 26 ## @code{type} normally prepends a header line describing the category
26 ## the @option{-q} option suppresses this behavior. 27 ## of @var{name} such as function or variable; The @option{-q} option
28 ## suppresses this behavior.
27 ## 29 ##
28 ## If an output argument is requested nothing is displayed. Instead, a cell 30 ## If no output variable is used the contents are displayed on screen.
29 ## array of strings is returned, where each element corresponds to the 31 ## Otherwise, a cell array of strings is returned, where each element
30 ## definition of each requested function. 32 ## corresponds to the contents of each requested function.
31 ## @end deftypefn 33 ## @end deftypefn
32 34
33 function retval = type (varargin) 35 function text = type (varargin)
34 ## Parse input 36
35 if (nargin == 0) 37 if (nargin == 0)
36 error ("type: not enough input arguments"); 38 print_usage ();
37 endif 39 elseif (! iscellstr (varargin))
38
39 if (!iscellstr (varargin))
40 error ("type: input arguments must be strings"); 40 error ("type: input arguments must be strings");
41 endif 41 endif
42 42
43 quiet = false; 43 quiet = false;
44 idx = strcmpi (varargin, "-q") | strcmpi (varargin, "-quiet"); 44 idx = strcmpi (varargin, "-q") | strcmpi (varargin, "-quiet");
45 if (any (idx)) 45 if (any (idx))
46 quiet = true; 46 quiet = true;
47 varargin (idx) = []; 47 varargin(idx) = [];
48 endif 48 endif
49 49
50 if (nargout > 0) 50 if (nargout > 0)
51 retval = cell (size (varargin)); 51 text = cell (size (varargin));
52 endif 52 endif
53 53
54 for n = 1:length (varargin) 54 for n = 1:length (varargin)
55 name = varargin {n}; 55 name = varargin{n};
56 56
57 ## Find function and get its code 57 ## Find function and get its code
58 text = ""; 58 txt = "";
59 cmd = sprintf ("exist ('%s')", name); 59 cmd = sprintf ("exist ('%s')", name);
60 e = evalin ("caller", cmd); 60 e = evalin ("caller", cmd);
61 if (e == 1) 61 if (e == 1)
62 ## Variable 62 ## Variable
63 cmd = sprintf ("disp (%s);", name); 63 cmd = sprintf ("disp (%s);", name);
64 desc = evalin ("caller", cmd); 64 desc = evalin ("caller", cmd);
65 if (quiet) 65 if (quiet)
66 text = desc; 66 txt = desc;
67 else 67 else
68 text = sprintf ("%s is a variable\n%s", name, desc); 68 txt = sprintf ("%s is a variable\n%s", name, desc);
69 endif 69 endif
70 elseif (e == 2) 70 elseif (e == 2)
71 ## m-file or ordinary file 71 ## m-file or ordinary file
72 file = which (name); 72 file = which (name);
73 if (isempty (file)) 73 if (length (file) > 2)
74 ext = file(end-1:end);
75 endif
76 if (isempty (file) || ! strcmpi (ext, ".m"))
74 ## 'name' is an ordinary file, and not a function name. 77 ## 'name' is an ordinary file, and not a function name.
75 ## FIXME: Should we just print it anyway? 78 file = file_in_loadpath (name);
76 error ("type: '%s' undefined\n", name); 79 quiet = true;
77 endif 80 endif
78 81
79 ## Read the file 82 ## Read the file
80 fid = fopen (file, "r"); 83 fid = fopen (file, "r");
81 if (fid < 0) 84 if (fid < 0)
83 endif 86 endif
84 contents = char (fread (fid).'); 87 contents = char (fread (fid).');
85 fclose (fid); 88 fclose (fid);
86 89
87 if (quiet) 90 if (quiet)
88 text = contents; 91 txt = contents;
89 else 92 else
90 text = sprintf ("%s is the user-defined function defined from: %s\n\n%s", 93 txt = sprintf ("%s is the user-defined function defined from: %s\n\n%s",
91 name, file, contents); 94 name, file, contents);
92 endif 95 endif
93 elseif (e == 3) 96 elseif (e == 3)
94 text = sprintf ("%s is a dynamically-linked function", name); 97 txt = sprintf ("%s is a dynamically-linked function", name);
95 elseif (e == 5) 98 elseif (e == 5)
96 text = sprintf ("%s is a built-in function", name); 99 txt = sprintf ("%s is a built-in function", name);
97 elseif (any (strcmp (__operators__ (), name))) 100 elseif (any (strcmp (__operators__ (), name)))
98 text = sprintf ("%s is an operator", name); 101 txt = sprintf ("%s is an operator", name);
99 elseif (any (strcmp (__keywords__ (), name))) 102 elseif (any (strcmp (__keywords__ (), name)))
100 text = sprintf ("%s is a keyword", name); 103 txt = sprintf ("%s is a keyword", name);
101 else 104 else
102 error ("type: '%s' undefined\n", name); 105 error ("type: '%s' undefined\n", name);
103 endif 106 endif
104 107
105 ## Should we return the text or print if
106 if (nargout == 0) 108 if (nargout == 0)
107 disp (text); 109 disp (txt);
108 else 110 else
109 retval {n} = text; 111 text{n} = txt;
110 endif 112 endif
111 endfor 113 endfor
112 endfunction 114 endfunction
113 115
114 116
115 %!test 117 %!test
116 %! var = 1; 118 %! var = 1;
117 %! typestr = type ("var"); 119 %! text = type ("var");
118 %! typestr = typestr{1}(1:17); 120 %! typestr = text{1}(1:17);
119 %! assert (typestr, "var is a variable"); 121 %! assert (typestr, "var is a variable");
122
123 %!test
124 %! text = type ("ls");
125 %! typestr = text{1}(1:31);
126 %! assert (typestr, "ls is the user-defined function");
127
128 %!test
129 %! text = type ("ls", "-q");
130 %! typestr = text{1}(1:21);
131 %! assert (typestr, "## Copyright (C) 2006");
120 132
121 %!assert (type ("amd"){1}, "amd is a dynamically-linked function") 133 %!assert (type ("amd"){1}, "amd is a dynamically-linked function")
122 %!assert (type ("cat"){1}, "cat is a built-in function") 134 %!assert (type ("cat"){1}, "cat is a built-in function")
123 %!assert (type ("+"){1}, "+ is an operator") 135 %!assert (type ("+"){1}, "+ is an operator")
124 %!assert (type ("end"){1}, "end is a keyword") 136 %!assert (type ("end"){1}, "end is a keyword")
125 %!error (type ('NO_NAME')) 137
138 %!error type ()
139 %!error <'__NO_NAME__' undefined> type ('__NO_NAME__')
126 140
127