Code covered by the MathWorks Limited License

Highlights from
Embedded Coder Support Package for Beagle Board

image thumbnail

Embedded Coder Support Package for Beagle Board

by

 

10 Feb 2011 (Updated )

Simulink block library for creating standalone applications for the Beagle Board

patch_installer(zipFileName, action)
function patch_installer(zipFileName, action)
% PATCH_INSTALLER Install/uninstall product patches.
%
% PATCH_INSTALLER(zipFileName, 'install') Installs the patch contained
% within the file zipFileName. zipFileName is the name of a ZIP archive
% which contains files required for the installation of a patch. If the
% archive is not in the current directory, specify full path name, i.e:
% zipFileName = 'C:\Applications\MATLAB71\work\patch_302609.zip'
%
% PATCH_INSTALLER(zipFileName, 'uninstall') Uninstalls the patch
% installed earlier.
%
% Examples:
% patch_installer('patch_302609.zip', 'install')
% 
% install patch_302609.zip patch.
%
% patch_installer('patch_302609.zip', 'uninstall')
%
% uninstall patch_302609.zip patch installed using the patch installer.

% Copyright 2006-2010 The MathWorks, Inc.

switch lower(action)
    case 'install'
        % Install files
        [succes, fullInstallDir] = installPatch(zipFileName);
         
        % Clean-up temporary files
        disp('Removing temporary files...');
        [ret, errMsg] = rmdir(fullInstallDir, 's');
        if (~ret)
            disp(errMsg);
        end
        
        if (succes == 1)
            % Rehash
            disp('Refreshing function and file system caches...');
            clear mex;
            clear functions;
            clear classes;
            rehash toolboxreset;
            rehash toolboxcache;
            sl_refresh_customizations;
            
            % Finish
            disp('Installation successful...');
        end
        
    case 'uninstall'
        
        % Uninstall patch
        [success, fullInstallDir] = uninstallPatch(zipFileName);
        
        % Clean-up temporary files
        disp('Removing temporary files...');
        [ret, errMsg] = rmdir(fullInstallDir, 's');
        if (~ret)
            disp(errMsg);
        end
        
        if (success == 1)
            % Clean-up
            clear mex;
            clear functions;
            clear classes;
            rehash toolboxreset;
            rehash toolboxcache;
            sl_refresh_customizations;
            
            % Finish
            disp('Uninstallation successful...');
        end
        
    case 'version'
        
        % Display the version number of this ptach installer utility
        disp('Version number of this patch installer is v1.0');
        
    otherwise
        EOL = char(10);
        errMsg = ['Action must be ''install'' or ''uninstall''' EOL];
        errMsg = [errMsg, 'Type: help patch_installer for more info.'];
        error('PatchInstaller:AbortInstall', errMsg);
end

return


%--------------------------------------------------------------------------
function prep(action)

% Close all open Simulink models
msgStr = sprintf( ['%s process needs to close all Simulink models. \n', ...
          'Save your Simulink work and press any key when ready: '], ...
          action);
userOk = input(msgStr, 's'); %#ok<NASGU>

% Close all open models if Simulink is installed
if exist('bdclose') %#ok<EXIST>
    bdclose('all');
end

% First unlock MEX files and clear classes.
clear mex;
clear classes;

return;

%--------------------------------------------------------------------------
function [success, fullInstallDir] = installPatch(zipFileName)

success = 0;

% Confirm that installation file is found
checkZipFile(zipFileName);

% Create a temporary directory for intstallation
tmpInstallDir = '.tmp_patch';
[~, fullInstallDir] = createTmpInstallDir(tmpInstallDir);

% Now unzip the archive into the temporary installation directory.
unzip(zipFileName, tmpInstallDir);
try
    installHelper = load(fullfile(tmpInstallDir, 'installHelper.mat'));
catch igException  %#ok<NASGU>
    s = ['Error: Corrupted archive? Cannot locate "installHelper.mat" ', ...
        'within extracted files.'];
    disp(s);
    disp('Aborting installation...');
    return;
end

