Skip to content

Commit b15065d

Browse files
committed
refactor: add explicit comparison to strcmp/stricmp results (bugprone-suspicious-string-compare)
1 parent e6c28a4 commit b15065d

File tree

38 files changed

+387
-220
lines changed

38 files changed

+387
-220
lines changed

.clang-tidy

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
# TheSuperHackers @build JohnsterID 15/09/2025 Add clang-tidy configuration for code quality analysis
2+
---
3+
# Clang-tidy configuration for GeneralsGameCode project
4+
# This configuration is tailored for a legacy C++98/C++20 hybrid codebase
5+
# with Windows-specific code and COM interfaces
6+
7+
# Enable specific checks that are appropriate for this codebase
8+
Checks: >
9+
-*,
10+
bugprone-*,
11+
-bugprone-easily-swappable-parameters,
12+
-bugprone-implicit-widening-of-multiplication-result,
13+
-bugprone-narrowing-conversions,
14+
-bugprone-signed-char-misuse,
15+
cert-*,
16+
-cert-dcl21-cpp,
17+
-cert-dcl50-cpp,
18+
-cert-dcl58-cpp,
19+
-cert-env33-c,
20+
-cert-err58-cpp,
21+
clang-analyzer-*,
22+
-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
23+
cppcoreguidelines-*,
24+
-cppcoreguidelines-avoid-c-arrays,
25+
-cppcoreguidelines-avoid-magic-numbers,
26+
-cppcoreguidelines-avoid-non-const-global-variables,
27+
-cppcoreguidelines-init-variables,
28+
-cppcoreguidelines-macro-usage,
29+
-cppcoreguidelines-no-malloc,
30+
-cppcoreguidelines-owning-memory,
31+
-cppcoreguidelines-pro-bounds-array-to-pointer-decay,
32+
-cppcoreguidelines-pro-bounds-constant-array-index,
33+
-cppcoreguidelines-pro-bounds-pointer-arithmetic,
34+
-cppcoreguidelines-pro-type-cstyle-cast,
35+
-cppcoreguidelines-pro-type-reinterpret-cast,
36+
-cppcoreguidelines-pro-type-union-access,
37+
-cppcoreguidelines-pro-type-vararg,
38+
-cppcoreguidelines-special-member-functions,
39+
google-*,
40+
-google-build-using-namespace,
41+
-google-explicit-constructor,
42+
-google-readability-casting,
43+
-google-readability-todo,
44+
-google-runtime-int,
45+
-google-runtime-references,
46+
hicpp-*,
47+
-hicpp-avoid-c-arrays,
48+
-hicpp-explicit-conversions,
49+
-hicpp-no-array-decay,
50+
-hicpp-signed-bitwise,
51+
-hicpp-special-member-functions,
52+
-hicpp-uppercase-literal-suffix,
53+
-hicpp-use-auto,
54+
-hicpp-vararg,
55+
misc-*,
56+
-misc-const-correctness,
57+
-misc-include-cleaner,
58+
-misc-non-private-member-variables-in-classes,
59+
-misc-use-anonymous-namespace,
60+
modernize-*,
61+
-modernize-avoid-c-arrays,
62+
-modernize-concat-nested-namespaces,
63+
-modernize-loop-convert,
64+
-modernize-pass-by-value,
65+
-modernize-raw-string-literal,
66+
-modernize-return-braced-init-list,
67+
-modernize-use-auto,
68+
-modernize-use-default-member-init,
69+
-modernize-use-nodiscard,
70+
-modernize-use-trailing-return-type,
71+
performance-*,
72+
-performance-avoid-endl,
73+
portability-*,
74+
readability-*,
75+
-readability-avoid-const-params-in-decls,
76+
-readability-braces-around-statements,
77+
-readability-convert-member-functions-to-static,
78+
-readability-function-cognitive-complexity,
79+
-readability-identifier-length,
80+
-readability-implicit-bool-conversion,
81+
-readability-isolate-declaration,
82+
-readability-magic-numbers,
83+
-readability-named-parameter,
84+
-readability-redundant-access-specifiers,
85+
-readability-uppercase-literal-suffix
86+
87+
# Treat warnings as errors for CI/CD
88+
WarningsAsErrors: false
89+
90+
# Header filter to include project headers
91+
HeaderFilterRegex: '(Core|Generals|GeneralsMD|Dependencies)/.*\.(h|hpp)$'
92+
93+
# Check options for specific rules
94+
CheckOptions:
95+
# Naming conventions - adapted for the existing codebase style
96+
- key: readability-identifier-naming.ClassCase
97+
value: CamelCase
98+
- key: readability-identifier-naming.StructCase
99+
value: CamelCase
100+
- key: readability-identifier-naming.FunctionCase
101+
value: CamelCase
102+
- key: readability-identifier-naming.MethodCase
103+
value: CamelCase
104+
- key: readability-identifier-naming.VariableCase
105+
value: lower_case
106+
- key: readability-identifier-naming.ParameterCase
107+
value: lower_case
108+
- key: readability-identifier-naming.MemberCase
109+
value: lower_case
110+
- key: readability-identifier-naming.MemberPrefix
111+
value: m_
112+
- key: readability-identifier-naming.ConstantCase
113+
value: UPPER_CASE
114+
- key: readability-identifier-naming.EnumConstantCase
115+
value: UPPER_CASE
116+
- key: readability-identifier-naming.MacroDefinitionCase
117+
value: UPPER_CASE
118+
119+
# Performance settings
120+
- key: performance-for-range-copy.WarnOnAllAutoCopies
121+
value: true
122+
- key: performance-unnecessary-value-param.AllowedTypes
123+
value: 'AsciiString;UnicodeString;Utf8String;Utf16String'
124+
125+
# Modernize settings - be conservative for legacy code
126+
- key: modernize-use-nullptr.NullMacros
127+
value: 'NULL'
128+
- key: modernize-replace-auto-ptr.IncludeStyle
129+
value: llvm
130+
131+
# Readability settings
132+
- key: readability-function-size.LineThreshold
133+
value: 150
134+
- key: readability-function-size.StatementThreshold
135+
value: 100
136+
- key: readability-function-size.BranchThreshold
137+
value: 25
138+
- key: readability-function-size.ParameterThreshold
139+
value: 8
140+
- key: readability-function-size.NestingThreshold
141+
value: 6
142+
143+
# Bugprone settings
144+
- key: bugprone-argument-comment.StrictMode
145+
value: false
146+
- key: bugprone-suspicious-string-compare.WarnOnImplicitComparison
147+
value: true
148+
- key: bugprone-suspicious-string-compare.WarnOnLogicalNotComparison
149+
value: true
150+
151+
# Google style settings
152+
- key: google-readability-braces-around-statements.ShortStatementLines
153+
value: 2
154+
- key: google-readability-function-size.StatementThreshold
155+
value: 100
156+
157+
# CERT settings
158+
- key: cert-dcl16-c.NewSuffixes
159+
value: 'L;LL;LU;LLU'
160+
- key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField
161+
value: false
162+
163+
# Use .clang-format for formatting suggestions
164+
FormatStyle: file
165+
166+
# Exclude certain directories and files
167+
# Note: This is handled by HeaderFilterRegex above, but can be extended

