Skip to content

Commit dd90001

Browse files
Merge branch 'cppcheck-opensource:master' into chr_utf16
2 parents 202f265 + 79db44c commit dd90001

9 files changed

Lines changed: 379 additions & 46 deletions

File tree

.github/workflows/CI-mingw.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ jobs:
3333
exclude:
3434
- msystem: CLANG64
3535
compiler: g++
36+
# the mingw-w64-i686-clang package is no longer available
37+
- msystem: MINGW32
38+
compiler: clang++
3639
fail-fast: false
3740

3841
runs-on: windows-2025

.github/workflows/CI-unixish.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,17 @@ jobs:
1010

1111
strategy:
1212
matrix:
13-
os: [ubuntu-22.04, ubuntu-24.04, macos-14, macos-15, macos-15-intel, macos-26]
13+
os: [ubuntu-22.04, ubuntu-22.04-arm, ubuntu-24.04, ubuntu-24.04-arm, macos-14, macos-15, macos-15-intel, macos-26, macos-26-intel]
1414
compiler: [clang++]
1515
include:
1616
- os: ubuntu-22.04
1717
compiler: g++
18+
- os: ubuntu-22.04-arm
19+
compiler: g++
1820
- os: ubuntu-24.04
1921
compiler: g++
22+
- os: ubuntu-24.04-arm
23+
compiler: g++
2024
fail-fast: false
2125

2226
runs-on: ${{ matrix.os }}

.github/workflows/CI-windows.yml

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,21 @@ permissions:
1212
defaults:
1313
run:
1414
shell: cmd
15-
15+
1616
jobs:
1717

1818
build:
1919
strategy:
2020
matrix:
2121
os: [windows-2022, windows-2025, windows-11-arm]
2222
config: [Release, Debug]
23+
include:
24+
- os: windows-2022
25+
sln: sln
26+
- os: windows-2025
27+
sln: slnx
28+
- os: windows-11-arm
29+
sln: sln
2330
fail-fast: false
2431

2532
runs-on: ${{ matrix.os }}
@@ -32,10 +39,10 @@ jobs:
3239
- name: Setup msbuild.exe
3340
uses: microsoft/setup-msbuild@v2
3441

35-
- name: Set up Python 3.13
42+
- name: Set up Python
3643
uses: actions/setup-python@v6
3744
with:
38-
python-version: '3.13'
45+
python-version: '3.14'
3946
check-latest: true
4047

4148
- name: Install missing Python packages
@@ -45,12 +52,12 @@ jobs:
4552
4653
- name: Run CMake
4754
run: |
48-
cmake -G "Visual Studio 17 2022" -A x64 -Werror=dev --warn-uninitialized -DCMAKE_COMPILE_WARNING_AS_ERROR=On . || exit /b !errorlevel!
55+
cmake -A x64 -Werror=dev --warn-uninitialized -DCMAKE_COMPILE_WARNING_AS_ERROR=On . || exit /b !errorlevel!
4956
5057
- name: Build
5158
run: |
52-
msbuild -m simplecpp.sln /p:Configuration=${{ matrix.config }} /p:Platform=x64 || exit /b !errorlevel!
53-
59+
msbuild -m simplecpp.${{ matrix.sln }} /p:Configuration=${{ matrix.config }} /p:Platform=x64 || exit /b !errorlevel!
60+
5461
- name: Test
5562
run: |
5663
.\${{ matrix.config }}\testrunner.exe || exit /b !errorlevel!
@@ -66,17 +73,17 @@ jobs:
6673
6774
- name: Run CMake (c++17)
6875
run: |
69-
cmake -S . -B build.cxx17 -G "Visual Studio 17 2022" -A x64 -Werror=dev --warn-uninitialized -DCMAKE_CXX_STANDARD=17 -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel!
76+
cmake -S . -B build.cxx17 -A x64 -Werror=dev --warn-uninitialized -DCMAKE_CXX_STANDARD=17 -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel!
7077
7178
- name: Build (c++17)
7279
run: |
73-
msbuild -m build.cxx17\simplecpp.sln /p:Configuration=${{ matrix.config }} /p:Platform=x64 || exit /b !errorlevel!
80+
msbuild -m build.cxx17\simplecpp.${{ matrix.sln }} /p:Configuration=${{ matrix.config }} /p:Platform=x64 || exit /b !errorlevel!
7481
7582
- name: Run CMake (c++20)
7683
run: |
77-
cmake -S . -B build.cxx20 -G "Visual Studio 17 2022" -A x64 -Werror=dev --warn-uninitialized -DCMAKE_CXX_STANDARD=20 -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel!
84+
cmake -S . -B build.cxx20 -A x64 -Werror=dev --warn-uninitialized -DCMAKE_CXX_STANDARD=20 -DCMAKE_COMPILE_WARNING_AS_ERROR=On || exit /b !errorlevel!
7885
7986
- name: Build (c++20)
8087
run: |
81-
msbuild -m build.cxx20\simplecpp.sln /p:Configuration=${{ matrix.config }} /p:Platform=x64 || exit /b !errorlevel!
88+
msbuild -m build.cxx20\simplecpp.${{ matrix.sln }} /p:Configuration=${{ matrix.config }} /p:Platform=x64 || exit /b !errorlevel!
8289

