| aselfpack(sourceDir,filt,packName,packTitle,packDescription,installNotes) |
function aselfpack(sourceDir,filt,packName,packTitle,packDescription,installNotes)
% ASELFPACK Creats self-extract package.
% Creates a single matlab self-extract p file with all the contents of a
% selected folder(including subdirectories) based on the filter FILT.
%
% USAGE:
% ASELFPACK(sourceDir,filt,packName,packTitle,packDescription,installNotes)
%
% INPUT:
% sourceDir - Source directory to be packed
% filt - string or cell array of string for filtering the files of source directory
% during packing.
% The typical form of valid filter:
% '~.m' - exclude all m files
% '*.m' - include all m files
% '*.*' - include all files (default)
% {'*.m' ,'*.p'} - include only m files and p files
% {'~.m' ,'~.asv'} - exclude m and asv files
% {'~.m', '~.asv','demo.m'} - exclude all m and asv files except demo.m
% {'*.m' ,'~demo.m'} - include all m files except demo.m
%
% packName - Filename of the self extracting package [ 'self' ]
% packTitle - Title of the self extracting package
% [ '<main folder> MATLAB Toolbox' ]
% packDescription - Information to be added in self extracting package,
% cell array [ <none> ]
% installNotes - Installation notes to be shown at the end of the
% extraction, cell array [ <none> ]
%
% OUTPUT:
%
% EXAMPLES:
% sourceDir = 'd:\My Matlab Tools\Mytoolbox';
% filt = {'~.m', '~.asv','demo.m'}
% packName = 'mytoolbox_install';
% packTitle = 'My analysis toolbox';
% packDescription = {'lots of files...','to do whatever...'};
% installNotes = {'just install... and ';'if you have doubts';
% 'write me to mail@mail.m'};
% ASELFPACK(sourceDir,filt,packName,packTitle,packDescription,installNotes)
%
% See also: SELFPACK, RPCODE
%
% NOTES:
% This ASELFPACK is improvement of the orginal submission SELFPACK
% by martinho@fis.ua.pt
% (http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=8565
%
% ADITIONAL FUNCTIONALITY compared to SELFPACK
% 1. Filter to exclude or include some files
% 2. Add folders to Matlab search path
% 3. User defined folder for installation
% HISTORY
% 1.0.0 - Initial release 16-Oct-2008
% 1.1.0 (27-Jan-2009)
% - Source directory is not created any more in the installation directory
% - Corrected double path separator
% - Private directory is not added to the path
% 1.2.0 (09-Nov-2009)
% - Bug fixed in filter
% ToDo
%
% Author: Durga Lal Shrestha
% UNESCO-IHE Institute for Water Education, Delft, The Netherlands
% eMail: durgalal.shrestha@gmail.com
% Website: www.durgalal.co.cc
% Copyright 2008-2009 Durga Lal Shrestha.
% $First created: : 16-Oct-2008
% $Revision: 1.2.0 $ $Date: 09-Nov-2009 13:55:49 $
% ***********************************************************************
%%
useTextAsBin = 1;
createPfile = 1;
pRemoveMFile = 0;
if nargin < 1
disp(':: you must input a folder name')
return
elseif ~exist(sourceDir,'dir')
disp(':: the selected folder do not exist')
return
end
% %deal with filesep:
sourceDir = strrep(sourceDir,'/',filesep);
sourceDir = strrep(sourceDir,'\',filesep);
%sourceDir = strrep(sourceDir,':',filesep); % Changed by DLS
sourceDir = realpath(sourceDir);
% find the main folder (remove extra path):
lastDir = basename(sourceDir);
%thePath = dirname(sourceDir);
thePath = sourceDir;
if nargin < 2 || isempty(filt)
filt = {'*.*'};
end
if nargin < 3
packName = 'self.m';
else
packName = [packName,'.m'];
end
if nargin < 4
packTitle = [lastDir,' MATLAB Toolbox'];
end
if nargin < 5
packDescription = {};
end
if nargin < 6
installNotes = {};
end
% check the output file:
mFile = packName;
pFile = [packName(1:end-1),'p'];
if createPfile
finalFile = pFile;
else
finalFile = mFile;
end
if exist([pwd,filesep,finalFile],'file') || exist([pwd,filesep,mFile],'file')
if exist([pwd,filesep,mFile],'file') && createPfile
fprintf(1,'\n :: Warning: the self-extract installation file %s will be overwritten !!\n',mFile);
end
fprintf(1,'\n :: Warning: the self-extract installation file %s already exist\n',finalFile);
while 1
yesno = input('\n Do you want to continue ([y],n) ? ','s');
if isempty(yesno) || isequal(yesno,'y')
break
elseif isequal(yesno,'n')
fprintf(1,'\n opperation canceled\n\n');
return
end
end
fprintf(1,'\n')
end
% get all available subdirs and number of files:
dirs = get_dirs(sourceDir);
nfiles = get_nfiles(dirs);
if nfiles > 0
fprintf(1,'\n%s\n',' ---------------------------------------------------');
fprintf(1,'%s\n',' MATLAB Utility: Self extractor');
fprintf(1,' %s\n',packTitle);
for i=1:length(packDescription)
fprintf(1,' %s\n',packDescription{i});
end
fprintf(1,'\n')
fprintf(1,' :: Source directory %s\n',sourceDir);
fprintf(1,' :: found %d folder\n',length(dirs));
fprintf(1,' :: found %d files\n',nfiles);
else
disp(':: there are no files to process')
return
end
% add first lines:
process_init(packName,packTitle,packDescription);
% add folders:
process_folders(dirs,packName,packTitle,packDescription,thePath);
% add files:
[numok,numbad] = process_files(dirs,filt,packName,useTextAsBin,thePath);
% add final lines:
process_final(packName,installNotes);
% add functions:
process_funcs(packName);
% create p file and delete the m file:
if createPfile
pcode([pwd,filesep,packName]);
if pRemoveMFile
delete([pwd,filesep,packName]);
end
end
% show size of the output file:
d = dir(finalFile);
nb = d.bytes;
fprintf(1,'\n :: done -- Self-extraction file %s (%d bytes)\n',finalFile,nb);
fprintf(1, ' :: number of files added = %d\n',numok);
fprintf(1, ' :: number of files NOT added(due to filtering or error) = %d\n',nfiles-numbad-numok);
%fprintf(1,'\n :: the installation folder is %s\n',lastDir);
fprintf(1,'%s\n\n',' ---------------------------------------------------');
% --------------------------------------------------------------------
function process_init(output,title,description)
fid=fopen(output,'w');
% function line:
fprintf(fid,'function %s\n',output(1:end-2));
% first line:
fprintf(fid,'%%%s',upper(output(1:end-2)));
fprintf(fid,'%s %s\n',' Installer of the',title);
% description:
for i=1:length(description)
fprintf(fid,'%% %s\n',description{i});
end
% more info:
fprintf(fid,'%%\n%s\n','% This is a self extraction file which will create the toolbox');
fprintf(fid,'\n');
fprintf(fid,'%% Ceated in %s\n',datestr(now));
fprintf(fid,'%% by the utility %s from Durga Lal Shrestha, durgals@hotmail.com\n',upper(mfilename));
fprintf(fid,'\n');
fclose(fid);
% --------------------------------------------------------------------
function withErrors = process_folders(dirs,output,title,description,thePath)
fid = fopen(output,'a');
for i=1:length(dirs)
% first I need to remove the extra path so that only the last dir remains:
dirs{i} = strrep(dirs{i},thePath,'');
%dirs{i}=dirs{i}(2:end);% DLS
% find if there is filesep at the begining and remove it
k = strfind(dirs{i}, 'filesep');
if ~isempty(k) && k(1)==3
dirs{i}=dirs{i}(k(1)+7+2:end);
end
fprintf(fid,'%s%d%s%s%s\n','dirs(',i,') = {[''',dirs{i},''']};');
end
fprintf(fid,'\n');
%fprintf(fid,'%s\n','% theMainDir = dirs{1};');
% show title and descripton:
fprintf(fid,'%s\n','fprintf(1,''\n ---------------------------------------------------\n'');');
fprintf(fid,'%s\n','fprintf(1,'' Installation of the matlab toolbox:\n'');');
fprintf(fid,'%s\n', ['fprintf(1,'' %s\n'',''',title,''');']);
for i=1:length(description)
fprintf(fid,'%s\n', ['fprintf(1,'' %s\n'',''',description{i},''');']);
end
%% Installation folder
% Added this functionality to the orginal submission by Durga Lal Shrestha
fprintf(fid,'%s\n','fprintf(1,'' %s\n'','''');');
fprintf(fid,'%s\n', 'fprintf(1,''\n :: Select directory to install, press any key to open directory selector\n\n'');');
fprintf(fid,'%s\n', ' pause');
fprintf(fid,'%s\n','install_dir = uigetdir(pwd,''Select directory to install files'');');
fprintf(fid,'%s\n','if isequal(install_dir,0)');
fprintf(fid,'%s\n',' install_dir = pwd;');
fprintf(fid,'%s\n','end');
%% ask if want to continue:
fprintf(fid,'%s\n', 'fprintf(1,''\n The installation will copy files to the folder %s\n'',install_dir);');
fprintf(fid,'%s\n', 'fprintf(1,''\n Warning: the folders may not be empty and new files will overwrite existing ones\n\n'');');
fprintf(fid,'\n');
fprintf(fid,'%s\n', 'yesno = input(''\n Do want to continue ([y],n) ? '',''s'');');
fprintf(fid,'%s\n', 'if isequal(yesno,''n'')');
fprintf(fid,'%s\n', ' fprintf(1,''\n installation canceled\n\n'');');
fprintf(fid,'%s\n', ' return');
fprintf(fid,'%s\n', 'end');
% create all folders:
fprintf(fid,'\n');
fprintf(fid,'%s\n','withErrors = 0;');
fprintf(fid,'%s\n','for i=1:length(dirs)');
fprintf(fid,'%s\n','completePath = [install_dir,filesep,dirs{i}];');
fprintf(fid,'%s\n',' if ~exist(completePath,''dir'')');
fprintf(fid,'%s\n',' fprintf(1,'' creating folder %s'',completePath);');
fprintf(fid,'%s\n',' try');
fprintf(fid,'%s\n',' mkdir(completePath);');
fprintf(fid,'%s\n',' fprintf(1,''\n'');');
fprintf(fid,'%s\n',' catch');
fprintf(fid,'%s\n',' fprintf(1,'' -- ERROR\n'')');
fprintf(fid,'%s\n',' withErrors = 1;');
fprintf(fid,'%s\n',' end');
fprintf(fid,'%s\n',' else');
fprintf(fid,'%s\n',' %fprintf(1,'' the folder %s already exist\n'',completePath);');
fprintf(fid,'%s\n',' end');
fprintf(fid,'%s\n','end');
%% Add path
% Added this functionality to the orginal submission by Durga Lal Shrestha
fprintf(fid,'%s\n','%% Add path;');
fprintf(1,'\n')
fprintf(fid,'%s\n','yesno = input(''\n Do you want to add above directories to MATLAB Path ([y],n) ? '',''s'');');
fprintf(fid,'%s\n','if isequal(yesno,''y'')');
fprintf(fid,'%s\n','% Add path;');
fprintf(fid,'%s\n',' for i=1:length(dirs);');
fprintf(fid,'%s\n',' completePath = [install_dir,filesep,dirs{i}];');
fprintf(fid,'%s\n',' k=strfind(completePath, ''private'');');
fprintf(fid,'%s\n',' if isempty(k);');
fprintf(fid,'%s\n',' addpath(completePath);');
fprintf(fid,'%s\n',' end');
fprintf(fid,'%s\n',' end');
fprintf(fid,'%s\n',' fprintf(1,''\n The directories have been added to MATLAB search path\n\n'');');
fprintf(fid,'%s\n','else');
fprintf(fid,'%s\n',' fprintf(1,''\n Paths have not been added, you can add manualy via File\Set Path... \n\n'');');
fprintf(fid,'%s\n','end');
fclose(fid);
% --------------------------------------------------------------------
function [numFilesOK,numFilesBAD] = process_files(dirs,filt,output,useTextAsBin,thePath)
fid = fopen(output,'a');
% find the main folder (remove extra path):
subDirs = dirs;
for nd=1:length(dirs)
%subDirs{nd}(1:length(thePath)+1) = '';
subDirs{nd}(1:length(thePath)) = '';
end
numFilesOK = 0;
numFilesBAD = 0;
for i=1:length(dirs)
str=['currentDir=[''',dirs{i},'''];'];
eval(str);
str=['currentShownDir=[''',subDirs{i},'''];'];
eval(str);
fprintf(1,' entering in folder %s\n',currentShownDir);
d=dir(currentDir);
isd = zeros(size(d));
nisnull = zeros(size(d));
for n=1:length(d)
isd(n) = d(n).isdir; % is dir
nisnull(n) = d(n).bytes; % not is null
end
% the nisnull condition is needed when dirs are chmod -x
files = {d(~isd&nisnull).name};
folders = {d(~~isd).name};
if isempty(files) && length(folders) == 2
fprintf(1,' the folder %s IS EMPTY\n',currentDir);
end
%% Apply filter
%filt={'~.m' '~.p'};
for n=1:length(files)
if applyfilter(files{n},filt) % Added this functionality to the
% orginal submission
currentFile = files{n};
fprintf(1,' processing file %s\n',currentFile);
theFile = [currentDir,filesep,currentFile];
% check file type:
[isbin,type] = isbinary(theFile);
if ~isempty(isbin)
f=fopen(theFile);
c=fread(f);
theRealSize=prod(size((c)));
if ~isbin & ~useTextAsBin
c=char(c');
c=strrep(c,char(13),'');
c=strrep(c,'''','''''');
if c(end)==10, c=c(1:end-1); end
c=strrep(c,char(10),['\n'');' 10 'fprintf(fid,''%s\n'',''']);
c=['fprintf(fid,''%s\n'',''',c,''');'];
theType = 'text';
else
c=sprintf('%02x\n',c);
c(3:3:end)='';
nChar=70;
m=floor(length(c)/nChar);
tmp='';
tmp=reshape(c(1:m*nChar),nChar,m);
tmp=tmp';
if mod(length(c),nChar)
tmp=strvcat(tmp,c(m*nChar+1:end));
end
tmp(:,2:end+1)=tmp;
tmp(:,1)='''';
tmp(:,end+1) = '''';
tmp(:,end+1) = ',';
tmp(:,end+1) = 10;
tmp(1,end)=10;
c=tmp;
theType = 'binary';
end
theSize=prod(size((c)));
if ~isbin & ~useTextAsBin
fprintf(fid,'\n');
fprintf(fid,'%s\n',['file = [install_dir,''' subDirs{i},''',filesep,''',currentFile,'''];']);
fprintf(fid,'%s\n',['[withErrors,fid] = ini_file(file,''',type,''');']);
fwrite(fid,c);
fprintf(fid,'\n');
fprintf(fid,'%s\n','fclose(fid);');
else
fprintf(fid,'\n');
fprintf(fid,'%s\n',['file = [install_dir,''' subDirs{i},''',filesep,''',currentFile,'''];']);
fprintf(fid,'%s\n',['[withErrors,fid] = ini_file(file,''',type,''');']);
fprintf(fid,'%s\n','hex = [');
fprintf(fid,'%s',c');
fprintf(fid,'%s\n','];');
fprintf(fid,'%s\n','finnish_file(fid,hex);');
end
f=fclose(f);
numFilesOK = numFilesOK + 1;
else
numFilesBAD = numFilesBAD + 1;
fprintf(1,' UNABLE to processing file %s\n',currentFile);
end % ~isempty(isbin)
end % if filt
end
end
fclose(fid);
% --------------------------------------------------------------------
function process_final(output,installNotes)
fid = fopen(output,'a');
fprintf(fid,'\n');
% show install notes:
if ~isempty(installNotes)
fprintf(fid,'%s\n', 'fprintf(1,''\n'');');
end
for i=1:length(installNotes)
fprintf(fid,'%s\n', ['fprintf(1,'' %s\n'',''',installNotes{i},''');']);
end
fprintf(fid,'\n');
% show installation finnished:
fprintf(fid,'%s\n', 'if withErrors');
fprintf(fid,'%s\n', ' fprintf(1,''\n installation finnished WITH ERRORS\n\n'')');
fprintf(fid,'%s\n', 'else');
fprintf(fid,'%s\n', ' fprintf(1,''\n installation finished\n'')');
fprintf(fid,'%s\n',' fprintf(1,'' ---------------------------------------------------\n\n'');');
fprintf(fid,'%s\n', 'end');
fclose(fid);
% --------------------------------------------------------------------
function process_funcs(output)
fid = fopen(output,'a');
fprintf(fid,'\n');
fprintf(fid,'%s\n', 'function bin=hex_to_bin(s)');
fprintf(fid,'%s\n', 'c = zeros(1, 256);');
fprintf(fid,'%s\n', 'c(abs(''0''):abs(''9'')) = 0:9;');
fprintf(fid,'%s\n', 'c(abs(''a''):abs(''f'')) = 10:15;');
fprintf(fid,'%s\n', 'hex = double(s);');
fprintf(fid,'%s\n', 'bin = 16*c(hex(1:2:end)) + c(hex(2:2:end));');
fprintf(fid,'\n');
fprintf(fid,'%s\n', 'function [withErrors,fid] = ini_file(file,type)');
fprintf(fid,'%s\n', 'fid=fopen(file,''w'');');
fprintf(fid,'%s\n','if fid == -1');
fprintf(fid,'%s\n',' errstr = '' -- ERROR'';');
fprintf(fid,'%s\n',' withErrors = 1;');
fprintf(fid,'%s\n','else');
fprintf(fid,'%s\n',' errstr='''';');
fprintf(fid,'%s\n',' withErrors = 0;');
fprintf(fid,'%s\n','end');
fprintf(fid,'%s\n','if isempty(type)');
fprintf(fid,'%s\n',[' fprintf(1,'' adding file %s%s\n'',file,errstr)']);
fprintf(fid,'%s\n','else');
fprintf(fid,'%s\n',[' fprintf(1,'' adding file %s (%s)%s\n'',file,type,errstr)']);
fprintf(fid,'%s\n','end');
fprintf(fid,'\n');
fprintf(fid,'%s\n', 'function finnish_file(fid,hex)');
fprintf(fid,'%s\n','if fid~=-1');
fprintf(fid,'%s\n',' hex=reshape(hex'',1,prod(size(hex)));');
fprintf(fid,'%s\n',' hex=strrep(hex,'' '','''');');
fprintf(fid,'%s\n',' bin=hex_to_bin(hex);');
fprintf(fid,'%s\n',' fwrite(fid,bin);');
fprintf(fid,'%s\n',' fclose(fid);');
fprintf(fid,'%s\n','end');
fclose(fid);
% --------------------------------------------------------------------
function [dirs,n]=get_dirs(current,dirs)
if nargin < 2, dirs = {current}; end
n=length(dirs);
str = ['d=dir([''',current,''']);'];
eval(str);
for i=1:length(d)
cdir=d(i);
if cdir.isdir==1 & ~isequal(cdir.name,'..') & ~isequal(cdir.name,'.')
n=n+1;
dirs{n}=[current,''',filesep,''',cdir.name];
[dirs,n]=get_dirs(dirs{n},dirs);
end
end
% --------------------------------------------------------------------
function nfiles=get_nfiles(dirname)
nfiles = 0;
for i=1:length(dirname)
str=['d=dir([''',dirname{i},''']);'];
eval(str);
isd = zeros(size(d));
nisnull = zeros(size(d));
for n=1:length(d)
isd(n) = d(n).isdir; % is dir
nisnull(n) = d(n).bytes; % not is null
end
% the nisnull condition is needed when dirs are chmod -x
files = {d(~isd&nisnull).name};
nfiles = length(files) + nfiles;
end
% --------------------------------------------------------------------
function [isbin,type]=isbinary(file)
isbin=0;
type='';
fid=fopen(file);
if fid~=-1
c=fread(fid,1000);
if any(c==0), isbin = 1; end
fclose(fid);
if isbin
type='binary';
else
type='text';
end
else
isbin=[];
type='';
end
% --------------------------------------------------------------------
function output = basename(theFile)
d = realpath(theFile);
[path,name,ext]=fileparts(d);
output = [name,ext];
function output = dirname(theFile)
d = realpath(theFile);
[path,name,ext]=fileparts(d);
output = path;
function output = realpath(thePath)
output = [];
isfile = 0;
if exist(thePath,'file') == 2 & isempty(which(thePath))
[path,name,ext]=fileparts(thePath);
thePath = path;
isfile = 1;
end
current = cd;
if exist(thePath,'dir') == 7 & ~isempty(dir(thePath))
cd(thePath);
output = cd;
cd(current);
if isempty(output)
if isunix, new = filesep; end
if ispc, new='C:\'; end
end
end
if isfile
output = [output,filesep,name,ext];
end
%%
function flag = applyfilter(filename,filefilt)
% APPLYFILTER returns true if the filename meets the condition given in
% the filter filt
% filename is the name of the file to be checked.
% filt is the cell array of string to be used as filter
% The form of filter should be like
% '~.m' - exclude all m files
% '*.m' - include all m files
% '*.*' - include all files (default)
% {'*.m' ,'*.p'} - include only m files and p files
% {'~.m' ,'~.p'} - exclude m files and p files
% {'~.m' ,'demo.m'} - exclude all m files except demo.m
% {'*.m' ,'~demo.m'} - include all m files except demo.m
%
% Please note that {'~.m', '*.p'} is equivalent to '*.p'. So such combination
% does not make any sense.
%
%%
% Check if filt is cell array
if ~iscell(filefilt)
filt{1}=filefilt;
else
filt=filefilt;
end
flag = false;
filename = lower(filename);
filt =lower(filt);
% If you want to include particular files
tf = ismember(filename, filt);
% if strcmpi(filt{1},'*.*')||tf % Corrected in version 1.2.0
% flag = true;
% return
% end
if tf
flag = true;
return
end
% To exclude some files given in filt
tf = ismember(['~' filename], filt);
if tf
flag = false;
return
end
[~, ~, ext] = fileparts(filename) ;
% Make sure that file like read.txt is not included given the filter
% *.* and ~.txt
% Bug fixed in this version 1.2.0. In the previous version if filter *.* is
% there, then it dominates all other filters. This behaviour is corrected.
tf = ismember('*.*', filt);
if tf
tmp = ['~' ext];
tf1 = ismember(tmp, filt);
if ~tf1
flag = true;
return
end
end
% Change filter like * ~ ~ to *
newfilt = [];
j=1;
for i=1:length(filt)
temp = filt{i}(1);
if strcmp(temp,'*')
newfilt{j} = filt{i};
j=j+1;
end
end
if isempty(newfilt)
newfilt=filt;
end
for i=1:length(newfilt)
filtType = newfilt{i}(1); % Whether filter is to include or exclude
filtExt = newfilt{i}(2:end); % Extension of filter
% Include files
if strcmp(filtType,'*')
flag = false;
if strcmpi(ext,filtExt)
flag=true;
return
end
% Exclude files
elseif strcmp(filtType,'~')
flag = true;
if strcmpi(ext,filtExt) || strcmpi('.*',filtExt)
flag=false;
return
end
end
end
|
|