Core/GameEngine/Source/Common/System/GameMemory.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2681,7 +2681,7 @@ MemoryPool *MemoryPoolFactory::findMemoryPool(const char *poolName)
26812681
{
26822682
for (MemoryPool *pool = m_firstPoolInFactory; pool; pool = pool->getNextPoolInList())
26832683
{
2684-
if (!strcmp(poolName, pool->getPoolName()))
2684+
if (strcmp(poolName, pool->getPoolName()) == 0)
26852685
{
26862686
DEBUG_ASSERTCRASH(poolName == pool->getPoolName(), ("hmm, ptrs should probably match here"));
26872687
return pool;

Core/GameEngine/Source/GameNetwork/GameSpy/PeerDefs.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ void GameSpyInfo::addGroupRoom( GameSpyGroupRoom room )
340340
groupLabel.format("GUI:%s", room.m_name.str());
341341
room.m_translatedName = TheGameText->fetch(groupLabel);
342342
m_groupRooms[room.m_groupID] = room;
343-
if ( !stricmp("quickmatch", room.m_name.str()) )
343+
if ( stricmp("quickmatch", room.m_name.str()) == 0 )
344344
{
345345
DEBUG_LOG(("Group room %d (%s) is the QuickMatch room", room.m_groupID, room.m_name.str()));
346346
TheGameSpyConfig->setQMChannel(room.m_groupID);

Core/GameEngine/Source/GameNetwork/GameSpy/Thread/PeerThread.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ Int PeerThreadClass::findServer( SBServer server )
471471
UnsignedInt oldPrivateIP = SBServerGetPrivateInetAddress(it->second);
472472
UnsignedShort oldPrivatePort = SBServerGetPrivateQueryPort(it->second);
473473
UnsignedInt oldPublicIP = SBServerGetPublicInetAddress(it->second);
474-
if (!strcmp(oldName, newName) &&
474+
if (strcmp(oldName, newName) == 0 &&
475475
oldPrivateIP == newPrivateIP &&
476476
oldPublicIP == newPublicIP &&
477477
oldPrivatePort == newPrivatePort)
@@ -1842,7 +1842,7 @@ void PeerThreadClass::handleQMMatch(PEER peer, Int mapIndex, Int seed,
18421842
Int i=0;
18431843
for (; i<MAX_SLOTS; ++i)
18441844
{
1845-
if (playerName[i] && stricmp(playerName[i], m_loginName.c_str()))
1845+
if (playerName[i] && stricmp(playerName[i], m_loginName.c_str()) != 0)
18461846
{
18471847
peerMessagePlayer( peer, playerName[i], "We're matched!", NormalMessage );
18481848
}
@@ -2705,7 +2705,7 @@ void playerLeftCallback(PEER peer, RoomType roomType, const char * nick, const c
27052705

27062706
if (t->getQMStatus() != QM_IDLE && t->getQMStatus() != QM_STOPPED)
27072707
{
2708-
if (!stricmp(t->getQMBotName().c_str(), nick))
2708+
if (stricmp(t->getQMBotName().c_str(), nick) == 0)
27092709
{
27102710
// matchbot left - bail
27112711
PeerResponse resp;
@@ -2845,9 +2845,9 @@ static void listingGamesCallback(PEER peer, PEERBool success, const char * name,
28452845
DEBUG_LOG(("Game name is '%s'", name));
28462846
const char *newname = SBServerGetStringValue(server, "gamename", (char *)name);
28472847
#if RTS_GENERALS
2848-
if (strcmp(newname, "ccgenerals"))
2848+
if (strcmp(newname, "ccgenerals") != 0)
28492849
#elif RTS_ZEROHOUR
2850-
if (strcmp(newname, "ccgenzh"))
2850+
if (strcmp(newname, "ccgenzh") != 0)
28512851
#endif
28522852
name = newname;
28532853
DEBUG_LOG(("Game name is now '%s'", name));

Core/GameEngine/Source/GameNetwork/NAT.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,7 +1169,7 @@ void NAT::processGlobalMessage(Int slotNum, const char *options) {
11691169
++ptr;
11701170
}
11711171
DEBUG_LOG(("NAT::processGlobalMessage - got message from slot %d, message is \"%s\"", slotNum, ptr));
1172-
if (!strncmp(ptr, "PROBED", strlen("PROBED"))) {
1172+
if (strncmp(ptr, "PROBED", strlen("PROBED")) == 0) {
11731173
// format: PROBED<node number>
11741174
// a probe has been sent at us, if we are waiting because of a netgear or something, we
11751175
// should start sending our own probes.
@@ -1180,7 +1180,7 @@ void NAT::processGlobalMessage(Int slotNum, const char *options) {
11801180
} else {
11811181
DEBUG_LOG(("NAT::processGlobalMessage - probed by node %d, not our target", node));
11821182
}
1183-
} else if (!strncmp(ptr, "CONNDONE", strlen("CONNDONE"))) {
1183+
} else if (strncmp(ptr, "CONNDONE", strlen("CONNDONE")) == 0) {
11841184
// format: CONNDONE<node number>
11851185
// we should get the node number of the player who's connection is done from the options
11861186
// and mark that down as part of the connectionStates.
@@ -1205,7 +1205,7 @@ void NAT::processGlobalMessage(Int slotNum, const char *options) {
12051205
} else {
12061206
DEBUG_LOG(("NAT::processGlobalMessage - got a connection done message that isn't from this round. node: %d sending node: %d", node, sendingNode));
12071207
}
1208-
} else if (!strncmp(ptr, "CONNFAILED", strlen("CONNFAILED"))) {
1208+
} else if (strncmp(ptr, "CONNFAILED", strlen("CONNFAILED")) == 0) {
12091209
// format: CONNFAILED<node number>
12101210
// we should get the node number of the player who's connection failed from the options
12111211
// and mark that down as part of the connectionStates.
@@ -1214,7 +1214,7 @@ void NAT::processGlobalMessage(Int slotNum, const char *options) {
12141214
DEBUG_LOG(("NAT::processGlobalMessage - node %d's connection failed, setting connection state to failed", node));
12151215
setConnectionState(node, NATCONNECTIONSTATE_FAILED);
12161216
}
1217-
} else if (!strncmp(ptr, "PORT", strlen("PORT"))) {
1217+
} else if (strncmp(ptr, "PORT", strlen("PORT")) == 0) {
12181218
// format: PORT<node number> <port number> <internal IP>
12191219
// we should get the node number and the mangled port number of the client we
12201220
// are supposed to be communicating with and start probing them. No, that was not

Core/GameEngineDevice/Source/StdDevice/Common/StdLocalFileSystem.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ void StdLocalFileSystem::getFileListInDirectory(const AsciiString& currentDirect
241241
while (!done) {
242242
std::string filenameStr = iter->path().filename().string();
243243
if (!iter->is_directory() && iter->path().extension() == searchExt &&
244-
(strcmp(filenameStr.c_str(), ".") && strcmp(filenameStr.c_str(), ".."))) {
244+
(strcmp(filenameStr.c_str(), ".") != 0 && strcmp(filenameStr.c_str(), ".."))) {
245245
// if we haven't already, add this filename to the list.
246246
// a stl set should only allow one copy of each filename
247247
AsciiString newFilename = iter->path().string().c_str();
@@ -268,7 +268,7 @@ void StdLocalFileSystem::getFileListInDirectory(const AsciiString& currentDirect
268268
while (!done) {
269269
std::string filenameStr = iter->path().filename().string();
270270
if(iter->is_directory() &&
271-
(strcmp(filenameStr.c_str(), ".") && strcmp(filenameStr.c_str(), ".."))) {
271+
(strcmp(filenameStr.c_str(), ".") != 0 && strcmp(filenameStr.c_str(), ".."))) {
272272
AsciiString tempsearchstr(filenameStr.c_str());
273273

274274
// recursively add files in subdirectories if required.

Core/GameEngineDevice/Source/Win32Device/Common/Win32LocalFileSystem.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ void Win32LocalFileSystem::getFileListInDirectory(const AsciiString& currentDire
139139

140140
while (!done) {
141141
if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
142-
(strcmp(findData.cFileName, ".") && strcmp(findData.cFileName, ".."))) {
142+
(strcmp(findData.cFileName, ".") != 0 && strcmp(findData.cFileName, ".."))) {
143143
// if we haven't already, add this filename to the list.
144144
// a stl set should only allow one copy of each filename
145145
AsciiString newFilename;
@@ -165,7 +165,7 @@ void Win32LocalFileSystem::getFileListInDirectory(const AsciiString& currentDire
165165

166166
while (!done) {
167167
if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
168-
(strcmp(findData.cFileName, ".") && strcmp(findData.cFileName, ".."))) {
168+
(strcmp(findData.cFileName, ".") != 0 && strcmp(findData.cFileName, ".."))) {
169169

170170
AsciiString tempsearchstr;
171171
tempsearchstr.concat(currentDirectory);

Core/Libraries/Source/WWVegas/WWDownload/Download.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ HRESULT CDownload::DownloadFile(LPCSTR server, LPCSTR username, LPCSTR password,
4747
// If we're still connected, make sure we're on the right server
4848
if (m_Status == DOWNLOADSTATUS_FINDINGFILE)
4949
{
50-
if ((strcmp(m_Server, server)) || (strcmp(m_Login, username)))
50+
if ((strcmp(m_Server, server) != 0) || (strcmp(m_Login, username)))
5151
{
5252
// Damn, a server switch. Close conn & fix state
5353
m_Ftp->DisconnectFromServer();

Core/Libraries/Source/WWVegas/WWLib/argv.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,15 @@ const char *ArgvClass::Find_Again(const char *arg)
103103
if (Is_Exact_Size()) {
104104
// Case Sensitive, Exact Size.
105105
for (; CurrentPos < Argc; CurrentPos++) {
106-
if (!strcmp(arg, Argv[CurrentPos])) {
106+
if (strcmp(arg, Argv[CurrentPos]) == 0) {
107107
return Argv[CurrentPos];
108108
}
109109
}
110110
} else {
111111
// Case Sensitive, Match first strlen(arg).
112112
int len = strlen(arg);
113113
for (; CurrentPos < Argc; CurrentPos++) {
114-
if (!strncmp(arg, Argv[CurrentPos], len)) {
114+
if (strncmp(arg, Argv[CurrentPos], len) == 0) {
115115
return Argv[CurrentPos];
116116
}
117117
}
@@ -120,15 +120,15 @@ const char *ArgvClass::Find_Again(const char *arg)
120120
if (Is_Exact_Size()) {
121121
// Note case sensitive, Exact Size.
122122
for (; CurrentPos < Argc; CurrentPos++) {
123-
if (!stricmp(arg, Argv[CurrentPos])) {
123+
if (stricmp(arg, Argv[CurrentPos]) == 0) {
124124
return Argv[CurrentPos];
125125
}
126126
}
127127
} else {
128128
// Note case sensitive, Match first strlen(arg).
129129
int len = strlen(arg);
130130
for (; CurrentPos < Argc; CurrentPos++) {
131-
if (!strnicmp(arg, Argv[CurrentPos], len)) {
131+
if (strnicmp(arg, Argv[CurrentPos], len) == 0) {
132132
return Argv[CurrentPos];
133133
}
134134
}
@@ -201,7 +201,7 @@ int ArgvClass::Init(char *lpCmdLine, const char *fileprefix)
201201
bool was_file = false;
202202

203203
// See if we are to load a file with parameters in it.
204-
if (fp_cmp_len && !strncmp(fileprefix, ptr, fp_cmp_len)) {
204+
if (fp_cmp_len && strncmp(fileprefix, ptr, fp_cmp_len) == 0) {
205205
ptr += fp_cmp_len;
206206
if (*ptr) {
207207
was_file = Load_File(ptr);

Core/Libraries/Source/WWVegas/WWLib/cpudetect.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1113,7 +1113,7 @@ void CPUDetectClass::Init_Compact_Log()
11131113
Get_OS_Info(os_info,OSVersionPlatformId,OSVersionNumberMajor,OSVersionNumberMinor,OSVersionBuildNumber);
11141114
COMPACTLOG(("%s\t",os_info.Code));
11151115

1116-
if (!stricmp(os_info.SubCode,"UNKNOWN")) {
1116+
if (stricmp(os_info.SubCode,"UNKNOWN") == 0) {
11171117
COMPACTLOG(("%d\t",OSVersionBuildNumber&0xffff));
11181118
}
11191119
else {

0 commit comments

Comments
 (0)