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.0p0 Hot Tips | CONFIDENTIAL | CodeSecure Inc |
This tutorial illustrates the use of the CodeSonar Plug-in API (C) 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.
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.
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:
Parts of file UCvar_plugin.c are reproduced below.
/* * Copyright (c) 2023, an unpublished work by CodeSecure, Inc. * ALL RIGHTS RESERVED * * Copyright (c) 2007-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.c * * a small example plugin that reports declarations for variables * whose names contain upper case characters */ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <ctype.h> /* All C plug-ins for CodeSonar must include this file. */ #include "csonar_plugin.h" /* This plug-in accesses various parts of the internal representation * (IR), so the relevant API headers must be included. */ #include "cs_pdg_vertex.h" #include "cs_abs_loc.h" #include "cs_pdg.h" #include "cs_utility.h" #include "cs_source_files.h" /* upvar is a new \warning class \ defined by this plug-in. It must be created in * a setup visitor. */ static cs_warningclass_t upvar; /* helper function for check_var_case * * returns 1 if instr contains an upper case character * (or a bad-valued character, although this should never happen) * 0 otherwise */ static int has_upper_char(cs_string instr, cs_size_t sz) { cs_size_t i; for (i=0; i<sz; i++) { if (isupper((unsigned char) instr[i])) return 1; } return 0; } /* 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 variable ABS_LOCs. */ static void check_var_case(cs_abs_loc sym, void *ctx) { cs_string varname; cs_size_t namesize,ns; char * buf; cs_abs_loc_kind varkind; /* We are only interested in user-defined variables. */ if ( cs_abs_loc_get_kind(sym, &varkind) != CS_SUCCESS ) return; if ( varkind != cs_abs_loc_kind_user) return; /* Retrieving the variable name is a three-step process. * * 1. Call cs_abs_loc_name() with NULL and 0 as the second and * third parameters, respectively, in order to set namesize to the * length of the name (+1). This call should return CS_TRUNCATED, * since a variable name should not be able to fit into a 0-byte * space. * * 2. Allocate space for the varname according to the value of * namesize. * * 3. Call cs_abs_loc_name() again to set varname to the variable * name. */ if ( cs_abs_loc_name(sym,NULL,0,&namesize) == CS_TRUNCATED) { varname = malloc(namesize * sizeof(char)); /* Check that malloc() didn't fail. */ if( !varname ) abort(); if ( cs_abs_loc_name(sym,varname,namesize,&ns) == CS_SUCCESS) { /* If an upper case character is found, and the variable * is declared in user code, issue a warning and return.*/ if ( has_upper_char(varname, namesize) ) { cs_sfid sfid; cs_line line; cs_result r; r = cs_abs_loc_file_line( sym, &sfid, &line ); /* ... and if the variable is declared at some * location in the source code... */ if ( r == CS_SUCCESS ) { char filename[1024]; cs_size_t filename_sz; /* ... and that location is not in a library...*/ r = cs_file_get_include_name( sfid, filename, sizeof(filename), &filename_sz ); if( r != CS_TRUNCATED && r != CS_SUCCESS ) abort(); if( strstr( filename, "/libmodels/" ) || strstr( filename, "\\\\libmodels\\\\" ) || strstr( filename, "/smel/" ) || strstr( filename, "\\\\smel\\\\" ) ) { free(varname); return; } /* ... then construct and issue a warning.*/ buf = malloc(namesize + strlen("variable name %s has upper case character")); if( !buf ) abort(); sprintf( buf, "variable name %s has upper case character", varname ); csonar_report_location_warning( sfid, line, upvar, buf, csrf_none, NULL, NULL); free(buf); } free(varname); return; } } free(varname); } } /* 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 with * csonar_create_warningclass(), which must be called from a setup * visitor.*/ static void setup(void *ctx) { upvar = csonar_create_warningclass( "Variable name has upper case characters", "", 1.0, csonar_bcf_padding, csws_style ); } /* Every C plug-in for CodeSonar must define this function, * which must contain all the calls to csonar_add_*_visitor() and * csonar_create_warningclass() required for the plug-in. */ static void cs_plug_main(void) { csonar_add_setup_visitor(NULL, setup, NULL); /* check_var_case() must be added as an ABS_LOC visitor inside * cs_plug_main() in order for CodeSonar to add it to the * visitor list. */ csonar_add_abs_loc_visitor(NULL, check_var_case, NULL); } /* All CodeSonar C plug-ins require a line of this form at the * top level. Note that the argument to CS_DEFINE_PLUGIN corresponds * to the name of the compiled plug-in (which will be either * UCvar_plugin.dll or UCvar_plugin.so, depending on your system).*/ CS_DEFINE_PLUGIN(UCvar_plugin)
Build the plug-in into a library.
| Compiler | Command Line | Notes | |
|---|---|---|---|
| Windows | |||
| cl |
cl /LD /MD
"/I%CSONAR%\codesonar\include"
"/I%CSONAR%\csurf\include" UCvar_plugin.c "%CSONAR%\codesonar\lib\codesonar.lib" |
|
|
| Cygwin gcc |
Note: Cygwin gcc is only suitable for building
32-bit CodeSonar plugins.
Cygwin gcc only builds
Cygwin binaries, so is not suitable for building 64-bit
CodeSonar plug-ins. If you do not have an alternative
gcc, you will need to
download and install one. One option is mingw-w64.
|
|
|
| MinGW gcc |
gcc -shared
"-I$CSONAR\codesonar\include"
"-I$CSONAR\csurf\include" UCvar_plugin.c -o UCvar_plugin.dll "-L$CSONAR\codesonar\lib" -lcodesonar |
|
|
| All Other Systems We provide a full example for gcc. For other compilers, build UCvar_plugin.so from UCvar_plugin.c, including $CSONAR/codesonar/include and $CSONAR/csurf/include. |
|||
| gcc |
gcc -fPIC -shared -o UCvar_plugin.so UCvar_plugin.c
-I$CSONAR/codesonar/include -I$CSONAR/csurf/include |
|
|
See Writing C Plug-Ins For CodeSonar for further compilation details and troubleshooting hints.
Install the plug-in:
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.
| with cl: |
codesonar analyze testvar host:port cl /c
testvar.c
|
|---|---|
| with gcc: |
codesonar analyze testvar host:port gcc -c
testvar.c
|
Note that procedure names are not associated with the warnings. This is because we issued the warnings with csonar_report_location_warning, which does not report a procedure name (because, among other reasons, a line may contain multiple procedures).
If you don't want to be warned in future about variable names containing upper case letters:
(If you used an alternative location, remove the associated PLUGINS configuration file setting).
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.c contains comments describing the various elements of the plug-in. See these comments for details.
Build the plug-in into a library.
| Compiler | Command Line | Notes | |
|---|---|---|---|
| Windows | |||
| cl |
cl /LD /MD
"/I%CSONAR%\codesonar\include"
"/I%CSONAR%\csurf\include" callseq_plugin.c "%CSONAR%\codesonar\lib\codesonar.lib" |
|
|
| Cygwin gcc |
Note: Cygwin gcc is only suitable for building
32-bit CodeSonar plugins.
Cygwin gcc only builds
Cygwin binaries, so is not suitable for building 64-bit
CodeSonar plug-ins. If you do not have an alternative
gcc, you will need to
download and install one. One option is mingw-w64.
|
|
|
| MinGW gcc |
gcc -shared
"-I$CSONAR\codesonar\include"
"-I$CSONAR\csurf\include" callseq_plugin.c -o callseq_plugin.dll "-L$CSONAR\codesonar\lib" -lcodesonar |
|
|
| All Other Systems We provide a full example for gcc. For other compilers, build callseq_plugin.so from callseq_plugin.c, including $CSONAR/codesonar/include and $CSONAR/csurf/include. |
|||
| gcc |
gcc -fPIC -shared -o callseq_plugin.so
callseq_plugin.c
-I$CSONAR/codesonar/include -I$CSONAR/csurf/include |
|
|
Install the plug-in:
We have provided an extremely short example program to exercise the plug-in.
| with cl: |
codesonar analyze callseq host:port cl /c
callseq_sample.c
|
|---|---|
| with gcc: |
codesonar analyze callseq host:port gcc -c
callseq_sample.c
|
If you don't want to use this plug-in in future:
(If you used an alternative location, remove the associated PLUGINS configuration file setting).
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 |