diff --git a/.github/workflows/makefile.yml b/.github/workflows/makefile.yml index f604641..c2a9046 100644 --- a/.github/workflows/makefile.yml +++ b/.github/workflows/makefile.yml @@ -26,16 +26,27 @@ jobs: steps: - name: Install dependencies - run: sudo apt install -y astyle + run: sudo apt install -y astyle cppcheck catch2 - uses: actions/checkout@v4 with: submodules: recursive - - name: check_format + - name: format_check working-directory: ./ run: ./format.sh --dry + - name: cpp_check + working-directory: ./ + run: ./cpp_check.sh + + - name: unit_tests + working-directory: build/tests + run: | + cmake -S . -B build + cmake --build build + ./build/osp2_tests + - name: build-qvm working-directory: build/qvm run: | @@ -62,6 +73,7 @@ jobs: mingw: name: MinGW GCC + needs: linux runs-on: windows-2022 diff --git a/code/cgame/cg_consolecmds.c b/code/cgame/cg_consolecmds.c index 52f75d7..6e4b480 100644 --- a/code/cgame/cg_consolecmds.c +++ b/code/cgame/cg_consolecmds.c @@ -354,11 +354,14 @@ void CG_OSPServerVersion_f(void) Q_strncpyz(buf, ptr, 1024); pos = buf; - while (pos != 0) + while (*pos != 0) { pack = pos; pos = strchr(pos, ' '); - if (pos == NULL) return; + if (pos == NULL) + { + break; + } *pos = 0; CG_Printf(" ^7%s\n", pack); diff --git a/code/cgame/cg_local.h b/code/cgame/cg_local.h index a58f020..83ac840 100644 --- a/code/cgame/cg_local.h +++ b/code/cgame/cg_local.h @@ -1545,6 +1545,10 @@ const char* CG_ConfigString(int index); const char* CG_Argv(int arg); void QDECL CG_Printf(const char* msg, ...); + +#ifdef __GNUC__ +__attribute__((noreturn)) +#endif void QDECL CG_Error(const char* msg, ...); void CG_PrintLog(char* msg); diff --git a/code/cgame/cg_main.c b/code/cgame/cg_main.c index 94d734e..4336efd 100644 --- a/code/cgame/cg_main.c +++ b/code/cgame/cg_main.c @@ -714,6 +714,10 @@ cvarTable_t* CG_GetCgCvarByName(const char* name) { target = target->next; } + if (target == NULL) + { + return NULL; + } return Q_stricmp(name, target->cvarName) == 0 ? target : NULL; } @@ -870,6 +874,9 @@ void QDECL CG_Printf(const char* msg, ...) trap_Print(text); } +#ifdef __GNUC__ +__attribute__((noreturn)) +#endif void QDECL CG_Error(const char* msg, ...) { va_list argptr; @@ -881,11 +888,17 @@ void QDECL CG_Error(const char* msg, ...) CG_PrintLog(text); trap_Error(text); +#ifdef __GNUC__ + while (1) {} +#endif } #ifndef CGAME_HARD_LINKED // this is only here so the functions in q_shared.c and bg_*.c can link (FIXME) +#ifdef __GNUC__ +__attribute__((noreturn)) +#endif void QDECL Com_Error(int level, const char* error, ...) { va_list argptr; diff --git a/code/cgame/cg_osphud.c b/code/cgame/cg_osphud.c index 221fcaa..9f85acd 100644 --- a/code/cgame/cg_osphud.c +++ b/code/cgame/cg_osphud.c @@ -2717,7 +2717,8 @@ static float CG_OSPHUDDrawScores(float y) y -= fontScoresH + 8; y1 = y; - fontStatusbarH = fontStatusbarW; + CG_OSPGetClientFontSize(&cf_Statusbar, &fontStatusbarW, &fontStatusbarH); + score = cg.snap->ps.persistant[PERS_SCORE]; spectator = (cg.snap->ps.persistant[PERS_TEAM] == TEAM_SPECTATOR); diff --git a/code/cgame/cg_osputil.c b/code/cgame/cg_osputil.c index 2a99ca7..f118306 100644 --- a/code/cgame/cg_osputil.c +++ b/code/cgame/cg_osputil.c @@ -62,9 +62,9 @@ void CG_OSPNormalizeText(char* src, int size, char* dst) int CG_OSPGetNormalizedStringSize(const char* str) { int i = 0; - while (*str) + while (str && *str) { - if (str && *str == '^' && *(str + 1) != 0 && *(str + 1) != '^') + if (*str == '^' && *(str + 1) != 0 && *(str + 1) != '^') { if (*(str + 1) == 'x' || *(str + 1) == 'X') { diff --git a/code/cgame/cg_snapshot.c b/code/cgame/cg_snapshot.c index 0acaa80..6bdad62 100644 --- a/code/cgame/cg_snapshot.c +++ b/code/cgame/cg_snapshot.c @@ -166,7 +166,7 @@ static void CG_TransitionSnapshot(void) CG_ExecuteNewServerCommands(cg.nextSnap->serverCommandSequence); // clear the currentValid flag for all entities in the existing snapshot - for (i = 0 ; i < cg.snap->numEntities ; i++) + for (i = 0 ; i < cg.snap->numEntities ; ++i) { cent = &cg_entities[ cg.snap->entities[ i ].number ]; cent->currentValid = qfalse; @@ -191,7 +191,6 @@ static void CG_TransitionSnapshot(void) cg.nextSnap = NULL; // check for playerstate transition events - if (oldFrame) { playerState_t* ops, *ps; @@ -256,7 +255,7 @@ static void CG_SetNextSnap(snapshot_t* snap) // if the next frame is a teleport for the playerstate, we // can't interpolate during demos - if (cg.snap && ((snap->ps.eFlags ^ cg.snap->ps.eFlags) & EF_TELEPORT_BIT)) + if ((snap->ps.eFlags ^ cg.snap->ps.eFlags) & EF_TELEPORT_BIT) { cg.nextFrameTeleport = qtrue; } diff --git a/code/cgame/cg_superhud.c b/code/cgame/cg_superhud.c index 6f3cf5d..525e9ed 100644 --- a/code/cgame/cg_superhud.c +++ b/code/cgame/cg_superhud.c @@ -423,6 +423,11 @@ void CG_SHUDEventTeamChat(const char* message) int index; superhudGlobalContext_t* ctx = CG_SHUDGetContext(); + if (message == NULL) + { + return; + } + if (customLocationsEnabled != 0) { char* cloc_begin, *cloc_end; diff --git a/code/qcommon/q_math.c b/code/qcommon/q_math.c index 905361e..f673054 100644 --- a/code/qcommon/q_math.c +++ b/code/qcommon/q_math.c @@ -290,7 +290,7 @@ void ByteToDir(int b, vec3_t dir) unsigned ColorBytes3(float r, float g, float b) { - unsigned i; + unsigned i = 0; ((byte*)&i)[0] = r * 255; ((byte*)&i)[1] = g * 255; @@ -301,7 +301,7 @@ unsigned ColorBytes3(float r, float g, float b) unsigned ColorBytes4(float r, float g, float b, float a) { - unsigned i; + unsigned i = 0; ((byte*)&i)[0] = r * 255; ((byte*)&i)[1] = g * 255; @@ -631,6 +631,7 @@ float Q_fabs(float f) tmp &= 0x7FFFFFFF; return * (float*) &tmp; } + #endif //============================================================ diff --git a/code/qcommon/q_shared.c b/code/qcommon/q_shared.c index ece27dc..2a9029c 100644 --- a/code/qcommon/q_shared.c +++ b/code/qcommon/q_shared.c @@ -1241,8 +1241,6 @@ void Info_RemoveKey(char* s, const char* key) o = value; while (*s != '\\' && *s) { - if (!*s) - return; *o++ = *s++; } *o = 0; @@ -1299,8 +1297,6 @@ void Info_RemoveKey_Big(char* s, const char* key) o = value; while (*s != '\\' && *s) { - if (!*s) - return; *o++ = *s++; } *o = 0; diff --git a/code/qcommon/q_shared.h b/code/qcommon/q_shared.h index 23ecaa4..e3bc9e6 100644 --- a/code/qcommon/q_shared.h +++ b/code/qcommon/q_shared.h @@ -593,7 +593,7 @@ extern vec4_t colorMdGrey; extern vec4_t colorDkGrey; #define Q_COLOR_ESCAPE '^' -#define Q_IsColorString(p) ( p && *(p) == Q_COLOR_ESCAPE && *((p)+1) && *((p)+1) != Q_COLOR_ESCAPE ) +#define Q_IsColorString(p) (*(p) == Q_COLOR_ESCAPE && *((p)+1) && *((p)+1) != Q_COLOR_ESCAPE ) #define COLOR_BLACK '0' #define COLOR_RED '1' @@ -996,6 +996,9 @@ qboolean Info_Validate(const char* s); void Info_NextPair(const char** s, char* key, char* value); // this is only here so the functions in q_shared.c and bg_*.c can link +#ifdef __GNUC__ + __attribute__ ((noreturn)) +#endif void QDECL Com_Error(int level, const char* error, ...); void QDECL Com_Printf(const char* msg, ...); diff --git a/cpp_check.sh b/cpp_check.sh new file mode 100755 index 0000000..4c78620 --- /dev/null +++ b/cpp_check.sh @@ -0,0 +1,3 @@ +#!/bin/bash +RET="$(cppcheck -D__GNUC__ -q -j32 --enable=warning,performance,portability --std=c89 --suppressions-list=./cppcheck_suppress.txt --error-exitcode=1 ./code)" +exit $RET diff --git a/cppcheck_suppress.txt b/cppcheck_suppress.txt new file mode 100644 index 0000000..3341095 --- /dev/null +++ b/cppcheck_suppress.txt @@ -0,0 +1,3 @@ +invalidPointerCast +invalidTestForOverflow +floatConversionOverflow