.github/workflows/clang-tidy.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ jobs:
4242
4343
- name: Prepare CMake
4444
run: |
45-
cmake -S . -B cmake.output -Werror=dev --warn-uninitialized -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
45+
cmake -S . -B cmake.output -Werror=dev --warn-uninitialized -DCMAKE_CXX_STANDARD=23 -DCMAKE_COMPILE_WARNING_AS_ERROR=On -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
4646
env:
4747
CXX: clang-22
4848

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Simple C/C++ preprocessor
22

3+
NOTE: This repository was recently moved from https://github.com/danmar/simplecpp to https://github.com/cppcheck-opensource/simplecpp. Please make sure to update all your references to it accordingly.
4+
35
This is a simple C/C++ preprocessor.
46

57
The goal is to have good conformance with the C and C++ standards and to handle nonstandard preprocessor extensions in gcc / clang / visual studio preprocessors. Most of the preprocessor testcases in gcc and clang are handled OK by simplecpp.

main.cpp

Lines changed: 62 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
#define SIMPLECPP_TOKENLIST_ALLOW_PTR 0
77
#include "simplecpp.h"
88

9+
#include <cstdint>
910
#include <cstdlib>
1011
#include <cstring>
1112
#include <fstream>
1213
#include <iostream>
13-
#include <sys/stat.h>
14+
#include <sstream>
1415
#include <string>
16+
#include <sys/stat.h>
1517
#include <utility>
1618
#include <vector>
1719

