Main Content

slcoverage.CodeSelector class

Package: slcoverage

Select custom C or C++ code for coverage filter

Description

Use objects of the slcoverage.CodeSelector class to specify custom C or C++ code selection criteria for a filter rule.

The slcoverage.CodeSelector class is a handle class.

Creation

sel = slcoverage.CodeSelector(type,fileName) creates CodeSelector object of the specified type based on the specified fileName and sets the Type and FileName properties.

sel = slcoverage.CodeSelector(type,fileName,functionName) creates a CodeSelector object based on the specified C or C++ functionName in the file and sets the FunctionName property.

sel = slcoverage.CodeSelector(type,fileName,functionName,expr,exprIndex) creates a CodeSelector object for the specified expression and expression index and sets the Expr and ExprIndex properties.

sel = slcoverage.CodeSelector(type,fileName,functionName,expr,exprIndex,outcomeIndex) creates a CodeSelector object based on the specified coverage outcome and sets the OutcomeIndex property.

sel = slcoverage.CodeSelector(type,fileName,functionName,expr,exprIndex,outcomeIndex,parentExprIndex) creates a CodeSelector object based on the specified coverage outcome that belongs to an expression owned by parentExprIndex and sets the DecOrCondIndex property to parentExprIndex.

Properties

expand all

Type of custom C or C++ code to select, specified as an enumeration of the slcoverage.CodeSelectorType class:

  • slcoverage.CodeSelectorType.File — A custom C or C++ code file name.

  • slcoverage.CodeSelectorType.Function — A custom C or C++ code function name.

  • slcoverage.CodeSelectorType.Decision — A custom C or C++ code decision.

  • slcoverage.CodeSelectorType.Condition — A custom C or C++ code condition.

  • slcoverage.CodeSelectorType.DecisionOutcome — A custom C or C++ code decision outcome.

  • slcoverage.CodeSelectorType.ConditionOutcome — A custom C or C++ code condition outcome.

  • slcoverage.CodeSelectorType.MCDCOutcome — A custom C or C++ code MCDC outcome.

  • slcoverage.CodeSelectorType.RelationalBoundaryOutcome — A custom C or C++ code relational boundary outcome.

Example: slcoverage.CodeSelectorType.Function

Attributes

SetAccess
protected

Data Types: slcoverage.CodeSelectorType

C or C++ file to select, specified as a character array or string array.

Example: 'myfile.c'

Attributes

SetAccess
protected

Data Types: char | string

C or C++ function to select, specified as a character array or string array.

Example: 'counterbusFcn'

Attributes

SetAccess
protected

Data Types: char | string

Decision or condition expression to select, specified as a character array or string array.

Example: 'x | y'

Attributes

SetAccess
protected

Data Types: char | string

Expression index, specified as an integer. If you are filtering an outcome, this property is the index of the expression that owns that outcome. If you are filtering an expression, this property is the index of that expression inside the body of the function.

Example: 2

Attributes

SetAccess
protected

Data Types: single | double | int

Index of outcome to select, specified as an integer:

  • For a Boolean expression, enter 1 for the F outcome or 2 for the T outcome.

  • For a switch/case statement, enter 1 for the first case, 2 for the second case, and so on.

  • For relational boundary

    • Integer type:

      • enter 1 for type -1.

      • enter 2 for type +1.

      • enter 3 for type 0.

    • Float type:

      • enter 1 for [-tol 0] or [-tol 0).

      • enter 2 for (0 tol] or [0 tol] is outcome 2

    For more information about relational boundary coverage, see Relational Boundary Coverage.

Example: 2

Attributes

SetAccess
protected

Data Types: single | double | int

Parent expression index, specified as an integer. Use this input when you are filtering an expression owned by a parent decision or condition. This property is the index of the parent decision or condition relative to the function.

Example: 2

Attributes

SetAccess
protected

Data Types: single | double | int

Code used to create this selector object, returned as a character vector.

Attributes

SetAccess
protected

Description of the selector, returned as a character vector. Simulink® Coverage™ creates the description based on the selector.

Attributes

SetAccess
protected

This property is empty for the slcoverage.CodeSelector class.

Attributes

SetAccess
protected

Data Types: char | string | handle | integer

Methods

expand all

Examples

collapse all

This example shows how to select custom C or C++ code for which you want to add a filter rule.

Load the model.

modelName = 'slcovCCallerExample';
Simulink.importExternalCTypes('my_func.h','EnumClass','dynamic');
load_system(modelName)