% Create an install log
[installLogFileName, instalLogFileDir] = getInstallLogFname(zipFileName);
installLog = []; %#ok<NASGU>
try
    if exist(installLogFileName, 'file') 
        % Try setting the writable attribute
        fileattrib(installLogFileName, '+w');
    end
    save(installLogFileName, 'installLog');
catch igException  %#ok<NASGU>
    s = sprintf('Cannot create installation log file:\n "%s"', ...
                 installLogFileName);
    disp(s);
    s = sprintf('Please check write permissions for the directory:\n%s', ...
                instalLogFileDir);
    disp(s);
    disp('Aborting installation process...');
    return;
end

% Determine the version of the patch installer
useFullPath = true;
if ~isfield(installHelper, 'patchInstallerVersion')
    installHelper.patchInstallerVersion = '0.1';
    useFullPath = false;
end

% Check if the patch is compatible with this version of MATLAB tools 
checkVersion(installHelper);
    
% Back-up original versions of the files.
installFiles = installHelper.installFiles;
[success, installLog] = backupFiles(tmpInstallDir, installHelper); %#ok<NASGU>
save(installLogFileName, 'installLog');
if ( ~success )
    return;
end

% Prepare for installation
prep('Installation');

% Back-up process has gone smoothly. Now, install the patch
disp('Installing patch...');        
for i = 1:length(installFiles)
    if (useFullPath)
        sourceFile = fullfile(tmpInstallDir, installFiles(i).path, ...
            installFiles(i).name);
    else
        sourceFile = fullfile(tmpInstallDir, installFiles(i).name);
    end
    destinationDir  = fullfile(matlabroot, installFiles(i).path);
    destinationFile = fullfile(destinationDir, installFiles(i).name);
    fileStatus      = installFiles(i).status;
   
    % See if the file needs to be delete
    if ( strcmpi(fileStatus, 'delete') )
        s = sprintf('[%d] Deleting "%s"\nstatus: ', i, destinationFile);
        try
            if exist(destinationFile, 'file')
                delete(destinationFile);
                s = [s 'OK.']; %#ok<*AGROW>
            else
                s = [s, 'WARNING: This file does not exist in '];
                s = [s, 'your MATLAB installation. Skipping.'];
            end
        catch delException
            s = sprintf([s 'ERROR: Cannot delete file: "%s"'], ...
                sourceFile);
            disp(s);
            disp('Error message returned from delete():');
            disp(delException.message);
            disp('Run: patch_installer(zipFileName, ''uninstall'')');
            disp('to restore your original files.');
            disp('Aborting installation...');
            return
        end
        disp(s);
    else
        % copy the file into its proper place (even if it is Read-only)
        if strcmpi(fileStatus, 'new') && ~exist(destinationDir, 'dir')
            [ret, errMsg] = mkdir(destinationDir);
            if ( ~ret )
                s = sprintf([s 'ERROR: Cannot create destination directory: "%s".'], ...
                    destinationDir);
                disp(s);
                disp('Error message returned from "mkdir":');
                disp(errMsg);
                disp('Run: patch_installer(zipFileName, ''uninstall'')');
                disp('to restore your original files.');
                disp('Aborting installation...');
                return
            end
        end
        s = sprintf('[%d] Installing "%s"\nstatus: ', i, destinationFile);
        if strcmpi(fileStatus, 'old') && ~exist(destinationFile, 'file')
            s = [s, 'WARNING: This file does not exist in ']; %#ok<AGROW>
            s = [s, 'your MATLAB installation. Skipping.']; %#ok<AGROW>
            disp(s);
            continue;
        end
        [ret, errMsg] = copyfile(sourceFile, destinationDir, 'f');
        if ( ~ret )
            s = sprintf([s 'ERROR: Cannot copy source: "%s" to destination: "%s".'], ...
                sourceFile, destinationDir);
            disp(s);
            disp('Error message returned from copyfile:');
            disp(errMsg);
            disp('Run: patch_installer(zipFileName, ''uninstall'')');
            disp('to restore your original files.');
            disp('Aborting installation...');
            return
        end
        s = [s 'OK.']; %#ok<AGROW>
        disp(s);
    end
end

% Add or remove paths
addRemovePaths(installHelper, 'install');

