Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Suppress warnings from CPD for C/C++ code

We are using PMD Copy Paste Detector (CPD) to analyze our C and C++ code. However, there are a few parts of the code that are very similar, but with a good reason and we would like to suppress the warnings for these parts.

The documentation of PMD CPD only mentions something about annotations, but this will not work for our these languages.

How can I still ignore warnings for specific parts?

Is there a comment to do so perhaps?

[UPDATE] I'm using the following Groovy script to run CPD:

@GrabResolver(name = 'jcenter', root = 'https://jcenter.bintray.com/')
@Grab('net.sourceforge.pmd:pmd-core:5.4.+')
@Grab('net.sourceforge.pmd:pmd-cpp:5.4.+')
import net.sourceforge.pmd.cpd.CPD
import net.sourceforge.pmd.cpd.CPDConfiguration
import java.util.regex.Pattern

def tokens = 60
def scanDirs = ['./path/to/scan', './scan/this/too']
def ignores = [
    './ignore/this/path',
    './this/must/be/ignored/too'
    ].collect({ it.replace('/', File.separator) })
def rootDir = new File('.')
def outputDir = new File('./reports/analysis/')

def filename_date_format = 'yyyyMMdd'
def encoding = System.getProperty('file.encoding')
def language_converter = new CPDConfiguration.LanguageConverter()
def config = new CPDConfiguration()
config.language = new CPDConfiguration.LanguageConverter().convert('c')
config.minimumTileSize = tokens
config.renderer = config.getRendererFromString 'xml', 'UTF-8'
config.skipBlocksPattern = '//DUPSTOP|//DUPSTART'
config.skipLexicalErrors = true
def cpd = new CPD(config)

scanDirs.each { path ->
    def dir = new File(path);
    dir.eachFileRecurse(groovy.io.FileType.FILES) {
        // Ignore file?
        def doIgnore = false
        ignores.each { ignore ->
            if(it.path.startsWith(ignore)) {
                doIgnore = true
            }
        }
        if(doIgnore) {
            return
        }

        // Other checks
        def lowerCaseName = it.name.toLowerCase()
        if(lowerCaseName.endsWith('.c') || lowerCaseName.endsWith('.cpp') || lowerCaseName.endsWith('.h')) {
            cpd.add it
        }
    }
}

cpd.go();

def duplicationFound = cpd.matches.hasNext()

def now = new Date().format(filename_date_format)
def outputFile = new File(outputDir.canonicalFile, "cpd_report_${now}.xml")
println "Saving report to ${outputFile.absolutePath}"

def absoluteRootDir = rootDir.canonicalPath
if(absoluteRootDir[-1] != File.separator) {
    absoluteRootDir += File.separator
}

outputFile.parentFile.mkdirs()
def xmlOutput = config.renderer.render(cpd.matches);
if(duplicationFound) {
  def filePattern = "(<file\\s+line=\"\\d+\"\\s+path=\")${Pattern.quote(absoluteRootDir)}([^\"]+\"\\s*/>)"
  xmlOutput = xmlOutput.replaceAll(filePattern, '$1$2')
} else {
  println 'No duplication found.'
}

outputFile.write xmlOutput
like image 941
Arno Moonen Avatar asked Jun 03 '16 09:06

Arno Moonen


People also ask

How do you suppress CPD?

You can use @SuppressWarnings("CPD-START") and @SuppressWarnings("CPD-END") around the code you want to skip. If you want to ignore a file from a specific line til EOF, using @SuppressWarnings("CPD-START") alone is enough.

How do you suppress warnings in VS code?

Choose Build, and go to the Errors and warnings subsection. In the Suppress warnings or Suppress specific warnings box, specify the error codes of the warnings that you want to suppress, separated by semicolons. For a list and descriptions of warning codes, see C# Compiler Messages.

What is CPD in Java?

Another significant piece of PMD is called CPD, the copy/paste detector. CPD can look through Java, JSP, C, C++, Fortran, or PHP source code files and find sections of code that are repeated. By using CPD to analyze your source code you can identify duplicate code that might be suitable for refactoring.


1 Answers

You can define your custom markers for excluding certain blocks from analysis through the --skip-blocks-pattern option.

--skip-blocks-pattern Pattern to find the blocks to skip. Start and End pattern separated by |. Default is #if 0|#endif.

For example the following will ignore blocks between /* SUPPRESS CPD START */ and /* SUPPRESS CPD END */ comments (the comment must occupy a separate line):

$ ./run.sh cpd --minimum-tokens 100 --files /path/to/c/source --language cpp ----skip-blocks-pattern '/* SUPPRESS CPD START */|/* SUPPRESS CPD END */'

Note however, that this will cause the tool perform copy-paste-detection inside code delimited by #if 0/#endif.

like image 162
Leon Avatar answered Oct 01 '22 20:10

Leon