Mercurial > octave-nkf
comparison scripts/miscellaneous/license.m @ 19237:6dfce51a7b40
license.m: update to treat packages as features (bug #43154).
* miscellaneous/license.m: this function was originally written when the only
feature was a monolithic installation of Octave Forge. This cset updates it
to treat packages as features. It also disables the TOOGLE option which does
not make any sense in the context of free software.
author | Carnë Draug <carandraug@octave.org> |
---|---|
date | Mon, 29 Sep 2014 00:29:32 +0100 |
parents | d63878346099 |
children | 672674d5e8d9 |
comparison
equal
deleted
inserted
replaced
19236:4871d0ecbfa7 | 19237:6dfce51a7b40 |
---|---|
1 ## Copyright (C) 2005-2013 William Poetra Yoga Hadisoeseno | 1 ## Copyright (C) 2005-2013 William Poetra Yoga Hadisoeseno |
2 ## Copyright (C) 2014 Carnë Draug | |
2 ## | 3 ## |
3 ## This file is part of Octave. | 4 ## This file is part of Octave. |
4 ## | 5 ## |
5 ## Octave is free software; you can redistribute it and/or modify it | 6 ## Octave is free software; you can redistribute it and/or modify it |
6 ## under the terms of the GNU General Public License as published by | 7 ## under the terms of the GNU General Public License as published by |
16 ## along with Octave; see the file COPYING. If not, see | 17 ## along with Octave; see the file COPYING. If not, see |
17 ## <http://www.gnu.org/licenses/>. | 18 ## <http://www.gnu.org/licenses/>. |
18 | 19 |
19 ## -*- texinfo -*- | 20 ## -*- texinfo -*- |
20 ## @deftypefn {Command} {} license | 21 ## @deftypefn {Command} {} license |
22 ## @deftypefnx {Command} {} license inuse | |
23 ## @deftypefnx {Command} {} license inuse @var{feature} | |
21 ## @deftypefnx {Function File} {} license ("inuse") | 24 ## @deftypefnx {Function File} {} license ("inuse") |
22 ## @deftypefnx {Function File} {@var{retval} =} license ("inuse") | 25 ## @deftypefnx {Function File} {@var{retval} =} license ("inuse") |
23 ## @deftypefnx {Function File} {@var{retval} =} license ("test", @var{feature}) | 26 ## @deftypefnx {Function File} {@var{retval} =} license ("test", @var{feature}) |
24 ## @deftypefnx {Function File} {} license ("test", @var{feature}, @var{toggle}) | |
25 ## @deftypefnx {Function File} {@var{retval} =} license ("checkout", @var{feature}) | 27 ## @deftypefnx {Function File} {@var{retval} =} license ("checkout", @var{feature}) |
26 ## | 28 ## @deftypefnx {Function File} {[@var{retval}, @var{errmsg}] =} license ("checkout", @var{feature}) |
27 ## Display the license of Octave. | 29 ## Get license information for Octave and Octave packages. |
28 ## | 30 ## |
29 ## @code{license ("inuse")} | 31 ## GNU Octave is free software distributed under the GNU General Public |
32 ## License (GPL), and a license manager makes no sense. This function is | |
33 ## provided only for @sc{Matlab} compatibility. | |
30 ## | 34 ## |
31 ## Display a list of packages currently being used. | 35 ## When called with no extra input arguments, it returns the Octave license, |
32 ## | 36 ## otherwise the first input defines the operation mode and must be one of |
33 ## @code{@var{retval} = license ("inuse")} | 37 ## the following strings: @code{inuse}, @code{test}, and @code{checkout}. |
34 ## | 38 ## The optional @var{feature} argument can either be @qcode{"octave"} (core), |
35 ## Return a structure containing the fields @code{feature} and @code{user}. | 39 ## or an Octave package. |
36 ## | |
37 ## @code{@var{retval} = license ("test", @var{feature})} | |
38 ## | |
39 ## Return 1 if a license exists for the product identified by the string | |
40 ## @var{feature} and 0 otherwise. The argument @var{feature} is case | |
41 ## insensitive and only the first 27 characters are checked. | |
42 ## | |
43 ## @code{license ("test", @var{feature}, @var{toggle})} | |
44 ## | |
45 ## Enable or disable license testing for @var{feature}, depending on | |
46 ## @var{toggle}, which may be one of: | |
47 ## | 40 ## |
48 ## @table @asis | 41 ## @table @asis |
49 ## @item @qcode{"enable"} | 42 ## @item @qcode{"inuse"} |
50 ## Future tests for the specified license of @var{feature} are conducted | 43 ## Returns a list of loaded features, i.e., octave and the list of loaded |
51 ## as usual. | 44 ## packages. If an output is requested, it returns a struct array with |
45 ## the fields @qcode{"feature"}, and @qcode{"user"}. | |
52 ## | 46 ## |
53 ## @item @qcode{"disable"} | 47 ## @item @qcode{"test"} |
54 ## Future tests for the specified license of @var{feature} return 0. | 48 ## Return true if the specified @var{feature} is installed, false otherwise. |
49 ## | |
50 ## An optional third argument @qcode{"enable"} or @qcode{"disable"} is | |
51 ## accepted but ignored. | |
52 ## | |
53 ## @item @qcode{"checkout"} | |
54 ## Return true if the specified @var{feature} is installed, false otherwise. | |
55 ## An optional second output will have an error message if a package is not | |
56 ## installed. | |
57 ## | |
55 ## @end table | 58 ## @end table |
56 ## | 59 ## |
57 ## @code{@var{retval} = license ("checkout", @var{feature})} | 60 ## @seealso{pkg, ver, version} |
58 ## | |
59 ## Check out a license for @var{feature}, returning 1 on success and 0 | |
60 ## on failure. | |
61 ## | |
62 ## This function is provided for compatibility with @sc{matlab}. | |
63 ## @seealso{ver, version} | |
64 ## @end deftypefn | 61 ## @end deftypefn |
65 | 62 |
66 ## Author: William Poetra Yoga Hadisoeseno <williampoetra@gmail.com> | 63 ## Author: William Poetra Yoga Hadisoeseno <williampoetra@gmail.com> |
67 | 64 |
68 function retval = license (varargin) | 65 function [retval, errmsg] = license (cmd, feature, toogle) |
69 | 66 |
70 persistent __octave_licenses__; | 67 if (nargin > 3) |
71 | |
72 if (isempty (__octave_licenses__)) | |
73 __octave_licenses__ = cell (); | |
74 __octave_licenses__{1,1} = "Octave"; | |
75 __octave_licenses__{1,2} = "GNU General Public License"; | |
76 __octave_licenses__{1,3} = true; | |
77 if (exist ("OCTAVE_FORGE_VERSION")) | |
78 __octave_licenses__{2,1} = "octave-forge"; | |
79 __octave_licenses__{2,2} = "<various licenses>"; | |
80 __octave_licenses__{2,3} = true; | |
81 endif | |
82 endif | |
83 | |
84 nout = nargout; | |
85 nin = nargin; | |
86 nr_licenses = rows (__octave_licenses__); | |
87 | |
88 if (nout > 1 || nin > 3) | |
89 print_usage (); | 68 print_usage (); |
90 endif | 69 endif |
91 | 70 |
92 if (nin == 0) | 71 ## Then only give information about Octave core |
72 if (nargin == 0) | |
73 retval = "GNU General Public License"; | |
74 return | |
75 endif | |
93 | 76 |
94 found = find (strcmp (__octave_licenses__(:,1), "Octave"), 1); | 77 [features, desc, flags] = get_all_features (); |
95 | 78 |
96 if (! isempty (found)) | 79 switch tolower (cmd) |
97 result = __octave_licenses__{found,2}; | 80 case "inuse" |
98 else | 81 if (nargin > 2) |
99 result = "unknown"; | 82 print_usage (); |
100 endif | |
101 | |
102 if (nout == 0) | |
103 printf ("%s\n", result); | |
104 else | |
105 retval = result; | |
106 endif | |
107 | |
108 elseif (nin == 1) | |
109 | |
110 if (nout == 0) | |
111 | |
112 if (! strcmp (varargin{1}, "inuse")) | |
113 usage ('license ("inuse")'); | |
114 endif | 83 endif |
115 | 84 |
116 printf ("%s\n", __octave_licenses__{:,1}); | 85 unloaded = cellfun (@(x) x.name, desc(strcmpi (flags, "Not loaded")), |
86 "UniformOutput", false); | |
87 features(ismember (features, unloaded)) = []; | |
117 | 88 |
118 else | 89 if (nargin > 1) |
119 | 90 features = features(strcmp (features, feature)); |
120 if (! strcmp (varargin{1}, "inuse")) | 91 endif |
121 usage ('retval = license ("inuse")'); | 92 if (nargout == 0) |
93 printf ("%s\n", features{:}); | |
94 else | |
95 retval = struct ("feature", features, "user", get_username ()); | |
122 endif | 96 endif |
123 | 97 |
124 pw = getpwuid (getuid ()); | 98 case "test" |
125 if (isstruct (pw)) | 99 if (nargin < 2) |
126 username = pw.name; | 100 print_usage (); |
127 else | |
128 username = "octave_user"; | |
129 endif | 101 endif |
130 | 102 |
131 retval = struct ("feature", __octave_licenses__(:,1), "user", username); | 103 if (nargin > 2) |
132 | 104 ## We ignore the toogle argument because... what's the point? We |
133 endif | 105 ## don't need a license management system on Octave. This function |
134 | 106 ## will return true, even if anyone tries to disabled a license. |
135 else | 107 switch tolower (toogle) |
136 | 108 case "enable", # do nothing |
137 feature = varargin{2}(1:(min ([(length (varargin{2})), 27]))); | 109 case "disable", # do nothing |
138 | 110 otherwise, error ("license: TOOGLE must be enable or disable"); |
139 if (strcmp (varargin{1}, "test")) | 111 endswitch |
140 | |
141 found = find (strcmpi (__octave_licenses__(:,1), feature), 1); | |
142 | |
143 if (nin == 2) | |
144 retval = ! isempty (found) && __octave_licenses__{found,3}; | |
145 else | |
146 if (! isempty (found)) | |
147 if (strcmp (varargin{3}, "enable")) | |
148 __octave_licenses__{found,3} = true; | |
149 elseif (strcmp (varargin{3}, "disable")) | |
150 __octave_licenses__{found,3} = false; | |
151 else | |
152 error ("license: TOGGLE must be either 'enable' or 'disable'"); | |
153 endif | |
154 else | |
155 error ("license: FEATURE '%s' not found", feature); | |
156 endif | |
157 endif | 112 endif |
158 | 113 |
159 elseif (strcmp (varargin{1}, "checkout")) | 114 retval = any (strcmp (features, feature)); |
160 | 115 |
161 if (nin != 2) | 116 case "checkout" |
162 usage ('retval = license ("checkout", feature)'); | 117 ## I guess we could have the checkout command load packages but it's not |
118 ## really the same thing. The closest we have is simply to check if | |
119 ## there is a package with the feature name, and give an error if not. | |
120 | |
121 if (nargin != 2) | |
122 print_usage (); | |
163 endif | 123 endif |
164 | 124 |
165 found = find (strcmpi (__octave_licenses__(:,1), feature), 1); | 125 retval = any (strcmp (features, feature)); |
126 errmsg = ""; | |
166 | 127 |
167 retval = ! isempty (found) && __octave_licenses__{found,3}; | 128 if (! retval) |
129 errmsg = ["No package named \"" feature "\" installed"]; | |
130 endif | |
168 | 131 |
169 else | 132 otherwise |
170 print_usage (); | 133 print_usage (); |
171 endif | 134 endswitch |
172 | |
173 endif | |
174 | 135 |
175 endfunction | 136 endfunction |
176 | 137 |
138 function username = get_username () | |
139 pw = getpwuid (getuid ()); | |
140 if (isstruct (pw)) | |
141 username = pw.name; | |
142 else | |
143 username = "octave_user"; | |
144 endif | |
145 endfunction | |
177 | 146 |
178 %!assert (license(), "GNU General Public License") | 147 function [features, desc, loaded] = get_all_features () |
179 %!assert ((license ("inuse")).feature, "Octave") | 148 [desc, loaded] = pkg ("describe", "all"); |
149 pkg_names = cellfun (@(x) x.name, desc, "UniformOutput", false); | |
150 features = {"octave", pkg_names{:}}; | |
151 endfunction | |
152 | |
153 %!assert (license (), "GNU General Public License") | |
154 %!assert ((license ("inuse", "octave")).feature, "octave") | |
180 | 155 |
181 %!test | 156 %!test |
182 %! lstate = license ("test", "Octave"); | 157 %! [desc, flags] = pkg ("describe", "all"); |
183 %! license ("test", "Octave", "disable"); | 158 %! for idx = 1: numel (desc) |
184 %! assert (license ("test", "Octave"), false); | 159 %! name = desc{idx}.name; |
185 %! license ("test", "Octave", "enable"); | 160 %! switch (flags{idx}) |
186 %! assert (license ("test", "Octave"), true); | 161 %! case "Loaded" |
187 %! if (lstate == false) | 162 %! assert ((license ("inuse", name)).feature, name); |
188 %! license ("test", "Octave", "disable"); | 163 %! case "Not loaded" |
189 %! endif | 164 %! rv = license ("inuse", name); |
165 %! assert (isstruct (rv)); | |
166 %! assert (all (ismember ({"feature", "user"}, fieldnames (rv)))); | |
167 %! otherwise | |
168 %! error ("code in license out of date"); | |
169 %! endswitch | |
170 %! endfor | |
190 | 171 |
191 %!assert (license ("checkout", "Octave"), true) | 172 %!assert (license ("test", "octave"), true) |
173 %!assert (license ("test", "not_a_valid package name"), false) | |
174 | |
175 %!test | |
176 %! desc = pkg ("describe", "all"); | |
177 %! for idx = 1: numel (desc) | |
178 %! assert (license ("test", desc{idx}.name), true) | |
179 %! endfor | |
180 | |
181 %!assert (license ("checkout", "octave"), true) | |
182 | |
183 %!test | |
184 %! [s, e] = license ("checkout", "NOT_A_PACKAGE"); | |
185 %! assert (e, "No package named \"NOT_A_PACKAGE\" installed"); | |
192 | 186 |
193 %% Test input validation | 187 %% Test input validation |
194 %!error license ("not_inuse") | 188 %!error license ("not_inuse") |
195 %!error <TOGGLE must be either> license ("test", "Octave", "not_enable") | 189 %!error license ("not_test", "octave", "enable") |
196 %!error <FEATURE 'INVALID' not found> license ("test", "INVALID", "enable") | 190 %!error <TOOGLE must be enable or disable> license ("test", "octave", "invalid_toogle") |
197 %!error license ("not_test", "Octave", "enable") | |
198 | 191 |