# CppCheck
##### 文章指令都是以「CLI」為主
## 輸出參數調整
3. [文件](https://cppcheck.sourceforge.io/manual.pdf)
cppcheck --xml --xml-version=2 --enable=all libzmq-master/ > OpenSourceResult.xml 2>&1
cppcheck-htmlreport --title=testHTML --file=report-basic2.xml --source-dir=. --report-dir=report/xml/index.xml
sudo yum install -y cppcheck-htmlreport
> 可以用 `cppcheck --help` 來查閱
### 參數目錄
`--output-file=<file>` : 用來把檔案輸出保存到目標文件內
`--xml` : 以 XML 格式生成,主要用於自動化
`--enable=<check>` : 啟用指定的檢查類型(比如 style)
`--disable=<check>` : 禁用指定的檢查類型(比如 performance)
`--std=<standard>` : 選擇符合的 C 標準如: C++11
`--library=<file>` : 指定自定義 Library
`--platform=<platform>` : 檢查在指定 OS 平台上的相容性
`--verbose` : 更加詳細的輸出(每個檢查訊息都有)
`--quiet` : 最小化輸出,只有 Error 跟 Warning
`--check-config` : 檢查 CppCheck 配置文件是否有錯,在執行前避免測試問題
## 重點整理
靜態分析是不能全部錯誤都發現的 EX. Halo World
- 執行指令 (如果指定的是 Floder 他會掃描內部全部 File)
`cppcheck file1.c`
- 產生結果示範
```
Checking file1.c...
[file1.c:4]: (error) Array 'a[10]' index 10 out of bounds
```
---
### 資料夾過濾
`cppcheck --file-filter=<str>` 可以指定只掃描特定資料夾
`cppcheck -i <Path>`不想掃描的話
---
### 輸出保存
`-cppcheck-build-dir=path` : 將分析信息保存在目標路徑,提高分析速度
`--output-file=<file>` : 把檔案輸出保存到目標文件內
---
### 預先處理
如果使用 `--project` 的話,Cppcheck 會自動導入項目內的預處理器
如果不是的話,可能需要手動定義
---
### 選擇掃描的平台類型
`--platform=<platform>` : 決定在指定 OS 平台上執行
默認使用本地 OS 配置執行,也可以使用 XML 來自定義平台配置

### 掃描類型
`--enable=<check>` : 啟用指定的檢查類型(比如 style)
`--disable=<check>` : 禁用指定的檢查類型(比如 performance)
**類型如下:**
1. `style` : 程式碼風格,比如駝峰命名跟 Black
2. `performance` : 性能方面,不需要的循環與低效能代碼
3. `portability` : 對於各個平台的可疑值性
4. `information` :檢查 Code 的訊息
-> (Function call / Variable型別與作用區 / Code structure / Include file 名稱路徑)
5. `warning`: 非錯誤,而是有風險的部分。
6. `error`: 導致代碼運行失敗
7. `performance-...` : 指定特定性能問題,如多線程性能或是不必要拷貝。
8. `portability-..`: 移植性檢查的子類別,如 POSIX 函數的使用與負數索引。
---
### 選擇掃描版本
`--std=<standard>` : 選擇標準
#### `--std=<standard>` 的版本
* c89: 使用 C89 標準
* c99: 使用 C99 標準
* c11: 使用 C11 標準 (default)
* c++98:使用 C++98 標準。
* c++03:是 C++98 的修訂版。
* c++11:被稱為 C++0x,引入了許多新特性。(default)
* c++14:對 C++11 進行了一些修訂和擴展。
* c++17:引入了更多的新功能和改進。
* c++20:C++17 的進一步擴展,引入了許多新特性。
### Cppcheck build dir
使用 `--cppcheck-build-dir` 來執行
可以加快速度,已知且未修改的錯誤不會再次掃描,會從 build dir 叫出重新顯示
**重點**:如果使用 multiple threads 時,必須 Build Dir 才能執行
### Suppressions 錯誤抑制
用來過濾掉某些錯誤的問題
**錯誤文字過濾**
範例
```
[error id]:[filename]:[line]
[error id]:[filename2]
[error id]
```
可以使用 –template=gcc 來抑制目標的 error id 而文件可以用 * 或 ?
**以 CLI 操作**
`cppcheck --suppress= memleak:src/file1.cpp src/`
**同樣可以使用 XML 來自定義設置**
`cppcheck --suppress-xml=suppressions.xml src/`
**或是指定程式碼內的特定行數**
`cppcheck --inline-suppr test.c`
**還能過濾特定的 Format 內容**
`cppcheck-suppress [aaaa, bbbb]`
### 回報格式-XML
指令如下
```
cppcheck --xml file1.cpp
```
`Error 元素格式`
* id : 錯誤的 id 與有效的符號名
* severity : 嚴重性 (warning/style/performance/portability/information)
* msg: 簡短的錯誤訊息
* verbose: 更詳細的錯誤訊息
* inconclusive: 此錯誤訊息無法確定
* CWE: 弱點標準,只有知道錯誤訊息的 CWE ID 時才使用
**Location 元素格式**
* file: 文件名稱,路徑可以相對或絕對
* file0: 文件的 Source Name
* line: 行數
* info: 簡短訊息
### 回報格式-Text OutPut
指令為: `cppcheck --template`
使用 VsCode 的模板 (Vs 限定)
`cppcheck --template=vs samples/arrayIndexOutOfBounds/bad.c`
也可以使用 gcc 的模板
`cppcheck --template=gcc samples/arrayIndexOutOfBounds/bad.c`
也可以自定義單行 / 多行的模板,範例如下:
```
cppcheck --template="{file}:{line}: {severity}: {message}" samples/arrayIndexOutOfBounds/bad
cppcheck --template="{file},{line},{severity},{id},{message}" samples/arrayIndexOutOfBounds/
```
他的選項有這些:
* {file}
* {line}
* {column}
* {callstack}
* {inconclusive:text}
* {inconclusive:inconclusive,}
* {severity}
* {message}
* {id}
* {code}
* \t
* \n
* \r
### 使用 Addons
- 分析 Cppcheck 文件的腳本,用來檢查兼容性與安全問題
- 有幾個內建的 addons,也可以自訂如 js 的腳本,比如下方範例
```
{
"script": "misra.py",
"args": [
"--rule-texts=misra.txt"
]
}
```
1. misra .py :嵌入式系統用,不可修改,有準則用來避免代碼問題
1. y2038 .py :檢查 Linux 的安全系統(到 2038 年)
1. threadsafety .py :檢查 thread 的安全問題如多線程
執行方式:
```
cppcheck --addon=<addon> <Target-File>
```
### 檢查 Library
如果使用外部的 Library 可能會偵測不到問題,需要手動加載 Library
`--check-library` : 用來獲得幫助
`--library=<file>` : 指定自定義 Library
### 回報格式-HTML 31 頁
- 需要 Python 跟 pygments 才能實現
- 把 XML 轉成 HTML,利用內建的 htmlreport 實現
- 指令是這個: `htmlreport/cppcheck-htmlreport -h`
- 相關參數如下:
```
Options:
-h, --help
show this help message and exit
--file=FILE
The cppcheck xml output file to read defects from.
Default is reading from stdin.
--report-dir=REPORT_DIR
The directory where the html report content is written.
--source-dir=SOURCE_DIR
Base directory where source code files can be found.
```
- 執行範例如下:
```
./cppcheck gui/test.cpp --xml 2> err.xml
htmlreport/cppcheck-htmlreport --file=err.xml --report-dir=test1 --source-dir=.
```
---
## 補充說明
### 決定檢查詳不詳細,快不快速
- 詳細度有 Normal 跟 Exhaustive 兩種,預設是普通
- 詳細版本會花費明顯較長時間去檢查,切換指令如下
```
--check-level=exhaustive.
```
- 而檢查的快速程度可以調整這個達到
- 如果是使用 GUI 會有更多且更有效的選項可以選擇
```
--performance-valueflow-max-if-count
```
### 如何 Import Project
#### GUI
`cppcheck --project=<Floder or File>`
#### Cmake
先生成 Database| `cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON`
然後在執行|`cppcheck --project=compile_commands.json`
#### Visual Studio
`cppcheck --project=foobar.sln`
也可以更詳細
```
cppcheck --project=foobar.sln "--project-configuration=Release|Win32"
```
### verbose / 原本 / quiet 的差異
-- quiet : 最簡潔的輸出,只有基本的錯誤訊息跟警告訊息
-- nomoral: 基本的輸出
-- verbose: 比較詳細的輸出,除了錯誤訊息外可能還會有檢查的程式,錯誤的行數等等
# 與 SonarQube 的連動:
1. [GitHub 的 CppCheck Plugin](https://github.com/SonarQubeCommunity/sonar-cppcheck)
2. [手動添加的方式](https://blog.csdn.net/qq_15559817/article/details/100736498)
### Note
1. Build image (Auto) ( 開專案去 Build -> Dev7 )
2. Sonarqube -> Cppcheck (C++) <- Plugun or rule (CE) <--- Docker Container (Sonqube 9.9.2)
## 實踐紀錄:
[官方說明不支援 CppCheck (DEV版本)](https://community.sonarsource.com/t/developer-edition-with-cppcheck/23139)
[Sonar-Scanner 設置](https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/scanners/sonarscanner/)
### 讓 C++ 專案在 Sonarqube 中執行
1. [X] 安裝 Sonarqube
2. [X] 安裝 Cxx Plugins
3. [X] 安裝 Host 端 Sonar-scanner-cli
4. [ ] 設定 sonar-project.properties
5. [ ] 設定好[C++額外的要求](https://docs.sonarsource.com/sonarqube/latest/analyzing-source-code/languages/c-family/)
### 把 CppCheck 的 XML 結果在 Sonarqube 上展宴
1. [ ] 完成 Sonarqube C++ 執行條件
2. [ ] 設定 sonar-project.properties
3. [ ] 設定 Cppchck.path