With the release of Understand 6.4, we now have the ability to access violations via the Python and Perl APIs. The API's can report any violations that appear in the Violation Browser, as the two work synchronously. These violations can include CodeCheck violations, analysis errors, and warnings.
Let's go through a simple example. My goal is to print a list of every file in my project that contains a violation from the Recommended Checks CodeCheck config. Here I'll use one of Understand's bundled Python scripts as my jumping off point. This script simply lists every file in a project database:
import understand import sys def fileList(db): for file in db.ents("File"): #If file is from the Standard library, skip to next if file.library() != "Standard": print (file.name()) if __name__ == '__main__': # Open Database args = sys.argv db = understand.open(args) fileList(db)
Now that we have our starting code, we need to set up our CodeCheck configuration as well as the Violation Browser to make the violations accessible with our script.
Within the GUI, we'll select Checks from the top level menu, then Select Checks. Here we'll create a new CodeCheck configuration and load in all 18 of Scitools' Recommended Checks:
Note that the option at the top of the configuration to have this configuration run automatically in the background MUST be selected in order for these checks to populate the Violation Browser.
Another thing to keep in mind is that we can also import SARIF files to populate the Violation Browser if so desired.
Now, once we close CodeCheck and analyze the project, our custom configuration will populate the Violation Browser with violations. We can confirm this by selecting Checks -> Browse Violations in the top level menu.
Ok, we're ready to access these violations using our Python API script!
#Print a list of the files in the project, along with the types of violations in each import understand import sys def fileList(db): for file in db.ents("File"): #If file is from the Standard library, skip to next if file.library() != "Standard": #Grab all violations in the file viols = file.violations() viol_IDs =  #Print only files containing at least one violation, print total if len(viols) != 0: print (file.name(), "- violation count:", len(viols)) #Print all unique check IDs of violations seen in this file for viol in viols: if viol.check_id() not in viol_IDs: print("--> check ID:", viol.check_id()) viol_IDs.append(viol.check_id()) print("\n") if __name__ == '__main__': # Open Database args = sys.argv db = understand.open(args) fileList(db)
As you can see, the first change we made was accessing all violations in the given file with the .violations() API method. I then declare an empty list to hold violation check ID's. If the file contains any violations, I print the file name along with the total number of violations in that file. Then, we go through each violation, calling the .check_id() method on that violation object. This returns the unique ID for that CodeCheck violation (or UND_ERROR/UND_WARNING for errors and warnings respectively), which is then printed below the filename.
Here is a snippet of the output following invocation of the script:
As you could imagine, this is just one of many use cases that retrieving violations from the API could have. We encourage you to explore the Perl and Python API's, and especially the new understand.Violation class within them, to see how powerful it is for yourself! And if you have some custom checks but don't have the time to implement them right now, reach out to us at firstname.lastname@example.org and let us work with you to determine exactly what you need, get you a quote, and get the job done for you as quickly as possible.