Skip to content

Commit 45702fc

Browse files
authored
Merge pull request #42 from JCash/master
Update main branch with latest fixes
2 parents c46ae82 + 71097ec commit 45702fc

File tree

7 files changed

+241
-54
lines changed

7 files changed

+241
-54
lines changed

.github/workflows/build.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,28 @@ jobs:
2020
- name: Run Tests
2121
run: ./scripts/run_tests.sh
2222

23+
build-linux-ubsan:
24+
runs-on: ubuntu-latest
25+
steps:
26+
- uses: actions/checkout@v2
27+
- name: Install
28+
run: sudo apt-get update && sudo apt-get install -y clang
29+
- name: Build tests
30+
run: CXX=clang++ STDVERSION=c++17 ARCH=-m64 USE_UBSAN=1 ./scripts/compile.sh
31+
- name: Run Tests
32+
run: ./scripts/run_tests.sh
33+
34+
build-linux-msan:
35+
runs-on: ubuntu-latest
36+
steps:
37+
- uses: actions/checkout@v2
38+
- name: Install
39+
run: sudo apt-get update && sudo apt-get install -y clang
40+
- name: Build tests
41+
run: CXX=clang++ STDVERSION=c++17 ARCH=-m64 USE_MSAN=1 ./scripts/compile.sh
42+
- name: Run Tests
43+
run: ./scripts/run_tests.sh
44+
2345
build-macos:
2446
strategy:
2547
matrix:
@@ -33,6 +55,26 @@ jobs:
3355
- name: Run Tests
3456
run: ./scripts/run_tests.sh
3557

58+
build-linux-staticanalyze:
59+
runs-on: ubuntu-latest
60+
steps:
61+
- uses: actions/checkout@v2
62+
- name: Install
63+
run: sudo apt-get update && sudo apt-get install -y clang
64+
- name: Build tests
65+
run: CXX=clang++ STDVERSION=c++17 ARCH=-m64 USE_STATICANALYZE=1 ./scripts/compile.sh
66+
- name: Run Tests
67+
run: ./scripts/run_tests.sh
68+
69+
build-macos-staticanalyze:
70+
runs-on: macos-latest
71+
steps:
72+
- uses: actions/checkout@v2
73+
- name: Build tests
74+
run: CXX=clang++ STDVERSION=c++17 ARCH=-m64 USE_STATICANALYZE=1 ./scripts/compile.sh
75+
- name: Run Tests
76+
run: ./scripts/run_tests.sh
77+
3678
build-windows:
3779
strategy:
3880
matrix:
@@ -47,3 +89,18 @@ jobs:
4789
run: ./scripts/compile_cl.bat
4890
- name: Run Tests
4991
run: ./scripts/run_tests.bat
92+
93+
build-windows-staticanalyze:
94+
runs-on: windows-latest
95+
if: ${{ false }}
96+
steps:
97+
- uses: actions/checkout@v2
98+
- uses: ilammy/msvc-dev-cmd@v1
99+
with:
100+
arch: amd64
101+
- name: Build tests
102+
env:
103+
USE_STATICANALYZE: 1
104+
run: ./scripts/compile_cl.bat
105+
- name: Run Tests
106+
run: ./scripts/run_tests.bat

AGENTS.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# AGENTS.md
2+
3+
These instructions apply to the entire repository.
4+
5+
## Language and Design
6+
7+
* Prefer C-like C++ ("Orthodox C++"): simple types, explicit ownership, RAII, and clear invariants.
8+
* Target C++98 when possible.
9+
* Do not introduce C++11+ features unless there is a clear need. If newer features are required, guard them and keep a C++98-compatible path when practical.
10+
* Keep dependencies minimal and avoid template-heavy or meta-programming-heavy solutions.
11+
* Do not rely on exceptions (the project builds with `-fno-exceptions`).
12+
13+
## Style
14+
15+
* Follow the existing style in nearby files. Do not reformat unrelated code.
16+
* Use 4 spaces for indentation and keep whitespace changes minimal.
17+
* Keep include order consistent with existing files: system headers first, then local headers.
18+
* Prefer project-established forms such as `#if defined(...)` preprocessor guards and uppercase macro names.
19+
* Use simple, readable control flow; avoid clever constructs.
20+
21+
## Compatibility Guidelines
22+
23+
* Prefer C/C++98-friendly headers and APIs already used in this repo (`<stdio.h>`, `<string.h>`, etc.) unless there is a reason to use something else.
24+
* Avoid unguarded use of features like `nullptr`, `auto`, lambdas, `override`, variadic templates, and `static_assert`.
25+
* Keep code warning-clean under the current compile flags.
26+
27+
## Validation
28+
29+
* Build with C++98 first when touching C++ code:
30+
* `STDVERSION=c++98 scripts/compile.sh`
31+
* Run tests after changes:
32+
* `scripts/run_tests.sh`

