JavaScript is not currently enabled, but is required for full CodeSonar manual search and browse functionality.

If you are viewing this file in your hub's Web GUI, enable JavaScript in your browser: you will also need it for GUI functionality.

If you opened this file directly from disk, your browser may be directly suppressing JavaScript functionality: certain browsers perform this suppression on local files (but not files delivered by web servers) for security reasons.

CodeSonar® 9.2p0 CONFIDENTIAL CodeSecure Inc
C and C++

Manipulating the Input to the Build and Analysis

This page outlines the various mechanisms allowing users to manipulate the input to the CodeSonar build and analysis.



Overview

CodeSonar offers a number of different techniques for manipulating the input to the CodeSonar build and analysis. The full set of techniques is listed below, with each list item linked to the corresponding entry in the Technique Details section. The remainder of the page provides a comparison table summarizing key technique features, and describes the two most typical source modifications: providing a definition for an undefined function and using csonar_replace_f().

The Techniques

Technique Details

Shortcut links are provided above.

Define a preprocessor macro

Summary Provide the CodeSonar build with definitions for one or more preprocessing symbols.
Method Add a new CFLAGS_APPEND rule to the appropriate configuration file:
CFLAGS_APPEND += -Dmacroname[=def]
Applications Good for:
  • Fixing parse errors.
  • Defining constants.
  • Specifying implicit compiler definitions.
  • Modeling simple functions (but beware of introducing parse errors when prototypes are expanded).

Can enhance analysis results.

Not suitable for creating new warning classes.

Notes Escaping the command line properly can be hard for complicated defines. In these cases, define and incorporate a preinclude file.
Example In this example, a C flag is used to define symbol __interrupt as a preprocessor macro whose value is the empty string. CodeSonar will therefore ignore the occurrence of __interrupt in myfile.c, rather than issuing a parse error.
/* myfile.c */
void __interrupt handle_interrupt(void){}
# myproj.conf
CFLAGS_APPEND += -D__interrupt=

Hard-define a preprocessor macro

Summary Provide the CodeSonar build with hard definitions for one or more preprocessing symbols.
Method Add a new EDG_FRONTEND_OPTIONS_APPEND rule to the appropriate configuration file:
EDG_FRONTEND_OPTIONS_APPEND += --hard_define_macro name [( param-list)] [ = def ]
Applications Good for:
  • Fixing parse errors.
  • Defining constants.
  • Specifying implicit compiler definitions.
  • Modeling simple functions (but beware of introducing parse errors when prototypes are expanded).

Can enhance analysis results.

Not suitable for creating new warning classes.

Notes Similar to defining a preprocessor macro, but can't be overridden.
Example In this example, a front-end option setting is used to hard-define symbol __interrupt as a preprocessor macro whose value is the empty string. CodeSonar will therefore ignore the occurrence of __interrupt in myfile.c, rather than issuing a parse error.
/* myfile.c */
void __interrupt handle_interrupt(void){}
# myproj.conf
EDG_FRONTEND_OPTIONS_APPEND += --hard_define_macro __interrupt=

Define and incorporate a preinclude file

Summary Provide the CodeSonar build with a preinclude file containing C code with your desired modifications.
Method
  1. Create a preinclude file headerfname containing the code you want to incorporate.
  2. Add a new EDG_FRONTEND_OPTIONS_APPEND rule to the appropriate configuration file:
    EDG_FRONTEND_OPTIONS_APPEND += --preinclude headerfname
    
Applications Good for:
  • Typedefs, inline functions, #defines.
  • Fixing parse errors.

Can enhance analysis results.

It is possible to create new warning classes in inline functions, but there are better alternatives: see the comparison table below.

Notes The preinclude file can contain arbitrary C code. Some typical modifications are described below.
Example In this example, file my_cs_preinclude.h defines symbol __interrupt as a preprocessor macro whose value is the empty string; then my_cs_preinclude.h is preincluded in every source file. CodeSonar will therefore ignore the occurrence of __interrupt in myfile.c, rather than issuing a parse error.
/* myfile.c */
void __interrupt handle_interrupt(void){}
/* my_cs_preinclude.h*/
#define __interrupt
# myproj.conf