success = 1;

return

%--------------------------------------------------------------------------
function [success, installLog] = backupFiles(tmpInstallDir, installHelper)

success = 1;

% Fetch back-up file extension which uniquely identifies the
% backup files
backupExt = [ '_' installHelper.patchIdStr];

% Initialize file backup log
installLog = [];

%Back-up files that will be over-written
disp('Backing-up files...');
installFiles = installHelper.installFiles;
for i = 1:length(installFiles)
    sourceFile = fullfile(tmpInstallDir, installFiles(i).name); %#ok<NASGU>
    destinationDir = fullfile(matlabroot, installFiles(i).path);
    destination = fullfile(destinationDir, installFiles(i).name);
    installLog(i).fileName = destination;
    s = sprintf('[%d] Backing up "%s"\nstatus: ', i, installLog(i).fileName);
    if ( strcmpi(installFiles(i).status, 'old') || ...
         strcmpi(installFiles(i).status, 'delete') )
        % Check if the specified file exists. If not
        % issue a warning but continue installation
        if ~exist(destination, 'file')
            installLog(i).status = 'not_found';
            s = [s 'WARNING: This file does not exist in your MATLAB installation. Skipping.'];
            disp(s);
            continue;
        end
        % Back-up this file
        backupFile = [destination, backupExt, '.bak'];
        % Prevent over-writing back-up files if patch is installed multiple
        % times
        installLog(i).backupFileName = backupFile;
        if ~exist(backupFile, 'file')
            ret = copyfile(destination, backupFile, 'f');
            if ( ~ret )
                installLog(i).status = 'error';
                s = [s 'WARNING: Cannot backup file. '];
                disp(s);
                response = input('Do you want to continue with the installation? [y/n]: ', 's');
                if ( strcmpi(response, 'n') )
                    success = 0;
                    return
                end
            else
                % File backup successful. Log accordingly
                installLog(i).status = 'ok';
                s = [s 'OK.'];
                disp(s);
            end
        else
            % Backup file already exists. Do not over-write simply log as
            % not backed up because file already existed
            installLog(i).status = 'exist';
            s = [s 'OK. File already backed-up.'];
            disp(s);
        end
    else
        % This is a new file that does not need back-up
        installLog(i).status = 'new_file';
        s = [s 'OK. New file. Does not need backup.'];
        disp(s);
    end
end

return


%--------------------------------------------------------------------------
function  [success, fullInstallDir] = uninstallPatch(zipFileName)

success = 0;

% Confirm that installation file is found
checkZipFile(zipFileName);

% Create a temporary directory for intstallation
tmpInstallDir = '.tmp_patch';
[~, fullInstallDir] = createTmpInstallDir(tmpInstallDir);

% Now unzip the archive into the temporary installation directory.
unzip(zipFileName, tmpInstallDir);
try
    installHelper = load(fullfile(tmpInstallDir, 'installHelper.mat'));
catch igException  %#ok<NASGU>
    s = ['Error: Corrupted archive? Cannot locate "installHelper.mat" ', ...
        'within extracted files.'];
    disp(s);
    disp('Aborting un-installation process...');
    return;
end

% Read install log. If it does not exist we cannot proceed with the
% uninstallation.
installLogFileName = getInstallLogFname(zipFileName);
try
    logStruct = load(installLogFileName);
    installLog = logStruct.installLog;
catch igException 
    EOL = char(10);
    s = sprintf('Cannot load installation log file:\n%s\n', installLogFileName);
    if ~exist(installLogFileName, 'file')
        s = [s 'File does not exist!' EOL];
    end
    s = [s 'Aborting uninstallation...'];
    error('PatchInstaller:AbortUninstall', s);
end

% Make sure that we can save the installation log
try
    fileattrib(installLogFileName, '+w');
    save(installLogFileName, 'installLog');
catch igException  
    s = sprintf('Cannot write to installation log file:\n%s\n', ...
                installLogFileName);
    s = [s 'Make sure that file is writable and re-run uninstallation script.'];
    error('PatchInstaller:AbortUninstall', s);
end

% Prepare for uninstallation
prep('Uninstallation');