@@ -28,7 +30,12 @@ int main(int argc, char **argv)
2830
{
2931
bool error = false;
3032
const char *filename = nullptr;
31-
bool use_istream = false;
33+
enum : std::uint8_t {
34+
File,
35+
Fstream,
36+
Sstream,
37+
CharBuffer
38+
} toklist_inf = File;
3239
bool fail_on_error = false;
3340
bool linenrs = false;
3441

@@ -86,9 +93,28 @@ int main(int argc, char **argv)
8693
break;
8794
}
8895
dui.includes.emplace_back(std::move(value));
89-
} else if (std::strncmp(arg, "-is",3)==0) {
96+
}
97+
else if (std::strncmp(arg, "-input=",7)==0) {
9098
found = true;
91-
use_istream = true;
99+
const std::string input = arg + 7;
100+
if (input.empty()) {
101+
std::cout << "error: option -input with no value." << std::endl;
102+
error = true;
103+
break;
104+
}
105+
if (input == "file") {
106+
toklist_inf = File;
107+
} else if (input == "fstream") {
108+
toklist_inf = Fstream;
109+
} else if (input == "sstream") {
110+
toklist_inf = Sstream;
111+
} else if (input == "buffer") {
112+
toklist_inf = CharBuffer;
113+
} else {
114+
std::cout << "error: unknown input type '" << input << "'." << std::endl;
115+
error = true;
116+
break;
117+
}
92118
}
93119
break;
94120
case 's':
@@ -104,20 +130,28 @@ int main(int argc, char **argv)
104130
}
105131
break;
106132
case 'q':
107-
found = true;
108-
quiet = true;
133+
if (std::strcmp(arg, "-q")==0) {
134+
found = true;
135+
quiet = true;
136+
}
109137
break;
110138
case 'e':
111-
found = true;
112-
error_only = true;
139+
if (std::strcmp(arg, "-e")==0) {
140+
found = true;
141+
error_only = true;
142+
}
113143
break;
114144
case 'f':
115-
found = true;
116-
fail_on_error = true;
145+
if (std::strcmp(arg, "-f")==0) {
146+
fail_on_error = true;
147+
found = true;
148+
}
117149
break;
118150
case 'l':
119-
linenrs = true;
120-
found = true;
151+
if (std::strcmp(arg, "-l")==0) {
152+
linenrs = true;
153+
found = true;
154+
}
121155
break;
122156
}
123157
if (!found) {
@@ -149,7 +183,7 @@ int main(int argc, char **argv)
149183
std::cout << " -UNAME Undefine NAME." << std::endl;
150184
std::cout << " -std=STD Specify standard." << std::endl;
151185
std::cout << " -q Quiet mode (no output)." << std::endl;
152-
std::cout << " -is Use std::istream interface." << std::endl;
186+
std::cout << " -input=INPUT Specify input type - file (default), fstream, sstream, buffer." << std::endl;
153187
std::cout << " -e Output errors only." << std::endl;
154188
std::cout << " -f Fail when errors were encountered (exitcode 1)." << std::endl;
155189
std::cout << " -l Print lines numbers." << std::endl;
@@ -189,8 +223,21 @@ int main(int argc, char **argv)
189223
simplecpp::TokenList outputTokens(files);
190224
{
191225
simplecpp::TokenList *rawtokens;
192-
if (use_istream) {
193-
rawtokens = new simplecpp::TokenList(f, files,filename,&outputList);
226+
if (toklist_inf == Fstream) {
227+
rawtokens = new simplecpp::TokenList(f,files,filename,&outputList);
228+
}
229+
else if (toklist_inf == Sstream || toklist_inf == CharBuffer) {
230+
std::ostringstream oss;
231+
oss << f.rdbuf();
232+
f.close();
233+
const std::string s = oss.str();
234+
if (toklist_inf == Sstream) {
235+
std::istringstream iss(s);
236+
rawtokens = new simplecpp::TokenList(iss,files,filename,&outputList);
237+
}
238+
else {
239+
rawtokens = new simplecpp::TokenList({s.data(),s.size()},files,filename,&outputList);
240+
}
194241
} else {
195242
f.close();
196243
rawtokens = new simplecpp::TokenList(filename,files,&outputList);

simplecpp.cpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -638,10 +638,10 @@ static bool isStringLiteralPrefix(const std::string &str)
638638
str == "R" || str == "uR" || str == "UR" || str == "LR" || str == "u8R";
639639
}
640640

641-
void simplecpp::TokenList::lineDirective(unsigned int fileIndex, unsigned int line, Location &location)
641+
void simplecpp::TokenList::lineDirective(unsigned int fileIndex_, unsigned int line, Location &location)
642642
{
643-
if (fileIndex != location.fileIndex || line >= location.line) {
644-
location.fileIndex = fileIndex;
643+
if (fileIndex_ != location.fileIndex || line >= location.line) {
644+
location.fileIndex = fileIndex_;
645645
location.line = line;
646646
return;
647647
}
@@ -1742,6 +1742,9 @@ namespace simplecpp {
17421742
return tok;
17431743
}
17441744

1745+
/**
1746+
* @throws Error thrown in case of __VA_OPT__ issues
1747+
*/
17451748
bool parseDefine(const Token *nametoken) {
17461749
nameTokDef = nametoken;
17471750
variadic = false;
@@ -2204,6 +2207,8 @@ namespace simplecpp {
22042207
}
22052208

22062209
output.push_back(newMacroToken(tok->str(), loc, true, tok));
2210+
if (it != macros.end())
2211+
output.back()->markExpandedFrom(&it->second);
22072212
return tok->next;
22082213
}
22092214

@@ -3382,6 +3387,17 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
33823387
}
33833388
output.clear();
33843389
return;
3390+
} catch (const simplecpp::Macro::Error& e) {
3391+
if (outputList) {
3392+
simplecpp::Output err{
3393+
Output::DUI_ERROR,
3394+
{},
3395+
e.what
3396+
};
3397+
outputList->emplace_back(std::move(err));
3398+
}
3399+
output.clear();
3400+
return;
33853401
}
33863402
}
33873403

@@ -3510,14 +3526,14 @@ void simplecpp::preprocess(simplecpp::TokenList &output, const simplecpp::TokenL
35103526
else
35113527
it->second = macro;
35123528
}
3513-
} catch (const std::runtime_error &) {
3529+
} catch (const std::runtime_error &err) {
35143530
if (outputList) {
3515-
simplecpp::Output err{
3531+
simplecpp::Output out{
35163532
Output::SYNTAX_ERROR,
35173533
rawtok->location,
3518-
"Failed to parse #define"
3534+
std::string("Failed to parse #define, ") + err.what()
35193535
};
3520-
outputList->emplace_back(std::move(err));
3536+
outputList->emplace_back(std::move(out));
35213537
}
35223538
output.clear();
35233539
return;

simplecpp.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ namespace simplecpp {
8383
, mSize(strlen(data))
8484
{}
8585

86-
// only provide when std::span is not available so using untyped initilization won't use View
86+
// only provide when std::span is not available so using untyped initialization won't use View
8787
#if !defined(__cpp_lib_span)
8888
View(const char* data, std::size_t size)
8989
: mData(data)
@@ -174,9 +174,9 @@ namespace simplecpp {
174174
bool isOneOf(const char ops[]) const;
175175
bool startsWithOneOf(const char c[]) const;
176176
bool endsWithOneOf(const char c[]) const;
177-
static bool isNumberLike(const std::string& str) {
178-
return std::isdigit(static_cast<unsigned char>(str[0])) ||
179-
(str.size() > 1U && (str[0] == '-' || str[0] == '+') && std::isdigit(static_cast<unsigned char>(str[1])));
177+
static bool isNumberLike(const std::string& s) {
178+
return std::isdigit(static_cast<unsigned char>(s[0])) ||
179+
(s.size() > 1U && (s[0] == '-' || s[0] == '+') && std::isdigit(static_cast<unsigned char>(s[1])));
180180
}
181181

182182
TokenString macro;
@@ -213,6 +213,9 @@ namespace simplecpp {
213213
bool isExpandedFrom(const Macro* m) const {
214214
return mExpandedFrom.find(m) != mExpandedFrom.end();
215215
}
216+
void markExpandedFrom(const Macro* m) {
217+
mExpandedFrom.insert(m);
218+
}
216219

217220
void printAll() const;
218221
void printOut() const;
@@ -376,7 +379,7 @@ namespace simplecpp {
376379
const std::string& file(const Location& loc) const;
377380

378381
private:
379-
TokenList(const unsigned char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename, OutputList *outputList, int unused);
382+
TokenList(const unsigned char* data, std::size_t size, std::vector<std::string> &filenames, const std::string &filename, OutputList *outputList, int /*unused*/);
380383

381384
void combineOperators();
382385

@@ -396,7 +399,7 @@ namespace simplecpp {
396399
void constFoldQuestionOp(Token *&tok1);
397400

398401
std::string readUntil(Stream &stream, const Location &location, char start, char end, OutputList *outputList);
399-
void lineDirective(unsigned int fileIndex, unsigned int line, Location &location);
402+
void lineDirective(unsigned int fileIndex_, unsigned int line, Location &location);
400403

401404
const Token* lastLineTok(int maxsize=1000) const;
402405
const Token* isLastLinePreprocessor(int maxsize=1000) const;

0 commit comments

Comments
 (0)