scripts/compile.sh

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,47 @@ fi
88
#DISASSEMBLY="-S -masm=intel"
99
#PREPROCESS="-E"
1010

11+
if [ "$CXX" == "" ]; then
12+
CXX=clang++
13+
fi
14+
15+
if [ "$USE_STATICANALYZE" != "" ]; then
16+
if [ "$CXX" == "clang++" ]; then
17+
STATIC_ANALYZER_CLANG=1
18+
STATIC_ANALYZER_FLAGS="-Xanalyzer -analyzer-output=text -Xanalyzer -analyzer-werror -Xanalyzer -analyzer-disable-checker -Xanalyzer deadcode.DeadStores"
19+
echo "Using STATIC ANALYZER (clang)"
20+
else
21+
echo "USE_STATICANALYZE requires clang++ in scripts/compile.sh"
22+
exit 1
23+
fi
24+
fi
25+
1126
if [ "$USE_ASAN" != "" ]; then
1227
if [ "$CXX" != "g++" ]; then
13-
ASAN="-fsanitize=address -fno-omit-frame-pointer -fsanitize-address-use-after-scope -fsanitize=undefined"
14-
ASAN_LDFLAGS="-fsanitize=address "
28+
SANITIZER_CXXFLAGS="$SANITIZER_CXXFLAGS -fsanitize=address -fno-omit-frame-pointer -fsanitize-address-use-after-scope"
29+
SANITIZER_LDFLAGS="$SANITIZER_LDFLAGS -fsanitize=address"
1530
echo "Using ASAN"
1631
fi
1732
fi
1833

34+
if [ "$USE_UBSAN" != "" ]; then
35+
if [ "$CXX" != "g++" ]; then
36+
SANITIZER_CXXFLAGS="$SANITIZER_CXXFLAGS -fsanitize=undefined -fno-omit-frame-pointer"
37+
SANITIZER_LDFLAGS="$SANITIZER_LDFLAGS -fsanitize=undefined"
38+
echo "Using UBSAN"
39+
fi
40+
fi
41+
42+
if [ "$USE_MSAN" != "" ]; then
43+
if [ "$CXX" != "clang++" ]; then
44+
echo "MSAN requires clang++"
45+
exit 1
46+
fi
47+
SANITIZER_CXXFLAGS="$SANITIZER_CXXFLAGS -fsanitize=memory -fsanitize-memory-track-origins=2 -fno-omit-frame-pointer"
48+
SANITIZER_LDFLAGS="$SANITIZER_LDFLAGS -fsanitize=memory"
49+
echo "Using MSAN"
50+
fi
51+
1952
if [ "$OPT" == "" ]; then
2053
OPT="-O2"
2154
fi
@@ -27,9 +60,6 @@ fi
2760
echo Using -std=$STDVERSION
2861

2962

30-
if [ "$CXX" == "" ]; then
31-
CXX=clang++
32-
fi
3363
echo Using CXX=$CXX
3464
$CXX --version
3565

@@ -39,17 +69,21 @@ if [ "$ARCH" == "" ]; then
3969
fi
4070
echo Using ARCH=$ARCH
4171

42-
CXXFLAGS="$CXXFLAGS -std=$STDVERSION -g -Wall -pedantic -fno-exceptions -Werror=format -Isrc -I. $ASAN $PREPROCESS -Wno-old-style-cast"
72+
CXXFLAGS="$CXXFLAGS -std=$STDVERSION -g -Wall -pedantic -fno-exceptions -Werror=format -Isrc -I. $SANITIZER_CXXFLAGS $PREPROCESS -Wno-old-style-cast"
4373

4474
if [ "$CXX" == "clang++" ]; then
45-
CXXFLAGS="$CXXFLAGS -Weverything -Wno-global-constructors"
75+
CXXFLAGS="$CXXFLAGS -Weverything -Wno-global-constructors -Wuninitialized -Wsometimes-uninitialized -Wconditional-uninitialized"
76+
fi
77+
78+
if [ "$CXX" == "g++" ]; then
79+
CXXFLAGS="$CXXFLAGS -Wuninitialized -Wmaybe-uninitialized"
4680
fi
4781

