2016-06-03 10 views
6

PMD 복사 붙여 넣기 감지기 (CPD)를 사용하여 C 및 C++ 코드를 분석합니다. 그러나 매우 유사한 몇 가지 코드가 있지만 좋은 이유가 있으며 이러한 부분에 대한 경고를 표시하지 않으려합니다.C/C++ 코드의 CPD에서 경고 표시 안 함

documentation of PMD CPD에는 특수 효과에 대해서만 언급되어 있지만이 언어에서는 작동하지 않습니다.

어떻게하면 특정 부품에 대한 경고를 무시할 수 있습니까?

아마도 그렇게 할 코멘트가 있습니까?

[업데이트] 내가 CPD 실행하려면 다음 그루비 스크립트를 사용하고 : GitHub의에 PMD의 코드를 검색 한 후

@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

을, 나는 안전하게이라고 말할 수 있다고 생각 하지 이 시점에서 지원됩니다 (현재 버전은 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"이 사용되었는지 확인하기 위해 테스트를 수행한다고 믿는다. 왜냐하면 우리는 이미 이것을 사용하면 안된다는 것을 이미 정의했기 때문이다. CPD를 실행하기 위해 커스텀 Groovy 스크립트를 사용하고 있으므로 스크립트에서'CPD.go (config)'를 호출 할 때 이것을 전달하는 방법을 알아야 할 필요가 있습니다. –

+0

'skipBlocksPattern' 옵션을 포함하여 CPD를 실행하는 데 사용하는 스크립트를 포함하도록 원본 게시물을 업데이트했습니다. 불행히도, 이것은 나를 위해 (아직?) 작동하지 않는 것 같습니다. 더 빨리 조사 할 예정입니다. –

-1

CPD에 대한 도움이 없습니다. 일반적으로 저는 그러한 도구에 대해 알고 있습니다. 나는 "경고"에 대해 조금 이해하지 못한다.

우리 CloneDR tool finds exact and near-miss duplicate code. IMHO, 언어 구문/구조를 지침으로 사용하기 때문에 CPD보다 우수한 복제본을 찾습니다. [이 사실은 사이트에서 찾을 수있는 제 3자가 수행 한 연구 보고서에 의해 뒷받침됩니다.] 그리고 "경고"는 나오지 않습니다.

이 복제에 포함되어 있다고 생각되는 코드 인 경우이 도구는 관련 클론에 대한 출력 보고서 페이지를 생성합니다. 그러나 그것은 경고가 아닙니다. 보고 동작을 억제 할 방법이 없습니다. 분명히 그러한 복제본을보고 흥미롭지 않다고 결정한 경우 클론 항목 중 하나에 관심없는 복제본임을 나타내는 주석을 표시 할 수 있습니다. 그 주석은 복제 보고서에 표시됩니다. (그러한) 주석은 CloneDR에 의해 검출 된 클론에 영향을 미치지 않으므로 이들을 추가해도 계산 된 응답이 변경되지 않습니다.

+0

글쎄, 나는 그것을 경고라고 부르지 만, 기본적으로 CPD도 그렇게한다. 단순히 찾은 클론을 나열하고 해당 클론을 해당 목록에서 "제외"하도록 지시하는 방법이 있습니다 (따라서 "경고"는 표시되지 않습니다). 이 도구는 일반 C에서도 작동합니까? –

+0

네, C 언어와 마찬가지로 다양한 언어에서 잘 작동합니다. 때때로 (C 언어의 경우) 구조 전 처리기 지시문을 제대로 처리 할 수없는 구성 데이터를 제공해야합니다. 몇 가지 예를 보려면 https://www.semanticdesigns.com/Products/Formatters/CPreprocessorConstraints.html을 참조하십시오. 모듈러스는 꽤 잘 작동합니다. –