Code covered by the BSD License  

Highlights from
Color Model from PolySpace Verification

image thumbnail

Color Model from PolySpace Verification

by

 

The tool colors Simulink Model using PolySpace code verification.

Color_Model_From_Verification(callbackInfo)
%% FUNCTION: Color_Model_From_Verification
%
%*************************************************************************
%  PURPOSE: Color Simulink model from Code Verification
%     After code generation with RTW and code verification with PolySpace,
% this tool allows to color each block of your model to show if it contains
% run-time errors.
%  4 colors:
%       - red: systematic run-time error
%       - grey: unreachable code
%       - green: safe code
%       - orange: potential error
%
%*************************************************************************
%  Version: v1.14
%
%  Author: David Jaffry
%
%*************************************************************************
% v1.14: add detection of color using function and fix some M-Lint messages
% Modifications in
%  - Read_RTE_View_File function
%  - Check_Colors_and_Links function
%
% v1.13: add some comments and fix some M-Lint messages
%
% v1.12: add R2010b compatibility:
%  PolySpace Product:
%   The location of command to generate HTML files changed
%   The name of RTE file changed (for Polyspace results)
%  Real-Time Workshop
%    Model Version syntax in HTML files changed
%
% v1.11: add some comments
%
% v1.10:  one minor change in Affect_Background_Colorfunction
% - change order of uniqueness for file links
%
% v1.09: some minors changes in Read_Source_File function
% - change regular expression to check Stateflow transition
% - change test if line is empty
%
% v1.08 some minors changes (to verify S-function block)
% in Read_Source_File function
% - add regular expression to test S-function link
% adding new function (Get_S_Function_Color) not yet used
%  - to Get the name of the Verified SubSystem
%
% v1.07 some minors changes
% - Delete old unused code
% - add some comments
%

%% FUNCTION: Color_Model_From_Verification
% PARAMETER:
%   - callbackInfo : information given by sl_customization function
% PURPOSE:
%  That is main function (entry point) called by sl_customization callback
function Color_Model_From_Verification(callbackInfo) %#ok<INUSD>
clc;
fid_color = -1;
% Get name of PolySpace result directory
result_dir = polyspace_get_resultdir;

if isempty(result_dir)
    disp('Error: PolySpace result directory does not exist.');
else
    model_name = bdroot;
    % Get name of RTE_View.txt file PolySpace file
    RTE_filename  = [result_dir '/PolySpace-Doc/' model_name '_RTE_View.txt'];
    
    SystemName = Get_Verified_SubSystem_Name(result_dir);
    if strcmp(SystemName,'')
        return;
    end
    
    if strcmp(model_name, SystemName)
        % Get name of header file in RTW result
        info = RTW.getBuildDir(model_name);
        modelheader_filename = [info.BuildDirectory '/' model_name '.h'];
        
        % Modify HTML file
        HTML_directory = [info.BuildDirectory '/html'];
        HTML_Content_filename = [HTML_directory '/' model_name '_contents.html'];
        HTML_Version_filename = [HTML_directory '/' model_name '_survey.html'];
        
    else % for sub system
        info = RTW.getBuildDir(model_name); % To get BuildDirSuffix of target
        % get name of header file in the Verification result
        %modelheader_filename=[result_dir '/ALL/SRC/' SystemName '__h.c'];
        modelheader_filename = [SystemName info.BuildDirSuffix '/' SystemName '.h'];
        % modify HTML file
        HTML_directory = [SystemName info.BuildDirSuffix '/html'];
        HTML_Content_filename = [HTML_directory '/' SystemName '_contents.html'];
        HTML_Version_filename = [HTML_directory '/' SystemName '_survey.html'];
    end
    
    
    %% Test Version
    disp('* Getting Versions...');
    ModelVersion=get_param(model_name,'ModelVersion'); % Version of Simulink Model
    fprintf(1, 'Model Version is: %s\n',ModelVersion);
    
    ResultVersion_filename = fullfile(result_dir,'code_generator_used');
    ResultVersion=Get_Result_Version(ResultVersion_filename); % Version of PolySpace result
    
    HTMLVersion = Get_HTML_Version(HTML_Version_filename);% Version of Generated Code
    
    % Version test
    if ~strcmp(ModelVersion, ResultVersion)
        fprintf(1, 'Error: The Version of the model (%s) and Verification Result(%s) are different.\n',ModelVersion,ResultVersion);
    end
    
    % Version test
    if ~strcmp(ModelVersion, HTMLVersion)
        fprintf(1, 'Error: The Version of the model (%s) and HTML(%s) are different.\n',ModelVersion,HTMLVersion);
    end
    
    
    % Version test
    if ~strcmp(ResultVersion, HTMLVersion)
        fprintf(1, 'Error: The Version of the HTML (%s) and Verification Result(%s) are different.\n',HTMLVersion,ResultVersion);
    else
        Generate_HTML_Files(result_dir, HTML_directory);
        Modify_Contents_HTMLFile(HTML_Content_filename);
    end
    
    
    % Create name which contains the current block color of the model
    % (will be created in PolySpace result directory)
    colorfilename = [result_dir '/oldcolor_blocks.txt'];
    
    
    % Test if this file exists
    if (Create_ColorBlocks_File(colorfilename) == true)
        g_Nb_Links = 0;
        g_FileLinks = {};
        SFunctions = {};
        SystemsList =  Read_HeaderFile_To_Get_SubsystemName(modelheader_filename);
        
        Read_RTE_View_File(RTE_filename,result_dir);
        Affect_Background_Color();
        Close_ColorBlocks_File();
    end
