Reference information on the macro language
Macro functions
C-SPY macro functions consist of C-SPY variable definitions and macro statements which are executed when the macro is called. An unlimited number of parameters can be passed to a macro function, and macro functions can return a value on exit.
A C-SPY macro has this form:
macroName(parameterList) {macroBody}
where parameterList is a list of macro parameters separated by commas, and macroBody is any series of C-SPY variable definitions and C-SPY statements.
Type checking is neither performed on the values passed to the macro functions nor on the return value.
Macro variables
A macro variable is a variable defined and allocated outside your application. It can then be used in a C-SPY expression, or you can assign application data—values of the variables in your application—to it. For more information about C-SPY expressions, see C-SPY expressions.
The syntax for defining one or more macro variables is:
__var nameList;where nameList is a list of C-SPY variable names separated by commas.
A macro variable defined outside a macro body has global scope, and it exists throughout the whole debugging session. A macro variable defined within a macro body is created when its definition is executed and destroyed on return from the macro.
By default, macro variables are treated as signed integers and initialized to 0. When a C-SPY variable is assigned a value in an expression, it also acquires the type of that expression. For example:
Expression | What it means |
|---|---|
|
|
|
|
In case of a name conflict between a C symbol and a C-SPY macro variable, C-SPY macro variables have a higher precedence than C variables. Note that macro variables are allocated on the debugger host and do not affect your application.
Macro parameters
A macro parameter is intended for parameterization of device support. The named parameter will behave as a normal C-SPY macro variable with these differences:
The parameter definition can have an initializer
Values of a parameters can be set through options (either in the IDE or in
cspybat).A value set from an option will take precedence over a value set by an initializer
A parameter must have an initializer, be set through an option, or both. Otherwise, it has an undefined value, and accessing it will cause a runtime error.
The syntax for defining one or more macro parameters is:
__paramparam[=value, ...;]
Use the command line option ‑‑macro_param to specify a value to a parameter, see ‑‑macro_param.
Macro strings
In addition to C types, macro variables can hold values of macro strings. Note that macro strings differ from C language strings.
When you write a string literal, such as "Hello!", in a C-SPY expression, the value is a macro string. It is not a C-style character pointer char*, because char* must point to a sequence of characters in target memory and C-SPY cannot expect any string literal to actually exist in target memory.
You can manipulate a macro string using a few built-in macro functions, for example __strFind or __subString. The result can be a new macro string. You can concatenate macro strings using the + operator, for example str + "tail". You can also access individual characters using subscription, for example str[3]. You can get the length of a string using sizeof(str). Note that a macro string is not NULL-terminated.
The macro function __toString is used for converting from a NULL-terminated C string in your application (char* or char[]) to a macro string. For example, assume this definition of a C string in your application:
char const *cstr = "Hello";
Then examine these macro examples:
__var str; /* A macro variable */ str = cstr /* str is now just a pointer to char */ sizeof str /* same as sizeof (char*), typically 2 or 4 */ str = __toString(cstr,512) /* str is now a macro string */ sizeof str /* 5, the length of the string */ str[1] /* 101, the ASCII code for 'e' */ str += " World!" /* str is now "Hello World!" */
See also Formatted output.
Macro statements
Statements are expected to behave in the same way as the corresponding C statements would do. The following C-SPY macro statements are accepted:
Expressions
expression;For more information about C-SPY expressions, see C-SPY expressions.
Conditional statements
if (expression)statementif (expression)statementelsestatement
Loop statements
for (init_expression;cond_expression;update_expression)statementwhile (expression)statementdostatementwhile (expression);
Return statements
return;
return expression;If the return value is not explicitly set, signed int 0 is returned by default.
Blocks
Statements can be grouped in blocks.
{
statement1
statement2
.
.
.
statementN
}Formatted output
C-SPY provides various methods for producing formatted output:
Prints the output to the Debug Log window. | |
Prints the output to the designated file. | |
Returns a string containing the formatted output. |
where argList is a comma-separated list of C-SPY expressions or strings, and file is the result of the __openFile system macro, see __openFile.
To produce messages in the Debug Log window:
var1 = 42;var2 = 37;__message "This line prints the values ", var1, " and ", var2, " in the Debug Log window.";
This produces this message in the Debug Log window:
This line prints the values 42 and 37 in the Debug Log window.
To write the output to a designated file:
__fmessage myfile, "Result is ", res, "!\n";To produce strings:
myMacroVar = __smessage 42, " is the answer.";
myMacroVar now contains the string "42 is the answer.".
Specifying display format of arguments
To override the default display format of a scalar argument (number or pointer) in argList, suffix it with a : followed by a format specifier. Available specifiers are:
| for binary scalar arguments |
| for octal scalar arguments |
| for decimal scalar arguments |
| for hexadecimal scalar arguments |
| for character scalar arguments |
These match the formats available in the Watch and Locals windows, but number prefixes and quotes around strings and characters are not printed.
Example:
__message "The character '", cvar:%c, "' has the decimal value ", cvar;Depending on the value of the variables, this produces this message:
The character 'A' has the decimal value 65
Note
A character enclosed in single quotes (a character literal) is an integer constant and is not automatically formatted as a character. For example:
__message 'A', " is the numeric value of the character ", 'A':%c;would produce:
65 is the numeric value of the character A
Optionally, a number can be inserted between the % and the letter, to format an integer to that minimum width. Binary, octal, and hexadecimal numbers will be left-padded with zeros, decimal numbers and characters will be padded with spaces. Note that numbers that do not fit within the requested minimum width will not be truncated.
Examples:
__message 31:%4x; // 001f __message 31:%4d; // 31 __message 31:%8b; // 00011111
Note
The default format for certain types is primarily designed to be useful in the Watch window and other related windows. For example, a value of type char is formatted as 'A' (0x41), while a pointer to a character (potentially a C string) is formatted as 0x8102 "Hello", where the string part shows the beginning of the string (currently up to 60 characters).
When printing a value of type char*, use the %x format specifier to print just the pointer value in hexadecimal notation, or use the system macro __toString to get the full string value.