Home > matpower7.1 > mptest > lib > have_feature.m

have_feature

PURPOSE ^

HAVE_FEATURE Test for optional functionality / version info.

SYNOPSIS ^

function rv = have_feature(tag, rtype)

DESCRIPTION ^

HAVE_FEATURE  Test for optional functionality / version info.
   TORF = HAVE_FEATURE(TAG)
   TORF = HAVE_FEATURE(TAG, TOGGLE)
   VER_STR = HAVE_FEATURE(TAG, 'vstr')
   VER_NUM = HAVE_FEATURE(TAG, 'vnum')
   DATE    = HAVE_FEATURE(TAG, 'date')
   INFO    = HAVE_FEATURE(TAG, 'all')
   HAVE_FEATURE(TAG, 'clear_cache')
   HAVE_FEATURE('all', 'clear_cache')

   Returns availability, version and release information for optional
   functionality. All information is cached, and the cached values
   returned on subsequent calls. If the functionality exists, an attempt is
   made to determine the release date and version number. The second
   argument defines which value is returned, as follows:
       <none>      1 = optional functionality is available, 0 = not available
       'vstr'      version number as a string (e.g. '3.11.4')
       'vnum'      version number as numeric value (e.g. 3.011004)
       'date'      release date as a string (e.g. '21-Sep-2020')
       'all'       struct with fields named 'av' (for 'availability'), 'vstr',
                   'vnum' and 'date', and values corresponding to the above,
                   respectively.

   For functionality that is not available, all calls with a string-valued
   second argument will return an empty value.

   Alternatively, the optional functionality specified by TAG can be toggled
   OFF or ON by calling HAVE_FEATURE with a numeric second argument TOGGLE
   with one of the following values:
       0 - turn OFF the optional functionality
       1 - turn ON the optional functionality (if available)
      -1 - toggle the ON/OFF state of the optional functionality

   Finally, passing 'clear_cache' as the second argument will cause the
   cached information to be cleared for the specified TAG or, if the first
   argument is 'all', for all optional functionality. When calling with
   'clear_cache' no return value is defined.

   For each valid value of TAG, there is a corresponding feature detection
   function named HAVE_FEATURE_<TAG>, where <TAG> is the TAG value for the
   feature in question. This makes HAVE_FEATURE modular and extensible.
   Each feature detection function takes no input values, but returns
   three outputs
       TORF - 1 = feature is available, 0 = feature is not available
       VSTR - version number as a string (e.g. '3.11.4')
       RDATE - release date as a string (e.g. '21-Sep-2020')

   TAG values for HAVE_FEATURE detection functions included in MP-Test:
       matlab      - code is running under MATLAB, as opposed to Octave
       octave      - code is running under GNU Octave, as opposed to MATLAB

   Examples:
       if have_feature('matlab')
           disp(['Running MATLAB version ', have_feature('matlab', 'vstr')])
       else
           disp(['Running Octave version ', have_feature('octave', 'vstr')])
       end

   See also HAVE_FEATURE_MATLAB, HAVE_FEATURE_OCTAVE

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SUBFUNCTIONS ^

SOURCE CODE ^