4882
if [ "$CXX" != "c++98" ]; then
4983
CXXFLAGS="$CXXFLAGS -Wno-zero-as-null-pointer-constant -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-suggest-override"
5084
fi
5185

52-
LDFLAGS="$LDFLAGS $ASAN_LDFLAGS"
86+
LDFLAGS="$LDFLAGS $SANITIZER_LDFLAGS"
5387

5488

5589

@@ -72,16 +106,37 @@ echo "COMPILING WITH JCTEST"
72106
PREFIX=jctest
73107

74108
EXAMPLE_SOURCE_DIR=./hugo/static/code
109+
ANALYZE_INDEX=0
110+
ANALYZED_MAIN=0
111+
112+
function analyze_source {
113+
local file=$1
114+
shift
115+
local outfile=./build/analyze_${ANALYZE_INDEX}.o
116+
ANALYZE_INDEX=$((ANALYZE_INDEX + 1))
117+
echo "Analyzing ${file}"
118+
$CXX --analyze $OPT $ARCH $SYSROOT $CXXFLAGS $STATIC_ANALYZER_FLAGS $* ${file} -o ${outfile}
119+
}
75120

76121
function compile_doc_example {
77122
local file=example_${1}.cpp
123+
if [ "$STATIC_ANALYZER_CLANG" != "" ]; then
124+
analyze_source ${EXAMPLE_SOURCE_DIR}/${file}
125+
fi
78126
echo "Compiling ${file}"
79127
$CXX -o ./build/example_${1} $OPT $ARCH $SYSROOT $CXXFLAGS ${EXAMPLE_SOURCE_DIR}/${file}
80128
}
81129

