Custom Test Result Display Functions for Complex C/C++ Data Types
The Polyspace®
Test™ xUnit API provides predefined assessment macros to display values for all fundamental data types. For example, to check for equality of two integers and display results when the equality fails, you can use the macro PST_VERIFY_EQ_INT. For the full list of predefined macros, see Assessment Macros in Polyspace Test API for C/C++ Code.
For more complex data types, you have to write your own comparison and display functions to compare and display values. This topic describes how to write a custom display function. For more information on writing custom assessments using these display functions, see Compare and Display Values for Complex C/C++ Data Types Using Polyspace Test xUnit API.
Prerequisites
This topic describes test authoring using the Polyspace Test xUnit API. To compile these tests, you are required to know some file paths in advance. For your convenience, you can define environment variables to stand for the file paths, or otherwise include the file paths in your build. For more information, see Set Up C/C++ Testing and Code Profiling Using Self-Managed Builds.
Display Function Format
A function that displays the value of an object funcDisp of type objToDisplay must have this signature:Type
void funcDisp (char *buffer, const pst_size_t bufferSize, const void* objToDisplay);
Note the following:
The third argument of the function is the object being displayed. Since the type of this argument is
const void*, to access fields of the object, you have to cast this pointer back to the correct object pointer typeconstusing the Polyspace Test xUnit API macroType*PST_STATIC_CAST. You can then continue to access the object fields through the resultingconstpointer.Type*For convenience, the display function can itself invoke a predefined variable-argument function
pst_formatwith the following signature, pass its first two arguments unchanged, and pass a custom display string for the third argument.void pst_format (char *buffer, size_t bufferSize, const char* format, ...);
If the display string passed as
contains format specifiers, the variables to substitute into the format specifiers become the fourth and later arguments.formatIn some cases, you might want to impose a maximum buffer size on the output being displayed. If you have such a size cutoff in mind, you can invoke
pst_formatwith the size cutoff as the second argument.
Example Display Function
Consider a structured type Point that contains two int fields x and y:
typedef struct Point {
int x;
int y;
}Point;Suppose you want to write a display function displayPoint that displays the value of a Point object in a specific format. For example, if the object value is {0 , 0}, you want to see the value displayed in the following way:
x:0, y:0
You can write the display function displayPoint as follows:
void displayPoint(char* buff, const pst_size_t buff_size, const void* val) {
const Point* val_Point = PST_STATIC_CAST(const Point*, val);
pst_format(buff, buff_size, "x:%d, y:%d", val_Point->x, val_Point->y);
}displayPoint:
Casts its third argument from
const void*toconst Point*.Invokes the function
pst_formatand passes on its first and second arguments unchanged, but defines the format string as the third argument. The format string uses the format specifier%dto indicate two integer values. The fourth and fifth arguments are the integer values to be substituted into the format specifier. These integer values correspond to the fields of the object that theconst Point*pointer points to.
For an example showing the usage of this custom display function, see Compare and Display Values for Complex C/C++ Data Types Using Polyspace Test xUnit API.