# It is important to quote this path because it contains whitespace.
EDG_FRONTEND_OPTIONS_APPEND += --preinclude "c:\my projects\myproj\my_cs_preinclude.h"

Regular-expression-based replacement on source code

Summary Specify a regular-expression-based text replacement to be carried out on source code before it is passed to the CodeSonar build.
Method Add a new SOURCE_PATTERN_REPLACEMENT rule to the appropriate configuration file:
SOURCE_PATTERN_REPLACEMENT +=  s/pattern/replacement/flags
Applications Good for:
  • Globally replacing strings that can be described with a regular expression.
  • Eliminating certain problematic compiler extensions, such as assembly blocks.
  • Fixing parse errors.

Can enhance analysis results.

Not suitable for creating new warning classes, or for modeling non-trivial functions.

Notes Some typical modifications are described below.

For more information, see C/C++ Source Modifications: Patching and Replacement.

Example In this example, regular-expression-based replacement is used to replace all occurrences of string __interrupt with the empty string in all source files. CodeSonar will therefore ignore the occurrence of __interrupt in myfile.c, rather than issuing a parse error.
/* myfile.c */
void __interrupt handle_interrupt(void){}
# myproj.conf
SOURCE_PATTERN_REPLACEMENT += s/__interrupt//g

Command-based replacement on source code

Summary Specify a command-based text replacement to be carried out on source code before it is passed to the CodeSonar build.
Method Add a new SOURCE_REPLACE_COMMAND rule to the appropriate configuration file:
SOURCE_REPLACE_COMMAND += command
Applications Good for:
  • Globally replacing strings that can be described with a regular expression.
  • Eliminating certain problematic compiler extensions, such as assembly blocks.
  • Fixing parse errors.

Can enhance analysis results.

Not suitable for creating new warning classes, or for modeling non-trivial functions.

Notes Users can specify arbitrarily complicated replacement commands: this technique is therefore more flexible than regular-expression-based replacement, but provides more avenues for accidentally introducing errors.

Some typical modifications are described below.

For more information, see C/C++ Source Modifications: Patching and Replacement.

Example In this example, command-based replacement is used to replace all occurrences of string __interrupt with the empty string in all source files. CodeSonar will therefore ignore the occurrence of __interrupt in myfile.c, rather than issuing a parse error.
/* myfile.c */
void __interrupt handle_interrupt(void){}
# myproj.conf
SOURCE_REPLACE_COMMAND += sed -e 's/__interrupt//g'

Apply patches to source code

Summary Specify a one or more patches to be applied to source code before it is passed to the CodeSonar build.
Method
  1. For each source file f.x that you wish to patch, create one or more patch files in directory patch_dir_path/f.x/
  2. Add a new SOURCE_PATCH_DIRECTORIES rule to the appropriate configuration file:
    SOURCE_PATCH_DIRECTORIES += patch_dir_path
    
Applications Good for:
  • Altering specific pieces of code in arbitrary ways .
  • Adding modeling logic to C++ templates.
  • Fixing parse errors.
  • Enhancing analysis results.
  • Creating new warning classes.

Not suitable for altering all occurrences of some construct (like a special asm syntax): use regular-expression-based replacement or command-based replacement for this purpose.

Notes Some typical modifications are described below.

For more information, see C/C++ Source Modifications: Patching and Replacement.

Example In this example, patch file c:\patchfiles\myfile.c\remove___interrupt.patch modifies the prototype for function handle_interrupt() so that it no longer contains symbol __interrupt. The project configuration file is updated with a rule specifying that patches from c:\patchfiles should be applied to files in the project: all patches in c:\patchfiles\myfile.c\ will be applied to myfile.c. CodeSonar will therefore ignore the occurrence of __interrupt in myfile.c, rather than issuing a parse error.
/* myfile.c */
void __interrupt handle_interrupt(void){}
/* c:\patchfiles\myfile.c\remove___interrupt.patch */
--- foo.c
+++ foo.c
@@ -1 +1 @@
-void __interrupt handle_interrupt(void){}
+void handle_interrupt(void){}
# myproj.conf
SOURCE_PATCH_DIRECTORIES += c:\patchfiles        