end


%% FUNCTION: Read_RTE_View_File
% PARAMETER:
%   - RTEfilename : it's the RTE_View.txt file containing checks (PolySpace file)
%   - result_dir  : it's the PolySapce results directory
% PURPOSE:
%  Read RTEfilename file to get color of checks
    function Read_RTE_View_File(RTEfilename,result_dir)
        
        fprintf(1,'* Reading %s file...\n',RTEfilename);
        
        fid_RTE = fopen(RTEfilename, 'rt');
        if (fid_RTE == -1)
            fprintf(1,'Error: this file does not exist.\n');
        else
            cnt_line_RTE = 0;   % contains the number of line of the file
            FileColors={};      % contains the worts color for each line of the source file
            old_filename='';    % contains the last source file
            while feof(fid_RTE) == 0
                cnt_line_RTE= cnt_line_RTE + 1;
                tline = fgetl(fid_RTE);
                % Find project name
                %-projectname		11		49			82		0
                [matches projeScts] = regexp(tline, '^-(?<projectname>\w+)\t', 'tokens', 'names');  %#ok<NASGU>
                if (~isempty(matches))
                    %fprintf(1,'%d: project: %s\n',cnt_line,projects(:,1).projectname);
                end
                
                %|  -file		11		16	1		59   file.c	0
                %|  -rtwdemo_fuelsys_v3_data					1			rtwdemo_fuelsys_v3_data.c	0
                %|  -__polyspace__stdstubs		20		111	1		85	__polyspace__stdstubs.c	0
                [matches files] = regexp(tline, '^[|]\s*-(?<filename>\w+)\t\d*\t\d*\t\d*\t\d*\t\d*\t\d*\t\d*\t(?<filename_with_ext>[a-zA-Z0-9_\.]+)', 'tokens', 'names'); % Find file name
                if (~isempty(matches))
                    % First, check color and link for any new file (not the
                    % first file)
                    if (~strcmp(old_filename,''))
                        if ((strcmp(old_filename,'__polyspace_main')) || (strcmp(old_filename,'__polyspace__stdstubs')))
                            % do not care for PolySpace files
                            fprintf(1,'Do not check %s source file.\n',old_filename);
                        else
                            Check_Colors_and_Links(FileColors, FileLinks);
                        end
                    end
                    % second, read the source file to refresh link and color
                    if ((strcmp(files(:).filename,'__polyspace_main')) || (strcmp(files(:).filename,'__polyspace__stdstubs')))
                        % do not care for PolySpace files
                    else
                        source_filename = [result_dir '/ALL/SRC/' files(:).filename_with_ext];
                        [Nb_line,FileLinks] = Read_Source_File(source_filename);
                        FileColors=zeros(Nb_line,1);
                    end
                    
                    % third, refresh the name of file
                    old_filename = files(:).filename;
                    
                    %fprintf(1,'%d: file: %s ext: %s\n',cnt_line,files(:).filename, files(:).filename_with_ext);
                end
                if ((strcmp(old_filename,'__polyspace_main')) || (strcmp(old_filename,'__polyspace__stdstubs')))
                    % do not care for PolySpace files
                else
                    %|  |  -function		11		16	36	5	59   file.c	0
                    [matches functions] = regexp(tline, '^\|\s*\|\s*-(?<fctname>\w+)\t\d*\t\d*\t\d*\t\d*\t(?<fctline>\d+)', 'tokens', 'names'); % Find function name
                    if (~isempty(matches))
                        %fprintf(1,'%d: function: %s\n',cnt_line,functions(:).fctname);
                        line = str2double(functions(:).fctline);
                        % Add  color To identify changed block (separate the block)
                        FileColors(line) = -1;  %#ok<AGROW>
                    end
                    
                    %|  |  |  V NIV.0				1	48	9		variable is initialized (type: float 64)	11				file.c
                    %|  |  |  ? OVFL.1		1			48	12		Warning : float variable may overflow on [/], range : {1.7977E+308 >= [expr]}	33			float	file.c
                    [matches checks] = regexp(tline, '^\|\s*\|\s*\|\s*(?<checktype>[?VX!])\s(?<checkname>\w+)\.\d+\t\d*\t\d*\t\d*\t\d*\t(?<checkline>\d+)\t(?<checkcol>\d+)', 'tokens', 'names'); % Find check
                    if (~isempty(matches))
                        %fprintf(1,'%d: check %s, line: %s, col: %s\n',cnt_line, checks(:).checkname,checks(:).checkline,checks(:).checkcol);
                        if (strcmp(checks(:).checktype,'V'))
                            colorpriority = 1;
                        elseif (strcmp(checks(:).checktype,'?'))
                            colorpriority = 2;
                        elseif (strcmp(checks(:).checktype,'X'))
                            colorpriority = 3;
                        elseif (strcmp(checks(:).checktype,'!'))
                            colorpriority = 4;
                        else
                            colorpriority = 5; % problem
                        end
                        line = str2double(checks(:).checkline);
                        if (FileColors(line) < colorpriority)
                            % Assign new priority
                            FileColors(line) = colorpriority;  %#ok<AGROW>
                        end
                        
                    end
                end
            end
            fclose(fid_RTE);
        end
        
        
    end



