function T = GenDataAssert(varargin)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Author: Claude TADONKI  (claude.tadonki@mines-paristech.fr)
% Institution: MINES ParisTech - PSL
% Year: 2015
% Comment: 
%  The aim of this routine is to collect all the inputs of a given 
%  user-defined MATLAB function (name, type, min_size, max_size) and 
%  generate the corresponding assert instructions that will  be considered
%  by MATLAB Coder for code generation. 
%  Copy it into your working directory
% Usage: 
%  Consider a matlab function Outputs = MyFunction(Inputs_List)
%  1. Add the following line just below the header of the function
%     T = GenDataAssert('','',Inputs_List);
%  2. Delete (if exists) the file InputForMatlabCoder.txt 
%  2. Run you code as usual (it will be slower because of file operations)
%  3. The result is in the file InputForMatlabCoder.txt (text form in T)
%  4. Just copy the content of the previous file below the #codegen pragma
%  5. Run your code generation
%
% Copyright: You should keep this bloc comment reference the author when using the tool.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
n = nargin;
T = char(varargin{1});
if(strcmp(T,'')&&(~exist('InputForMatlabCoder.mat'))) 
    L={'Name','Type','MinSize','MaxSize'}; save('InputForMatlabCoder.mat','L'); 
else
   load('InputForMatlabCoder.mat','L'); 
end;
esp = char(varargin{2});
for(i=3:n)
   Id = size(findstr(T, char(10)),2)+1; 
   v = varargin{i};
   T = sprintf('%s\n%d: %s%s %s %s %s',T,Id,esp,inputname(i),char(class(v)),mat2str(size(v)),mat2str(size(v)));
   if(size(L,1)<=Id)
     L = [L;{strtrim(sprintf('%s%s',esp,inputname(i))),char(class(v)),mat2str(size(v)),mat2str(size(v))}];
   else
      minS = min(size(v),str2num(char(L(Id+1,3))));
      maxS = max(size(v),str2num(char(L(Id+1,4))));
      L(Id+1,:) = {strtrim(sprintf('%s%s',esp,inputname(i))),char(class(v)),mat2str(minS),mat2str(maxS)};
   end
   if(strcmp(char(class(v)),'struct'))
       save('InputForMatlabCoder.mat','L');
       f = fieldnames(v);
       vn = inputname(i);
       m = length(f); 
       for(j=1:m)
          T =  GenDataAssert(T,sprintf('\t%s%s.%s',char(varargin{2}),vn,char(f{j})),getfield(v,f{j}));
       end
       load('InputForMatlabCoder.mat','L');
   end
end
% Generating the assert
[n,m] = size(L);
TxT = '% Just put this at the beginning of the routine to be processed bt Matlab Coder';
for(i=2:n)
   if((prod(str2num(char(L{i,3})))==1)&&(prod(str2num(char(L{i,4})))==1)) c='%'; else c=''; end
   TxT = sprintf('%s\nassert(isa(%s,%s%s%s)); %s assert(all(size(%s) >= %s)); assert(all(size(%s) <= %s));',TxT,...
           char(L{i,1}),char(39),char(L{i,2}),char(39),c,char(L{i,1}),char(L{i,3}),char(L{i,1}),char(L{i,4})); 
end
fileID = fopen('InputForMatlabCoder.txt','w');
fprintf(fileID,'%s\n',TxT);
fclose(fileID);
%
save('InputForMatlabCoder.mat','L');