%Un-install patch files
uninstallOk = 1;
disp('Uninstalling patch...');
for i = 1:length(installLog)
    destinationFile = installLog(i).fileName;
    if strcmp(installLog(i).status, 'not_found')
        s = sprintf('[%d] Restoring "%s"\nstatus: ', ...
            i, destinationFile);
        s = [s 'WARNING: This file does not exist in your MATLAB installation. '];
        s = [s 'Skipping.'];
        disp(s);
        continue;
    elseif strcmp(installLog(i).status, 'new_file')
        s = sprintf('[%d] Deleting "%s"\nstatus: ', i, destinationFile);
        if exist(destinationFile, 'file')
            try
                delete(destinationFile);
                installLog(i).status = 'deleted';
                s = [s 'OK.'];
            catch igException  %#ok<NASGU>
                s = [s 'WARNING. Cannot delete file.'];
                uninstallOk = 0;
            end
        else
            s = [s 'WARNING. Cannot locate file.'];
            installLog(i).status = 'lost';
        end
        disp(s);
    elseif ( strcmp(installLog(i).status, 'ok') || ...
             strcmp(installLog(i).status, 'exist') )
        s = sprintf('[%d] Restoring "%s"\nstatus: ', i, destinationFile);
        sourceFile = installLog(i).backupFileName;
        if exist(sourceFile, 'file')
            % Restore original file
            ret = movefile(sourceFile, destinationFile, 'f');
            if ( ~ret )
                uninstallOk = 0;
                s = [s 'ERROR. Cannot restore file.']; %#ok<AGROW>
                installLog(i).status = 'error';
                disp(s);
                response = input('Do you want to continue with the uninstallation? [y/n]: ', 's');
                if ( strcmpi(response, 'n') )
                    return
                end
            else
                % Mark the files as restored
                installLog(i).status = 'restored';
                s = [s 'OK.']; %#ok<AGROW>
                disp(s);
            end
        else
            uninstallOk = 0;
            s = [s 'ERROR. Cannot locate backup file.']; %#ok<AGROW>
            installLog(i).status = 'lost';
            disp(s);
            response = input('Do you want to continue with the uninstallation? [y/n]: ', 's');
            if ( strcmpi(response, 'n') )
                return
            end
        end
    end
end %for

% Restore MATLAB paths
addRemovePaths(installHelper, 'uninstall');

% Save modified backup log into our MAT file if uninstallation was not
% completely successful for some reason
if ( ~uninstallOk ) 
    save(installLogFileName, 'installLog');
else
    % Uninstallation was successful. Remove install log file
    delete(installLogFileName);
end

success = 1;

return


%==========================================================================
function addRemovePaths(installHelper, event)

% Add or remove paths

if isfield(installHelper, 'installPaths')
    s = sprintf('\nModifying MATLAB path...');
    disp(s);
    curAction = '';
    for i = 1:length(installHelper.installPaths)
        pathName = fullfile(matlabroot, installHelper.installPaths(i).name);
        ret = dir(pathName);
        if isempty(ret)
            disp(['WARNING: Cannot locate the following path: "', ...
                pathName, '".']);
            continue;
        end
        if strcmp(installHelper.installPaths(i).action, 'add')
            if strcmp(event, 'install')
                addpath(pathName);
                curAction = 'add';
            else
                rmpath(pathName);
                curAction = 'remove';
            end
        elseif strcmp(installHelper.installPaths(i).action, 'remove')
            if strcmp(event, 'install')
                rmpath(pathName);
                curAction = 'remove';
            else
                addpath(pathName);
                curAction = 'add';
            end
        else
            disp(['WARNING: Cannot determine whether to add or remove path "', ...
                installHelper.installPaths(i).name, '".']);
        end
        s = sprintf('[%d] %s path "%s', i, ...
            upper(curAction), pathName);
        disp(s);
    end
    savepath;
end

%--------------------------------------------------------------------------
function [installLogFileName, instalLogFileDir] = getInstallLogFname(zipFileName)