%% FUNCTION: Read_Source_File
% PARAMETER:
%   - sourcefilename : .c file to read (generated or manually source code file)
% PURPOSE:
%  Read Source file to get the hyperlinks for each block file
%
% EXAMPLE OF HYPERLINKS:
%     /* Switch: '<S3>/Switch' incorporates:
%      *  Constant: '<S3>/Constant1'
%      *  Constant: '<S3>/Constant2'
%      *  Inport: '<Root>/In4'
%      *  RelationalOperator: '<S3>/Relational Operator'
%      */
% or:
%      * block: 'link'
% Possible usage:
%    javascript:rtwHilite('model/Product1')
    function [cnt_line_source,FileLinks] = Read_Source_File(sourcefilename)
        cnt_line_source = 0;
        FileLinks = {};
        SFunctions = {};
        
        fprintf(1,'* Reading %s source file...\n',sourcefilename);
        fid_source = fopen(sourcefilename, 'rt');
        if (fid_source == -1)
            fprintf(1,'Error: this file does not exist.\n');
        else
            while feof(fid_source) == 0
                cnt_line_source= cnt_line_source + 1; % Number of line of the file
                % Initialize link for the current line
                FileLinks(cnt_line_source).blockname = '';  %#ok<AGROW>
                FileLinks(cnt_line_source).blockpath = '';  %#ok<AGROW>
                FileLinks(cnt_line_source).color = 0; %#ok<AGROW>
                tline = fgetl(fid_source);
                
                % This case is not checked for the moment
                %/* S-Function (my_function_test): '<S3>/my_function_test' */
                [tokens names] = regexp(tline, '\*\sS-Function\s\((?<functionname>[a-zA-Z0-9_\s]+)\):\s*''(?<blockpath>[<>a-zA-Z0-9\-/=()\.\*,_\s]+)''', 'tokens', 'names');
                if (~isempty(tokens)) % if hyperlink is found
                    NumberSFunctions = length(SFunctions) + 1;
                    SFunctions(NumberSFunctions).functionname = names.functionname;
                    SFunctions(NumberSFunctions).blockpath = names.blockpath;
                    SFunctions(cnt_line_source).color = 0;
                    continue;
                end
                % Do not check line of chart or embML block:
                % ==> ':' caracter is not added to blokcpath
                %/* Transition: '<S4>:25' */
                %[tokens names] = regexp(tline, '\*\s*(?<blockname>[a-zA-Z0-9_\s]+):\s*''(?<blockpath><S[0-9]+>:[0-9]+)''', 'tokens', 'names');
                % Do not treat: /* '<S4>:1:4' */
                %if (~isempty(tokens)) % if hyperlink is found
                %continue;
                %end
                
                %/* Embedded MATLAB: '<S2>/Embedded MATLAB Function' incorporates:
                %/* Lookup: '<S7>/Look-Up Table'
                %/* Integrator: '<S12>/p0 = 0.589 bar' */
                %/* Lookup2D: '<S25>/Thrott Estimation Table (2-D)' */
                %/* Update for Sin: '<Root>/2*pi' */
                [tokens names] = regexp(tline, '\*\s*(?<blockname>[a-zA-Z0-9_\s]+):\s*''(?<blockpath>[<>a-zA-Z0-9\-/=()\.\*,_\s]+)''', 'tokens', 'names');
                % Do not treat: /* '<S4>:1:4' */
                if (~isempty(tokens)) % if hyperlink is found
                    % save the link for current line
                    FileLinks(cnt_line_source).blockname = names.blockname; %#ok<AGROW>
                    FileLinks(cnt_line_source).blockpath = names.blockpath; %#ok<AGROW>
                    FileLinks(cnt_line_source).color = 0; %#ok<AGROW>
                    %fprintf(1,'%d: Name: %s; Path: %s\n',cnt_line_source, names.blockname,names.blockpath);
                end
                % treat: /* '<S4>:1:4' */
                %/* Transition: '<S1>:25' */
                % keep only the system (ex:'<S1>) (not the line (ex: ':25')
                [tokens names] = regexp(tline, '\*\s*.*''(?<blockpath><S[0-9]+>):[0-9]+[0-9:]*''', 'tokens', 'names');
                
                if (~isempty(tokens)) % if hyperlink is found
                    % save the link for current line
                    FileLinks(cnt_line_source).blockname = 'Transition'; %#ok<AGROW>
                    FileLinks(cnt_line_source).blockpath = names.blockpath; %#ok<AGROW>
                    FileLinks(cnt_line_source).color = 0; %#ok<AGROW>
                    %fprintf(1,'%d: Name: %s; Path: %s\n',cnt_line_source, names.blockname,names.blockpath);
                end
                % if line is empty
                %[tokens names] = regexp(tline, '^$', 'tokens', 'names');
                %if (~isempty(tokens)) && (PreviousLineIsLink)
                if (isempty(tline))
                    if (cnt_line_source > 1)
                        % if previous line was hyperlink
                        if (~strcmp(FileLinks(cnt_line_source - 1).blockpath,''))
                            %ReCopy the link (to conserver the block)
                            FileLinks(cnt_line_source).blockname = FileLinks(cnt_line_source - 1).blockname; %#ok<AGROW>
                            FileLinks(cnt_line_source).blockpath = FileLinks(cnt_line_source - 1).blockpath; %#ok<AGROW>
                            FileLinks(cnt_line_source).color = 0; %#ok<AGROW>
                        end
                    end
                end
                
                %* Model version                        : 1.109
                [tokens model] = regexp(tline, '\* Model version\s*:\s*(?<version>\d+\.\d+)\s*$', 'tokens', 'names');
                if (~isempty(tokens)) % if model version  is found
                    % Version test
                    if ~strcmp(ResultVersion, model.version)
                        fprintf(1, 'Error: The Version of code_generator_used file (%s) and Verification Result(%s) are different.\n',model.version,ResultVersion);
                        ResultVersion = model.version;
                    end
                end
            end
            fclose(fid_source);
        end
    end

%% FUNCTION: Check_Colors_and_Links
% PARAMETER:
%   - FileColors : contains for each line of the current source file,
%   the worst color (0: nothing), (it's a vector of size number of line
%   of the file)
%   - FileLinks : contains for each line of the current source file,
%   the information about hyperlinks. It's a structure with 3 fields
%   blockname, blockpath and color
% PURPOSE:
%  Get worst color for each block of hyperlinks
    function Check_Colors_and_Links(FileColors, FileLinks)
        if (length(FileColors) ~= length(FileLinks))
            fprintf(1,'Numbers of lines are different (Color:%d Link:%d',length(FileColors), length(FileLinks));
        end
        bStartToLookForHyperlinkBlocks=true;
        
        % Save old color for each block
        IndexSystems   = ~cellfun('isempty',{FileLinks.blockpath});
        NameSystems   = {FileLinks(IndexSystems).blockpath};
        NameSystems = unique(NameSystems);
        % if no blocks
        if (isempty(NameSystems))
            fprintf(1,'There is no block.\n');
            return;
        end
        
        FileLinks = Convert_SubsystemName(FileLinks, SystemsList);
        
        fprintf(1,'  - Getting Blocks Color...\n');
        for index_line=1:length(FileLinks)
            if (bStartToLookForHyperlinkBlocks == true)
                if (strcmp(FileLinks(index_line).blockname,''))
                    % Do nothing
                else
                    bStartToLookForHyperlinkBlocks = false;
                    Block_Start_Line=index_line;
                end
            else
                if (strcmp(FileLinks(index_line).blockname,''))
                    % if it's end of block (we started a new block)
                    bStartToLookForHyperlinkBlocks = true;
                    Block_End_Line = index_line - 1;
                    % Look for the next block of new function
                    for index_next_block=index_line:length(FileLinks)
                        % Detect next block
                        if (~strcmp(FileLinks(index_next_block).blockname,''))
                            break
                        end
                        % Detect new function
                        if (FileColors(index_next_block)== -1)
                            break
                        end
                    end
                    % keep index_next_block: (line of next blcok)
                    % Look For worst color between block and next block
                    colorpriority=0; % low priority
                    for k=index_line:index_next_block
                        if (colorpriority < FileColors(k))
                            colorpriority = FileColors(k); % Assign new priority
                        end
                    end
                    
                    % Affect background color
                    for index=Block_Start_Line:Block_End_Line
                        FileLinks(index).color = colorpriority;
                        
                        % Save the link
                        g_Nb_Links = g_Nb_Links + 1;
                        g_FileLinks(g_Nb_Links).blockname = FileLinks(index).blockname;
                        g_FileLinks(g_Nb_Links).blockpath = FileLinks(index).blockpath;
                        g_FileLinks(g_Nb_Links).color     = FileLinks(index).color;
                    end
                end
            end
        end
        fprintf(1,'Done.\n');
    end

%% FUNCTION: Affect_Background_Color
% PARAMETER:
% PURPOSE:
%  Change background color of blocks in the Simulink model
    function Affect_Background_Color()
        
        fprintf(1,'* Saving and Changing Blocks Color...\n');
        % Add subsystems list
        for index=1:length(SystemsList)
            g_Nb_Links = g_Nb_Links + 1;
            g_FileLinks(g_Nb_Links).blockname = SystemsList(index).name;
            g_FileLinks(g_Nb_Links).blockpath = SystemsList(index).path;
            g_FileLinks(g_Nb_Links).color     = 0;
        end
        
        
        %if isempty(unique_blockpath)
        if isempty(g_FileLinks)
            fprintf(1,'0 systems modified (Systems List is empty).\n');
        else
            Nb_ModifiedSubSystems = 0;
            Nb_NoModifiedSubSystems = 0;
            Nb_NoUsedSubSystems = 0;
            Nb_LibrarySubSystems = 0;
            unique_blockpath = unique({g_FileLinks.blockpath}); % sort
            % Get index for each block found (strictly name)
            %ii  = cellfun(@(sys) strncmp({g_FileLinks.blockpath},sys,length(sys)),unique_blockpath,'UniformOutput',false);
            ii  = cellfun(@(sys) strcmp({g_FileLinks.blockpath},sys),unique_blockpath,'UniformOutput',false);
            ColorSystems  = cellfun(@(j) max([g_FileLinks(j).color]),ii,'UniformOutput',false);
            
            unique_blockpath_v2=unique_blockpath; % Pre-allocation
            for i=1:length(unique_blockpath)
                unique_blockpath_v2{i} = [unique_blockpath{i} '/'];
            end
            % Get index for each system found (name)
            ii_2  = cellfun(@(sys) strncmp({g_FileLinks.blockpath},sys,length(sys)),unique_blockpath_v2,'UniformOutput',false);
            ColorSystems_2  = cellfun(@(j) max([g_FileLinks(j).color]),ii_2,'UniformOutput',false);
            ColorSystems=cellfun(@(j,k) max([j, k] ),ColorSystems_2,ColorSystems,'UniformOutput',false);
            % Change color type (double to char)
            for index_sys=1:length(ColorSystems)
                colorpriority=ColorSystems{index_sys};
                if ~isempty(colorpriority)
                    % Define color type
                    if (colorpriority == 0) % there is no check (ex: call a function)
                        color = 'green';
                    elseif (colorpriority == 1)
                        color = 'green';
                    elseif (colorpriority == 2)
                        color = 'orange';
                    elseif (colorpriority == 3)
                        color = 'gray';
                    elseif (colorpriority == 4)
                        color = 'red';
                    else
                        color = 'blue'; % problem
                    end
                    
                    try % if the system is invalid (name of block can contain '/')
                        % test if the name of block is not the model name
                        if (~strcmp(unique_blockpath{index_sys},get_param(bdroot,'Name')))
                            old_clr = get_param(unique_blockpath{index_sys},'BackgroundColor');
                            
                            if (Change_BackgroundColor(unique_blockpath{index_sys},color))
                                Nb_ModifiedSubSystems = Nb_ModifiedSubSystems + 1;
                                Save_ColorBlocks(unique_blockpath{index_sys},old_clr);
                            else
                                Nb_LibrarySubSystems = Nb_LibrarySubSystems + 1;
                                disp([' ' unique_blockpath{index_sys} ' is library block.']);
                                Save_ColorBlocks([ '#' unique_blockpath{index_sys} ' # Library'],old_clr);
                            end
                        end
                    catch %#ok<CTCH>
                        disp([unique_blockpath{index_sys} ' block does not exist.']);
                        Nb_NoModifiedSubSystems = Nb_NoModifiedSubSystems + 1;
                    end
                else
                    Nb_NoUsedSubSystems = Nb_NoUsedSubSystems + 1;
                end
            end
            
            fprintf(1,'%d blocks modified; (%d no modified, %d no used, %d libraries).\n', Nb_ModifiedSubSystems, Nb_NoModifiedSubSystems, Nb_NoUsedSubSystems, Nb_LibrarySubSystems);
        end
    end



%% FUNCTION: Create_ColorBlocks_File
% PARAMETER:
%   - colorfilename : filename which contains the block background color
% PURPOSE:
%  Create a save file which contains current background color block before apply PolySpace color
%  -If the file does not exist, the function creates a new file and returns true
%  -If the file exists, the fucntion applies previous backgroung block
%  color to replace PolySpace color
    function [bPolySpaceColor] = Create_ColorBlocks_File(colorfilename)
        bPolySpaceColor = false;
        % Test if file exist
        if (exist(colorfilename,'file') == 2)
            Nb_ModifiedBlocks = 0;
            Nb_NoModifiedBlocks = 0;
            Nb_LibraryBlocks = 0;
            % Apply old blocks color then delete
            disp('* Applying old colors...');
            fid_color = fopen(colorfilename, 'rt');
            if (fid_color == -1)
                fprintf(1,'Error: this file cannot be open.\n');
            else
                while feof(fid_color) == 0
                    tline = fgetl(fid_color);
                    if (tline ~= -1)
                        [matches comment] = regexp(tline, '^\s*#(?<comment>.*)', 'tokens', 'names'); %#ok<NASGU>
                        if (~isempty(matches))
                            continue;
                        end
                        [matches blockcolors] = regexp(tline, '^(?<blockpath>.*) = (?<color>\w+)', 'tokens', 'names');
                        if (~isempty(matches))
                            %disp(['set_param(' blockcolors.blockpath ', BackgroundColor ,' blockcolors.color ')']);
                            try
                                if (Change_BackgroundColor(blockcolors.blockpath,blockcolors.color))
                                    Nb_ModifiedBlocks = Nb_ModifiedBlocks + 1;
                                else
                                    Nb_LibraryBlocks = Nb_LibraryBlocks + 1;
                                end
                            catch %#ok<CTCH>
                                disp([blockcolors.blockpath ' block does not exist.']);
                                Nb_NoModifiedBlocks = Nb_NoModifiedBlocks + 1;
                            end
                        end
                    end
                end
                fprintf(1,'%d block colors modified; (%d no modified, %d Libraries).\n', Nb_ModifiedBlocks, Nb_NoModifiedBlocks, Nb_LibraryBlocks);
                fclose(fid_color);
                fileattrib(colorfilename,'+w')
                delete(colorfilename);
            end
        else % File does not exist
            fid_color = fopen(colorfilename, 'w+t');
            if (fid_color ~= -1)
                % file has been created, find blocks color
                bPolySpaceColor = true;
            end
            
        end
    end

%% FUNCTION: Save_ColorBlocks
% PARAMETER:
% PURPOSE:
%  Write information (block path and background block color) in the
%  save file
    function Save_ColorBlocks(blockpath,color)
        fprintf(fid_color, '%s = %s\n', blockpath, color);
    end
%% FUNCTION: Close_ColorBlocks_File
% PARAMETER:
% PURPOSE:
%  Close the save file which contains  block path and background block color
    function Close_ColorBlocks_File()
        fclose(fid_color);
    end

%% FUNCTION: Read_HeaderFile_To_Get_SubsystemName
% PARAMETER:
%   - filename : name of "model.h" file which  model is the name of
%   Simulink model
% PURPOSE:
%  Read model.h file to get and return the list of Subsystems (get Subsystem Name)
    function SystemsList = Read_HeaderFile_To_Get_SubsystemName(filename)
        SystemsList = {};
        index = 0;
        disp('* Getting Subsystems Name...');
        % Test if file exist
        if (exist(filename,'file') == 2)
            fid_header = fopen(filename, 'rt');
            while feof(fid_header) == 0
                tline = fgetl(fid_header);
                if (tline ~= -1)
                    % * '<S1>'   : rtwdemo_fuelsys_v2/EGO sensor
                    [matches systems] = regexp(tline, '^\s**\s*''(?<name>.*)''\s*:\s*(?<path>.*)$', 'tokens', 'names');
                    if (~isempty(matches))
                        index = index + 1;
                        SystemsList(index).name = systems.name; %#ok<AGROW>
                        SystemsList(index).path = systems.path; %#ok<AGROW>
                    end
                end
            end
            fprintf(1,'%d definitions of systems found.\n', index);
            fclose(fid_header);
        else
            fprintf(1,'Error: %s Header file does not exist.\n', filename);
        end
    end

%% FUNCTION: Convert_SubsystemName
% PARAMETER:
%   - FileLinks : List of hyperlinks, it's a structure with 3 fields
%   (blockname, blockpath and color)
%   - SystemsList : list of Subsystems name, it's a structure with 2 fields
%   (name and path)
%   (example: name <S1> ; path: rtwdemo_iec61508/Requirements)
% PURPOSE:
%  Function to convert Subsystem Name, by the real path
    function FileLinks = Convert_SubsystemName(FileLinks, SystemsList)
        NbModifiedName = 0;
        fprintf(1,'  - Converting the Subsystem names.\n');
        for index_link=1:length(FileLinks)
            tline = FileLinks(index_link).blockpath;
            [matches system] = regexp(tline, '^(?<sysname><Root>)(?<endpath>.*)$', 'tokens', 'names');
            if (~isempty(matches))
                bSystemFound = 0;
                for index_sys=1:length(SystemsList)
                    % if find system name, replace the name
                    if strcmp(system.sysname,SystemsList(index_sys).name) ~= 0
                        FileLinks(index_link).blockpath=[SystemsList(index_sys).path system.endpath];
                        NbModifiedName = NbModifiedName +1;
                        bSystemFound = 1;
                    end
                end
                if (bSystemFound == 0)
                    fprintf(1,' %s Subsystem did not converted.\n',FileLinks(index_link).blockpath);
                end
            end
            [matches system] = regexp(tline, '^(?<sysname><S\d+>)(?<endpath>.*)$', 'tokens', 'names');
            if (~isempty(matches))
                bSystemFound = 0;
                for index_sys=1:length(SystemsList)
                    % if find system name, replace the name
                    if strcmp(system.sysname,SystemsList(index_sys).name) ~= 0
                        FileLinks(index_link).blockpath=[SystemsList(index_sys).path system.endpath];
                        NbModifiedName = NbModifiedName +1;
                        bSystemFound = 1;
                    end
                end
                if (bSystemFound == 0)
                    fprintf(1,' %s Subsystem did not converted.\n',FileLinks(index_link).blockpath);
                end
            end
        end
        % To get number of systems
        IndexSystems   = ~cellfun('isempty',{FileLinks.blockpath});
        NameSystems   = {FileLinks(IndexSystems).blockpath};
        fprintf(1,'%d Subsystem names converted on %d links.\n',NbModifiedName, length(NameSystems));
    end


%% FUNCTION: Change_BackgroundColor
% PARAMETER:
%   - system : contains the name of block path
%   - color : contains the backgroung color name
%   (example: name <S1> ; path: rtwdemo_iec61508/Requirements)
% PURPOSE:
%  Function to change the Background Color of the block if possible
%  Test if the block is a library ==> do not modify return false
    function return_value = Change_BackgroundColor(system,color)
        return_value=false;
        % none, resolved, unresolved, implicit, inactive, restore and propagate
        Status = get_param(system,'LinkStatus');
        % if it's no more a library block
        %if (strcmp(Status,'none') || strcmp(Status,'inactive'))
        if (strcmp(Status,'none') || strcmp(Status,'inactive') || strcmp(Status,'resolved'))
            set_param(system,'BackgroundColor',color);
            return_value=true;
        end
    end


%% FUNCTION: Modify_Contents_HTMLFile
% PARAMETER:
%   - filename : contains the file name  (<model>_contents.html)
% PURPOSE:
%  Function to Modify HTML files of RTW
%  Benefit is to be able to open the PolySpace result in the HTML RTW report
    function Modify_Contents_HTMLFile(filename)
        File = {};
        index_line = 0;
        index_Insertion = -1;
        index_PolySpace = -1;
        disp('* Modifying RTW Content HTML file...');
        % Test if file exist
        if (exist(filename,'file') == 2) % Is HTML File exist?
            % Modify the file
            fid_HTML = fopen(filename, 'rt');
            while feof(fid_HTML) == 0
                index_line = index_line + 1;
                tline = fgetl(fid_HTML);
                if (tline ~= -1)
                    % <B>Generated Source Files</B>
                    %matches = findstr(tline, '<B>Generated Source Files</B>');
                    %<!--ADD_CODE_PROFILE_REPORT_LINK_HERE-->
                    matches = strfind(tline, '<!--ADD_CODE_PROFILE_REPORT_LINK_HERE-->');
                    if (~isempty(matches))
                        index_Insertion = index_line;
                    end
                    matches = strfind(tline, '<!--POLYSPACE VERIFICATION-->');
                    if (~isempty(matches))
                        index_PolySpace = index_line;
                    end
                    
                end
                File{index_line} = tline; %#ok<AGROW>
            end
            fclose(fid_HTML);
            % Modify the file
            if (index_PolySpace == -1) % if not already add
                fid_HTML = fopen(filename, 'wt');
                for index_line=1:length(File)
                    fprintf(fid_HTML,  '%s\n', File{index_line});
                    if (index_Insertion == index_line)
                        fprintf(fid_HTML, '<!--POLYSPACE VERIFICATION-->\n'); % To know if it's already added
                        comment = '<TABLE BORDER="0" CELLSPACING="0" CELLPADDING="4" WIDTH="100%" BGCOLOR="#ffffff"><TR><TD>';
                        fprintf(fid_HTML, '%s\n',comment);
                        fprintf(fid_HTML, '<B>Verified Source Files</B>\n');
                        fprintf(fid_HTML, '</TD></TR><TR></TR>\n');
                        fprintf(fid_HTML, '<TR><TD><A HREF="HTML_Report/index.htm" ONCLICK="if (top) if (top.tocHiliteMe) top.tocHiliteMe(window, this, false);" ID="index.htm" TARGET="rtwreport_document_frame" NAME="rtwIdGenFileLinks">index</A><SPAN> </SPAN></TD></TR><TR></TR>\n');
                        fprintf(fid_HTML, '</TABLE>\n');
                    end
                end
                fclose(fid_HTML);
            else
                disp('HTML file has been already modified.');
            end
        else % Is HTML File exist?
            disp('HTML files are not generated.');
        end
    end

%% FUNCTION: Generate_HTML_Files
% PARAMETER:
%   - result_dir : contains the Polyspace result directory
%   - HTML_directory : contains the RTW HTML directory
% PURPOSE:
%  Function to generate HTML files from PolySpace result
    function return_value = Generate_HTML_Files(result_dir, HTML_directory)
        return_value = false;
        disp('* Generating HTML files...');
        POLYSPACE_COMMON = getenv('POLYSPACE_COMMON');
        if isempty(POLYSPACE_COMMON)
            disp('Error: You need PolySpace to generate HTML files.');
        else
            CMD_HTML = fullfile(POLYSPACE_COMMON,'Viewer','wbin','gen-HTML-files.exe');
            HTML_directory_Report = [HTML_directory '/HTML_Report'];
            
            
            % Test Command to get PolySpace HTML files
            if ~(exist(CMD_HTML,'file') == 2) % Is CMD_HTML File exist?
                fprintf(1, '%s file does not exist.\n',CMD_HTML);
                POLYSPACE_C = getenv('POLYSPACE_C');
                if isempty(POLYSPACE_C)
                    disp('Error: You need PolySpace to generate HTML files.');
                else
                    % gen-HTML-files.exe file is :
                    %     -  Verifier\wbin
                    % or  -  PVE\wbin
                    CMD_HTML = fullfile(POLYSPACE_C,'Verifier','wbin','gen-HTML-files.exe');
                    if ~(exist(CMD_HTML,'file') == 2) % Is CMD_HTML File exist?
                        fprintf(1, '%s file does not exist.\n',CMD_HTML);
                    end
                end
            end
            
            % Test Project file
            % Old name (vesion < 10a) RTE_px_O2_ADL_Sim_LAST_RESULTS.rte
            % New name( > 10b) RTE_px_ADL_Sim_LAST_RESULTS.rte
            %Project_file   = [result_dir '/RTE_px_O2_' model_name '_LAST_RESULTS.rte'];
            RTE_files = dir(fullfile(result_dir, '*LAST_RESULTS.rte'));
            RTE_namefile = fullfile(result_dir, RTE_files.name);
            
            % Test HTML directory
            if ~(exist(HTML_directory,'dir') == 7) % Is HTML File exist?
                fprintf(1, '%s directory does not exist.\n',HTML_directory);
            else
                if (exist(HTML_directory_Report,'dir') == 7) % Is HTML File exist?
                    fprintf(1, '%s directory already exists.\n',HTML_directory_Report);
                else
                    % create the command line
                    command = [CMD_HTML ' -results-dir ' HTML_directory_Report ' -proj-file ' RTE_namefile];
                    [status, result] = system(command); %#ok<NASGU>
                    if (status == 0)
                        disp('Done.');
                        return_value = true;
                    else
                        fprintf(1, 'Error during HTML generation. (Status: %d)\n',status);
                    end
                end
            end
        end
    end

%% FUNCTION: Get_Verified_SubSystem_Name
% PARAMETER:
%   - result_dir : contains the Polyspace result directory
% PURPOSE:
%  Function to get the name of the Verified SubSystem
    function SystemName = Get_Verified_SubSystem_Name(result_dir)
        filename = fullfile(result_dir, 'block_names');
        disp('* Getting Verified SubSystem Name...');
        SystemName = '';
        % Test if file exist
        if (exist(filename,'file') == 2) % Is  File exist?
            % Modify the file
            fid_SS_Name = fopen(filename, 'rt');
            while feof(fid_SS_Name) == 0
                tline = fgetl(fid_SS_Name);
                if (tline ~= -1)
                    %# Code was generated for subsystem SystemName
                    [matches system] = regexp(tline, '^# Code was generated for subsystem (?<sysname>.*)$', 'tokens', 'names');
                    if (~isempty(matches))
                        SystemName=system.sysname;
                    end
                end
            end
            fclose(fid_SS_Name);
            if strcmp(SystemName,'')
                fprintf(1, 'System Name was not found. \n');
            else
                fprintf(1, 'System Name is: %s\n',SystemName);
            end
        else
            fprintf(1, 'Error: %s file does not exist.\n',filename);
        end
    end

%% FUNCTION: Get_Result_Version
% PARAMETER:
%   - filename : path name of 'code_generator_used' file located in Polyspace
%   result
% PURPOSE:
%  Function to get the version of PolySpace result in the 'code_generator_used' file
    function ResultVersion = Get_Result_Version(filename)
        ResultVersion = '';
        % Test if file exist
        if (exist(filename,'file') == 2) % Is  File exist?
            % Modify the file
            fid_ResVers = fopen(filename, 'rt');
            while feof(fid_ResVers) == 0
                tline = fgetl(fid_ResVers);
                if (tline ~= -1)
                    %ModelVersion=modelname:1.107
                    [matches system] = regexp(tline, '^ModelVersion=(?<sysname>.*):(?<version>\d+\.\d+)$', 'tokens', 'names');
                    if (~isempty(matches))
                        ResultVersion=system.version;
                    end
                end
            end
            fclose(fid_ResVers);
            if strcmp(ResultVersion,'')
                fprintf(1, 'PolySpace Result Version was not found. \n');
            else
                fprintf(1, 'PolySpace Result Version is: %s\n',ResultVersion);
            end
        else
            fprintf(1, 'Error: %s file does not exist.\n',filename);
        end
    end


%% FUNCTION: Get_HTML_Version
% PARAMETER:
%   - filename : path name of '<model>_survey.html' file located in RTW
%   HTML result
% PURPOSE:
%  Function to get the version of RTW result in the '<model>_survey.html' file
    function HTMLVersion = Get_HTML_Version(filename)
        HTMLVersion = '';
        % Test if file exist
        if (exist(filename,'file') == 2) % Is  File exist?
            % Modify the file
            fid_HTMLVers = fopen(filename, 'rt');
            while feof(fid_HTMLVers) == 0
                tline = fgetl(fid_HTMLVers);
                if (tline ~= -1)
                    %<TR><TD>Model Version              </TD><TD>:1.107</TD></TR>
                    %<TR><TD>Model version              </TD><TD>: 1.172</TD></TR>
                    [matches system] = regexp(tline, '<TR><TD>Model [Vv]ersion\s*</TD><TD>:\s*(?<version>\d+\.\d+)</TD></TR>', 'tokens', 'names');
                    if (~isempty(matches))
                        HTMLVersion=system.version;
                    end
                end
            end
            fclose(fid_HTMLVers);
            if strcmp(HTMLVersion,'')
                fprintf(1, 'RTW HTML Version was not found. \n');
            else
                fprintf(1, 'RTW HTML Version is: %s\n',HTMLVersion);
            end
        else
            fprintf(1, 'Error: %s file does not exist.\n',filename);
        end
    end

%% FUNCTION: Get_S_Function_Color
% PARAMETER:
% PURPOSE:
    function  Get_S_Function_Color()
        %SFunctions(NumberSFunctions).functionname = names.functionname;
        %SFunctions(NumberSFunctions).blockpath = names.blockpath;
        %SFunctions(cnt_line_source).color = 0;
        for index=1:length(SFunctions)
            
            maskDescription = get_param(SFunctions(index).blockpath,'MaskDescription');
            [matches projects] = regexp(maskDescription, 'def\.SourceFiles = {(?<files>[^\n]*)};\n', 'tokens', 'names');
            if (~isempty(matches))
                files = regexp(projects.files, ',', 'split');
            end
        end
    end
end

Contact us