function varargout=ver(arg)
%VER MATLAB, SIMULINK, and TOOLBOX version information.
%   VER displays the current MATLAB and toolbox version numbers.
%   VER(TOOLBOX_DIR) displays the current version information for the
%   toolbox specified by the string TOOLBOX_DIR.
%
%   For example,
%      ver control
%   returns the version info for the Control System Toolbox.
%
%   For tips on how to hook your toolboxes into VER 'type ver.m'.
%
%   See also VERSION, HOSTID, LICENSE, INFO, WHATSNEW.

% Tips on how to get your toolbox to work with VER:
%
%   VER TOOLBOX_DIR looks for lines of the form
%
%     % Toolbox Description
%     % Version xxx dd-mmm-yyyy
%
%   as the first two lines of the Contents.m in the directory specified.  
%   The date cannot have any spaces in it and must use a 2 char day (that
%   is, use 02-Mar-1997 instead of 2-Mar-1997). 
%
%   To produce the display, VER combines the description and version
%   information into a single line, separating the date so that all the
%   dates line up.  Look at the Contents.m in any MathWorks toolbox (but
%   not MATLAB) for an example.

%   Copyright 1984-2000 The MathWorks, Inc. 
%   $Revision: 5.30 $  $Date: 2000/08/15 13:55:00 $

if nargout>0
   isArgout=logical(1);
   verStruct=struct('Name',{},'Version',{},'Release',{},'Date',{});
else
   isArgout=logical(0);
end

nameLen = 38;
releaseLen = 12;
verLen = 19-releaseLen;

p = path2cell(matlabpath);

if nargin > 0
   % Reverse the path strings for easy searching later
   for i=1:length(p),
      p{i} = fliplr(p{i});
   end
   if strcmp(lower(deblank(arg)),'matlab')
      if ~isArgout
         LocDisplayMatlabInformation
      end
      arg = 'general';
      larg = length(arg);
   end
   arg = fixarg(p,arg);
   if strncmp(computer,'MAC',3)
      arg = [arg filesep];
   end
   targ = fliplr([filesep arg]);
   larg = length(targ);
   for i=1:length(p),
      if strncmp(targ,p{i},larg);
         fName = fullfile(fliplr(p{i}),'Contents.m');
         [structInfo,dispString]=LocParseContentsFile(fName);
         if ~isArgout
            if ~isempty(dispString)
               disp(dispString);
            else
               disp(['No Contents.m file for ' fliplr(p{i})])
            end
         elseif isArgout & ~isempty(structInfo)
            verStruct(end+1)=structInfo;
         end
      end
   end
else
   if ~isArgout
      disp('--------------------------------------------------')
      LocDisplayMatlabInformation
      disp('--------------------------------------------------')
   end
   
   % Remove the toolbox/matlab directories
   d = [];
   tm  = ['toolbox' filesep 'matlab'];
   tmg = ['toolbox' filesep 'matlab' filesep 'general'];
   
   % Look for and remove toolbox/local as well
   tl = ['toolbox' filesep 'local'];

   for i=1:length(p),
      if ~isempty(findstr(tmg,lower(p{i}))), k = i; end
      if ~isempty(findstr(tm,lower(p{i}))), 
         d = [d i]; 
      end
      if ~isempty(findstr(tl,lower(p{i}))), d = [d i]; end
   end
   p = [p(k);p];
   p(d+1) = [];
   
   % Now go through each directory and print out the version information
   % from the Contents.m file.
   for i=1:length(p)
      [structInfo,dispString]=LocParseContentsFile(fullfile(p{i},'Contents.m'));
      if ~isArgout & ~isempty(dispString)
         disp(dispString);
      elseif isArgout & ~isempty(structInfo)
         verStruct(end+1)=structInfo;
      end
   end
end

if isArgout
   varargout{1}=verStruct;
end


%--------------------------------------------------
function c = path2cell(p)
%PATH2CELL Split path into cell array of strings.
%   PATH2CELL(PATH) returns a cell array of strings containing the
%   individual path elements.

seps = [0 find(p==pathsep) length(p)+1];

c = cell(length(seps)-1,1);
for i=1:length(seps)-1,
   c{i} = p(seps(i)+1:seps(i+1)-1);
   if c{i}(end) == ']',
      c{i}(end) = [];
   end
end
%--------------------------------------------------
function newarg = fixarg (p, arg)
%FIXARG Fix the argument for special cases
%   FIXARG (PATH, ARG) returns a modified argument
%   for the special cases below.
%   1. toolboxes lmi, mpc, or mutools are not
%      conforming.
%   2. matlabroot/simulink is on the MAC path so
%      handle simulink differently in this case.

switch arg
case 'lmi'
   dir = 'lmilab';