% Create an install log
%instalLogFileDir = fullfile(matlabroot,'toolbox','shared','etargets');
instalLogFileDir = fileparts(zipFileName);
I = strfind(zipFileName, '.');
if ~isempty(I)
    fname = zipFileName(1:I(1)-1);
end
installLogFileName = fullfile(instalLogFileDir, [fname '_install_log.mat']);
return

%--------------------------------------------------------------------------
function [parentDir, fullInstallDir] = createTmpInstallDir(tmpInstallDir)

parentDir = pwd;
fullInstallDir = fullfile(parentDir, tmpInstallDir);
if ~exist(fullInstallDir, 'dir')
    [ret, errMsg] = mkdir(parentDir, tmpInstallDir);
    if ( ~ret )
        disp(errMsg);
        s = sprintf('Cannot create temporary installation directory:\n"%s". ', ...
            fullInstallDir);
        s = [s 'Aborting...'];
        error('PatchInstaller:AbortInstall', s);
    end
end

return

%--------------------------------------------------------------------------
function checkZipFile(zip_file_name)

% First check if the zip file is in the current directory:
if ~exist(zip_file_name, 'file')
    s = sprintf('Cannot locate archive:\n"%s".\n', zip_file_name);
    s = [s 'This file is required for the installation process.\n'];
    s = [s 'Please check file name and location and re-run installation script.'];
    error('PatchInstaller:AbortInstall', s);
end

return

%--------------------------------------------------------------------------
function checkVersion(installHelper)
 
% Get MATLAB version info and locate version information
patchVer = installHelper.patchVer;
if (isempty(patchVer))
    %No version check needed
    return;
else
    % Convert Name and Version to cell arrays
    % Included here for backward compatibility
    if ~iscell(patchVer.Name)
        patchVer.Name = {patchVer.Name};
    end
    if ~iscell(patchVer.Version)
        patchVer.Version = {patchVer.Version};
    end
    prodVer.Name    = cell(size(patchVer.Name));
    prodVer.Version = cell(size(patchVer.Name));
    prodVer.Release = cell(size(patchVer.Name));
    
    % Get version number of products we want to install
    a = ver;
    isInstalledProd = false;
    for i = 1:length(a)
        tf = strcmpi(a(i).Name, patchVer.Name);
        if ( any(tf) )
            prodVer.Name{tf == true}    = a(i).Name;
            prodVer.Version{tf == true} = a(i).Version;
            prodVer.Release{tf == true} = a(i).Release;
            isInstalledProd = true;
        end
    end

    % Did we find the version info?
    if (~isInstalledProd)
        fmt = ['{', repmat('%s, ', 1, length(patchVer.Name)-1), '%s}'];
        error('PatchInstaller:AbortInstall', ...
        ['This patch is released for product(s) ', fmt, '. ', ...
            'The patch installer cannot locate required products in ', ...
            'your installation of MATLAB.'], patchVer.Name{:});
    end
    
    % Check that product version info matches to that of the
    % patch
    % For version > 1.0, patchVer.Version must be a cell array
    % Example:
    % patchVer.Name    = 'Target Support Package'
    % patchVer.Version = {'4.0', '4.1'}
    % patchVer.Release = {'(R2009b)', '(R2010a)'}
    versionMatch = false;
    if ~isempty(prodVer.Version)
        if (isempty(patchVer.Version) || ...
                any(ismember(prodVer.Version, patchVer.Version)) )
            versionMatch = true;
        end
    end
  
    if ~versionMatch
        fmt = ['{', repmat('%s %s, ', 1, length(patchVer.Version)-1), '%s %s}'];
        verStr = cell(1, 2*length(patchVer.Version));
        verStr(1:2:end) = patchVer.Version(:);
        verStr(2:2:end) = patchVer.Release(:);
        s = sprintf(['This patch is compatible with version ', fmt, ' of %s.\n'], ...
            verStr{:}, patchVer.Name{1});
        s = sprintf([s 'You have version %s %s of %s.\n'], ...
            prodVer.Version{1}, prodVer.Release{1}, prodVer.Name{1});
        s = [s 'Aborting installation.']; %#ok<AGROW>
        error('PatchInstaller:AbortInstall', s);
    end
end

return

Contact us