82130
function compile_test {
83131
local name=$1
84132
shift
133+
if [ "$STATIC_ANALYZER_CLANG" != "" ]; then
134+
analyze_source test/test_${name}.cpp $*
135+
if [ "$ANALYZED_MAIN" == "0" ]; then
136+
analyze_source test/main.cpp
137+
ANALYZED_MAIN=1
138+
fi
139+
fi
85140
echo "Compiling test $name"
86141
$CXX -o ./build/${PREFIX}_test_${name}.o $OPT $DISASSEMBLY $ARCH $SYSROOT $CXXFLAGS $* -c test/test_${name}.cpp
87142
$CXX -o ./build/${PREFIX}_main.o $OPT $DISASSEMBLY $ARCH $SYSROOT $CXXFLAGS -c test/main.cpp
@@ -91,6 +146,9 @@ function compile_test {
91146
function compile_test_with_main {
92147
local name=$1
93148
shift
149+
if [ "$STATIC_ANALYZER_CLANG" != "" ]; then
150+
analyze_source test/test_${name}.cpp $*
151+
fi
94152
echo "Compiling test $name"
95153
$CXX -o ./build/${PREFIX}_test_${name}.o $OPT $DISASSEMBLY $ARCH $SYSROOT $CXXFLAGS $* -c test/test_${name}.cpp
96154
$CXX -o ./build/${PREFIX}_${name} $OPT $ARCH ./build/${PREFIX}_test_${name}.o $LDFLAGS

scripts/compile_cl.bat

Lines changed: 41 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,41 @@
1-
rem echo off
2-
3-
call python3 --version 2>NUL
4-
if '%errorlevel%'=='1' goto errorNoPython
5-
set TIMEIT=python %~dp0\timeit.py
6-
goto hasPython
7-
:errorNoPython
8-
echo "No python found!"
9-
goto end
10-
11-
set TIMEIT
12-
:hasPython
13-
14-
mkdir build
15-
16-
set FLAGS=/Od /Zi /D_CRT_SECURE_NO_WARNINGS /nologo /D_HAS_EXCEPTIONS=0 /EHsc /W4 /wd4611 /Isrc
17-
18-
call %TIMEIT% cl.exe %FLAGS% test\test_params.cpp test\main.cpp /link /out:.\build\test_params.exe
19-
call %TIMEIT% cl.exe %FLAGS% test\test_typed_test.cpp test\main.cpp /link /out:.\build\test_typed_test.exe
20-
call %TIMEIT% cl.exe %FLAGS% test\test_expect.cpp test\main.cpp /link /out:.\build\test_expect.exe
21-
call %TIMEIT% cl.exe %FLAGS% test\test_death.cpp test\main.cpp /link /out:.\build\test_death.exe
22-
call %TIMEIT% cl.exe %FLAGS% test\test_empty.cpp test\main.cpp /link /out:.\build\test_empty.exe
23-
call %TIMEIT% cl.exe %FLAGS% test\test_array.cpp test\main.cpp /link /out:.\build\test_array.exe
24-
call %TIMEIT% cl.exe %FLAGS% test\test_color_off.cpp /link /out:.\build\test_color_off.exe
25-
call %TIMEIT% cl.exe %FLAGS% test\test_color_on.cpp /link /out:.\build\test_color_on.exe
26-
27-
del *.obj
28-
29-
:end
1+
@echo off
2+
3+
call python3 --version 2>NUL
4+
if '%errorlevel%'=='1' goto errorNoPython
5+
set TIMEIT=python3 %~dp0\timeit.py
6+
goto hasPython
7+
:errorNoPython
8+
echo "No python found!"
9+
exit /b 1
10+
11+
set TIMEIT
12+
:hasPython
13+
14+
if not exist build mkdir build
15+
16+
set FLAGS=/Od /Zi /D_CRT_SECURE_NO_WARNINGS /nologo /D_HAS_EXCEPTIONS=0 /EHsc /W4 /wd4611 /Isrc
17+
if not "%USE_STATICANALYZE%"=="" (
18+
set FLAGS=%FLAGS% /analyze /WX
19+
echo Using STATIC ANALYZER (msvc)
20+
)
21+
22+
call %TIMEIT% cl.exe %FLAGS% test\test_params.cpp test\main.cpp /link /out:.\build\test_params.exe
23+
if errorlevel 1 exit /b %errorlevel%
24+
call %TIMEIT% cl.exe %FLAGS% test\test_typed_test.cpp test\main.cpp /link /out:.\build\test_typed_test.exe
25+
if errorlevel 1 exit /b %errorlevel%
26+
call %TIMEIT% cl.exe %FLAGS% test\test_expect.cpp test\main.cpp /link /out:.\build\test_expect.exe
27+
if errorlevel 1 exit /b %errorlevel%
28+
call %TIMEIT% cl.exe %FLAGS% test\test_death.cpp test\main.cpp /link /out:.\build\test_death.exe
29+
if errorlevel 1 exit /b %errorlevel%
30+
call %TIMEIT% cl.exe %FLAGS% test\test_empty.cpp test\main.cpp /link /out:.\build\test_empty.exe
31+
if errorlevel 1 exit /b %errorlevel%
32+
call %TIMEIT% cl.exe %FLAGS% test\test_array.cpp test\main.cpp /link /out:.\build\test_array.exe
33+
if errorlevel 1 exit /b %errorlevel%
34+
call %TIMEIT% cl.exe %FLAGS% test\test_color_off.cpp /link /out:.\build\test_color_off.exe
35+
if errorlevel 1 exit /b %errorlevel%
36+
call %TIMEIT% cl.exe %FLAGS% test\test_color_on.cpp /link /out:.\build\test_color_on.exe
37+
if errorlevel 1 exit /b %errorlevel%
38+
39+
del *.obj
40+
41+
exit /b 0

scripts/run_tests.bat

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
1-
echo off
2-
3-
.\build\test_params.exe
4-
.\build\test_typed_test.exe
5-
.\build\test_expect.exe
6-
.\build\test_death.exe
7-
.\build\test_empty.exe
8-
.\build\test_array.exe
9-
.\build\test_doctest.exe
10-
.\build\test_color_off.exe
11-
.\build\test_color_on.exe
1+
@echo off
2+
3+
call :run_test .\build\test_params.exe
4+
call :run_test .\build\test_typed_test.exe
5+
call :run_test .\build\test_expect.exe
6+
call :run_test .\build\test_death.exe
7+
call :run_test .\build\test_empty.exe
8+
call :run_test .\build\test_array.exe
9+
call :run_test .\build\test_color_off.exe
10+
call :run_test .\build\test_color_on.exe
11+
exit /b 0
12+
13+
:run_test
14+
if not exist "%~1" (
15+
echo Missing test executable: %~1
16+
exit /b 1
17+
)
18+
call "%~1"
19+
if errorlevel 1 exit /b %errorlevel%
20+
exit /b 0

scripts/timeit.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@
66
p.wait()
77
tend = time.time()
88
print("%s took %f ms" % (sys.argv[1], (tend-tstart)*1000.0))
9+
sys.exit(p.returncode)

0 commit comments

Comments
 (0)