case 'mpc'
   dir = 'mpccmds';
case 'mutools'
   dir = 'commands';
otherwise
   dir = '';
end
if ~isempty(dir)
   targ = fliplr([filesep arg]);
   larg = length(targ);
   found = 0;
   for i=1:length(p)
      if strncmp(targ,p{i},larg)
         found = 1;
         break;
      end
   end
   if ~found
      newarg = [ arg filesep dir ];
   else
      newarg = arg;
   end
else
   newarg = arg;
end
switch newarg
case 'simulink'
   if strncmp(computer,'MAC',3)
      newarg = [newarg filesep newarg];
   end
end


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [structInfo,dispString]=LocParseContentsFile(fName);

nameLen = 38;
releaseLen = 13;
verLen = 19-releaseLen;

dispString='';
structInfo=struct('Name',{},'Version',{},...
   'Release',{},'Date',{});

if exist(fName)
   c = computer;
   if c(1:2) == 'PC'
      fp = fopen(fName,'rb');
   else
      fp = fopen(fName,'r');
   end
   
   if fp>0
      s = fgetl(fp);
      if ~isstr(s)
         s = '';
      else
         s  = [s '  '];
         s(1:2) = [];
      end
      
      s1 = fgetl(fp);
      if ~isstr(s1)
         s1 = '';
      else
         s1 = [s1 '  '];
         s1(1:2) = [];
      end
      fclose(fp);
   else
      s='';
      s1='';
   end
   
   if ~isempty(findstr(fName,'general'))
      % Look for Version
      k = findstr('Version',s1);
      s = s1(1:k-1);
      s1 = s1(k:end);
   end
   
   s = deblank(s);
   % Remove any trailing period.
   if ~isempty(s) & s(end)=='.'
      s(end)=[];
   end
   
   % Force the name to fit within the specified number of characters
   productName=s;
   if length(s) > nameLen
      s = [s(1:nameLen-3) '...'];
   end
   
   %remove trailing spaces
   s1 = deblank(s1);
   if ~isempty(s1)
      verLoc=findstr(lower(s1),'version ');
      if ~isempty(verLoc)
         s1=s1(verLoc+length('version '):end);
         %remove leading spaces
         s1= fliplr(deblank(fliplr(s1)));
         blankLoc=findstr(s1,' ');
         
         if length(blankLoc)>0
            %Version is everything from beginning to first space
            verNum=s1(1:blankLoc(1)-1);
            
            %Date is everything from last space to end
            dateString=s1(blankLoc(end)+1:end);
            dateString=LocCleanDate(dateString);
            
            %Release number is everything from first to last space
            releaseNum=s1(blankLoc(1):blankLoc(end));
            %remove leading and trailing blanks from releaseNum
            releaseNum=deblank(releaseNum);
            releaseNum=fliplr(deblank(fliplr(releaseNum)));
            
            structInfo=struct('Name',productName,...
               'Version',verNum,...
               'Release',releaseNum,...
               'Date',dateString);
            
            s=[s blanks(nameLen-length(s))];
            %Note that if verNum and releaseNum expand beyond their
            %available column width, they are NOT truncated.  
            verNum=[verNum blanks(verLen-length(verNum)-1) ' '];
            releaseNum=[releaseNum blanks(releaseLen-length(releaseNum)-1) ' '];
            
            dispString=[s '  Version ' verNum releaseNum dateString];
         end
      end
   end
   
else
   % Skip this directory since there's no Contents.m
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function LocDisplayMatlabInformation

disp([prepender('MATLAB Version '),version,' on ',computer]);
if isunix
   list = hostid; len = length(list);
   if len == 1
      disp(['MATLAB Server Hostid: ',list{1}])
   else
      disp(['MATLAB Server Hostid: ',list{1},' :'])
      for i=2:len-1
         disp(['                      ',list{i},' :'])
      end
      disp(['                      ',list{len}])
   end
end
disp(['MATLAB License Number: ',license]);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function cleanDate=LocCleanDate(dirtyDate);
%LocCleanDate forces a date to be in the format of DD-Mmm-YYYY

slashLoc=findstr(dirtyDate,'-');
if length(slashLoc)>1
   dayStr=dirtyDate(1:slashLoc(1)-1);
   monthStr=dirtyDate(slashLoc(1)+1:slashLoc(2)-1);
   yearStr=dirtyDate(slashLoc(2)+1:end);
   
   if length(dayStr)==1
      dayStr=['0' dayStr];
   end
   
   if length(monthStr)>2
      monthStr=[upper(monthStr(1)),lower(monthStr(2:3))];
   end
   
   cleanDate=[dayStr '-' monthStr '-' yearStr];
   
else
   cleanDate=dirtyDate;
end