Reroute function calls with FUNCTION_MAP

Summary Instruct CodeSonar to treat all calls to function A as if they are calls to function B.
Method Add a new FUNCTION_MAP rule to the appropriate configuration file:
FUNCTION_MAP += A -> B        
Applications Useful for enhancing analysis results.
Example In this example, function fatal() is mapped to abort(). CodeSonar understands the semantics of abort(), so will not issue a Division by Zero warning on the second line of myfunc().
/* myfile.c */
int myfunc(int i){
    if( i != 0 ) fatal("oops, i is 0");
    return 100/i;
 }        
# myproj.conf
FUNCTION_MAP += fatal -> abort

Add CodeSonar-only code to the underlying project

Summary Edit the original source files to add code that will only be seen by the CodeSonar build and analysis.
Method Add new code to one or more project source files, enclosing it in #ifdef __CODESONAR__ ... #endif directives.
/* regular project code */                     
  
#ifdef __CODESONAR__
/* code that will only be seen by CodeSonar */
#endif

/* regular project code */     
        
Applications Good for:
  • Altering specific pieces of code in arbitrary ways.
  • Adding modeling logic to C++ templates.
  • Fixing parse errors.
  • Enhancing analysis results.
  • Creating new warning classes.
  • Applying csonar_replace_*-based function replacement.

Not suitable for altering all occurrences of some construct (like a special asm syntax): use regular-expression-based replacement or command-based replacement for this purpose.

Not suitable for users who can't or do not want to modify the underlying project code. In this case, use file patching or CodeSonar-only files to introduce your modifications.

Notes Some typical modifications are described below.

For further information about this technique, including detailed examples, see Implementing and Including Custom Checks with the Extension API: [Method I] Add lines to original code. Note that, while this section refers to the Extension API, the technique can be used to introduce arbitrary C or C++ code.

Example 1 (Define csonar_replace_fatal() in the underlying project, and make the definition visible only to CodeSonar.)

In this example, myfile.c has been edited directly to include a definition of csonar_replace_fatal(). This definition is guarded by #ifdef __CODESONAR__ so will only be seen by the CodeSonar analysis, and not by the regular software build. csonar_replace_fatal() calls abort(), so CodeSonar will treat calls to fatal() as if they are (transitive) calls to abort(). In particular, it will not issue a Division by Zero warning on the second line of myfunc().

/* myfile.c */
#ifdef __CODESONAR__
/* Only seen by CodeSonar. */
/* Using csonar_replace_* avoids duplicate function problems. */
void csonar_replace_fatal(void){ abort(); }
#endif

int myfunc(int i){
    if( i != 0 ) fatal("oops, i is 0");
    return 100/i;
 }
        
Example 2 (Define fatal() in the underlying project, and make the definition visible only to CodeSonar. Note that this approach is only suitable if no conflicting version of fatal() is visible.)

In this example, myfile.c has been edited directly to include a definition of fatal(). This definition is guarded by #ifdef __CODESONAR__ so will only be seen by the CodeSonar analysis, and not by the regular software build. fatal() calls abort(), so CodeSonar will treat calls to fatal() as if they are (transitive) calls to abort(). In particular, it will not issue a Division by Zero warning on the second line of myfunc().

/* myfile.c */
#ifdef __CODESONAR__
/* Only seen by CodeSonar. */
void fatal(void){ abort(); }
#endif

int myfunc(int i){
    if( i != 0 ) fatal("oops, i is 0");
    return 100/i;
 }

Build Additional, CodeSonar-only files into the CodeSonar project

Summary Implement your modifications in one or more new source files that are included in the CodeSonar project but not in the underlying software build.
Method
  1. Define a new source file fname.x that contains your additional code.
  2. Use codesonar build to incorporate CodeSonar representation for fname.x into your CodeSonar project.
  3. Continue with building and analyzing the CodeSonar project.
