From f3e286e787da2a2f348e8952e39be287e56f84e9 Mon Sep 17 00:00:00 2001 From: Greg Gauthier Date: Mon, 26 Jan 2026 20:55:11 +0000 Subject: [PATCH] pruned clang-tidy, added splint and cppcheck --- .clang-tidy | 24 +++++++----------------- Makefile | 25 ++++++++++++++++++++++++- build.sh | 2 +- game.o | Bin 0 -> 3328 bytes include/words.h | 2 +- main.o | Bin 0 -> 9624 bytes src/main.c | 4 ++-- src/ui.c | 7 ++++--- src/words.c | 5 ++--- ui.o | Bin 0 -> 6192 bytes words.o | Bin 0 -> 4248 bytes 11 files changed, 41 insertions(+), 28 deletions(-) create mode 100644 game.o create mode 100644 main.o create mode 100644 ui.o create mode 100644 words.o diff --git a/.clang-tidy b/.clang-tidy index ed0a13a..760391e 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,25 +1,15 @@ Checks: > -*, clang-diagnostic-*, - clang-analyzer-*, - readability-*, - -readability-identifier-length, - -readability-magic-numbers, - -readability-function-cognitive-complexity, - bugprone-*, - -bugprone-easily-swappable-parameters, - misc-*, - -misc-unused-parameters, - portability-* + bugprone-macro-parentheses, + bugprone-suspicious-string-compare, + bugprone-sizeof-expression, + bugprone-signed-char-misuse, + cert-dcl37-c, + readability-misleading-indentation WarningsAsErrors: '' HeaderFilterRegex: '.*' -CheckOptions: - - key: readability-function-size.LineThreshold - value: '100' - - key: readability-function-size.StatementThreshold - value: '50' - -FormatStyle: none \ No newline at end of file +FormatStyle: none diff --git a/Makefile b/Makefile index b611062..350b23b 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ # Compiler and flags CC = gcc -CFLAGS = -std=c90 -pedantic -Wpedantic -Wall -Wextra +CFLAGS = -std=c90 -pedantic -Wpedantic -Wall -Wextra -Wstrict-prototypes -Wold-style-definition # Platform detection ifdef COMSPEC @@ -95,3 +95,26 @@ help: @echo " - GNU Make" .PHONY: all clean install uninstall rebuild wordlists help + +# Static analysis targets +analyze: cppcheck + +# Relaxed splint (too noisy with +standard) +splint: + @echo "Running splint with relaxed checks..." + @splint -weak +posixlib -I./include src/*.c 2>&1 | grep -v "Definition of" || true + +# Strict splint (very verbose, use with caution) +splint-strict: + splint +standard -I./include src/*.c + +cppcheck: + @echo "Running cppcheck..." + @cppcheck --std=c90 --enable=warning,style,performance,portability \ + --suppress=missingIncludeSystem --quiet -I./include src/ + +strict-compile: + gcc -std=c90 -pedantic -Wpedantic -Wall -Wextra \ + -Wstrict-prototypes -Wold-style-definition \ + -Wmissing-prototypes -Wdeclaration-after-statement \ + -Iinclude -c src/*.c diff --git a/build.sh b/build.sh index a11a5f9..e1324fa 100755 --- a/build.sh +++ b/build.sh @@ -4,7 +4,7 @@ mkdir -p build/cordle echo "Building application." -gcc -v -std=c90 -pedantic -Wpedantic -o build/cordle/cordle src/*.c -Iinclude -lncurses > build/cordle-build.log 2>&1 +gcc -std=c90 -pedantic -Wpedantic -Wall -Wextra -Wstrict-prototypes -Wold-style-definition export RESULT=$? if (( RESULT == 0 )); then diff --git a/game.o b/game.o new file mode 100644 index 0000000000000000000000000000000000000000..0ab6ff64bb76856169504c250a67dc455b188b0f GIT binary patch literal 3328 zcmb_eUuauZ7(X{nwpzQTN*^XGH6WFZxl2=+%8*g*t~<^tRSdqkrD<~e$2M(AZnRYv zJ3_?EHRIyT_Ts}taNtWp8N~;U6`BZT1RtCaB6|^16L9NOgkt=@bI-XwyS<%5{NVPS z^ZUNv_kHI(-#O_A+PN14ib8}aX5^LJ`qtW!&?SC+^A zaIA2(zMR69qv&kNif&vvie5=kSw3{ns*kTKS_|2YKBQQ&7ES&{FRfKi5>g4;s3~YI zrEszJSpGL*nxxh%bxQ-&8Z~QFDO1JyTcx45A+2@bYTL}K>X>fRVw8tWq<#Le1Fq6t#i_M}S04traa#g#Rpu zk7~7va9+C&`&gwV8|y<$T9cYTQ?pXXY^W7m0ccBtDq0majVCOvO0R}*oDOY;ZpKcut=d53>O~31M1{IbEvo`#ERtV-`X<+wYSzAH7(CRRr`PaQ+H5xqyZ39kVBN)CM zYq#4C#r8{rZ7g^8{w^VKv78&YzY#P)7G4}>`103(x7#+LuF!|lZp=8@GcMa}&&B@`W zyH_`AX;eX-X|ohCQ}=$#ml2ZgM?2@K!ty&Se5!EOIEHIyBT&aYK3TrTU`tjVehkm6 zm%SD4d66?CBPSzA&b%5s8i}4zhtz0fXmIF6G#VX3CSjL20%Hh1up$AXl<{JtOB98# z#k1Y(z(jfPb)qcxD2KcEcVheW0gfL^2+7YM?D;S-a$sKvQNV=ho?}`f2yih0?_Q2nl@O_f~HC_kwvtPn*N;vkM@PAjr<+umY0SFGV|EDFq3v|LyUczNR z-$*!4g?&T9AC~afkPL!qIsXWPAlTyg2^r=Sfr~yH^WdUCh?-qW8;Nlkjf^u+iCIRU zO{j*xXb?4(FcL%^ha*;#^Xarc2iV-ap{sD0kF!JO>&dyCx{#TN(>Iog$~@>(@rev} z%Ksq|aDqpTXCTWkU%bidC3L(k#F89_8P;;xMVv_;iwhFr1UyTe;yp$=Bwqe`(D|KTC;#D~oQvm&T)`LT=NB6(W4xgvyij-t l@r=BD4C6gJfXFiM9~~Exh`I~t5t#V#M|u9U!jO+%{y*My?7aX0 literal 0 HcmV?d00001 diff --git a/include/words.h b/include/words.h index f84dc2f..b36d995 100644 --- a/include/words.h +++ b/include/words.h @@ -5,7 +5,7 @@ #include "game.h" int load_words(GameState* game, const char* filename); -int is_valid_word(GameState* game, const char* word); +int is_valid_word(const GameState* game, const char* word); void to_upper(char* str); #endif /* WORDS_H */ diff --git a/main.o b/main.o new file mode 100644 index 0000000000000000000000000000000000000000..5c8fed2c5b87e1417bf0c0d868340595910ba542 GIT binary patch literal 9624 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 literal 0 HcmV?d00001 diff --git a/src/main.c b/src/main.c index 0e0529c..55697b5 100644 --- a/src/main.c +++ b/src/main.c @@ -15,7 +15,7 @@ #include "../include/ui.h" /* Parse command line arguments */ -void parse_arguments(int argc, char *argv[], char *filename, char *difficulty) { +static void parse_arguments(int argc, char **argv, char *filename, char *difficulty) { int i; /* Default values */ @@ -53,7 +53,7 @@ void parse_arguments(int argc, char *argv[], char *filename, char *difficulty) { } /* Main game loop */ -int main_game_loop(int argc, char *argv[]) { +static int main_game_loop(int argc, char *argv[]) { WINDOW *stdscr; GameState game; char filename[MAX_FILENAME]; diff --git a/src/ui.c b/src/ui.c index 34e9109..4a3acf1 100644 --- a/src/ui.c +++ b/src/ui.c @@ -31,14 +31,14 @@ void draw_title(WINDOW *win, int y, const char *difficulty) { /* Draw the game board */ void draw_board(WINDOW *win, GameState *game, int y) { int width, board_x; - int row, col, x_pos, y_pos; + int row, col, x_pos; char cell[4]; width = getmaxx(win); board_x = (width - (WORD_LENGTH * 4 - 1)) / 2; for (row = 0; row < MAX_GUESSES; row++) { - y_pos = y + row * 2; + int y_pos = y + row * 2; if (row < game->guess_count) { /* Draw a completed guess */ @@ -77,7 +77,7 @@ void draw_board(WINDOW *win, GameState *game, int y) { /* Draw visual keyboard */ void draw_keyboard(WINDOW *win, GameState *game, int y) { int width; - int row_idx, x, y_pos, i; + int row_idx, i; const char *row; char letter; int status, color; @@ -85,6 +85,7 @@ void draw_keyboard(WINDOW *win, GameState *game, int y) { width = getmaxx(win); for (row_idx = 0; row_idx < 3; row_idx++) { + int x, y_pos; row = keyboard_rows[row_idx]; x = (width - strlen(row) * 2 + 1) / 2; y_pos = y + row_idx; diff --git a/src/words.c b/src/words.c index e9284e5..21df5e8 100644 --- a/src/words.c +++ b/src/words.c @@ -56,7 +56,6 @@ int load_words(GameState *game, const char *filename) { FILE *file; char line[32]; char word[WORD_LENGTH + 1]; - int len; /* Try to open the file */ file = open_wordlist(filename); @@ -67,7 +66,7 @@ int load_words(GameState *game, const char *filename) { game->word_count = 0; while (fgets(line, sizeof(line), file) && game->word_count < MAX_WORDS) { /* Remove newline and whitespace */ - len = strlen(line); + int len = strlen(line); while (len > 0 && (line[len - 1] == '\n' || line[len - 1] == '\r' || line[len - 1] == ' ')) { line[--len] = '\0'; } @@ -94,7 +93,7 @@ int load_words(GameState *game, const char *filename) { } /* Check if word exists in a word list */ -int is_valid_word(GameState *game, const char *word) { +int is_valid_word(const GameState *game, const char *word) { int i; char upper_word[WORD_LENGTH + 1]; diff --git a/ui.o b/ui.o new file mode 100644 index 0000000000000000000000000000000000000000..74fc151dbe1cca2fd5de115d7eafdacfc1797b23 GIT binary patch literal 6192 zcmcIoeQXrR6`wuZ;3N*`fLozZwcA!yMu8JXf(ExlhGX%TV&fRD=0nsupBMXz?X&jw ziXF)%=y1Ynd({0S5~`|-R;iRfh-9fMK~-uDA+js1%85{QN-g#N0M*2nN>y4R^}~I? z*_pfX`i%Pdq}_S*oA=(l_vX#pv(Fia4umv~Nz&L$tTdA-W83RWd=qDzSS<^)nCad> zVxC_#Ny&77IsK2NCHLpI>211iUZ z2QtrLZxnV2<5PDuPcx6d%|yPa}nI z_q18pSR~a+@3ra$#&#QX;oKHFgDIoHh1U`98HHTkD5m5d6dsyhW|B}dF-?Zd#4OUL zO`4kjerRgbX4SVoVJv)&g(qfvkCXhWfSSI$Ns*w zgd6cVcq9DVaD=YIF}e=d={k(Nv8yCWtgQdJDPx9`%^uv~1w3P3Hgk0!05Nk_eDEqm z=q0@F@}xX3l~KulGsx}J&<%{d7rW{iGbsH+c4S7&tjQXAZQ*I+LzznAE2fND7=5sl z?>37o0gKu!-GGb6o$!QlC)aj^uyHf-k$L{sG%xHimoDkZy$Yue?{iz|tvS!rJLEjG zuxZM;OE;A*JWosonCFP81XE4S8e+z>BX`$ij+5Ez{9;g-s#Oj?@3j=Lw)}3a4^PDI zaQHXHh|3ySNO;EG;??taD4FtN|FZcfnW5x`vc|0D8OxJ)fo{&v=#FJ6?MQR@(wAvA zM)e@OA zA(t<5KOw=`xv5-D$cvR}pj*pZs|mrmVC1;6B>xqo5dQ87y4doR$TjwIhtYoYc}Vd+w`NomLA=`UGGTQ-F=qc9PhXElbh40 z*vZWadQpGl)SR)>Y26{=o!j~>$FXevENSS;0ezS5*hwq>c`g@C^`-1|qu$(Z7_EDv zDciOZ&Q|@nap=(Djy)ZAYM@6SOr?`fGBvPOZ#VYuX-zq>0&DE(@Svsp=E=t1Z6}y9 zKwCBHM>1XgNk{L27i?cVaV9+&Pgsrmev71~3X3{+-wRPaW$VU~Xrume1}YSgAHx6l z-5jMI>zi9+Tl9vVksXl+eaH44I~y7rcJO`CKXiJ~14)R5m^KNF`W7cGFqc2qv{&1i zHdL!^s##k-M#4Htf5ul~I+XXWt9?BbeRhqRt*F?bk(9sQBxKg1gGrf+rz#+z6Z8r_ zoY3mzx5uVjB*TCqStMKLSO zS1Wk-mSdPzFf`@m1VmHtjba&j1+I&ElNi59<9cOZ9S#yj=&9x0^4G3a@RwG>jaBg0 zRq&&$;JA+E{OMT*A0ixa$#{4@5SA5q1Vso!9T0t=o^tjt6An8Ok!oHOg#A?D_XW=D zfH16=v%@mUNP?ZQhPzU6ySvj)olUdkK-#f03ABWCWIOA&<7Ydaq|;}y^q`#_a89!x z%ju5~4Kb4Ivj*7NxZ~KJDPsCl-?nJl-3=2GKYf~YcBUQb5}k?OGo7d7$v)pG-_vKM z2V6PP>x2E&UE)2KKT*9B4h+)|b&3mwbm3~ryVwSh24U!^OAkzn~J>Z{~HRf`gvs) zJJ%I?)qnU1!gUp;$LF{sAc-SKAlb7ej@Uptf0yKCzpD@6j+k!`;P?)KUi63JzEZv^ zfL{}HGk{Nvx!hm+$^XSdYsUiee-?9HjL1J8N&5vOaUBMUy8VI6VoiQ0F9vZ@A6Emo z{2sDMdbr<-chTtB{@5!y+vp=U#=mo7-ZPMi4BDwd%XWsz5X@V>ou}>p;ZI*dl7ingn-O z)S+Au>6BBpi8$PurXu1qgD6^}aV!#H3f*cE&LSMze2W5K*Lx}|Q_qNav`X&8`Ezmi7 zU^A$n7y8o>QYfhZDy@~vU;PGOX-McIf9Q!)U*@me-cY%M=1o*99K*K)aR&9_X0Y}M eV&iD?L^u4Q_zvdpIa(>Fe?|E37Bzh)sQ*tmtmVo8 literal 0 HcmV?d00001 diff --git a/words.o b/words.o new file mode 100644 index 0000000000000000000000000000000000000000..494348da471b3ab1de7250d38fbab980065171b0 GIT binary patch literal 4248 zcmcguU2IfE6h615AV|BFfHnc+`hZ~2-EK`aD3}Uf7!pM!X^?2#F5A0wW&g7GE>c1T zvsSsTi+#`p<4dD2`(lDG4QSCt5{f+N`V(#93p^N$?SuNDHL28d=FaTSPP;r9;xuz- z<~!dx^Uax`?Q!#|9ZiM-vKa6<)J75o=xD9=dw918+MpGBnfo()b*8fkfVt-<|Cyif zXN4u}HzI|(=4`0U3LIrc9)K0skTWZGd(H4~=&{S4W$wgTLZ&=ekhqn(KcLk!xWiYG z&+_M~0cRyEaNzo#DEWVx=p)p}iY;7aP1KYpiW+cYnvlY~+ zNRqtNutM)_KijmL?}*dF)A;2@zH9jzKXZqsCd@fn&UC0?&ar5P70fASRD5IL8!L+? zx)VcTSAspwY40hT#hS-)B z&QJ9~t8=9u@H^+wu_b4*Vs8a!xT0o}55=)7n56>OL-}zl%qU}q=v(M5G2;u*^%8S` z^iFA&Ufg3~I!o>dtp&+tTE=I7T8}(D!)0d;alH6jeH#FLr`qOmM+=x4$*K~D%eiGd zQPcZA$1vV~5iBuzZ>jJm&G+74f4kqfmm5gNh^(cbWYw5jZPLrI+U613TzIra%pz~VX~ z2rs9z{fW5k*s$KFKgiPD!JM59CeqPJB4`gpvQ{ukG%HwRvuB<*0eymjo6&eg*tvcC zqyCLMclX}!4|NB+0wI4_XIFP96zZb6s4T(i$4XBH@}LQfGGVkRDuy;*?ZIFi-3!K% zc4O_zWw(tWc^%?Zsf>~H6K(CUH*IfS+WfJB6mHwXtpG1lEA37D$;|C92>W++{$Ex7 zj|qFJ&i_O1FH8#>3bh1&pI=}=pt-urdTTS!Mm@G1hnSlx$k&LYyRf!b(OT!82Kf30 z_yY~_t%$F}dF6aOcZlt1z~3$StMP}93eP3B`>`&jv#$YuumPTIfIAKF!3Oxz2KaHr zX}!NRV+RZ0Yix^H7t_zLksXLaI%B26@|J*|$;MMo3}OVsLCdjHhanucok;XhI681B z9E-#g;H1O3OvcJ$$7>VmNIwr^gY9G!=!#7=GYByZVM8pMNZS@T@uUTIHj?UxxE($m zNyI%TPEKY>Hf-WwIx}?60Os(iq#`e##BX@;{AP`hSAv&4qNO`YcT~pNCvX|ZC&qEn z5`QUH$$v-Sk}vW1HC*2B4>VlrIVW&kPg&zjJ>M#PRnMOq|6wt{q41YsU+TPDTs>X? zCJmQw%r=4RI(KP&sq=Y-uj)M3fPbn1|BQlD&ZPcp3cfcy2diN?gomr{VRd6-FpMqnd^obPmaS#92aQV*mX}Ek(PiVM&ryyVtCY{Iu zY@Mvv4#-~CN<;#Vb;N-{f5eGE;DBvIAe;6E(R4CtrO=j2J5~UHgCFFtlo%gOzok}#)#PO z+Yu&T0Yiu2-zRWE6DYvf+Pu=B&riRb6!X9OhtQW|s%HX+P!aR%S(f^VLxtXL^6#X9 zQo8A}#@KOcaJbC Udj9AwTg-n{=y$kR?W6nu3vH*HaR2}S literal 0 HcmV?d00001