2016-06-03 2 views
6

Мы используем PMD Copy Paste Detector (CPD) для анализа нашего кода на C и C++. Однако есть несколько частей кода, которые очень похожи, но с серьезной причиной, и мы хотели бы подавить предупреждения для этих частей.Подавлять предупреждения от CPD для кода C/C++

documentation of PMD CPD только упоминает что-то об аннотациях, но это не будет работать для наших этих языков.

Как я могу игнорировать предупреждения для определенных частей?

Есть ли комментарий, чтобы сделать это, возможно?

[UPDATE] Я использую следующий Groovy скрипт для запуска 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 

ответ

2

После поиска через код ПМД на GitHub, я думаю, что я могу с уверенностью сказать, что это НЕ поддерживаемый в этот момент времени (текущая версия - PMD 5.5.0).

Поиск CPD-START в их репозитории не содержит никаких результатов в каталоге pmd-cpp (см. the search results on GitHub).

+0

Несчастливо. Но PMD * был разработан для Java в конце концов. Может быть, статический анализатор Clang (или другой инструмент) может предоставить вам лучшую настройку? – StoryTeller

+0

Мне не известно о дублировании кода/«детекторе копирования пасты» в Clang, так как я знаю, что это не альтернатива. –

3

Вы можете определить свои пользовательские маркеры для исключения определенных блоков из анализа с помощью опции --skip-blocks-pattern.

--skip-блоки-модели шаблон, чтобы найти блоки, чтобы пропустить. Начальный и конечный паттерны, разделенные символом |. По умолчанию #if 0|#endif.

Например следующие будут игнорировать блоки между /* SUPPRESS CPD START */ и /* SUPPRESS CPD END */ комментарии (комментарий должен занимать отдельную строку):

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

Однако обратите внимание, что это приведет инструмент выполнения копирования-вставки-обнаружение внутренний код, ограниченный #if 0/#endif.

+0

Я попробую это позже сегодня. Я считаю, что еще один инструмент уже проверяет, используется ли «#if 0», потому что мы уже определили, что это не должно использоваться. Обратите внимание, что я использую собственный скрипт Groovy для запуска CPD, поэтому мне нужно будет выяснить, как передать это, когда я вызываю 'CPD.go (config)' из моего скрипта. –

+0

Я обновил исходное сообщение, чтобы включить сценарий, который я использую для запуска CPD, включая опцию 'skipBlocksPattern'. К сожалению, это не работает для меня (пока?). Буду расследовать это скорее, надеюсь. –

-1

У меня нет помощи для CPD. В общем, я знаю о таких инструментах; Я не понимаю, что такое «предупреждения».

Наши CloneDR tool finds exact and near-miss duplicate code. IMHO, он находит лучшие клоны, чем CPD, потому что он использует синтаксис/структуру языка в качестве руководства. [Этот факт подкреплен исследовательским отчетом третьей стороны, который вы можете найти на сайте]. И он не выдаёт «предупреждения».

Если является кодом, который, по его мнению, участвует в клоне, инструмент будет генерировать страницу отчета о результатах для задействованных клонов. Но это не предупреждение. Невозможно подавить поведение отчетности. Очевидно, если вы видели такой клон и решили, что это не интересно, вы можете отметить одну из записей клона комментарием, заявив, что это неинтересный клон; этот комментарий будет отображаться в отчете о клоне. (Такие) комментарии не влияют на то, какие клоны обнаружены CloneDR, поэтому их добавление не изменяет вычисленный ответ.

+0

Ну, я называю это предупреждением, но в основном это делает CPD. Он просто перечисляет найденные клоны, и есть способ сказать ему «исключить» его из этого списка (таким образом, подавляя «предупреждение»). Этот инструмент также работает для простого C? –

+0

Да, он работает для самых разных языков, как и для обычного C. Иногда (для C) вы должны предоставить ему несколько конфигурационных данных для обработки директив препроцессора с плохой структурой. Для некоторых примеров см. Https://www.semanticdesigns.com/Products/Formatters/CPreprocessorConstraints.html. Modulo, что он работает очень хорошо. –

Смежные вопросы