Applications Good for:
  • Altering specific pieces of code in arbitrary ways.
  • Adding modeling logic to C++ templates.
  • Fixing parse errors.
  • Enhancing analysis results.
  • Creating new warning classes.
  • Applying csonar_replace_*-based function replacement.

Not suitable for altering all occurrences of some construct (like a special asm syntax): use regular-expression-based replacement or command-based replacement for this purpose.

Notes Some typical modifications are described below.

For further information about this technique, including detailed examples, see the following manual sections. Note that while these sections all refer to the Extension API, the technique can be used to introduce arbitrary C or C++ code.

Example 1
(Define csonar_replace_fatal() in a CodeSonar-only file.)

In this example, a new source file csonar_stubs.c has been created and populated with a definition of csonar_replace_fatal(). csonar_replace_fatal() calls abort(): when csonar_stubs.c is built into a project, CodeSonar will treat calls to fatal() as if they are (transitive) calls to abort(). In particular, if csonar_stubs.c is built into the project containing myfile.c, CodeSonar will not issue a Division by Zero warning on the second line of myfunc().

/* myfile.c */
int myfunc(int i){
    if( i != 0 ) fatal("oops, i is 0");
    return 100/i;
 }
/* csonar_stubs.c */
#include <stdlib.h>
#ifdef __CODESONAR__
/* Only seen by CodeSonar. */
/* Using csonar_replace_* avoids duplicate function problems. */
void csonar_replace_fatal(void){ abort(); }
#endif
Use codesonar build to observe the compilation of csonar_stubs.c and add a corresponding CodeSonar representation to the project, then proceed with the remainder of the CodeSonar build/analysis. For example:
codesonar build myproject cc -c csonar_stubs.c
codesonar analyze myproject make
For detailed build instructions and examples, see Implementing and Including Custom Checks with the Extension API.
Example 2
(Define fatal() in a CodeSonar-only file. Note that this approach is only suitable if no conflicting version of fatal() is visible.)

In this example, a new source file csonar_stubs.c has been created and populated with a definition of fatal(). fatal() calls abort(): when csonar_stubs.c is built into a project, CodeSonar will treat calls to fatal() as if they are (transitive) calls to abort(). In particular, if csonar_stubs.c is built into the project containing myfile.c, CodeSonar will not issue a Division by Zero warning on the second line of myfunc().

/* myfile.c */
int myfunc(int i){
    if( i != 0 ) fatal("oops, i is 0");
    return 100/i;
 }
/* csonar_stubs.c */
#include <stdlib.h>
#ifdef __CODESONAR__
/* Only seen by CodeSonar. */
void fatal(void){ abort(); }
#endif
Use codesonar build to observe the compilation of csonar_stubs.c and add a corresponding CodeSonar representation to the project, then proceed with the remainder of the CodeSonar build/analysis. For example:
codesonar build myproject cc -c csonar_stubs.c
codesonar analyze myproject make
For detailed build instructions and examples, see Implementing and Including Custom Checks with the Extension API.

Comparison Table

Technique Enhance Analysis Results? Define New Warning Classes? Fix Parse Errors?
Define preprocessor macro yes no yes
Hard-define preprocessor macro yes no yes
Preinclude file yes yes yes
Regular-expression-based replacement yes no yes
Command-based replacement yes no yes
Source file patching good good yes
Reroute function calls with FUNCTION_MAP yes no no
Edit underlying source code good good no
Add CodeSonar-only source files good good no

Typical Source Modifications

The two most common source modifications are providing a definition for an undefined function and using csonar_replace_f() to intercept calls to f().

General method

The following applies to both providing a definition for an undefined function and using csonar_replace_f().

  1. Create a definition for f() or csonar_replace_f().
  2. Add the definition to the CodeSonar project. The following techniques are suitable.
 

To report problems with this documentation, please visit https://support.codesecure.com/.