Plug-In Tutorial: C++ Version

This tutorial illustrates the use of the CodeSonar C++ API to construct custom plug-ins for CodeSonar.

Note: Depending on the hub configuration, you may be prompted for hub user account credentials to authenticate and authorize codesonar build and codesonar analyze commands. See Hub Authentication: Authenticated codesonar Subcommands for more information.

CodeSonar SaaS Note: If you want to use your own custom plug-ins with CodeSonar SaaS, contact CodeSecure support for assistance. The installation instructions provided in this page are not sufficient to make plug-ins available to SaaS analyses.



Preliminaries

It is important to build your plug-in with the same pointer width as that of your CodeSonar installation. Otherwise, the plug-in build will fail and report errors in cs_basic_types.h.

Part One

The plug-in for Part One implements a check for variable names containing upper case characters. There are three important elements in the plug-in:

UCvar_plugin.cpp

File UCvar_plugin.cpp is reproduced below.

  //
//      Copyright (c) 2023, an unpublished work by CodeSecure, Inc.
//                      ALL RIGHTS RESERVED
//
//      Copyright (c) 2017-2023, an unpublished work by GrammaTech, Inc.
//                      ALL RIGHTS RESERVED
// 
//      This software is furnished under a license and may be used and
//      copied only in accordance with the terms of such license and the
//      inclusion of the above copyright notice.  This software or any
//      other copies thereof may not be provided or otherwise made
//      available to any other person.  Title to and ownership of the
//      software is retained by CodeSecure, Inc.
// 

// UCvar_plugin.cpp
// 
//  A small example plugin that reports declarations for variables
//  whose names contain upper case characters.

// Must precede #include "csonar_api.hpp".
#define CS_CPP_IMPL

// For Visual C++
#define _CRT_SECURE_NO_WARNINGS 1
 
// Include the entire CodeSonar C++ API.
#include "csonar_api.hpp"  
 
// for std::cout
#include <iostream>

// for isupper
#include <cctype>



// The plug-in defines a new warning class to go with its new check. We
// do not associate any CodeSonar mnemonics or CWE identifiers with the
// new class, as none are appropriate.  The new warning class must be
// created either in the top level scope or inside cs_plug_main().

static cs::warningclass upvar_wc = cs::analysis::create_warningclass(
    "Variable name has upper case characters",
    "",
    1.0,
    cs::warningclass_flags::PADDING,
    cs::warning_significance::STYLE
    );


// Visitors should be at the finest granularity that is appropriate
// for the check. This plug-in is checking a property of variable
// names, so we define a visitor that operates on symbols.

class check_var_case: public cs::visitor<cs::symbol>
{
  void operator()(cs::symbol sym){
    std::string nm = sym.name();                   // cs::symbol::name()

    // If there are one or more upper case characters and the variable
    // is declared in user code, issue a warning and return.
    for ( std::string::iterator it=nm.begin(); it!=nm.end(); ++it){
      if (isupper(*it)){
        
        try {
          cs::sfileinst_line_pair symfl = sym.file_line();
          if (!symfl.first.is_system_include()){   // cs::sfileinst::is_system_include()
            upvar_wc.report(symfl.first,
                            symfl.second,
                            "Variable name " + nm + " has upper case character");
            
            return;
          }
        }
        catch( const cs::result &r ){
            // If no position, do not report warning. Rethrow any
            // other cs::result exceptions.
          if (r==cs::result::NO_POSITION) return;
          throw;
        }
      }
    }
  }
};

// Create an instance of check_var_case, and add it as a symbol
// visitor.  Visitors must be added either in the top-level scope or
// in cs_plug_main().
static char dummy = (cs::analysis::add_symbol_visitor(new check_var_case()), 0);    

// Every C++ plug-in for CodeSonar must define this function. 
static void cs_plug_main(void){}


// All CodeSonar C++ plug-ins must finish with a line of this form (at
// the top level). Note that the argument UCvar_plugin to
// CS_DEFINE_PLUGIN corresponds to the name of the compiled plug-in
// (which will be UCvar_plugin.dll, UCvar_plugin.bundle, or
// UCvar_plugin.so, depending on your system).
CS_DEFINE_PLUGIN(UCvar_plugin)

  

Build

Build the plug-in into a library.

See Writing C++ Plug-Ins For CodeSonar for further compilation details and troubleshooting hints.

Install

Install the plug-in:

Exercise

We have provided an extremely short example program to exercise the plug-in. You can also try building other programs into CodeSonar projects to see how many variables they contain whose names include upper case letters.

Clean Up

If you don't want to be warned in future about variable names containing upper case letters:

Part Two

The plug-in for Part Two implements a check for mismatched parentheses in the output of a program. This involves setting up a step visitor to ensure that the control-flow paths in the program involve properly balanced calls to the procedures that write opening and closing parentheses.

callseq_plugin.cpp

callseq_plugin.cpp contains comments describing the various elements of the plug-in. See these comments for details.

Build

Build the plug-in into a library.

Install

Install the plug-in:

Exercise

We have provided an extremely short example program to exercise the plug-in.

Clean Up

If you don't want to use this plug-in in future:

More on Plug-Ins

General Information:

Visitors Plug-ins are based on visitors, which specify actions to be carried out on elements of the CodeSonar internal representation (IR) at various stages of the analysis.
Writing Plug-Ins General information about creating plug-ins to attach custom functionality to the CodeSonar analysis.
Plug-In Tutorial Two annotated example plug-ins (each provided in all API languages), with building and installation instructions.
AST API Tutorial The AST API tutorial (provided in all API languages) also uses plug-ins.

Specific API Language:

  Plug-In Guidelines Key API References
C++ Writing C++ Plug-Ins classes analysis, visitor, warningclass, project_metricclass, compunit_metricclass, sfile_metricclass, procedure_metricclass.
Python Writing Python Plug-Ins Visitor decorators, Metric decorators; classes analysis, warningclass, project_metricclass, compunit_metricclass, sfile_metricclass, procedure_metricclass.
C Writing C Plug-Ins CodeSonar Plug-In API: C Functions and Types for Visitors, Warnings, and Metrics