0001 function rv = have_feature(tag, rtype)
0002 %HAVE_FEATURE  Test for optional functionality / version info.
0003 %   TORF = HAVE_FEATURE(TAG)
0004 %   TORF = HAVE_FEATURE(TAG, TOGGLE)
0005 %   VER_STR = HAVE_FEATURE(TAG, 'vstr')
0006 %   VER_NUM = HAVE_FEATURE(TAG, 'vnum')
0007 %   DATE    = HAVE_FEATURE(TAG, 'date')
0008 %   INFO    = HAVE_FEATURE(TAG, 'all')
0009 %   HAVE_FEATURE(TAG, 'clear_cache')
0010 %   HAVE_FEATURE('all', 'clear_cache')
0011 %
0012 %   Returns availability, version and release information for optional
0013 %   functionality. All information is cached, and the cached values
0014 %   returned on subsequent calls. If the functionality exists, an attempt is
0015 %   made to determine the release date and version number. The second
0016 %   argument defines which value is returned, as follows:
0017 %       <none>      1 = optional functionality is available, 0 = not available
0018 %       'vstr'      version number as a string (e.g. '3.11.4')
0019 %       'vnum'      version number as numeric value (e.g. 3.011004)
0020 %       'date'      release date as a string (e.g. '21-Sep-2020')
0021 %       'all'       struct with fields named 'av' (for 'availability'), 'vstr',
0022 %                   'vnum' and 'date', and values corresponding to the above,
0023 %                   respectively.
0024 %
0025 %   For functionality that is not available, all calls with a string-valued
0026 %   second argument will return an empty value.
0027 %
0028 %   Alternatively, the optional functionality specified by TAG can be toggled
0029 %   OFF or ON by calling HAVE_FEATURE with a numeric second argument TOGGLE
0030 %   with one of the following values:
0031 %       0 - turn OFF the optional functionality
0032 %       1 - turn ON the optional functionality (if available)
0033 %      -1 - toggle the ON/OFF state of the optional functionality
0034 %
0035 %   Finally, passing 'clear_cache' as the second argument will cause the
0036 %   cached information to be cleared for the specified TAG or, if the first
0037 %   argument is 'all', for all optional functionality. When calling with
0038 %   'clear_cache' no return value is defined.
0039 %
0040 %   For each valid value of TAG, there is a corresponding feature detection
0041 %   function named HAVE_FEATURE_<TAG>, where <TAG> is the TAG value for the
0042 %   feature in question. This makes HAVE_FEATURE modular and extensible.
0043 %   Each feature detection function takes no input values, but returns
0044 %   three outputs
0045 %       TORF - 1 = feature is available, 0 = feature is not available
0046 %       VSTR - version number as a string (e.g. '3.11.4')
0047 %       RDATE - release date as a string (e.g. '21-Sep-2020')
0048 %
0049 %   TAG values for HAVE_FEATURE detection functions included in MP-Test:
0050 %       matlab      - code is running under MATLAB, as opposed to Octave
0051 %       octave      - code is running under GNU Octave, as opposed to MATLAB
0052 %
0053 %   Examples:
0054 %       if have_feature('matlab')
0055 %           disp(['Running MATLAB version ', have_feature('matlab', 'vstr')])
0056 %       else
0057 %           disp(['Running Octave version ', have_feature('octave', 'vstr')])
0058 %       end
0059 %
0060 %   See also HAVE_FEATURE_MATLAB, HAVE_FEATURE_OCTAVE
0061 
0062 %   The following calling syntaxes are also implemented to set and get the
0063 %   entire cache struct and are used during testing only.
0064 %       CACHE = HAVE_FEATURE('all', 'get_cache')
0065 %       HAVE_FEATURE(CACHE, 'set_cache')
0066 
0067 %   MP-Test
0068 %   Copyright (c) 2004-2020, Power Systems Engineering Research Center (PSERC)
0069 %   by Ray Zimmerman, PSERC Cornell
0070 %
0071 %   This file is part of MP-Test.
0072 %   Covered by the 3-clause BSD License (see LICENSE file for details).
0073 %   See https://github.com/MATPOWER/mptest for more info.
0074 
0075 persistent h_f_cache;
0076 
0077 action = 'D';                   %% detecting functionality (default)
0078 if nargin > 1
0079     if isnumeric(rtype) && ~isempty(rtype)
0080         action = 'T';           %% toggling functionality
0081         on_off = rtype;
0082         if on_off < 0                   %% flip the toggle
0083             TorF = have_feature(tag);
0084             on_off = ~TorF;
0085         end
0086     elseif length(rtype) > 4
0087         switch lower(rtype)
0088             case 'get_cache'
0089                 action = 'C';   %% getting cache
0090                 rv = h_f_cache;
0091             case 'set_cache'
0092                 action = 'C';   %% setting cache
0093                 h_f_cache = tag;
0094             case 'clear_cache'
0095                 action = 'C';   %% clearing cache
0096                 if strcmpi(tag, 'all')  %% delete all fields
0097                     h_f_cache = struct();
0098                 else                    %% delete field to force single re-check
0099                     if isfield(h_f_cache, tag)
0100                         h_f_cache = rmfield(h_f_cache, tag);
0101                     end
0102                 end
0103         end
0104     end
0105 end
0106 
0107 if action == 'T'            %% change availability
0108     if on_off                   %% turn on if available
0109         if isfield(h_f_cache, tag)  %% delete field to force single re-check
0110             h_f_cache = rmfield(h_f_cache, tag);
0111         end
0112     else                        %% turn off
0113         if ~isfield(h_f_cache, tag)     %% not yet been checked
0114             TorF = have_feature(tag);   %% cache result first
0115         end
0116         h_f_cache.(tag).av = 0;         %% then turn off
0117     end
0118     TorF = have_feature(tag);           %% return availability
0119                                         %% (recheck if ON, cached 0 if OFF)
0120 elseif action == 'D'        %% detect availability
0121     %% info not yet cached?
0122     if ~isfield(h_f_cache, tag)
0123         %%-----  determine installation status, version number, etc.  -----
0124         %% initialize default values
0125         TorF = 0;
0126         vstr = '';
0127         rdate = '';
0128 
0129         %% check for feature
0130         fcn = ['have_feature_' tag];
0131         if isempty(which(fcn))
0132             warning('have_feature: unknown functionality ''%s''', tag);
0133             vstr = 'unknown';
0134         else
0135             [TorF, vstr, rdate] = feval(fcn);
0136         end
0137 
0138         %% assign values to cache
0139         h_f_cache.(tag).av   = TorF;
0140         h_f_cache.(tag).vstr = vstr;
0141         if isempty(vstr)
0142             h_f_cache.(tag).vnum = [];
0143         else
0144             h_f_cache.(tag).vnum = vstr2num(vstr);
0145         end
0146         h_f_cache.(tag).date = rdate;
0147     end
0148 end
0149 
0150 %% extract desired values from cache
0151 if action ~= 'C' || nargout
0152     if nargin < 2 || action == 'T'
0153         rv = h_f_cache.(tag).av;
0154     else
0155         switch lower(rtype)
0156             case 'vstr'
0157                 rv = h_f_cache.(tag).vstr;
0158             case 'vnum'
0159                 rv = h_f_cache.(tag).vnum;
0160             case 'date'
0161                 rv = h_f_cache.(tag).date;
0162             case 'all'
0163                 rv = h_f_cache.(tag);
0164             case {'', 'av'}
0165                 rv = h_f_cache.(tag).av;
0166         end
0167     end
0168 end
0169 
0170 function num = vstr2num(vstr)
0171 % Converts version string to numerical value suitable for < or > comparisons
0172 % E.g. '3.11.4' -->  3.011004
0173 pat = '\.?(\d+)';
0174 [s,e,tE,m,t] = regexp(vstr, pat);
0175 b = 1;
0176 num = 0;
0177 for k = 1:length(t)
0178     num = num + b * str2num(t{k}{1});
0179     b = b / 1000;
0180 end

Generated on Fri 09-Oct-2020 11:21:31 by m2html © 2005