Configure coverage settings using a Simulink.SimulationInput object.

covSet = Simulink.SimulationInput(modelName);
covSet = covSet.setModelParameter('CovEnable','on');
covSet = covSet.setModelParameter('CovMetricStructuralLevel','MCDC');
covSet = covSet.setModelParameter('CovSFcnEnable','on');
covSet = covSet.setModelParameter('CovSaveSingleToWorkspaceVar','on');
covSet = covSet.setModelParameter('CovSaveName','covData');
covSet = covSet.setModelParameter('SimAnalyzeCustomCode','on');

Simulate the model using covSet object as the input.

simOut = sim(covSet);
covData = simOut.covData;

Create a selector object to filter the custom C function timesK.

sel = slcoverage.CodeSelector(slcoverage.CodeSelectorType.Function, 'my_func.c', 'timesK');

Create a filter object and create a rule based on the selector, then add the rule to the filter.

filt = slcoverage.Filter;
rule = slcoverage.FilterRule(sel,'Tested elsewhere',...
           slcoverage.FilterMode.Exclude);
addRule(filt,rule);
setFilterName(filt,'Code Filter')

Save the filter as codefilter and add it to the cvdata object for my_func.c. Because the coverage data is stored in a cv.cvdatagroup object, use the get method to set the property.

save(filt,'codefilter');
covData.get('my_func.c').filter = 'codefilter';

Generate a coverage report.

cvhtml('codeCovReport',covData)

Review the report. Under Custom Code File(s), click my_func.c and find the filter rule that you added under Objects Filtered from Coverage Analysis.

This example shows how to use an slcoverage.CodeSelector object to filter a code outcome in a custom C or C++ program called by a C Caller block.

Open the Model and Enable Coverage Analysis

Open the model.

modelName = 'slcovCCallerExample';
Simulink.importExternalCTypes('my_func.h','EnumClass','dynamic');
load_system(modelName)

Configure coverage settings using a Simulink.SimulationInput object.

covSet = Simulink.SimulationInput(modelName);
covSet = covSet.setModelParameter('CovEnable','on');
covSet = covSet.setModelParameter('CovMetricStructuralLevel','ConditionDecision');
covSet = covSet.setModelParameter('CovSFcnEnable','on');
covSet = covSet.setModelParameter('CovSaveSingleToWorkspaceVar','on');
covSet = covSet.setModelParameter('CovSaveName','covData');

Simulate the model using covSet as the input.

simOut = sim(covSet);
covData = simOut.covData;

The simulation returns the coverage data as a cv.cvdatagroup object when both the model and custom code are analyzed for coverage. To extract the code coverage data, use the get method of the cvdatagroup class.

codeCovData = get(covData,'my_func.c');

Justify the Missing Outcome

In this example, you justify the F outcome of the inputGElower condition in the (u1->limits.upper_saturation_limit >= limit) && inputGElower decision, which is located inside the counterbusFcn function in the my_func.c source file.

Create a selector object using slcoverage.CodeSelector. The first input is a CodeSelectorType enumeration. To justify a condition outcome, use a ConditionOutcome enumeration. The second input is the code source file, my_func.c. The third input is the name of the function that contains the outcome, counterbusFcn. The fourth input is the expression which contains the outcome, (u1->limits.upper_saturation_limit >= limit) && inputGElower. The fifth input is the index of the expression that owns the outcome. In this case, inputGElower is the second condition within its parent condition, so this input is 2. The sixth input is the condition outcome index, which is 1 for the F outcome of a Boolean expression. The seventh input is the index of the parent decision or condition, which is 1 for (u1->limits.upper_saturation_limit >= limit) && inputGElower because it is the first decision in the function.

enum = slcoverage.CodeSelectorType.ConditionOutcome;
sel = slcoverage.CodeSelector(enum,'my_func.c','counterbusFcn','(u1->limits.upper_saturation_limit >= limit) && inputGElower',2,1,1);

Create a Filter object and a FilterRule object and apply the rule to the filter.

filt = slcoverage.Filter;
rule = slcoverage.FilterRule(sel,'condition does not apply');
addRule(filt,rule);

Save the filter to a filter file and then apply the filter to the cvdata object.

save(filt,'codeOutcomeFilter');
codeCovData.filter = 'codeOutcomeFilter';

Review the Coverage Report

Verify the outcome is filtered by generating a coverage report using cvhtml.

cvhtml('filteredCodeCovReport',codeCovData)

Introduced in R2018b