From: Joel Rosdahl Date: Wed, 24 Jul 2019 11:18:17 +0000 (+0200) Subject: C++-ify source code X-Git-Tag: v4.0~852 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=68e42bd71650d003cb8f01d6572020015ecc2e58;p=thirdparty%2Fccache.git C++-ify source code The ccache source code will be converted to C++, targeting C++11. This commit only arranges the existing C-style code to be built as C++ code. This makes it possible to call new C++ code from old C-style code. Gradual conversion to C++ functionality and idioms will follow in a slow and controlled fashion – no big bang rewrites. The alternative would be to convert code in a top-down fashion, i.e. only calling legacy C code from new C++ code, not the other way around. That approach is however not a good idea since the code that will benefit most from being written in proper C++ is code deep down in the call chains. Except for renaming source code files to .cpp and .hpp, this commit makes minimal changes to make the code base buildable again, for example: - Instructs configure.ac to look for a mandatory C++11-compliant compiler. - Adds Makefile rules for building C++ code. - Sets up Travis-CI to pass C++ compiler flags and similar to the build. - Adds new casts where needed. - Adds const keywords where needed. - Renames variables to something else than C++ keywords (e.g. “template”). - Rearranges some code to avoid complaints about goto jumps that cross variable lifetimes. --- diff --git a/.editorconfig b/.editorconfig index 1164b5c1a..da20c97f7 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,7 +5,7 @@ end_of_line = lf insert_final_newline = true charset = utf-8 -[*.{c,h}] +[*.{c,cpp,h,hpp}] indent_style = tab indent_size = 2 diff --git a/.gitignore b/.gitignore index 4ed7b4ace..4e2e6b7dc 100644 --- a/.gitignore +++ b/.gitignore @@ -21,8 +21,8 @@ dev.mk dev_mode_disabled doc/ccache.1 perfdir.* -src/*_lookup.c -src/version.c +src/*_lookup.cpp +src/version.cpp testdir.* unittest/run -unittest/suites.h +unittest/suites.hpp diff --git a/.travis.sh b/.travis.sh index f01b2bc43..c6291538b 100755 --- a/.travis.sh +++ b/.travis.sh @@ -1,10 +1,10 @@ #!/bin/sh -ex make clean -make travis CC=gcc -make travis CC=clang -make travis CC=gcc CFLAGS="-m32 -g -O2" LDFLAGS="-m32" CONFIGURE="--host=i386-linux-gnu --with-libzstd-from-internet --with-libb2-from-internet" +make travis CC=gcc CXX=g++ +make travis CC=clang CXX=clang++ +make travis CC=gcc CFLAGS="-m32 -g -O2" CXX=g++ CXXFLAGS="-m32 -g -O2" LDFLAGS="-m32" CONFIGURE="--host=i386-linux-gnu --with-libzstd-from-internet --with-libb2-from-internet" make travis CC=i686-w64-mingw32-gcc CONFIGURE="--host=i686-w64-mingw32 --with-libzstd-from-internet --with-libb2-from-internet" TEST="unittest/run.exe" -make travis CC=clang CFLAGS="-fsanitize=undefined" LDFLAGS="-fsanitize=undefined" ASAN_OPTIONS="detect_leaks=0" -make travis CC=clang CFLAGS="-fsanitize=address -g" LDFLAGS="-fsanitize=address" ASAN_OPTIONS="detect_leaks=0" -make travis CC=/usr/bin/clang TEST=analyze +make travis CC=clang CXX=clang++ CFLAGS="-fsanitize=undefined" LDFLAGS="-fsanitize=undefined" ASAN_OPTIONS="detect_leaks=0" +make travis CC=clang CXX=clang++ CFLAGS="-fsanitize=address -g" LDFLAGS="-fsanitize=address" ASAN_OPTIONS="detect_leaks=0" +make travis CC=/usr/bin/clang CXX=/usr/bin/clang++ TEST=analyze diff --git a/.travis.yml b/.travis.yml index 7864768ab..cbbf0c194 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -language: c +language: cpp dist: xenial script: @@ -42,17 +42,18 @@ matrix: # Job 4: Linux 32-bit native - os: linux compiler: gcc - env: V=1 CFLAGS="-m32 -g -O2" LDFLAGS="-m32" CONFIGURE="--host=i386-linux-gnu --with-libzstd-from-internet --with-libb2-from-internet" ENABLE_CACHE_CLEANUP_TESTS=1 + env: V=1 CFLAGS="-m32 -g -O2" CXXFLAGS="-m32 -g -O2" LDFLAGS="-m32" CONFIGURE="--host=i386-linux-gnu --with-libzstd-from-internet --with-libb2-from-internet" ENABLE_CACHE_CLEANUP_TESTS=1 addons: apt: packages: - gcc-multilib - gperf + - lib32stdc++-5-dev # Job 5: Linux cross-compiled 32-bit MinGW - os: linux - compiler: i686-w64-mingw32-gcc - env: V=1 CONFIGURE="--host=i686-w64-mingw32 --with-libzstd-from-internet --with-libb2-from-internet" TEST="unittest/run.exe" ENABLE_CACHE_CLEANUP_TESTS=1 + compiler: i686-w64-mingw32-g++ + env: V=1 CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++ CONFIGURE="--host=i686-w64-mingw32 --with-libzstd-from-internet --with-libb2-from-internet" TEST="unittest/run.exe" ENABLE_CACHE_CLEANUP_TESTS=1 addons: apt: packages: @@ -61,8 +62,8 @@ matrix: # Job 6: Linux cross-compiled 64-bit MinGW - os: linux - compiler: x86_64-w64-mingw32-gcc - env: V=1 CONFIGURE="--host=x86_64-w64-mingw32 --with-libzstd-from-internet --with-libb2-from-internet" TEST="unittest/run.exe" ENABLE_CACHE_CLEANUP_TESTS=1 + compiler: x86_64-w64-mingw32-g++ + env: V=1 CC=i686-w64-mingw32-gcc CXX=i686-w64-mingw32-g++ CONFIGURE="--host=x86_64-w64-mingw32 --with-libzstd-from-internet --with-libb2-from-internet" TEST="unittest/run.exe" ENABLE_CACHE_CLEANUP_TESTS=1 addons: apt: packages: @@ -72,7 +73,7 @@ matrix: # Job 7: Clang's undefined behavior sanitizer (UBSan) - os: linux compiler: clang - env: V=1 CFLAGS="-fsanitize=undefined" LDFLAGS="-fsanitize=undefined" ASAN_OPTIONS="detect_leaks=0" ENABLE_CACHE_CLEANUP_TESTS=1 + env: V=1 CFLAGS="-fsanitize=undefined" CXXFLAGS="-fsanitize=undefined" LDFLAGS="-fsanitize=undefined" ASAN_OPTIONS="detect_leaks=0" ENABLE_CACHE_CLEANUP_TESTS=1 addons: apt: packages: @@ -84,7 +85,7 @@ matrix: # Job 8: Clang's address sanitizer - os: linux compiler: clang - env: V=1 CFLAGS="-fsanitize=address -g" LDFLAGS="-fsanitize=address" ASAN_OPTIONS="detect_leaks=0" ENABLE_CACHE_CLEANUP_TESTS=1 + env: V=1 CFLAGS="-fsanitize=address -g" CXXFLAGS="-fsanitize=address -g" LDFLAGS="-fsanitize=address" ASAN_OPTIONS="detect_leaks=0" ENABLE_CACHE_CLEANUP_TESTS=1 addons: apt: packages: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 74ba58760..27bbc93b5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -34,10 +34,10 @@ proposal(s) on [GitHub](https://github.com/ccache/ccache). Here are some hints to make the process smoother: * If you plan to implement major changes it is wise to open an issue on GitHub - (or send a mail to the mailing list) asking for comments on your plans before - doing the bulk of the work. That way you can avoid potentially wasting time - on doing something that may need major rework to be accepted, or maybe - doesn'tend up being accepted at all. + (or ask in the Gitter room, or send a mail to the mailing list) asking for + comments on your plans before doing the bulk of the work. That way you can + avoid potentially wasting time on doing something that may need major rework + to be accepted, or maybe doesn't end up being accepted at all. * Is your pull request "work in progress", i.e. you don't think that it's ready for merging yet but you want early comments? Then create a draft pull request as described in [this Github blog @@ -48,41 +48,35 @@ Here are some hints to make the process smoother: Messages](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) when writing commit messages. -### Code style +## Code style -#### Formatting +ccache was written in C99 until 2019 when it started being converted to C++11. +The conversion is a slow work in progress, which is why there are lots of +C-style code left. Please refrain from doing large C to C++ conversions at +once; do it little by little. -* Use tabs for indenting and spaces for aligning C code. -* Use 4 spaces for indenting other code (and spaces for aligning). -* Put the opening curly brace on a new line when defining a function, otherwise - at the end of the same line. -* Put no space between function name and the following parenthesis. -* Put one space between if/switch/for/while/do and opening curly brace. -* Always use curly braces around if/for/while/do bodies, even if they only - contain one statement. +Tip: Install the tool [Uncrustify(http://uncrustify.sourceforge.net) and then +run `make uncrustify` to fix up source code formatting. + +### New code + +* Use tabs for indenting and spaces for aligning. * If possible, keep lines at most 80 character wide for a 2 character tab width. -* Use only lowercase names for functions and variables. -* Use only uppercase names for enum items and (with some exceptions) macros. -* Don't use typedefs for structs and enums. -* Use //-style comments. +* Put the opening curly brace on a new line when defining a class, struct or + function, otherwise at the end of the same line. +* Use UpperCamelCase for classes, structs, functions, methods, members and + global variables. +* Use lowerCamelCase for parameters, arguments and local variables. +* Use UPPER_CASE names for macros. -Tip: Install the tool [Uncrustify(http://uncrustify.sourceforge.net) and then -run `make uncrustify` to fix up source code formatting. +### Legacy C-style code style -#### Idioms - -* Declare variables as late as convenient, not necessarily at the beginning of - the scope. -* Use NULL to initialize null pointers. -* Don't use NULL when comparing pointers. -* Use format(), x_malloc() and friends instead of checking for memory - allocation failure explicitly. -* Use str_eq() instead of strcmp() when testing for string (in)equality. -* Consider using str_startswith() instead of strncmp(). -* Use bool, true and false for boolean values. -* Use tmp_unlink() or x_unlink() instead of unlink(). -* Use x_rename() instead of rename(). +* Put the opening curly brace on a new line when defining a function, otherwise + at the end of the same line. +* Put no space between function name and the following parenthesis. +* Use UPPER_CASE names for enum values and macros. +* Use snake_case for everything else. #### Other diff --git a/LICENSE.adoc b/LICENSE.adoc index 2cc1e3bd8..ec3e1b8a4 100644 --- a/LICENSE.adoc +++ b/LICENSE.adoc @@ -129,6 +129,30 @@ following license: ------------------------------------------------------------------------------- +m4/ax_cxx_compile_stdcxx.m4 +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Downloaded from the +https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html[GNU +Autoconf Archive]. It has the following license: + +------------------------------------------------------------------------------- + Copyright (c) 2008 Benjamin Kosnik + Copyright (c) 2012 Zack Weinberg + Copyright (c) 2013 Roy Stogner + Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov + Copyright (c) 2015 Paul Norman + Copyright (c) 2015 Moritz Klammler + Copyright (c) 2016, 2018 Krzesimir Nowak + Copyright (c) 2019 Enji Cooper + + Copying and distribution of this file, with or without modification, are + permitted in any medium without royalty provided the copyright notice + and this notice are preserved. This file is offered as-is, without any + warranty. +------------------------------------------------------------------------------- + + m4/feature_macros.m4 ~~~~~~~~~~~~~~~~~~~~ diff --git a/Makefile.in b/Makefile.in index 75e427352..7ae24f1b1 100644 --- a/Makefile.in +++ b/Makefile.in @@ -14,11 +14,14 @@ BASH = @BASH@ CC = @CC@ CFLAGS = @CFLAGS@ CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXFLAGS = @CXXFLAGS@ EXEEXT = @EXEEXT@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ all_cflags = $(CFLAGS) +all_cxxflags = $(CXXFLAGS) all_cppflags = @DEFS@ -DSYSCONFDIR=$(sysconfdir) -I. -I$(srcdir)/src -I$(builddir)/unittest $(CPPFLAGS) extra_libs = @extra_libs@ @@ -28,35 +31,35 @@ quiet := $(v_at_$(V)) Q=$(if $(quiet),@) non_third_party_sources = \ - src/args.c \ - src/ccache.c \ - src/cleanup.c \ - src/common_header.c \ - src/compopt.c \ - src/compr_none.c \ - src/compr_zstd.c \ - src/compress.c \ - src/compression.c \ - src/conf.c \ - src/confitems.c \ - src/counters.c \ - src/decompr_none.c \ - src/decompr_zstd.c \ - src/execute.c \ - src/exitfn.c \ - src/hash.c \ - src/hashutil.c \ - src/language.c \ - src/lockfile.c \ - src/manifest.c \ - src/result.c \ - src/stats.c \ - src/unify.c \ - src/util.c + src/args.cpp \ + src/ccache.cpp \ + src/cleanup.cpp \ + src/common_header.cpp \ + src/compopt.cpp \ + src/compr_none.cpp \ + src/compr_zstd.cpp \ + src/compress.cpp \ + src/compression.cpp \ + src/conf.cpp \ + src/confitems.cpp \ + src/counters.cpp \ + src/decompr_none.cpp \ + src/decompr_zstd.cpp \ + src/execute.cpp \ + src/exitfn.cpp \ + src/hash.cpp \ + src/hashutil.cpp \ + src/language.cpp \ + src/lockfile.cpp \ + src/manifest.cpp \ + src/result.cpp \ + src/stats.cpp \ + src/unify.cpp \ + src/util.cpp generated_sources = \ - src/confitems_lookup.c \ - src/envtoconfitems_lookup.c \ - src/version.c + src/confitems_lookup.cpp \ + src/envtoconfitems_lookup.cpp \ + src/version.cpp third_party_sources = \ src/third_party/getopt_long.c \ src/third_party/hashtable.c \ @@ -65,17 +68,17 @@ third_party_sources = \ src/third_party/xxhash.c extra_sources = @extra_sources@ base_sources = $(non_third_party_sources) $(generated_sources) $(third_party_sources) $(extra_sources) -base_objs = $(base_sources:.c=.o) +base_objs = $(patsubst %.c, %.o, $(patsubst %.cpp, %.o, $(base_sources))) -non_third_party_objs = $(non_third_party_sources:.c=.o) +non_third_party_objs = $(patsubst %.c, %.o, $(patsubst %.cpp, %.o, $(non_third_party_sources))) -ccache_sources = src/main.c $(base_sources) -ccache_objs = $(ccache_sources:.c=.o) +ccache_sources = src/main.cpp $(base_sources) +ccache_objs = $(patsubst %.c, %.o, $(patsubst %.cpp, %.o, $(ccache_sources))) test_suites = @test_suites@ -test_sources = unittest/main.c unittest/framework.c unittest/util.c +test_sources = unittest/main.cpp unittest/framework.cpp unittest/util.cpp test_sources += $(test_suites) -test_objs = $(test_sources:.c=.o) +test_objs = $(test_sources:.cpp=.o) all_sources = $(ccache_sources) $(test_sources) all_objs = $(ccache_objs) $(test_objs) @@ -95,7 +98,7 @@ all: ccache$(EXEEXT) ccache$(EXEEXT): $(ccache_objs) $(extra_libs) $(if $(quiet),@echo " LD $@") - $(Q)$(CC) -o $@ $(ccache_objs) $(LDFLAGS) $(extra_libs) $(LIBS) + $(Q)$(CXX) -o $@ $(ccache_objs) $(LDFLAGS) $(extra_libs) $(LIBS) ccache.1: doc/ccache.1 $(if $(quiet),@echo " CP $@") @@ -116,7 +119,7 @@ clean: [ ! -d src/third_party/zstd ] || $(MAKE) -C src/third_party/zstd/lib clean [ ! -d src/third_party/libb2 ] || $(MAKE) -C src/third_party/libb2 clean -src/snprintf.o: CFLAGS += @no_implicit_fallthrough_warning@ +src/third_party/snprintf.o: CFLAGS += @no_implicit_fallthrough_warning@ libzstd_options = \ ZSTD_LEGACY_SUPPORT=0 \ @@ -146,7 +149,7 @@ src/third_party/libb2/src/.libs/libb2.a: .PHONY: performance performance: ccache$(EXEEXT) - $(srcdir)/misc/performance --ccache ccache$(EXEEXT) $(CC) $(all_cppflags) $(all_cflags) $(srcdir)/src/ccache.c + $(srcdir)/misc/performance --ccache ccache$(EXEEXT) $(CXX) $(all_cppflags) $(all_cxxflags) $(srcdir)/src/ccache.cpp .PHONY: test test: ccache$(EXEEXT) unittest/run$(EXEEXT) @@ -162,11 +165,11 @@ unittest: unittest/run$(EXEEXT) unittest/run$(EXEEXT): $(base_objs) $(test_objs) $(extra_libs) $(if $(quiet),@echo " LD $@") - $(Q)$(CC) -o $@ $(base_objs) $(test_objs) $(LDFLAGS) $(extra_libs) $(LIBS) + $(Q)$(CXX) -o $@ $(base_objs) $(test_objs) $(LDFLAGS) $(extra_libs) $(LIBS) -unittest/main.o: unittest/suites.h +unittest/main.o: unittest/suites.hpp -unittest/suites.h: $(test_suites) Makefile +unittest/suites.hpp: $(test_suites) Makefile $(if $(quiet),@echo " GEN $@") $(Q)ls $^ | grep -v Makefile | xargs sed -n 's/TEST_SUITE(\(.*\))/SUITE(\1)/p' >$@ @@ -186,4 +189,8 @@ installcheck: ccache$(EXEEXT) unittest/run$(EXEEXT) $(if $(quiet),@echo " CC $@") $(Q)$(CC) $(all_cppflags) $(all_cflags) -c -o $@ $< +.cpp.o: + $(if $(quiet),@echo " CXX $@") + $(Q)$(CXX) $(all_cppflags) $(all_cxxflags) -c -o $@ $< + @include_dev_mk@ diff --git a/configure.ac b/configure.ac index 994b341fc..f94781309 100644 --- a/configure.ac +++ b/configure.ac @@ -29,18 +29,15 @@ AC_SUBST(no_implicit_fallthrough_warning) AC_SUBST(test_suites) m4_include(m4/feature_macros.m4) +m4_include(m4/ax_cxx_compile_stdcxx.m4) m4_include(m4/clang.m4) mkdir -p .deps src/third_party unittest dnl Checks for programs. AC_PROG_CC +AX_CXX_COMPILE_STDCXX(11, noext, mandatory) _AC_LANG_COMPILER_CLANG -AC_PROG_CC_C99 -if test "$ac_cv_prog_cc_c99" = no; then - AC_MSG_ERROR(cannot find a C99-compatible compiler) -fi - AC_PROG_INSTALL # Prefer bash, needed for test.sh @@ -49,19 +46,28 @@ AC_PATH_TOOL(BASH, bash, "/bin/bash") # If GCC (or clang), turn on warnings. if test "$ac_compiler_gnu" = yes; then CFLAGS="$CFLAGS -Wall -W" + CXXFLAGS="$CXXFLAGS -Wall -W" else - CFLAGS="$CFLAGS -O" + CFLAGS="$CXXFLAGS -O" + CXXFLAGS="$CXXFLAGS -O" fi more_warnings="-Wextra -Wpedantic" if test "$ac_compiler_clang" = yes; then more_warnings="$more_warnings -Weverything" + more_warnings="$more_warnings -Wno-c++98-compat" + more_warnings="$more_warnings -Wno-c++98-compat-pedantic" more_warnings="$more_warnings -Wno-conversion" more_warnings="$more_warnings -Wno-disabled-macro-expansion" more_warnings="$more_warnings -Wno-format-nonliteral" + more_warnings="$more_warnings -Wno-implicit-fallthrough" more_warnings="$more_warnings -Wno-padded" more_warnings="$more_warnings -Wno-shorten-64-to-32" more_warnings="$more_warnings -Wno-sign-conversion" + +# TODO: Enable these in the future: + more_warnings="$more_warnings -Wno-old-style-cast" + more_warnings="$more_warnings -Wno-zero-as-null-pointer-constant" fi AC_ARG_ENABLE(more_warnings, @@ -69,6 +75,7 @@ AC_ARG_ENABLE(more_warnings, [enable more compiler warnings])]) if test x${enable_more_warnings} = xyes; then CFLAGS="$CFLAGS $more_warnings" + CXXFLAGS="$CXXFLAGS $more_warnings" fi AC_HEADER_DIRENT @@ -251,7 +258,7 @@ if test ! -f $srcdir/dev_mode_disabled; then AC_CONFIG_FILES([dev.mk]) include_dev_mk='include dev.mk' version=`(git --git-dir=$srcdir/.git describe --dirty 2>/dev/null || echo vunknown) | sed -e 's/v//' -e 's/-/+/' -e 's/-/_/g'` - echo "extern const char CCACHE_VERSION@<:@@:>@; const char CCACHE_VERSION@<:@@:>@ = \"$version\";" >src/version.c + echo "extern const char CCACHE_VERSION@<:@@:>@; const char CCACHE_VERSION@<:@@:>@ = \"$version\";" >src/version.cpp AC_CHECK_TOOL(GPERF, gperf) if test -z "$GPERF"; then AC_MSG_ERROR(please install gperf) @@ -260,9 +267,9 @@ else AC_MSG_NOTICE(developer mode disabled) fi -if test ! -f $srcdir/src/version.c -a ! -f src/version.c ; then +if test ! -f $srcdir/src/version.cpp -a ! -f src/version.cpp ; then AC_MSG_WARN(unable to determine ccache version) - echo "extern const char CCACHE_VERSION@<:@@:>@; const char CCACHE_VERSION@<:@@:>@ = \"unknown\";" >src/version.c + echo "extern const char CCACHE_VERSION@<:@@:>@; const char CCACHE_VERSION@<:@@:>@ = \"unknown\";" >src/version.cpp fi dnl Check for -Wno-implicit-fallthrough @@ -277,7 +284,7 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])], CFLAGS=$saved_cflags dnl Find test suite files. -test_suites=`cd $srcdir && ls unittest/test_*.c | egrep -v 'BASE|BACKUP|LOCAL|REMOTE' | xargs echo` +test_suites=$(cd $srcdir && ls unittest/test_*.cpp | egrep -v 'BASE|BACKUP|LOCAL|REMOTE' | xargs echo) AC_CONFIG_FILES([Makefile]) AC_OUTPUT diff --git a/dev.mk.in b/dev.mk.in index 5c8a073d0..7f185cb44 100644 --- a/dev.mk.in +++ b/dev.mk.in @@ -2,6 +2,7 @@ all_cflags += -Werror all_cppflags += -MD -MP -MF .deps/$(subst .._,,$(subst /,_,$(subst $(srcdir)/,,$<))).d +all_cxxflags += -Werror A2X = a2x ASCIIDOC = asciidoc @@ -34,39 +35,39 @@ generated_docs = \ built_dist_files = $(generated_sources) $(generated_docs) headers = \ - src/ccache.h \ - src/common_header.h \ - src/compopt.h \ - src/compression.h \ - src/conf.h \ - src/confitems.h \ - src/counters.h \ - src/envtoconfitems.h \ - src/hash.h \ - src/hashutil.h \ - src/int_bytes_conversion.h \ - src/language.h \ - src/macroskip.h \ - src/manifest.h \ - src/result.h \ - src/system.h \ + src/ccache.hpp \ + src/common_header.hpp \ + src/compopt.hpp \ + src/compression.hpp \ + src/conf.hpp \ + src/confitems.hpp \ + src/counters.hpp \ + src/envtoconfitems.hpp \ + src/hash.hpp \ + src/hashutil.hpp \ + src/int_bytes_conversion.hpp \ + src/language.hpp \ + src/macroskip.hpp \ + src/manifest.hpp \ + src/result.hpp \ + src/system.hpp \ src/third_party/getopt_long.h \ src/third_party/hashtable.h \ src/third_party/hashtable_itr.h \ src/third_party/hashtable_private.h \ src/third_party/minitrace.h \ src/third_party/xxhash.h \ - src/unify.h \ - unittest/framework.h \ - unittest/util.h + src/unify.hpp \ + unittest/framework.hpp \ + unittest/util.hpp generated_headers = \ - unittest/suites.h + unittest/suites.hpp files_to_clean += *.tar.gz *.tar.xz *.xml doc/*.xml .deps/* perfdir.* files_to_clean += compile_commands.json -files_to_clean += src/confitems_lookup.c -files_to_clean += src/envtoconfitems_lookup.c -files_to_distclean += $(built_dist_files) src/version.c unittest/suites.h +files_to_clean += src/confitems_lookup.cpp +files_to_clean += src/envtoconfitems_lookup.cpp +files_to_distclean += $(built_dist_files) src/version.cpp unittest/suites.hpp files_to_distclean += .deps dev.mk source_dist_files = \ @@ -92,10 +93,10 @@ source_dist_files = \ install-sh \ m4 \ src/confitems.gperf \ - src/confitems_lookup.c \ + src/confitems_lookup.cpp \ src/envtoconfitems.gperf \ - src/envtoconfitems_lookup.c \ - src/main.c \ + src/envtoconfitems_lookup.cpp \ + src/main.cpp \ src/third_party/minitrace.c \ test/run \ test/suites/*.bash @@ -104,17 +105,17 @@ dist_files = \ $(addprefix $(srcdir)/, $(source_dist_files)) \ $(built_dist_files) -ifneq ($(shell sed 's/.*"\(.*\)".*/\1/' src/version.c 2>/dev/null),$(version)) - $(shell echo 'extern const char CCACHE_VERSION[]; const char CCACHE_VERSION[] = "$(version)";' >src/version.c) +ifneq ($(shell sed 's/.*"\(.*\)".*/\1/' src/version.cpp 2>/dev/null),$(version)) + $(shell echo 'extern const char CCACHE_VERSION[]; const char CCACHE_VERSION[] = "$(version)";' >src/version.cpp) endif -src/version.o: src/version.c +src/version.o: src/version.cpp # $(1): Name. # $(2): Command for fixing up source file before the gperf call. define generate_gperf_lookup -src/$(1)_lookup.c: src/$(1).gperf +src/$(1)_lookup.cpp: src/$(1).gperf $$(if $$(quiet),@echo " GEN $$@") - $$(Q)$(2) $$< | tr -d '\r' | $$(GPERF) | sed 's/#error/#warning/' >$$@.tmp + $$(Q)$(2) $$< | tr -d '\r' | $$(GPERF) | sed -e 's/#error/#warning/' -e 's/register//g' >$$@.tmp # Fix for gperf < 3.1 (fix parameter type and remove inlining of the get function): $$(Q)perl -00 -pi -e 's/unsigned int len/size_t len/; s/#ifdef __GNUC__.*?gnu_inline.*?#endif\n#endif\n//sg' $$@.tmp $$(Q)echo "size_t $(1)_count(void) { return $$$$(perl -ne '/TOTAL_KEYWORDS = (.+?),/ && print $$$$1' $$@.tmp); }" >>$$@.tmp @@ -159,8 +160,8 @@ define do_distcheck chmod u+w $(dist_dir)/build && \ cd $(dist_dir)/build && \ ../configure --enable-more-warnings --prefix=$$tmpdir/root $(1) && \ - $(MAKE) install CFLAGS=-Werror V=1 && \ - $(MAKE) installcheck) && \ + $(MAKE) install CFLAGS=-Werror CXXFLAGS=-Werror V=1 && \ + $(MAKE) installcheck V=1) && \ chmod -R u+w $$tmpdir/$(dist_dir) && \ rm -rf $$tmpdir endef @@ -170,7 +171,7 @@ distcheck: $(firstword $(dist_archives)) $(call do_distcheck) $(call do_distcheck, --with-libzstd-from-internet) $(call do_distcheck, --with-libb2-from-internet) - $(call do_distcheck, CC=clang) + $(call do_distcheck, CC=clang CXX=clang++) .PHONY: docs docs: $(generated_docs) @@ -187,7 +188,7 @@ docs: $(generated_docs) $(Q)$(ASCIIDOC) -a revnumber=$(version) -d manpage -b docbook -o - $< | \ perl -pe 's!(.*?)!\1!g' >$@ -$(non_third_party_objs) $(test_objs): CFLAGS += @more_warnings@ +$(non_third_party_objs) $(test_objs): CXXFLAGS += @more_warnings@ doc/ccache.1: doc/MANUAL.xml $(if $(quiet),@echo " A2X $@") @@ -201,14 +202,14 @@ update-authors: .PHONY: check-syntax check-syntax: - $(CC) $(all_cppflags) -I. $(all_cflags) -S -o /dev/null $(CHK_SOURCES) + $(CC) $(all_cppflags) -I. $(all_cxxflags) -S -o /dev/null $(CHK_SOURCES) .PHONY: cppcheck cppcheck: $(CPPCHECK) --suppressions-list=$(CPPCHECK_SUPPRESSIONS) \ --inline-suppr -q --enable=all --force -I . \ --template='cppcheck: warning: {id}:{file}:{line}: {message}' \ - $(non_third_party_sources) src/confitems_lookup.c src/main.c $(test_sources) + $(non_third_party_sources) src/confitems_lookup.cpp src/main.cpp $(test_sources) .PHONY: shellcheck shellcheck: test/suites/*.bash @@ -228,8 +229,8 @@ tidy: compile_commands.json .PHONY: analyze analyze: - $(SCAN_BUILD) --use-cc=$(CC) $(srcdir)/configure - $(SCAN_BUILD) --use-cc=$(CC) --status-bugs $(MAKE) -B + $(SCAN_BUILD) --use-cc="$(CC)" --use-c++="$(CXX)" $(srcdir)/configure + $(SCAN_BUILD) --use-cc="$(CC)" --use-c++="$(CXX)" --status-bugs $(MAKE) -B BUILDENV = ubuntu DOCKER_IMAGE_TAG = ccache/build:$(BUILDENV) @@ -243,6 +244,6 @@ docker: buildenv/$(BUILDENV)/Dockerfile travis: .travis/Dockerfile $(DOCKER) inspect travis-build >/dev/null || $(DOCKER) build -t travis-build .travis $(DOCKER) run --rm --volume $(PWD):/src --tmpfs /dst:rw,exec --env ASAN_OPTIONS='$(ASAN_OPTIONS)' travis-build \ - sh -c "cd /src && ./autogen.sh && cd /dst && CC=$(CC) CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' /src/configure $(CONFIGURE) && CC=$(CC) CFLAGS='$(CFLAGS)' make V=$(V) && CC=$(CC) make V=$(V) $(TEST)" + sh -c "cd /src && ./autogen.sh && cd /dst && CC=$(CC) CFLAGS='$(CFLAGS)' CXX=$(CXX) CXXFLAGS='$(CXXFLAGS)' LDFLAGS='$(LDFLAGS)' /src/configure $(CONFIGURE) && CC=$(CC) CFLAGS='$(CFLAGS)' make V=$(V) && CC=$(CC) make V=$(V) $(TEST)" -include .deps/*.d diff --git a/doc/INSTALL-from-release-archive.md b/doc/INSTALL-from-release-archive.md index d758377f9..0a54b384f 100644 --- a/doc/INSTALL-from-release-archive.md +++ b/doc/INSTALL-from-release-archive.md @@ -7,7 +7,8 @@ Prerequisites To build ccache from a [release archive](https://ccache.dev/download.html), you need: -- A C compiler (for instance GCC). +- A C++11 compiler. +- A C89 compiler. - [libb2](https://github.com/BLAKE2/libb2). If you don't have libb2 installed and can't or don't want to install it on your system, you can pass `--with-libb2-from-internet` to the configure script, which will make the diff --git a/doc/INSTALL.md b/doc/INSTALL.md index c12f7b98e..76c874dc6 100644 --- a/doc/INSTALL.md +++ b/doc/INSTALL.md @@ -6,7 +6,8 @@ Prerequisites To build ccache from a source repository, you need: -- A C compiler (for instance GCC) +- A C++11 compiler. +- A C89 compiler. - GNU Bourne Again SHell (bash) for tests. - [AsciiDoc](https://www.methods.co.nz/asciidoc/) to build the HTML documentation. diff --git a/m4/ax_cxx_compile_stdcxx.m4 b/m4/ax_cxx_compile_stdcxx.m4 new file mode 100644 index 000000000..43087b2e6 --- /dev/null +++ b/m4/ax_cxx_compile_stdcxx.m4 @@ -0,0 +1,951 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional]) +# +# DESCRIPTION +# +# Check for baseline language coverage in the compiler for the specified +# version of the C++ standard. If necessary, add switches to CXX and +# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard) +# or '14' (for the C++14 standard). +# +# The second argument, if specified, indicates whether you insist on an +# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g. +# -std=c++11). If neither is specified, you get whatever works, with +# preference for an extended mode. +# +# The third argument, if specified 'mandatory' or if left unspecified, +# indicates that baseline support for the specified C++ standard is +# required and that the macro should error out if no mode with that +# support is found. If specified 'optional', then configuration proceeds +# regardless, after defining HAVE_CXX${VERSION} if and only if a +# supporting mode is found. +# +# LICENSE +# +# Copyright (c) 2008 Benjamin Kosnik +# Copyright (c) 2012 Zack Weinberg +# Copyright (c) 2013 Roy Stogner +# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov +# Copyright (c) 2015 Paul Norman +# Copyright (c) 2015 Moritz Klammler +# Copyright (c) 2016, 2018 Krzesimir Nowak +# Copyright (c) 2019 Enji Cooper +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 11 + +dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro +dnl (serial version number 13). + +AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl + m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"], + [$1], [14], [ax_cxx_compile_alternatives="14 1y"], + [$1], [17], [ax_cxx_compile_alternatives="17 1z"], + [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$2], [], [], + [$2], [ext], [], + [$2], [noext], [], + [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl + m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true], + [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true], + [$3], [optional], [ax_cxx_compile_cxx$1_required=false], + [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])]) + AC_LANG_PUSH([C++])dnl + ac_success=no + + m4_if([$2], [noext], [], [dnl + if test x$ac_success = xno; then + for alternative in ${ax_cxx_compile_alternatives}; do + switch="-std=gnu++${alternative}" + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + fi]) + + m4_if([$2], [ext], [], [dnl + if test x$ac_success = xno; then + dnl HP's aCC needs +std=c++11 according to: + dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf + dnl Cray's crayCC needs "-h std=c++11" + for alternative in ${ax_cxx_compile_alternatives}; do + for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do + cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch]) + AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch, + $cachevar, + [ac_save_CXX="$CXX" + CXX="$CXX $switch" + AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])], + [eval $cachevar=yes], + [eval $cachevar=no]) + CXX="$ac_save_CXX"]) + if eval test x\$$cachevar = xyes; then + CXX="$CXX $switch" + if test -n "$CXXCPP" ; then + CXXCPP="$CXXCPP $switch" + fi + ac_success=yes + break + fi + done + if test x$ac_success = xyes; then + break + fi + done + fi]) + AC_LANG_POP([C++]) + if test x$ax_cxx_compile_cxx$1_required = xtrue; then + if test x$ac_success = xno; then + AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.]) + fi + fi + if test x$ac_success = xno; then + HAVE_CXX$1=0 + AC_MSG_NOTICE([No compiler with C++$1 support was found]) + else + HAVE_CXX$1=1 + AC_DEFINE(HAVE_CXX$1,1, + [define if the compiler supports basic C++$1 syntax]) + fi + AC_SUBST(HAVE_CXX$1) +]) + + +dnl Test body for checking C++11 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 +) + + +dnl Test body for checking C++14 support + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 +) + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17], + _AX_CXX_COMPILE_STDCXX_testbody_new_in_11 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_14 + _AX_CXX_COMPILE_STDCXX_testbody_new_in_17 +) + +dnl Tests for new features in C++11 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[ + +// If the compiler admits that it is not ready for C++11, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201103L + +#error "This is not a C++11 compiler" + +#else + +namespace cxx11 +{ + + namespace test_static_assert + { + + template + struct check + { + static_assert(sizeof(int) <= sizeof(T), "not big enough"); + }; + + } + + namespace test_final_override + { + + struct Base + { + virtual ~Base() {} + virtual void f() {} + }; + + struct Derived : public Base + { + virtual ~Derived() override {} + virtual void f() override {} + }; + + } + + namespace test_double_right_angle_brackets + { + + template < typename T > + struct check {}; + + typedef check single_type; + typedef check> double_type; + typedef check>> triple_type; + typedef check>>> quadruple_type; + + } + + namespace test_decltype + { + + int + f() + { + int a = 1; + decltype(a) b = 2; + return a + b; + } + + } + + namespace test_type_deduction + { + + template < typename T1, typename T2 > + struct is_same + { + static const bool value = false; + }; + + template < typename T > + struct is_same + { + static const bool value = true; + }; + + template < typename T1, typename T2 > + auto + add(T1 a1, T2 a2) -> decltype(a1 + a2) + { + return a1 + a2; + } + + int + test(const int c, volatile int v) + { + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == false, ""); + auto ac = c; + auto av = v; + auto sumi = ac + av + 'x'; + auto sumf = ac + av + 1.0; + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == true, ""); + static_assert(is_same::value == false, ""); + static_assert(is_same::value == true, ""); + return (sumf > 0.0) ? sumi : add(c, v); + } + + } + + namespace test_noexcept + { + + int f() { return 0; } + int g() noexcept { return 0; } + + static_assert(noexcept(f()) == false, ""); + static_assert(noexcept(g()) == true, ""); + + } + + namespace test_constexpr + { + + template < typename CharT > + unsigned long constexpr + strlen_c_r(const CharT *const s, const unsigned long acc) noexcept + { + return *s ? strlen_c_r(s + 1, acc + 1) : acc; + } + + template < typename CharT > + unsigned long constexpr + strlen_c(const CharT *const s) noexcept + { + return strlen_c_r(s, 0UL); + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("1") == 1UL, ""); + static_assert(strlen_c("example") == 7UL, ""); + static_assert(strlen_c("another\0example") == 7UL, ""); + + } + + namespace test_rvalue_references + { + + template < int N > + struct answer + { + static constexpr int value = N; + }; + + answer<1> f(int&) { return answer<1>(); } + answer<2> f(const int&) { return answer<2>(); } + answer<3> f(int&&) { return answer<3>(); } + + void + test() + { + int i = 0; + const int c = 0; + static_assert(decltype(f(i))::value == 1, ""); + static_assert(decltype(f(c))::value == 2, ""); + static_assert(decltype(f(0))::value == 3, ""); + } + + } + + namespace test_uniform_initialization + { + + struct test + { + static const int zero {}; + static const int one {1}; + }; + + static_assert(test::zero == 0, ""); + static_assert(test::one == 1, ""); + + } + + namespace test_lambdas + { + + void + test1() + { + auto lambda1 = [](){}; + auto lambda2 = lambda1; + lambda1(); + lambda2(); + } + + int + test2() + { + auto a = [](int i, int j){ return i + j; }(1, 2); + auto b = []() -> int { return '0'; }(); + auto c = [=](){ return a + b; }(); + auto d = [&](){ return c; }(); + auto e = [a, &b](int x) mutable { + const auto identity = [](int y){ return y; }; + for (auto i = 0; i < a; ++i) + a += b--; + return x + identity(a + b); + }(0); + return a + b + c + d + e; + } + + int + test3() + { + const auto nullary = [](){ return 0; }; + const auto unary = [](int x){ return x; }; + using nullary_t = decltype(nullary); + using unary_t = decltype(unary); + const auto higher1st = [](nullary_t f){ return f(); }; + const auto higher2nd = [unary](nullary_t f1){ + return [unary, f1](unary_t f2){ return f2(unary(f1())); }; + }; + return higher1st(nullary) + higher2nd(nullary)(unary); + } + + } + + namespace test_variadic_templates + { + + template + struct sum; + + template + struct sum + { + static constexpr auto value = N0 + sum::value; + }; + + template <> + struct sum<> + { + static constexpr auto value = 0; + }; + + static_assert(sum<>::value == 0, ""); + static_assert(sum<1>::value == 1, ""); + static_assert(sum<23>::value == 23, ""); + static_assert(sum<1, 2>::value == 3, ""); + static_assert(sum<5, 5, 11>::value == 21, ""); + static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); + + } + + // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae + // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function + // because of this. + namespace test_template_alias_sfinae + { + + struct foo {}; + + template + using member = typename T::member_type; + + template + void func(...) {} + + template + void func(member*) {} + + void test(); + + void test() { func(0); } + + } + +} // namespace cxx11 + +#endif // __cplusplus >= 201103L + +]]) + + +dnl Tests for new features in C++14 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[ + +// If the compiler admits that it is not ready for C++14, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201402L + +#error "This is not a C++14 compiler" + +#else + +namespace cxx14 +{ + + namespace test_polymorphic_lambdas + { + + int + test() + { + const auto lambda = [](auto&&... args){ + const auto istiny = [](auto x){ + return (sizeof(x) == 1UL) ? 1 : 0; + }; + const int aretiny[] = { istiny(args)... }; + return aretiny[0]; + }; + return lambda(1, 1L, 1.0f, '1'); + } + + } + + namespace test_binary_literals + { + + constexpr auto ivii = 0b0000000000101010; + static_assert(ivii == 42, "wrong value"); + + } + + namespace test_generalized_constexpr + { + + template < typename CharT > + constexpr unsigned long + strlen_c(const CharT *const s) noexcept + { + auto length = 0UL; + for (auto p = s; *p; ++p) + ++length; + return length; + } + + static_assert(strlen_c("") == 0UL, ""); + static_assert(strlen_c("x") == 1UL, ""); + static_assert(strlen_c("test") == 4UL, ""); + static_assert(strlen_c("another\0test") == 7UL, ""); + + } + + namespace test_lambda_init_capture + { + + int + test() + { + auto x = 0; + const auto lambda1 = [a = x](int b){ return a + b; }; + const auto lambda2 = [a = lambda1(x)](){ return a; }; + return lambda2(); + } + + } + + namespace test_digit_separators + { + + constexpr auto ten_million = 100'000'000; + static_assert(ten_million == 100000000, ""); + + } + + namespace test_return_type_deduction + { + + auto f(int& x) { return x; } + decltype(auto) g(int& x) { return x; } + + template < typename T1, typename T2 > + struct is_same + { + static constexpr auto value = false; + }; + + template < typename T > + struct is_same + { + static constexpr auto value = true; + }; + + int + test() + { + auto x = 0; + static_assert(is_same::value, ""); + static_assert(is_same::value, ""); + return x; + } + + } + +} // namespace cxx14 + +#endif // __cplusplus >= 201402L + +]]) + + +dnl Tests for new features in C++17 + +m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[ + +// If the compiler admits that it is not ready for C++17, why torture it? +// Hopefully, this will speed up the test. + +#ifndef __cplusplus + +#error "This is not a C++ compiler" + +#elif __cplusplus < 201703L + +#error "This is not a C++17 compiler" + +#else + +#include +#include +#include + +namespace cxx17 +{ + + namespace test_constexpr_lambdas + { + + constexpr int foo = [](){return 42;}(); + + } + + namespace test::nested_namespace::definitions + { + + } + + namespace test_fold_expression + { + + template + int multiply(Args... args) + { + return (args * ... * 1); + } + + template + bool all(Args... args) + { + return (args && ...); + } + + } + + namespace test_extended_static_assert + { + + static_assert (true); + + } + + namespace test_auto_brace_init_list + { + + auto foo = {5}; + auto bar {5}; + + static_assert(std::is_same, decltype(foo)>::value); + static_assert(std::is_same::value); + } + + namespace test_typename_in_template_template_parameter + { + + template typename X> struct D; + + } + + namespace test_fallthrough_nodiscard_maybe_unused_attributes + { + + int f1() + { + return 42; + } + + [[nodiscard]] int f2() + { + [[maybe_unused]] auto unused = f1(); + + switch (f1()) + { + case 17: + f1(); + [[fallthrough]]; + case 42: + f1(); + } + return f1(); + } + + } + + namespace test_extended_aggregate_initialization + { + + struct base1 + { + int b1, b2 = 42; + }; + + struct base2 + { + base2() { + b3 = 42; + } + int b3; + }; + + struct derived : base1, base2 + { + int d; + }; + + derived d1 {{1, 2}, {}, 4}; // full initialization + derived d2 {{}, {}, 4}; // value-initialized bases + + } + + namespace test_general_range_based_for_loop + { + + struct iter + { + int i; + + int& operator* () + { + return i; + } + + const int& operator* () const + { + return i; + } + + iter& operator++() + { + ++i; + return *this; + } + }; + + struct sentinel + { + int i; + }; + + bool operator== (const iter& i, const sentinel& s) + { + return i.i == s.i; + } + + bool operator!= (const iter& i, const sentinel& s) + { + return !(i == s); + } + + struct range + { + iter begin() const + { + return {0}; + } + + sentinel end() const + { + return {5}; + } + }; + + void f() + { + range r {}; + + for (auto i : r) + { + [[maybe_unused]] auto v = i; + } + } + + } + + namespace test_lambda_capture_asterisk_this_by_value + { + + struct t + { + int i; + int foo() + { + return [*this]() + { + return i; + }(); + } + }; + + } + + namespace test_enum_class_construction + { + + enum class byte : unsigned char + {}; + + byte foo {42}; + + } + + namespace test_constexpr_if + { + + template + int f () + { + if constexpr(cond) + { + return 13; + } + else + { + return 42; + } + } + + } + + namespace test_selection_statement_with_initializer + { + + int f() + { + return 13; + } + + int f2() + { + if (auto i = f(); i > 0) + { + return 3; + } + + switch (auto i = f(); i + 4) + { + case 17: + return 2; + + default: + return 1; + } + } + + } + + namespace test_template_argument_deduction_for_class_templates + { + + template + struct pair + { + pair (T1 p1, T2 p2) + : m1 {p1}, + m2 {p2} + {} + + T1 m1; + T2 m2; + }; + + void f() + { + [[maybe_unused]] auto p = pair{13, 42u}; + } + + } + + namespace test_non_type_auto_template_parameters + { + + template + struct B + {}; + + B<5> b1; + B<'a'> b2; + + } + + namespace test_structured_bindings + { + + int arr[2] = { 1, 2 }; + std::pair pr = { 1, 2 }; + + auto f1() -> int(&)[2] + { + return arr; + } + + auto f2() -> std::pair& + { + return pr; + } + + struct S + { + int x1 : 2; + volatile double y1; + }; + + S f3() + { + return {}; + } + + auto [ x1, y1 ] = f1(); + auto& [ xr1, yr1 ] = f1(); + auto [ x2, y2 ] = f2(); + auto& [ xr2, yr2 ] = f2(); + const auto [ x3, y3 ] = f3(); + + } + + namespace test_exception_spec_type_system + { + + struct Good {}; + struct Bad {}; + + void g1() noexcept; + void g2(); + + template + Bad + f(T*, T*); + + template + Good + f(T1*, T2*); + + static_assert (std::is_same_v); + + } + + namespace test_inline_variables + { + + template void f(T) + {} + + template inline T g(T) + { + return T{}; + } + + template<> inline void f<>(int) + {} + + template<> int g<>(int) + { + return 5; + } + + } + +} // namespace cxx17 + +#endif // __cplusplus < 201703L + +]]) diff --git a/misc/uncrustify.cfg b/misc/uncrustify.cfg index 30cabd205..6e4fb68de 100644 --- a/misc/uncrustify.cfg +++ b/misc/uncrustify.cfg @@ -120,17 +120,17 @@ sp_balance_nested_parens = false # false/true sp_paren_brace = force # ignore/add/remove/force # Add or remove space before pointer star '*'. -sp_before_ptr_star = force # ignore/add/remove/force +sp_before_ptr_star = ignore # ignore/add/remove/force # Add or remove space before pointer star '*' that isn't followed by a variable name # If set to 'ignore', sp_before_ptr_star is used instead. -sp_before_unnamed_ptr_star = force # ignore/add/remove/force +sp_before_unnamed_ptr_star = ignore # ignore/add/remove/force # Add or remove space between pointer stars '*'. sp_between_ptr_star = remove # ignore/add/remove/force # Add or remove space after pointer star '*', if followed by a word. -sp_after_ptr_star = remove # ignore/add/remove/force +sp_after_ptr_star = ignore # ignore/add/remove/force # Add or remove space after pointer star '*', if followed by a qualifier. sp_after_ptr_star_qualifier = ignore # ignore/add/remove/force diff --git a/src/args.c b/src/args.cpp similarity index 94% rename from src/args.c rename to src/args.cpp index 54dc7cefa..9ff7d5c3e 100644 --- a/src/args.c +++ b/src/args.cpp @@ -1,5 +1,5 @@ // Copyright (C) 2002 Andrew Tridgell -// Copyright (C) 2009-2018 Joel Rosdahl and other contributors +// Copyright (C) 2009-2019 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -17,10 +17,10 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "ccache.h" +#include "ccache.hpp" struct args * -args_init(int init_argc, char **init_args) +args_init(int init_argc, const char * const*init_args) { struct args *args = (struct args *)x_malloc(sizeof(struct args)); args->argc = 0; @@ -58,7 +58,7 @@ args_init_from_gcc_atfile(const char *filename) struct args *args = args_init(0, NULL); char *pos = argtext; - char *argbuf = x_malloc(strlen(argtext) + 1); + char* argbuf = static_cast(x_malloc(strlen(argtext) + 1)); char *argpos = argbuf; // Used to track quoting state; if \0, we are not inside quotes. Otherwise @@ -283,14 +283,14 @@ args_strip(struct args *args, const char *prefix) // Format args to a space-separated string. Does not quote spaces. Caller // frees. char * -args_to_string(struct args *args) +args_to_string(const struct args *args) { unsigned size = 0; for (char **p = args->argv; *p; p++) { size += strlen(*p) + 1; } - char *result = x_malloc(size + 1); + char* result = static_cast(x_malloc(size + 1)); int pos = 0; for (char **p = args->argv; *p; p++) { pos += sprintf(&result[pos], "%s ", *p); @@ -301,7 +301,7 @@ args_to_string(struct args *args) // Returns true if args1 equals args2, else false. bool -args_equal(struct args *args1, struct args *args2) +args_equal(const struct args *args1, const struct args *args2) { if (args1->argc != args2->argc) { return false; diff --git a/src/ccache.c b/src/ccache.cpp similarity index 96% rename from src/ccache.c rename to src/ccache.cpp index ee8d430f8..32e0477c7 100644 --- a/src/ccache.c +++ b/src/ccache.cpp @@ -17,21 +17,21 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "ccache.h" -#include "compopt.h" +#include "ccache.hpp" +#include "compopt.hpp" #ifdef HAVE_GETOPT_LONG #include #else #include "third_party/getopt_long.h" #endif -#include "hash.h" +#include "hash.hpp" #include "third_party/hashtable.h" #include "third_party/hashtable_itr.h" -#include "hashutil.h" -#include "language.h" -#include "manifest.h" -#include "result.h" -#include "unify.h" +#include "hashutil.hpp" +#include "language.hpp" +#include "manifest.hpp" +#include "result.hpp" +#include "unify.hpp" #define STRINGIFY(x) #x #define TO_STRING(x) STRINGIFY(x) @@ -225,7 +225,6 @@ bool output_is_precompiled_header = false; enum guessed_compiler guessed_compiler = GUESSED_UNKNOWN; // Profile generation / usage information. -static char *profile_dir = NULL; static bool profile_use = false; static bool profile_generate = false; @@ -360,7 +359,7 @@ static void add_pending_tmp_file(const char *path) { block_signals(); - struct pending_tmp_file *e = x_malloc(sizeof(*e)); + auto e = static_cast(x_malloc(sizeof(pending_tmp_file))); e->path = x_strdup(path); e->next = pending_tmp_files; pending_tmp_files = e; @@ -567,6 +566,7 @@ remember_include_file(char *path, struct hash *cpp_hash, bool system, struct hash *depend_mode_hash) { struct hash *fhash = NULL; + bool is_pch = false; size_t path_len = strlen(path); if (path_len >= 2 && (path[0] == '<' && path[path_len - 1] == '>')) { @@ -590,11 +590,13 @@ remember_include_file(char *path, struct hash *cpp_hash, bool system, } #ifdef _WIN32 - // stat fails on directories on win32. - DWORD attributes = GetFileAttributes(path); - if (attributes != INVALID_FILE_ATTRIBUTES && - attributes & FILE_ATTRIBUTE_DIRECTORY) { - goto out; + { + // stat fails on directories on win32. + DWORD attributes = GetFileAttributes(path); + if (attributes != INVALID_FILE_ATTRIBUTES && + attributes & FILE_ATTRIBUTE_DIRECTORY) { + goto out; + } } #endif @@ -613,24 +615,26 @@ remember_include_file(char *path, struct hash *cpp_hash, bool system, } // Canonicalize path for comparison; clang uses ./header.h. - char *canonical = path; - size_t canonical_len = path_len; - if (canonical[0] == '.' && canonical[1] == '/') { - canonical += 2; - canonical_len -= 2; - } - - for (size_t i = 0; i < ignore_headers_len; i++) { - char *ignore = ignore_headers[i]; - size_t ignore_len = strlen(ignore); - if (ignore_len > canonical_len) { - continue; + { + char *canonical = path; + size_t canonical_len = path_len; + if (canonical[0] == '.' && canonical[1] == '/') { + canonical += 2; + canonical_len -= 2; } - if (strncmp(canonical, ignore, ignore_len) == 0 - && (ignore[ignore_len-1] == DIR_DELIM_CH - || canonical[ignore_len] == DIR_DELIM_CH - || canonical[ignore_len] == '\0')) { - goto out; + + for (size_t i = 0; i < ignore_headers_len; i++) { + char *ignore = ignore_headers[i]; + size_t ignore_len = strlen(ignore); + if (ignore_len > canonical_len) { + continue; + } + if (strncmp(canonical, ignore, ignore_len) == 0 + && (ignore[ignore_len-1] == DIR_DELIM_CH + || canonical[ignore_len] == DIR_DELIM_CH + || canonical[ignore_len] == '\0')) { + goto out; + } } } @@ -653,7 +657,7 @@ remember_include_file(char *path, struct hash *cpp_hash, bool system, // Let's hash the include file content. fhash = hash_init(); - bool is_pch = is_precompiled_header(path); + is_pch = is_precompiled_header(path); if (is_pch) { if (!included_pch_file) { cc_log("Detected use of precompiled header: %s", path); @@ -703,7 +707,7 @@ remember_include_file(char *path, struct hash *cpp_hash, bool system, } } - struct digest *d = x_malloc(sizeof(*d)); + auto d = static_cast(x_malloc(sizeof(digest))); hash_result_as_bytes(fhash, d); hashtable_insert(included_files, path, d); path = NULL; // Ownership transferred to included_files. @@ -734,7 +738,7 @@ print_included_files(FILE *fp) { struct hashtable_itr *iter = hashtable_iterator(included_files); do { - char *path = hashtable_iterator_key(iter); + char* path = static_cast(hashtable_iterator_key(iter)); fprintf(fp, "%s\n", path); } while (hashtable_iterator_advance(iter)); } @@ -834,8 +838,8 @@ process_preprocessed_file(struct hash *hash, const char *path, bool pump) p = x_strdup(conf->ignore_headers_in_manifest); q = p; while ((header = strtok_r(q, PATH_DELIM, &saveptr))) { - ignore_headers = x_realloc(ignore_headers, - (ignore_headers_len+1) * sizeof(char *)); + ignore_headers = static_cast( + x_realloc(ignore_headers, (ignore_headers_len+1) * sizeof(char *))); ignore_headers[ignore_headers_len++] = x_strdup(header); q = NULL; } @@ -1138,9 +1142,9 @@ result_name_from_depfile(const char *depfile, struct hash *hash) print_included_files(stdout); } - struct digest *digest = x_malloc(sizeof(*digest)); - hash_result_as_bytes(hash, digest); - return digest; + auto d = static_cast(x_malloc(sizeof(digest))); + hash_result_as_bytes(hash, d); + return d; } // Send cached stderr, if any, to stderr. @@ -1562,7 +1566,7 @@ get_result_name_from_cpp(struct args *args, struct hash *hash) hash_string(hash, "false"); } - struct digest *name = x_malloc(sizeof(*name)); + auto name = static_cast(x_malloc(sizeof(digest))); hash_result_as_bytes(hash, name); return name; } @@ -1709,16 +1713,20 @@ hash_common_info(struct args *args, struct hash *hash) char *map = debug_prefix_maps[i]; char *sep = strchr(map, '='); if (sep) { - char *old = x_strndup(map, sep - map); - char *new = x_strdup(sep + 1); - cc_log("Relocating debuginfo CWD %s from %s to %s", cwd, old, new); - if (str_startswith(cwd, old)) { - char *dir = format("%s%s", new, cwd + strlen(old)); + char *old_path = x_strndup(map, sep - map); + char* new_path = static_cast(x_strdup(sep + 1)); + cc_log( + "Relocating debuginfo CWD %s from %s to %s", + cwd, + old_path, + new_path); + if (str_startswith(cwd, old_path)) { + char *dir = format("%s%s", new_path, cwd + strlen(old_path)); free(cwd); cwd = dir; } - free(old); - free(new); + free(old_path); + free(new_path); } } if (cwd) { @@ -2565,9 +2573,10 @@ cc_process_args(struct args *args, struct args **preprocessor_args, if (str_startswith(argv[i], "-fdebug-prefix-map=") || str_startswith(argv[i], "-ffile-prefix-map=")) { - debug_prefix_maps = x_realloc( - debug_prefix_maps, - (debug_prefix_maps_len + 1) * sizeof(char *)); + debug_prefix_maps = static_cast( + x_realloc( + debug_prefix_maps, + (debug_prefix_maps_len + 1) * sizeof(char *))); debug_prefix_maps[debug_prefix_maps_len++] = x_strdup(&argv[i][argv[i][2] == 'f' ? 18 : 19]); args_add(common_args, argv[i]); @@ -2698,9 +2707,10 @@ cc_process_args(struct args *args, struct args **preprocessor_args, continue; } if (str_startswith(argv[i], "-fsanitize-blacklist=")) { - sanitize_blacklists = x_realloc( - sanitize_blacklists, - (sanitize_blacklists_len + 1) * sizeof(char *)); + sanitize_blacklists = static_cast( + x_realloc( + sanitize_blacklists, + (sanitize_blacklists_len + 1) * sizeof(char *))); sanitize_blacklists[sanitize_blacklists_len++] = x_strdup(argv[i] + 21); args_add(common_args, argv[i]); continue; @@ -3068,46 +3078,48 @@ cc_process_args(struct args *args, struct args **preprocessor_args, // creates object files with these defined (confirmed with GCC 8.2.1), i.e. // they work as -MMD/-MD, not -MM/-M. These environment variables do nothing // on Clang. - char *dependencies_env = getenv("DEPENDENCIES_OUTPUT"); - bool using_sunpro_dependencies = false; - if (!dependencies_env) { - dependencies_env = getenv("SUNPRO_DEPENDENCIES"); - using_sunpro_dependencies = true; - } - if (dependencies_env) { - generating_dependencies = true; - dependency_filename_specified = true; - char *saveptr = NULL; - char *abspath_file = strtok_r(dependencies_env, " ", &saveptr); - - free(output_dep); - output_dep = make_relative_path(x_strdup(abspath_file)); - - // Specifying target object is optional. - char *abspath_obj = strtok_r(NULL, " ", &saveptr); - if (abspath_obj) { - // It's the "file target" form. + { + char *dependencies_env = getenv("DEPENDENCIES_OUTPUT"); + bool using_sunpro_dependencies = false; + if (!dependencies_env) { + dependencies_env = getenv("SUNPRO_DEPENDENCIES"); + using_sunpro_dependencies = true; + } + if (dependencies_env) { + generating_dependencies = true; + dependency_filename_specified = true; + char *saveptr = nullptr; + char *abspath_file = strtok_r(dependencies_env, " ", &saveptr); - dependency_target_specified = true; - char *relpath_obj = make_relative_path(x_strdup(abspath_obj)); - // Ensure compiler gets relative path. - char *relpath_both = format("%s %s", output_dep, relpath_obj); - if (using_sunpro_dependencies) { - x_setenv("SUNPRO_DEPENDENCIES", relpath_both); + free(output_dep); + output_dep = make_relative_path(x_strdup(abspath_file)); + + // specifying target object is optional. + char *abspath_obj = strtok_r(nullptr, " ", &saveptr); + if (abspath_obj) { + // it's the "file target" form. + + dependency_target_specified = true; + char *relpath_obj = make_relative_path(x_strdup(abspath_obj)); + // ensure compiler gets relative path. + char *relpath_both = format("%s %s", output_dep, relpath_obj); + if (using_sunpro_dependencies) { + x_setenv("SUNPRO_DEPENDENCIES", relpath_both); + } else { + x_setenv("DEPENDENCIES_OUTPUT", relpath_both); + } + free(relpath_obj); + free(relpath_both); } else { - x_setenv("DEPENDENCIES_OUTPUT", relpath_both); - } - free(relpath_obj); - free(relpath_both); - } else { - // It's the "file" form. + // it's the "file" form. - dependency_implicit_target_specified = true; - // Ensure compiler gets relative path. - if (using_sunpro_dependencies) { - x_setenv("SUNPRO_DEPENDENCIES", output_dep); - } else { - x_setenv("DEPENDENCIES_OUTPUT", output_dep); + dependency_implicit_target_specified = true; + // ensure compiler gets relative path. + if (using_sunpro_dependencies) { + x_setenv("SUNPRO_DEPENDENCIES", output_dep); + } else { + x_setenv("DEPENDENCIES_OUTPUT", output_dep); + } } } } @@ -3253,15 +3265,17 @@ cc_process_args(struct args *args, struct args **preprocessor_args, goto out; } - char *output_dir = x_dirname(output_obj); - if (stat(output_dir, &st) != 0 || !S_ISDIR(st.st_mode)) { - cc_log("Directory does not exist: %s", output_dir); - stats_update(STATS_BADOUTPUTFILE); - result = false; + { + char *output_dir = x_dirname(output_obj); + if (stat(output_dir, &st) != 0 || !S_ISDIR(st.st_mode)) { + cc_log("Directory does not exist: %s", output_dir); + stats_update(STATS_BADOUTPUTFILE); + result = false; + free(output_dir); + goto out; + } free(output_dir); - goto out; } - free(output_dir); // Some options shouldn't be passed to the real compiler when it compiles // preprocessed code: @@ -3865,7 +3879,8 @@ static void configuration_printer(const char *descr, const char *origin, void *context) { assert(context); - fprintf(context, "(%s) %s\n", origin, descr); + auto f = static_cast(context); + fprintf(f, "(%s) %s\n", origin, descr); } // The main program when not doing a compile. diff --git a/src/ccache.h b/src/ccache.hpp similarity index 97% rename from src/ccache.h rename to src/ccache.hpp index cac27d49f..8e3f10f33 100644 --- a/src/ccache.h +++ b/src/ccache.hpp @@ -20,9 +20,9 @@ #ifndef CCACHE_H #define CCACHE_H -#include "system.h" -#include "conf.h" -#include "counters.h" +#include "system.hpp" +#include "conf.hpp" +#include "counters.hpp" #include "third_party/minitrace.h" #ifdef __GNUC__ @@ -125,7 +125,7 @@ struct args { int argc; }; -struct args *args_init(int, char **); +struct args *args_init(int, const char * const*); struct args *args_init_from_string(const char *); struct args *args_init_from_gcc_atfile(const char *filename); struct args *args_copy(struct args *args); @@ -138,8 +138,8 @@ void args_pop(struct args *args, int n); void args_set(struct args *args, int index, const char *value); void args_strip(struct args *args, const char *prefix); void args_remove_first(struct args *args); -char *args_to_string(struct args *args); -bool args_equal(struct args *args1, struct args *args2); +char *args_to_string(const struct args *args); +bool args_equal(const struct args *args1, const struct args *args2); // ---------------------------------------------------------------------------- // util.c @@ -261,7 +261,7 @@ void compress_stats(struct conf *conf); int execute(char **argv, int fd_out, int fd_err, pid_t *pid); char *find_executable(const char *name, const char *exclude_name); void print_command(FILE *fp, char **argv); -char *format_command(char **argv); +char *format_command(const char* const* argv); // ---------------------------------------------------------------------------- // lockfile.c diff --git a/src/cleanup.c b/src/cleanup.cpp similarity index 99% rename from src/cleanup.c rename to src/cleanup.cpp index 8eca68cc3..8116aa601 100644 --- a/src/cleanup.c +++ b/src/cleanup.cpp @@ -17,7 +17,7 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "ccache.h" +#include "ccache.hpp" #include diff --git a/src/common_header.c b/src/common_header.cpp similarity index 97% rename from src/common_header.c rename to src/common_header.cpp index 3418599c2..f7f88d048 100644 --- a/src/common_header.c +++ b/src/common_header.cpp @@ -16,9 +16,9 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "ccache.h" -#include "int_bytes_conversion.h" -#include "common_header.h" +#include "ccache.hpp" +#include "int_bytes_conversion.hpp" +#include "common_header.hpp" bool common_header_initialize_for_writing( @@ -139,7 +139,7 @@ bool common_header_initialize_for_reading( XXH64_update(checksum, header_bytes, sizeof(header_bytes)); } - *decompr_state = (*decompressor)->init(input, checksum); + *decompr_state = (*decompressor)->init(input, checksum); if (!*decompr_state) { *errmsg = x_strdup("Failed to initialize decompressor"); return false; diff --git a/src/common_header.h b/src/common_header.hpp similarity index 99% rename from src/common_header.h rename to src/common_header.hpp index 45514f321..c131ee48d 100644 --- a/src/common_header.h +++ b/src/common_header.hpp @@ -19,7 +19,7 @@ #ifndef COMMON_HEADER_H #define COMMON_HEADER_H -#include "compression.h" +#include "compression.hpp" #include "third_party/xxhash.h" #define COMMON_HEADER_SIZE 15 diff --git a/src/compopt.c b/src/compopt.cpp similarity index 98% rename from src/compopt.c rename to src/compopt.cpp index 63204d4f0..afc46753a 100644 --- a/src/compopt.c +++ b/src/compopt.cpp @@ -16,8 +16,8 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "ccache.h" -#include "compopt.h" +#include "ccache.hpp" +#include "compopt.hpp" // The option it too hard to handle at all. #define TOO_HARD (1 << 0) @@ -150,9 +150,10 @@ find(const char *option) { struct compopt key; key.name = option; - return bsearch( + void* result = bsearch( &key, compopts, ARRAY_SIZE(compopts), sizeof(compopts[0]), compare_compopts); + return static_cast(result); } static const struct compopt * @@ -160,9 +161,10 @@ find_prefix(const char *option) { struct compopt key; key.name = option; - return bsearch( + void* result = bsearch( &key, compopts, ARRAY_SIZE(compopts), sizeof(compopts[0]), compare_prefix_compopts); + return static_cast(result); } // Runs fn on the first two characters of option. diff --git a/src/compopt.h b/src/compopt.hpp similarity index 98% rename from src/compopt.h rename to src/compopt.hpp index 4c37aab1a..84a6c2f48 100644 --- a/src/compopt.h +++ b/src/compopt.hpp @@ -19,7 +19,7 @@ #ifndef CCACHE_COMPOPT_H #define CCACHE_COMPOPT_H -#include "system.h" +#include "system.hpp" bool compopt_short(bool (*fn)(const char *option), const char *option); bool compopt_affects_cpp(const char *option); diff --git a/src/compr_none.c b/src/compr_none.cpp similarity index 94% rename from src/compr_none.c rename to src/compr_none.cpp index 16b3f1469..7d5cfa91f 100644 --- a/src/compr_none.c +++ b/src/compr_none.cpp @@ -16,7 +16,7 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "compression.h" +#include "compression.hpp" struct state { FILE *output; @@ -26,7 +26,7 @@ struct state { static struct compr_state * compr_none_init(FILE *output, int8_t level, XXH64_state_t *checksum) { - struct state *state = malloc(sizeof(struct state)); + auto state = static_cast(malloc(sizeof(struct state))); state->output = output; state->checksum = checksum; (void)level; diff --git a/src/compr_zstd.c b/src/compr_zstd.cpp similarity index 97% rename from src/compr_zstd.c rename to src/compr_zstd.cpp index a0381f0e5..873b9e7f9 100644 --- a/src/compr_zstd.c +++ b/src/compr_zstd.cpp @@ -16,8 +16,8 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "ccache.h" -#include "compression.h" +#include "ccache.hpp" +#include "compression.hpp" #include @@ -36,7 +36,7 @@ struct state { static struct compr_state * compr_zstd_init(FILE *output, int8_t level, XXH64_state_t *checksum) { - struct state *state = malloc(sizeof(struct state)); + auto state = static_cast(malloc(sizeof(struct state))); state->output = output; state->checksum = checksum; state->stream = ZSTD_createCStream(); diff --git a/src/compress.c b/src/compress.cpp similarity index 90% rename from src/compress.c rename to src/compress.cpp index 1d815a862..e9299058e 100644 --- a/src/compress.c +++ b/src/compress.cpp @@ -16,11 +16,11 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "ccache.h" +#include "ccache.hpp" -#include "common_header.h" -#include "manifest.h" -#include "result.h" +#include "common_header.hpp" +#include "manifest.hpp" +#include "result.hpp" static bool get_content_size( @@ -65,32 +65,40 @@ measure_fn(const char *fname, struct stat *st) char *p = x_basename(fname); if (str_eq(p, "stats")) { - goto out; + free(p); + return; } if (str_startswith(p, ".nfs")) { // Ignore temporary NFS files that may be left for open but deleted files. - goto out; + free(p); + return; } if (strstr(p, ".tmp.")) { // Ignore tmp files since they are transient. - goto out; + free(p); + return; } if (strstr(p, "CACHEDIR.TAG")) { - goto out; + free(p); + return; } + free(p); + on_disk_size += file_size(st); size_t content_size = 0; const char *file_ext = get_extension(p); bool is_compressible = false; if (str_eq(file_ext, ".manifest")) { - is_compressible = get_content_size(fname, MANIFEST_MAGIC, MANIFEST_VERSION, &content_size); + is_compressible = get_content_size( + fname, MANIFEST_MAGIC, MANIFEST_VERSION, &content_size); } else if (str_eq(file_ext, ".result")) { - is_compressible = get_content_size(fname, RESULT_MAGIC, RESULT_VERSION, &content_size); + is_compressible = get_content_size( + fname, RESULT_MAGIC, RESULT_VERSION, &content_size); } if (is_compressible) { @@ -99,9 +107,6 @@ measure_fn(const char *fname, struct stat *st) } else { incompr_size += st->st_size; } - -out: - free(p); } // Process up all cache subdirectories. diff --git a/src/compression.c b/src/compression.cpp similarity index 97% rename from src/compression.c rename to src/compression.cpp index d74daca0c..f210541fa 100644 --- a/src/compression.c +++ b/src/compression.cpp @@ -16,8 +16,8 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "compression.h" -#include "conf.h" +#include "compression.hpp" +#include "conf.hpp" extern struct conf *conf; diff --git a/src/compression.h b/src/compression.hpp similarity index 99% rename from src/compression.h rename to src/compression.hpp index 1b272070d..3cddb3de5 100644 --- a/src/compression.h +++ b/src/compression.hpp @@ -19,7 +19,7 @@ #ifndef COMPRESSION_H #define COMPRESSION_H -#include "system.h" +#include "system.hpp" #include "third_party/xxhash.h" struct compr_state; diff --git a/src/conf.c b/src/conf.cpp similarity index 97% rename from src/conf.c rename to src/conf.cpp index 2cba90026..379a23156 100644 --- a/src/conf.c +++ b/src/conf.cpp @@ -16,10 +16,10 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "conf.h" -#include "confitems.h" -#include "envtoconfitems.h" -#include "ccache.h" +#include "conf.hpp" +#include "confitems.hpp" +#include "envtoconfitems.hpp" +#include "ccache.hpp" enum handle_conf_result { HANDLE_CONF_OK, @@ -128,7 +128,7 @@ parse_line(const char *line, char **key, char **value, char **errmsg) struct conf * conf_create(void) { - struct conf *conf = x_malloc(sizeof(*conf)); + auto conf = static_cast(x_malloc(sizeof(struct conf))); conf->base_dir = x_strdup(""); conf->cache_dir = format("%s/.ccache", get_home_directory()); @@ -166,7 +166,8 @@ conf_create(void) conf->umask = UINT_MAX; // Default: don't set umask. conf->unify = false; - conf->item_origins = x_malloc(confitems_count() * sizeof(char *)); + conf->item_origins = static_cast( + x_malloc(confitems_count() * sizeof(char *))); for (size_t i = 0; i < confitems_count(); ++i) { conf->item_origins[i] = "default"; } diff --git a/src/conf.h b/src/conf.hpp similarity index 99% rename from src/conf.h rename to src/conf.hpp index 7049cf113..5fc408150 100644 --- a/src/conf.h +++ b/src/conf.hpp @@ -19,7 +19,7 @@ #ifndef CONF_H #define CONF_H -#include "system.h" +#include "system.hpp" struct conf { char *base_dir; diff --git a/src/confitems.c b/src/confitems.cpp similarity index 99% rename from src/confitems.c rename to src/confitems.cpp index 1194b2412..1b4023f49 100644 --- a/src/confitems.c +++ b/src/confitems.cpp @@ -16,8 +16,8 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "confitems.h" -#include "ccache.h" +#include "confitems.hpp" +#include "ccache.hpp" static char * format_string(const void *value) diff --git a/src/confitems.gperf b/src/confitems.gperf index 972e0bdd3..fe9a1201b 100644 --- a/src/confitems.gperf +++ b/src/confitems.gperf @@ -6,8 +6,8 @@ %define lookup-function-name confitems_get %define initializer-suffix ,0,0,NULL,NULL,NULL %{ -#include "confitems.h" -#include "conf.h" +#include "confitems.hpp" +#include "conf.hpp" #undef bool #define ITEM_ENTRY(name, type, verify_fn) \ diff --git a/src/confitems.h b/src/confitems.hpp similarity index 99% rename from src/confitems.h rename to src/confitems.hpp index 53d53303a..8505d0997 100644 --- a/src/confitems.h +++ b/src/confitems.hpp @@ -19,7 +19,7 @@ #ifndef CONFITEMS_H #define CONFITEMS_H -#include "system.h" +#include "system.hpp" typedef bool (*conf_item_parser)(const char *str, void *result, char **errmsg); typedef bool (*conf_item_verifier)(const void *value, char **errmsg); diff --git a/src/counters.c b/src/counters.cpp similarity index 90% rename from src/counters.c rename to src/counters.cpp index 757313180..d846f9d83 100644 --- a/src/counters.c +++ b/src/counters.cpp @@ -18,14 +18,14 @@ // A simple array of unsigned integers used for the statistics counters. -#include "ccache.h" +#include "ccache.hpp" // Allocate and initialize a struct counters. Data entries up to the size are // set to 0. struct counters * counters_init(size_t initial_size) { - struct counters *c = x_malloc(sizeof(*c)); + auto c = static_cast(x_malloc(sizeof(counters))); c->data = NULL; c->size = 0; c->allocated = 0; @@ -54,7 +54,8 @@ counters_resize(struct counters *c, size_t new_size) realloc = true; } if (realloc) { - c->data = x_realloc(c->data, c->allocated * sizeof(c->data[0])); + c->data = static_cast( + x_realloc(c->data, c->allocated * sizeof(c->data[0]))); } for (size_t i = c->size; i < new_size; i++) { c->data[i] = 0; diff --git a/src/counters.h b/src/counters.hpp similarity index 100% rename from src/counters.h rename to src/counters.hpp diff --git a/src/decompr_none.c b/src/decompr_none.cpp similarity index 94% rename from src/decompr_none.c rename to src/decompr_none.cpp index 25087e153..e4c87c7e0 100644 --- a/src/decompr_none.c +++ b/src/decompr_none.cpp @@ -16,7 +16,7 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "compression.h" +#include "compression.hpp" struct state { FILE *input; @@ -27,7 +27,7 @@ struct state { static struct decompr_state * decompr_none_init(FILE *input, XXH64_state_t *checksum) { - struct state *state = malloc(sizeof(struct state)); + auto state = static_cast(malloc(sizeof(struct state))); state->input = input; state->checksum = checksum; state->failed = false; diff --git a/src/decompr_zstd.c b/src/decompr_zstd.cpp similarity index 96% rename from src/decompr_zstd.c rename to src/decompr_zstd.cpp index 082f93668..b6691654e 100644 --- a/src/decompr_zstd.c +++ b/src/decompr_zstd.cpp @@ -16,8 +16,8 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "ccache.h" -#include "compression.h" +#include "ccache.hpp" +#include "compression.hpp" #include @@ -42,7 +42,7 @@ struct state { static struct decompr_state * decompr_zstd_init(FILE *input, XXH64_state_t *checksum) { - struct state *state = malloc(sizeof(struct state)); + auto state = static_cast(malloc(sizeof(struct state))); state->input = input; state->checksum = checksum; diff --git a/src/envtoconfitems.gperf b/src/envtoconfitems.gperf index 042aadc21..f7703f143 100644 --- a/src/envtoconfitems.gperf +++ b/src/envtoconfitems.gperf @@ -7,7 +7,7 @@ %define slot-name env_name %define initializer-suffix ,"" %{ -#include "envtoconfitems.h" +#include "envtoconfitems.hpp" %} struct env_to_conf_item; %% diff --git a/src/envtoconfitems.h b/src/envtoconfitems.hpp similarity index 92% rename from src/envtoconfitems.h rename to src/envtoconfitems.hpp index dcd08559f..8e5553c37 100644 --- a/src/envtoconfitems.h +++ b/src/envtoconfitems.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2018 Joel Rosdahl and other contributors +// Copyright (C) 2018-2019 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -19,7 +19,7 @@ #ifndef ENVTOCONFITEMS_H #define ENVTOCONFITEMS_H -#include "system.h" +#include "system.hpp" struct env_to_conf_item { const char *env_name; @@ -27,6 +27,7 @@ struct env_to_conf_item { }; const struct env_to_conf_item *envtoconfitems_get(const char *str, size_t len); + size_t envtoconfitems_count(void); #endif diff --git a/src/execute.c b/src/execute.cpp similarity index 97% rename from src/execute.c rename to src/execute.cpp index d822e139c..2a31bfae7 100644 --- a/src/execute.c +++ b/src/execute.cpp @@ -17,7 +17,7 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "ccache.h" +#include "ccache.hpp" extern struct conf *conf; @@ -51,7 +51,7 @@ win32argvtos(char *prefix, char **argv, int *length) k += (bs << 1) + 3; } while ((arg = argv[i++])); - char *ptr = malloc(k + 1); + char *ptr = static_cast(malloc(k + 1)); char *str = ptr; if (!str) { *length = 0; @@ -68,8 +68,10 @@ win32argvtos(char *prefix, char **argv, int *length) case '\\': bs++; break; + // Fallthrough. case '"': bs = (bs << 1) + 1; + // Fallthrough. default: while (bs && bs--) { *ptr++ = '\\'; @@ -372,7 +374,7 @@ print_command(FILE *fp, char **argv) } char * -format_command(char **argv) +format_command(const char* const* argv) { size_t len = 0; for (int i = 0; argv[i]; i++) { @@ -380,13 +382,13 @@ format_command(char **argv) len += strlen(argv[i]); } len += 1; - char *buf = x_malloc(len + 1); + char *buf = static_cast(x_malloc(len + 1)); char *p = buf; for (int i = 0; argv[i]; i++) { if (i != 0) { *p++ = ' '; } - for (char *q = argv[i]; *q != '\0'; q++) { + for (const char *q = argv[i]; *q != '\0'; q++) { *p++ = *q; } } diff --git a/src/exitfn.c b/src/exitfn.cpp similarity index 87% rename from src/exitfn.c rename to src/exitfn.cpp index 67cf1bacc..bc0562f74 100644 --- a/src/exitfn.c +++ b/src/exitfn.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2010-2018 Joel Rosdahl and other contributors +// Copyright (C) 2010-2019 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -16,7 +16,7 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "ccache.h" +#include "ccache.hpp" struct exit_function { void (*function)(void *); @@ -52,8 +52,8 @@ exitfn_init(void) void exitfn_add_nullary(void (*function)(void)) { - struct nullary_exit_function *p = x_malloc(sizeof(*p)); - p->function = function; + auto p = static_cast(x_malloc(sizeof(exit_function))); + p->function = reinterpret_cast(function); exitfn_add(call_nullary_exit_function, p); } @@ -62,7 +62,7 @@ exitfn_add_nullary(void (*function)(void)) void exitfn_add(void (*function)(void *), void *context) { - struct exit_function *p = x_malloc(sizeof(*p)); + auto p = static_cast(x_malloc(sizeof(exit_function))); p->function = function; p->context = context; p->next = exit_functions; @@ -75,7 +75,7 @@ exitfn_add(void (*function)(void *), void *context) void exitfn_add_last(void (*function)(void *), void *context) { - struct exit_function *p = x_malloc(sizeof(*p)); + auto p = static_cast(x_malloc(sizeof(exit_function))); p->function = function; p->context = context; p->next = NULL; diff --git a/src/hash.c b/src/hash.cpp similarity index 95% rename from src/hash.c rename to src/hash.cpp index b194c48ff..b3d6d4689 100644 --- a/src/hash.c +++ b/src/hash.cpp @@ -17,8 +17,8 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "ccache.h" -#include "hash.h" +#include "ccache.hpp" +#include "hash.hpp" #include #define HASH_DELIMITER "\000cCaChE" @@ -63,7 +63,7 @@ do_debug_text(struct hash *hash, const void *s, size_t len) struct hash * hash_init(void) { - struct hash *hash = malloc(sizeof(struct hash)); + auto hash = static_cast(malloc(sizeof(struct hash))); blake2b_init(&hash->state, DIGEST_SIZE); hash->debug_binary = NULL; hash->debug_text = NULL; @@ -73,7 +73,7 @@ hash_init(void) struct hash * hash_copy(struct hash *hash) { - struct hash *result = malloc(sizeof(struct hash)); + auto result = static_cast(malloc(sizeof(struct hash))); result->state = hash->state; result->debug_binary = NULL; result->debug_text = NULL; diff --git a/src/hash.h b/src/hash.hpp similarity index 99% rename from src/hash.h rename to src/hash.hpp index 8a2386de3..3f7f1eef9 100644 --- a/src/hash.h +++ b/src/hash.hpp @@ -19,7 +19,7 @@ #ifndef HASH_H #define HASH_H -#include "system.h" +#include "system.hpp" #define DIGEST_SIZE 20 #define DIGEST_STRING_BUFFER_SIZE (2 * DIGEST_SIZE + 1) diff --git a/src/hashutil.c b/src/hashutil.cpp similarity index 98% rename from src/hashutil.c rename to src/hashutil.cpp index 548b30767..c9848a570 100644 --- a/src/hashutil.c +++ b/src/hashutil.cpp @@ -16,9 +16,9 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "ccache.h" -#include "hashutil.h" -#include "macroskip.h" +#include "ccache.hpp" +#include "hashutil.hpp" +#include "macroskip.hpp" #include "third_party/xxhash.h" unsigned @@ -260,7 +260,7 @@ hash_command_output(struct hash *hash, const char *command, dup2(pipefd[1], 1); dup2(pipefd[1], 2); _exit(execvp(args->argv[0], args->argv)); - return false; // Never reached. + // Never reached. } else { // Parent. args_free(args); diff --git a/src/hashutil.h b/src/hashutil.hpp similarity index 97% rename from src/hashutil.h rename to src/hashutil.hpp index e5b47d6ba..083f9892f 100644 --- a/src/hashutil.h +++ b/src/hashutil.hpp @@ -19,8 +19,8 @@ #ifndef HASHUTIL_H #define HASHUTIL_H -#include "conf.h" -#include "hash.h" +#include "conf.hpp" +#include "hash.hpp" #include unsigned hash_from_string(void *str); diff --git a/src/int_bytes_conversion.h b/src/int_bytes_conversion.hpp similarity index 100% rename from src/int_bytes_conversion.h rename to src/int_bytes_conversion.hpp diff --git a/src/language.c b/src/language.cpp similarity index 98% rename from src/language.c rename to src/language.cpp index 1dbf96208..24b99ff00 100644 --- a/src/language.c +++ b/src/language.cpp @@ -16,9 +16,9 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "ccache.h" +#include "ccache.hpp" -#include "language.h" +#include "language.hpp" // Supported file extensions and corresponding languages (as in parameter to // the -x option). diff --git a/src/language.h b/src/language.hpp similarity index 100% rename from src/language.h rename to src/language.hpp diff --git a/src/lockfile.c b/src/lockfile.cpp similarity index 97% rename from src/lockfile.c rename to src/lockfile.cpp index d0b840025..d904b190a 100644 --- a/src/lockfile.c +++ b/src/lockfile.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2010-2018 Joel Rosdahl and other contributors +// Copyright (C) 2010-2019 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -16,7 +16,7 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "ccache.h" +#include "ccache.hpp" // This function acquires a lockfile for the given path. Returns true if the // lock was acquired, otherwise false. If the lock has been considered stale @@ -73,7 +73,7 @@ lockfile_acquire(const char *path, unsigned staleness_limit) } free(content); const size_t bufsize = 1024; - content = x_malloc(bufsize); + content = static_cast(x_malloc(bufsize)); int len = read(fd, content, bufsize - 1); if (len == -1) { cc_log("lockfile_acquire: read %s: %s", lockfile, strerror(errno)); diff --git a/src/macroskip.h b/src/macroskip.hpp similarity index 100% rename from src/macroskip.h rename to src/macroskip.hpp diff --git a/src/main.c b/src/main.cpp similarity index 100% rename from src/main.c rename to src/main.cpp diff --git a/src/manifest.c b/src/manifest.cpp similarity index 90% rename from src/manifest.c rename to src/manifest.cpp index 791c8ebdc..788f313f0 100644 --- a/src/manifest.c +++ b/src/manifest.cpp @@ -16,13 +16,13 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "ccache.h" +#include "ccache.hpp" #include "third_party/hashtable_itr.h" -#include "hashutil.h" -#include "common_header.h" -#include "compression.h" -#include "int_bytes_conversion.h" -#include "manifest.h" +#include "hashutil.hpp" +#include "common_header.hpp" +#include "compression.hpp" +#include "int_bytes_conversion.hpp" +#include "manifest.hpp" #include "third_party/xxhash.h" // Manifest data format @@ -100,7 +100,7 @@ // 1: Introduced in ccache 3.0. (Files are always compressed with gzip.) // 2: Introduced in ccache 3.8. -const char MANIFEST_MAGIC[4] = "cCmF"; +const char MANIFEST_MAGIC[4] = {'c', 'C', 'm', 'F'}; static const uint32_t MAX_MANIFEST_ENTRIES = 100; static const uint32_t MAX_MANIFEST_FILE_INFO_ENTRIES = 10000; @@ -228,7 +228,7 @@ free_manifest(struct manifest *mf) #define READ_STR(str_var, len_var) \ do { \ READ_UINT16(len_var); \ - (str_var) = x_malloc(len_var + 1); \ + (str_var) = static_cast(x_malloc(len_var + 1)); \ READ_BYTES(str_var, len_var); \ str_var[len_var] = '\0'; \ } while (false) @@ -236,7 +236,7 @@ free_manifest(struct manifest *mf) static struct manifest * create_empty_manifest(void) { - struct manifest *mf = x_malloc(sizeof(*mf)); + auto mf = static_cast(x_malloc(sizeof(manifest))); mf->n_files = 0; mf->files = NULL; mf->n_file_infos = 0; @@ -256,6 +256,8 @@ read_manifest(const char *path, char **errmsg) struct decompr_state *decompr_state = NULL; *errmsg = NULL; XXH64_state_t *checksum = XXH64_createState(); + uint64_t actual_checksum; + uint64_t expected_checksum; FILE *f = fopen(path, "rb"); if (!f) { @@ -276,13 +278,14 @@ read_manifest(const char *path, char **errmsg) } READ_UINT32(mf->n_files); - mf->files = x_calloc(mf->n_files, sizeof(*mf->files)); + mf->files = static_cast(x_calloc(mf->n_files, sizeof(file))); for (uint32_t i = 0; i < mf->n_files; i++) { READ_STR(mf->files[i].path, mf->files[i].path_len); } READ_UINT32(mf->n_file_infos); - mf->file_infos = x_calloc(mf->n_file_infos, sizeof(*mf->file_infos)); + mf->file_infos = + static_cast(x_calloc(mf->n_file_infos, sizeof(file_info))); for (uint32_t i = 0; i < mf->n_file_infos; i++) { READ_UINT32(mf->file_infos[i].index); READ_BYTES(mf->file_infos[i].digest.bytes, DIGEST_SIZE); @@ -292,20 +295,18 @@ read_manifest(const char *path, char **errmsg) } READ_UINT32(mf->n_results); - mf->results = x_calloc(mf->n_results, sizeof(*mf->results)); + mf->results = static_cast(x_calloc(mf->n_results, sizeof(result))); for (uint32_t i = 0; i < mf->n_results; i++) { READ_UINT32(mf->results[i].n_file_info_indexes); - mf->results[i].file_info_indexes = - x_calloc(mf->results[i].n_file_info_indexes, - sizeof(*mf->results[i].file_info_indexes)); + mf->results[i].file_info_indexes = static_cast( + x_calloc(mf->results[i].n_file_info_indexes, sizeof(uint32_t))); for (uint32_t j = 0; j < mf->results[i].n_file_info_indexes; j++) { READ_UINT32(mf->results[i].file_info_indexes[j]); } READ_BYTES(mf->results[i].name.bytes, DIGEST_SIZE); } - uint64_t actual_checksum = XXH64_digest(checksum); - uint64_t expected_checksum; + actual_checksum = XXH64_digest(checksum); READ_UINT64(expected_checksum); if (actual_checksum == expected_checksum) { success = true; @@ -396,16 +397,16 @@ write_manifest(FILE *f, const struct manifest *mf) struct compressor *compressor; struct compr_state *compr_state; if (!common_header_initialize_for_writing( - &header, - f, - MANIFEST_MAGIC, - MANIFEST_VERSION, - compression_type_from_config(), - compression_level_from_config(), - content_size, - checksum, - &compressor, - &compr_state)) { + &header, + f, + MANIFEST_MAGIC, + MANIFEST_VERSION, + compression_type_from_config(), + compression_level_from_config(), + content_size, + checksum, + &compressor, + &compr_state)) { goto out; } @@ -452,13 +453,13 @@ verify_result(struct conf *conf, struct manifest *mf, struct result *result, for (uint32_t i = 0; i < result->n_file_info_indexes; i++) { struct file_info *fi = &mf->file_infos[result->file_info_indexes[i]]; char *path = mf->files[fi->index].path; - struct file_stats *st = hashtable_search(stated_files, path); + auto st = static_cast(hashtable_search(stated_files, path)); if (!st) { struct stat file_stat; if (x_stat(path, &file_stat) != 0) { return false; } - st = x_malloc(sizeof(*st)); + st = static_cast(x_malloc(sizeof(file_stats))); st->size = file_stat.st_size; st->mtime = file_stat.st_mtime; st->ctime = file_stat.st_ctime; @@ -497,7 +498,7 @@ verify_result(struct conf *conf, struct manifest *mf, struct result *result, } } - struct digest *actual = hashtable_search(hashed_files, path); + auto actual = static_cast(hashtable_search(hashed_files, path)); if (!actual) { struct hash *hash = hash_init(); int ret = hash_source_code_file(conf, hash, path); @@ -511,7 +512,7 @@ verify_result(struct conf *conf, struct manifest *mf, struct result *result, return false; } - actual = malloc(sizeof(*actual)); + actual = static_cast(malloc(sizeof(digest))); hash_result_as_bytes(hash, actual); hashtable_insert(hashed_files, x_strdup(path), actual); hash_free(hash); @@ -530,7 +531,7 @@ create_file_index_map(struct file *files, uint32_t len) struct hashtable *h = create_hashtable(1000, hash_from_string, strings_equal); for (uint32_t i = 0; i < len; i++) { - uint32_t *index = x_malloc(sizeof(*index)); + auto index = static_cast(x_malloc(sizeof(uint32_t))); *index = i; hashtable_insert(h, x_strdup(files[i].path), index); } @@ -543,9 +544,9 @@ create_file_info_index_map(struct file_info *infos, uint32_t len) struct hashtable *h = create_hashtable(1000, hash_from_file_info, file_infos_equal); for (uint32_t i = 0; i < len; i++) { - struct file_info *fi = x_malloc(sizeof(*fi)); + auto fi = static_cast(x_malloc(sizeof(file_info))); *fi = infos[i]; - uint32_t *index = x_malloc(sizeof(*index)); + uint32_t *index = static_cast(x_malloc(sizeof(uint32_t))); *index = i; hashtable_insert(h, fi, index); } @@ -556,13 +557,13 @@ static uint32_t get_include_file_index(struct manifest *mf, char *path, struct hashtable *mf_files) { - uint32_t *index = hashtable_search(mf_files, path); + uint32_t *index = static_cast(hashtable_search(mf_files, path)); if (index) { return *index; } uint32_t n = mf->n_files; - mf->files = x_realloc(mf->files, (n + 1) * sizeof(*mf->files)); + mf->files = static_cast(x_realloc(mf->files, (n + 1) * sizeof(file))); mf->n_files++; mf->files[n].path_len = strlen(path); mf->files[n].path = x_strdup(path); @@ -603,13 +604,14 @@ get_file_info_index(struct manifest *mf, fi.fsize = 0; } - uint32_t *fi_index = hashtable_search(mf_file_infos, &fi); + auto fi_index = static_cast(hashtable_search(mf_file_infos, &fi)); if (fi_index) { return *fi_index; } uint32_t n = mf->n_file_infos; - mf->file_infos = x_realloc(mf->file_infos, (n + 1) * sizeof(*mf->file_infos)); + mf->file_infos = static_cast( + x_realloc(mf->file_infos, (n + 1) * sizeof(file_info))); mf->n_file_infos++; mf->file_infos[n] = fi; return n; @@ -631,8 +633,8 @@ add_file_info_indexes(uint32_t *indexes, uint32_t size, struct hashtable_itr *iter = hashtable_iterator(included_files); uint32_t i = 0; do { - char *path = hashtable_iterator_key(iter); - struct digest *digest = hashtable_iterator_value(iter); + auto path = static_cast(hashtable_iterator_key(iter)); + auto digest = static_cast(hashtable_iterator_value(iter)); indexes[i] = get_file_info_index(mf, path, digest, mf_files, mf_file_infos); i++; @@ -649,14 +651,15 @@ add_result_entry(struct manifest *mf, struct hashtable *included_files) { uint32_t n_results = mf->n_results; - mf->results = x_realloc(mf->results, (n_results + 1) * sizeof(*mf->results)); + mf->results = static_cast( + x_realloc(mf->results, (n_results + 1) * sizeof(result))); mf->n_results++; struct result *result = &mf->results[n_results]; uint32_t n_fii = hashtable_count(included_files); result->n_file_info_indexes = n_fii; - result->file_info_indexes = - x_malloc(n_fii * sizeof(*result->file_info_indexes)); + result->file_info_indexes = static_cast( + x_malloc(n_fii * sizeof(uint32_t))); add_file_info_indexes(result->file_info_indexes, n_fii, mf, included_files); result->name = *result_digest; } @@ -685,7 +688,7 @@ manifest_get(struct conf *conf, const char *manifest_path) for (uint32_t i = mf->n_results; i > 0; i--) { if (verify_result(conf, mf, &mf->results[i - 1], stated_files, hashed_files)) { - name = x_malloc(sizeof(*name)); + name = static_cast(x_malloc(sizeof(digest))); *name = mf->results[i - 1].name; goto out; } diff --git a/src/manifest.h b/src/manifest.hpp similarity index 96% rename from src/manifest.h rename to src/manifest.hpp index adf0db380..7bbc7c127 100644 --- a/src/manifest.h +++ b/src/manifest.hpp @@ -19,8 +19,8 @@ #ifndef MANIFEST_H #define MANIFEST_H -#include "conf.h" -#include "hashutil.h" +#include "conf.hpp" +#include "hashutil.hpp" #include "third_party/hashtable.h" extern const char MANIFEST_MAGIC[4]; diff --git a/src/result.c b/src/result.cpp similarity index 88% rename from src/result.c rename to src/result.cpp index 72ceed85a..45eac6397 100644 --- a/src/result.c +++ b/src/result.cpp @@ -16,12 +16,12 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "ccache.h" -#include "common_header.h" -#include "int_bytes_conversion.h" -#include "compression.h" -#include "hash.h" -#include "result.h" +#include "ccache.hpp" +#include "common_header.hpp" +#include "int_bytes_conversion.hpp" +#include "compression.hpp" +#include "hash.hpp" +#include "result.hpp" // Result data format // ================== @@ -84,7 +84,7 @@ extern const struct conf *conf; extern char *stats_file; -const char RESULT_MAGIC[4] = "cCrS"; +const char RESULT_MAGIC[4] = {'c', 'C', 'r', 'S'}; enum { // File data stored inside the result file. @@ -124,7 +124,7 @@ typedef bool (*write_entry_fn)( struct result_files * result_files_init(void) { - struct result_files *list = x_malloc(sizeof(*list)); + auto list = static_cast(x_malloc(sizeof(result_files))); list->n_files = 0; list->files = NULL; list->sizes = NULL; @@ -137,8 +137,10 @@ result_files_add(struct result_files *list, const char *path, const char *suffix) { uint32_t n = list->n_files; - list->files = x_realloc(list->files, (n + 1) * sizeof(*list->files)); - list->sizes = x_realloc(list->sizes, (n + 1) * sizeof(*list->sizes)); + list->files = static_cast( + x_realloc(list->files, (n + 1) * sizeof(result_file))); + list->sizes = static_cast( + x_realloc(list->sizes, (n + 1) * sizeof(uint64_t))); struct result_file *f = &list->files[list->n_files]; list->n_files++; @@ -192,7 +194,7 @@ read_embedded_file_entry( FILE *dump_stream) { (void)result_path_in_cache; - + bool found = false; bool success = false; FILE *subfile = NULL; @@ -206,7 +208,6 @@ read_embedded_file_entry( uint64_t file_len; READ_UINT64(file_len); - bool found = false; if (dump_stream) { fprintf( dump_stream, @@ -397,14 +398,14 @@ read_result( struct common_header header; if (!common_header_initialize_for_reading( - &header, - f, - RESULT_MAGIC, - RESULT_VERSION, - &decompressor, - &decompr_state, - checksum, - errmsg)) { + &header, + f, + RESULT_MAGIC, + RESULT_VERSION, + &decompressor, + &decompr_state, + checksum, + errmsg)) { goto out; } @@ -446,17 +447,19 @@ read_result( goto out; } - uint64_t actual_checksum = XXH64_digest(checksum); - uint64_t expected_checksum; - READ_UINT64(expected_checksum); - - if (actual_checksum == expected_checksum) { - success = true; - } else { - *errmsg = format( - "Incorrect checksum (actual %016llx, expected %016llx)", - (unsigned long long)actual_checksum, - (unsigned long long)expected_checksum); + { + uint64_t actual_checksum = XXH64_digest(checksum); + uint64_t expected_checksum; + READ_UINT64(expected_checksum); + + if (actual_checksum == expected_checksum) { + success = true; + } else { + *errmsg = format( + "Incorrect checksum (actual %016llx, expected %016llx)", + (unsigned long long)actual_checksum, + (unsigned long long)expected_checksum); + } } out: @@ -504,8 +507,11 @@ write_embedded_file_entry( const struct result_file *file) { (void)result_path_in_cache; - bool success = false; + size_t suffix_len; + FILE* f; + char buf[READ_BUFFER_SIZE]; + size_t remain; cc_log( "Storing embedded file #%u %s (%llu bytes) from %s", @@ -515,18 +521,17 @@ write_embedded_file_entry( file->path); WRITE_BYTE(EMBEDDED_FILE_MARKER); - size_t suffix_len = strlen(file->suffix); + suffix_len = strlen(file->suffix); WRITE_BYTE(suffix_len); WRITE_BYTES(file->suffix, suffix_len); WRITE_UINT64(file->size); - FILE *f = fopen(file->path, "rb"); + f = fopen(file->path, "rb"); if (!f) { cc_log("Failed to open %s for reading", file->path); goto error; } - char buf[READ_BUFFER_SIZE]; - size_t remain = file->size; + remain = file->size; while (remain > 0) { size_t n = MIN(remain, sizeof(buf)); if (fread(buf, 1, n, f) != n) { @@ -552,6 +557,14 @@ write_raw_file_entry( const struct result_file *file) { bool success = false; + size_t suffix_len; + char* raw_file; + struct stat old_stat; + bool old_existed; + struct stat new_stat; + bool new_exists; + size_t old_size; + size_t new_size; cc_log( "Storing raw file #%u %s (%llu bytes) from %s", @@ -561,23 +574,19 @@ write_raw_file_entry( file->path); WRITE_BYTE(RAW_FILE_MARKER); - size_t suffix_len = strlen(file->suffix); + suffix_len = strlen(file->suffix); WRITE_BYTE(suffix_len); WRITE_BYTES(file->suffix, suffix_len); WRITE_UINT64(file->size); - char *raw_file = get_raw_file_path(result_path_in_cache, entry_number); - struct stat old_stat; - bool old_existed = stat(raw_file, &old_stat) == 0; - + raw_file = get_raw_file_path(result_path_in_cache, entry_number); + old_existed = stat(raw_file, &old_stat) == 0; success = copy_raw_file(file->path, raw_file, true); - - struct stat new_stat; - bool new_exists = stat(raw_file, &new_stat) == 0; + new_exists = stat(raw_file, &new_stat) == 0; free(raw_file); - size_t old_size = old_existed ? file_size(&old_stat) : 0; - size_t new_size = new_exists ? file_size(&new_stat) : 0; + old_size = old_existed ? file_size(&old_stat) : 0; + new_size = new_exists ? file_size(&new_stat) : 0; stats_update_size( stats_file, new_size - old_size, @@ -627,7 +636,7 @@ write_result( ? write_raw_file_entry : write_embedded_file_entry; if (!write_entry( - compressor, compr_state, result_path_in_cache, i, &list->files[i])) { + compressor, compr_state, result_path_in_cache, i, &list->files[i])) { goto error; } } @@ -663,6 +672,8 @@ bool result_put(const char *path, struct result_files *list) { bool ret = false; XXH64_state_t *checksum = XXH64_createState(); + bool ok; + uint64_t content_size; char *tmp_file = format("%s.tmp", path); int fd = create_tmp_fd(&tmp_file); @@ -672,7 +683,7 @@ bool result_put(const char *path, struct result_files *list) goto out; } - uint64_t content_size = COMMON_HEADER_SIZE; + content_size = COMMON_HEADER_SIZE; content_size += 1; // n_entries for (uint32_t i = 0; i < list->n_files; i++) { content_size += 1; // embedded_file_marker @@ -687,21 +698,21 @@ bool result_put(const char *path, struct result_files *list) struct compressor *compressor; struct compr_state *compr_state; if (!common_header_initialize_for_writing( - &header, - f, - RESULT_MAGIC, - RESULT_VERSION, - compression_type_from_config(), - compression_level_from_config(), - content_size, - checksum, - &compressor, - &compr_state)) { + &header, + f, + RESULT_MAGIC, + RESULT_VERSION, + compression_type_from_config(), + compression_level_from_config(), + content_size, + checksum, + &compressor, + &compr_state)) { goto out; } - bool ok = write_result(list, compressor, compr_state, checksum, path) - && compressor->free(compr_state); + ok = write_result(list, compressor, compr_state, checksum, path) + && compressor->free(compr_state); if (!ok) { cc_log("Failed to write result file"); goto out; diff --git a/src/result.h b/src/result.hpp similarity index 98% rename from src/result.h rename to src/result.hpp index cb2173148..8e059ef48 100644 --- a/src/result.h +++ b/src/result.hpp @@ -19,7 +19,7 @@ #ifndef RESULT_H #define RESULT_H -#include "conf.h" +#include "conf.hpp" extern const char RESULT_MAGIC[4]; #define RESULT_VERSION 1 diff --git a/src/stats.c b/src/stats.cpp similarity index 99% rename from src/stats.c rename to src/stats.cpp index 4cf505d28..033b458e2 100644 --- a/src/stats.c +++ b/src/stats.cpp @@ -20,8 +20,8 @@ // Routines to handle the stats files. The stats file is stored one per cache // subdirectory to make this more scalable. -#include "ccache.h" -#include "hashutil.h" +#include "ccache.hpp" +#include "hashutil.hpp" #include #include diff --git a/src/system.h b/src/system.hpp similarity index 97% rename from src/system.h rename to src/system.hpp index 1bad3c8a6..2c1d6a0cb 100644 --- a/src/system.h +++ b/src/system.hpp @@ -21,6 +21,7 @@ #ifdef __MINGW32__ # define __USE_MINGW_ANSI_STDIO 1 +# define __STDC_FORMAT_MACROS 1 # define ATTRIBUTE_FORMAT_PRINTF __MINGW_PRINTF_FORMAT #else # define ATTRIBUTE_FORMAT_PRINTF printf @@ -70,6 +71,8 @@ extern char **environ; #define ESTALE -1 #endif +extern "C" { + #if !HAVE_VSNPRINTF int rpl_vsnprintf(char *, size_t, const char *, va_list); #define vsnprintf rpl_vsnprintf @@ -87,4 +90,6 @@ extern char **environ; #define asprintf rpl_asprintf #endif +} // extern "C" + #endif // CCACHE_SYSTEM_H diff --git a/src/third_party/hashtable.h b/src/third_party/hashtable.h index 91fb387d8..de3d25721 100644 --- a/src/third_party/hashtable.h +++ b/src/third_party/hashtable.h @@ -34,6 +34,10 @@ #include "config.h" +#if defined (__cplusplus) +extern "C" { +#endif + struct hashtable; /* Example of use: @@ -194,6 +198,10 @@ hashtable_count(struct hashtable *h); void hashtable_destroy(struct hashtable *h, int free_values); +#if defined (__cplusplus) +} +#endif + #endif /* HASHTABLE_CWC22_H */ /* diff --git a/src/third_party/hashtable_itr.h b/src/third_party/hashtable_itr.h index a0ac22cbc..823e55618 100644 --- a/src/third_party/hashtable_itr.h +++ b/src/third_party/hashtable_itr.h @@ -5,6 +5,10 @@ #include "hashtable.h" #include "hashtable_private.h" /* needed to enable inlining */ +#if defined (__cplusplus) +extern "C" { +#endif + /*****************************************************************************/ /* This struct is only concrete here to allow the inlining of two of the * accessor functions. */ @@ -84,7 +88,9 @@ int fnname (struct hashtable_itr *i, struct hashtable *h, keytype *k) \ return (hashtable_iterator_search(i,h,k)); \ } - +#if defined (__cplusplus) +} +#endif #endif /* HASHTABLE_ITR_CWC22_H */ diff --git a/src/third_party/hashtable_private.h b/src/third_party/hashtable_private.h index 260afcab9..b0a8c6581 100644 --- a/src/third_party/hashtable_private.h +++ b/src/third_party/hashtable_private.h @@ -5,6 +5,10 @@ #include "hashtable.h" +#if defined (__cplusplus) +extern "C" { +#endif + /*****************************************************************************/ struct entry { @@ -51,6 +55,10 @@ indexFor(unsigned int tablelength, unsigned int hashvalue) /*****************************************************************************/ +#if defined (__cplusplus) +} +#endif + #endif /* HASHTABLE_PRIVATE_CWC22_H */ /* diff --git a/src/third_party/snprintf.c b/src/third_party/snprintf.c index e4cdadea5..82f50668d 100644 --- a/src/third_party/snprintf.c +++ b/src/third_party/snprintf.c @@ -528,6 +528,10 @@ do { \ (len)++; \ } while (/* CONSTCOND */ 0) +#if defined (__cplusplus) +extern "C" { +#endif + static void fmtstr(char *, size_t *, size_t, const char *, int, int, int); static void fmtint(char *, size_t *, size_t, INTMAX_T, int, int, int, int); static void fmtflt(char *, size_t *, size_t, LDOUBLE, int, int, int, int *); @@ -2111,6 +2115,11 @@ do { \ } return (failed == 0) ? 0 : 1; } + +#if defined (__cplusplus) +} +#endif + #endif /* TEST_SNPRINTF */ /* vim: set joinspaces textwidth=80: */ diff --git a/src/unify.c b/src/unify.cpp similarity index 90% rename from src/unify.c rename to src/unify.cpp index 9b55abb30..e2f700e20 100644 --- a/src/unify.c +++ b/src/unify.cpp @@ -29,9 +29,9 @@ // syntactic errors is important to cope with C/C++ extensions in the local // compiler (for example, inline assembly systems). -#include "ccache.h" -#include "hash.h" -#include "unify.h" +#include "ccache.hpp" +#include "hash.hpp" +#include "unify.hpp" static bool print_unified = true; @@ -84,17 +84,17 @@ build_table(void) tokens[c].type |= C_HEX; } } - tokens['\''].type |= C_QUOTE; - tokens['"'].type |= C_QUOTE; - tokens['l'].type |= C_FLOAT; - tokens['L'].type |= C_FLOAT; - tokens['f'].type |= C_FLOAT; - tokens['F'].type |= C_FLOAT; - tokens['U'].type |= C_FLOAT; - tokens['u'].type |= C_FLOAT; + tokens[static_cast('\'')].type |= C_QUOTE; + tokens[static_cast('"')].type |= C_QUOTE; + tokens[static_cast('l')].type |= C_FLOAT; + tokens[static_cast('L')].type |= C_FLOAT; + tokens[static_cast('f')].type |= C_FLOAT; + tokens[static_cast('F')].type |= C_FLOAT; + tokens[static_cast('U')].type |= C_FLOAT; + tokens[static_cast('u')].type |= C_FLOAT; - tokens['-'].type |= C_SIGN; - tokens['+'].type |= C_SIGN; + tokens[static_cast('-')].type |= C_SIGN; + tokens[static_cast('+')].type |= C_SIGN; for (int i = 0; s_tokens[i]; i++) { unsigned char c = s_tokens[i][0]; diff --git a/src/unify.h b/src/unify.hpp similarity index 97% rename from src/unify.h rename to src/unify.hpp index 94e41376b..4d0e53f48 100644 --- a/src/unify.h +++ b/src/unify.hpp @@ -19,7 +19,7 @@ #ifndef UNIFY_H #define UNIFY_H -#include "hash.h" +#include "hash.hpp" int unify_hash(struct hash *hash, const char *fname, bool print); diff --git a/src/util.c b/src/util.cpp similarity index 97% rename from src/util.c rename to src/util.cpp index da3b1f33e..ca0ec00b8 100644 --- a/src/util.c +++ b/src/util.cpp @@ -17,7 +17,7 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "ccache.h" +#include "ccache.hpp" #ifdef HAVE_PWD_H #include @@ -84,7 +84,7 @@ init_log(void) assert(conf); if (conf->debug) { debug_log_buffer_capacity = DEBUG_LOG_BUFFER_MARGIN; - debug_log_buffer = x_malloc(debug_log_buffer_capacity); + debug_log_buffer = static_cast(x_malloc(debug_log_buffer_capacity)); debug_log_size = 0; } if (str_eq(conf->log_file, "")) { @@ -114,7 +114,8 @@ append_to_debug_log(const char *s, size_t len) assert(debug_log_buffer); if (debug_log_size + len + 1 > debug_log_buffer_capacity) { debug_log_buffer_capacity += len + 1 + DEBUG_LOG_BUFFER_MARGIN; - debug_log_buffer = x_realloc(debug_log_buffer, debug_log_buffer_capacity); + debug_log_buffer = static_cast( + x_realloc(debug_log_buffer, debug_log_buffer_capacity)); } memcpy(debug_log_buffer + debug_log_size, s, len); debug_log_size += len; @@ -344,17 +345,17 @@ copy_fd(int fd_in, int fd_out) #ifndef HAVE_MKSTEMP // Cheap and nasty mkstemp replacement. int -mkstemp(char *template) +mkstemp(char *name_template) { #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif - mktemp(template); + mktemp(name_template); #ifdef __GNUC__ #pragma GCC diagnostic pop #endif - return open(template, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600); + return open(name_template, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600); } #endif @@ -641,7 +642,9 @@ int create_cachedirtag(const char *dir) { char *filename = format("%s/CACHEDIR.TAG", dir); + FILE* f; struct stat st; + if (stat(filename, &st) == 0) { if (S_ISREG(st.st_mode)) { goto success; @@ -649,7 +652,8 @@ create_cachedirtag(const char *dir) errno = EEXIST; goto error; } - FILE *f = fopen(filename, "w"); + + f = fopen(filename, "w"); if (!f) { goto error; } @@ -721,7 +725,7 @@ x_strndup(const char *s, size_t n) while (m < n && s[m]) { m++; } - char *ret = malloc(m + 1); + char *ret = static_cast(malloc(m + 1)); if (ret) { memcpy(ret, s, m); ret[m] = '\0'; @@ -902,7 +906,7 @@ traverse(const char *dir, void (*fn)(const char *, struct stat *)) char * x_basename(const char *path) { - char *p = strrchr(path, '/'); + const char *p = strrchr(path, '/'); if (p) { path = p + 1; } @@ -1109,7 +1113,7 @@ static BOOL GetFileNameFromHandle(HANDLE file_handle, TCHAR *filename, TEXT("%s%s"), drive, filename+name_len); - _tcsncpy(filename, temp_file, _tcslen(temp_file)); + strcpy(filename, temp_file); } } } @@ -1136,7 +1140,7 @@ char * x_realpath(const char *path) { long maxlen = path_max(path); - char *ret = x_malloc(maxlen); + char *ret = static_cast(x_malloc(maxlen)); char *p; #if HAVE_REALPATH @@ -1202,8 +1206,9 @@ gnu_getcwd(void) } } -#ifndef HAVE_LOCALTIME_R -// localtime_r replacement. +#if !defined(_WIN32) && !defined(HAVE_LOCALTIME_R) +// localtime_r replacement. (Mingw-w64 has an inline localtime_r which is not +// detected by AC_CHECK_FUNCS.) struct tm * localtime_r(const time_t *timep, struct tm *result) { @@ -1242,15 +1247,15 @@ strtok_r(char *str, const char *delim, char **saveptr) int create_tmp_fd(char **fname) { - char *template = format("%s.%s", *fname, tmp_string()); - int fd = mkstemp(template); + char *tmpl = format("%s.%s", *fname, tmp_string()); + int fd = mkstemp(tmpl); if (fd == -1 && errno == ENOENT) { if (create_parent_dirs(*fname) != 0) { fatal("Failed to create directory %s: %s", x_dirname(*fname), strerror(errno)); } - reformat(&template, "%s.%s", *fname, tmp_string()); - fd = mkstemp(template); + reformat(&tmpl, "%s.%s", *fname, tmp_string()); + fd = mkstemp(tmpl); } if (fd == -1) { fatal("Failed to create temporary file for %s: %s", @@ -1263,7 +1268,7 @@ create_tmp_fd(char **fname) #endif free(*fname); - *fname = template; + *fname = tmpl; return fd; } @@ -1602,7 +1607,7 @@ char * x_readlink(const char *path) { long maxlen = path_max(path); - char *buf = x_malloc(maxlen); + char *buf = static_cast(x_malloc(maxlen)); ssize_t len = readlink(path, buf, maxlen-1); if (len == -1) { free(buf); @@ -1631,13 +1636,13 @@ read_file(const char *path, size_t size_hint, char **data, size_t *size) return false; } size_t allocated = size_hint; - *data = x_malloc(allocated); + *data = static_cast(x_malloc(allocated)); int ret; size_t pos = 0; while (true) { if (pos > allocated / 2) { allocated *= 2; - *data = x_realloc(*data, allocated); + *data = static_cast(x_realloc(*data, allocated)); } ret = read(fd, *data + pos, allocated - pos); if (ret == 0 || (ret == -1 && errno != EINTR)) { @@ -1667,7 +1672,7 @@ read_text_file(const char *path, size_t size_hint) size_t size; char *data; if (read_file(path, size_hint, &data, &size)) { - data = x_realloc(data, size + 1); + data = static_cast(x_realloc(data, size + 1)); data[size] = '\0'; return data; } else { diff --git a/unittest/framework.c b/unittest/framework.cpp similarity index 91% rename from unittest/framework.c rename to unittest/framework.cpp index 72d7df384..ca4bbbe3d 100644 --- a/unittest/framework.c +++ b/unittest/framework.cpp @@ -16,8 +16,8 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "framework.h" -#include "util.h" +#include "framework.hpp" +#include "util.hpp" #include #include @@ -39,6 +39,7 @@ static int verbose; static const char COLOR_END[] = "\x1b[m"; static const char COLOR_GREEN[] = "\x1b[1;32m"; static const char COLOR_RED[] = "\x1b[1;31m"; +static char CONFIG_PATH_ENV[] = "CCACHE_CONFIG_PATH=/dev/null"; #define COLOR(tty, color) ((tty) ? COLOR_ ## color : "") @@ -127,7 +128,7 @@ cct_test_begin(const char *name) cct_chdir(name); current_test = name; - putenv("CCACHE_CONFIG_PATH=/dev/null"); + putenv(CONFIG_PATH_ENV); cc_reset(); } @@ -212,14 +213,15 @@ cct_check_int_eq(const char *file, int line, const char *expression, } bool cct_check_data_eq(const char *file, int line, const char *expression, - void *expected, void *actual, size_t size) + const uint8_t *expected, const uint8_t *actual, + size_t size) { if (memcmp(actual, expected, size) == 0) { cct_check_passed(file, line, expression); return true; } else { - char *exp_str = x_malloc(2 * size + 1); - char *act_str = x_malloc(2 * size + 1); + char *exp_str = static_cast(x_malloc(2 * size + 1)); + char *act_str = static_cast(x_malloc(2 * size + 1)); format_hex(expected, size, exp_str); format_hex(actual, size, act_str); cct_check_failed(file, line, expression, exp_str, act_str); @@ -231,7 +233,7 @@ bool cct_check_data_eq(const char *file, int line, const char *expression, bool cct_check_str_eq(const char *file, int line, const char *expression, - char *expected, char *actual, + const char *expected, const char *actual, bool free1, bool free2) { bool result; @@ -249,17 +251,17 @@ cct_check_str_eq(const char *file, int line, const char *expression, } if (free1) { - free(expected); + free(const_cast(expected)); } if (free2) { - free(actual); + free(const_cast(actual)); } return result; } bool cct_check_args_eq(const char *file, int line, const char *expression, - struct args *expected, struct args *actual, + const struct args *expected, const struct args *actual, bool free1, bool free2) { bool result; @@ -277,10 +279,10 @@ cct_check_args_eq(const char *file, int line, const char *expression, } if (free1) { - args_free(expected); + args_free(const_cast(expected)); } if (free2) { - args_free(actual); + args_free(const_cast(actual)); } return result; } diff --git a/unittest/framework.h b/unittest/framework.hpp similarity index 93% rename from unittest/framework.h rename to unittest/framework.hpp index 56d101fb4..b812b5b5e 100644 --- a/unittest/framework.h +++ b/unittest/framework.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2010-2018 Joel Rosdahl and other contributors +// Copyright (C) 2010-2019 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -19,7 +19,7 @@ #ifndef TEST_FRAMEWORK_H #define TEST_FRAMEWORK_H -#include "../src/ccache.h" +#include "../src/ccache.hpp" // ============================================================================ @@ -154,12 +154,12 @@ bool cct_check_double_eq(const char *file, int line, const char *expression, bool cct_check_int_eq(const char *file, int line, const char *expression, int64_t expected, int64_t actual); bool cct_check_data_eq(const char *file, int line, const char *expression, - void *expected, void *actual, size_t size); + const uint8_t *expected, const uint8_t *actual, size_t size); bool cct_check_str_eq(const char *file, int line, const char *expression, - char *expected, char *actual, - bool free1, bool free2); + const char *expected, const char *actual, + bool free1, bool free2); bool cct_check_args_eq(const char *file, int line, const char *expression, - struct args *expected, struct args *actual, + const struct args *expected, const struct args *actual, bool free1, bool free2); void cct_chdir(const char *path); void cct_wipe(const char *path); diff --git a/unittest/main.c b/unittest/main.cpp similarity index 96% rename from unittest/main.c rename to unittest/main.cpp index 40f528fee..337f25da8 100644 --- a/unittest/main.c +++ b/unittest/main.cpp @@ -16,7 +16,7 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "framework.h" +#include "framework.hpp" #ifdef HAVE_GETOPT_LONG #include #else @@ -25,7 +25,7 @@ // *INDENT-OFF* disable uncrustify #define SUITE(name) unsigned suite_ ## name(unsigned); -#include "suites.h" +#include "suites.hpp" #undef SUITE // *INDENT-ON* enable uncrustify @@ -42,7 +42,7 @@ main(int argc, char **argv) { suite_fn suites[] = { #define SUITE(name) &suite_ ## name, -#include "suites.h" +#include "suites.hpp" #undef SUITE NULL }; diff --git a/unittest/test_args.c b/unittest/test_args.cpp similarity index 97% rename from unittest/test_args.c rename to unittest/test_args.cpp index 20e6939da..551290954 100644 --- a/unittest/test_args.c +++ b/unittest/test_args.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2010-2018 Joel Rosdahl and other contributors +// Copyright (C) 2010-2019 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -18,9 +18,9 @@ // This file contains tests for the functions operating on struct args. -#include "../src/ccache.h" -#include "framework.h" -#include "util.h" +#include "../src/ccache.hpp" +#include "framework.hpp" +#include "util.hpp" TEST_SUITE(args) @@ -35,7 +35,7 @@ TEST(args_init_empty) TEST(args_init_populated) { - char *argv[] = {"first", "second"}; + const char *argv[] = {"first", "second"}; struct args *args = args_init(2, argv); CHECK(args); CHECK_INT_EQ(2, args->argc); diff --git a/unittest/test_argument_processing.c b/unittest/test_argument_processing.cpp similarity index 99% rename from unittest/test_argument_processing.c rename to unittest/test_argument_processing.cpp index 9d426ad58..c940ec611 100644 --- a/unittest/test_argument_processing.c +++ b/unittest/test_argument_processing.cpp @@ -18,10 +18,10 @@ // This file contains tests for the processing of compiler arguments. -#include "../src/ccache.h" -#include "../src/conf.h" -#include "framework.h" -#include "util.h" +#include "../src/ccache.hpp" +#include "../src/conf.hpp" +#include "framework.hpp" +#include "util.hpp" extern struct conf *conf; diff --git a/unittest/test_compopt.c b/unittest/test_compopt.cpp similarity index 95% rename from unittest/test_compopt.c rename to unittest/test_compopt.cpp index 65f42cf9e..1b0c5bf51 100644 --- a/unittest/test_compopt.c +++ b/unittest/test_compopt.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2010-2018 Joel Rosdahl and other contributors +// Copyright (C) 2010-2019 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -18,9 +18,9 @@ // This file contains tests for the compopt_* functions. -#include "../src/ccache.h" -#include "../src/compopt.h" -#include "framework.h" +#include "../src/ccache.hpp" +#include "../src/compopt.hpp" +#include "framework.hpp" TEST_SUITE(compopt) diff --git a/unittest/test_compr_none.c b/unittest/test_compr_none.cpp similarity index 96% rename from unittest/test_compr_none.c rename to unittest/test_compr_none.cpp index dda02ffb9..76411e7b9 100644 --- a/unittest/test_compr_none.c +++ b/unittest/test_compr_none.cpp @@ -16,9 +16,9 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "../src/compression.h" -#include "framework.h" -#include "util.h" +#include "../src/compression.hpp" +#include "framework.hpp" +#include "util.hpp" TEST_SUITE(compr_type_none) diff --git a/unittest/test_compr_zstd.c b/unittest/test_compr_zstd.cpp similarity index 97% rename from unittest/test_compr_zstd.c rename to unittest/test_compr_zstd.cpp index 8117149eb..89d75b7fb 100644 --- a/unittest/test_compr_zstd.c +++ b/unittest/test_compr_zstd.cpp @@ -16,9 +16,9 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "../src/compression.h" -#include "framework.h" -#include "util.h" +#include "../src/compression.hpp" +#include "framework.hpp" +#include "util.hpp" TEST_SUITE(compr_type_zstd) diff --git a/unittest/test_conf.c b/unittest/test_conf.cpp similarity index 88% rename from unittest/test_conf.c rename to unittest/test_conf.cpp index a891b8f42..b2a765ae1 100644 --- a/unittest/test_conf.c +++ b/unittest/test_conf.cpp @@ -16,9 +16,9 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "../src/conf.h" -#include "framework.h" -#include "util.h" +#include "../src/conf.hpp" +#include "framework.hpp" +#include "util.hpp" #define N_CONFIG_ITEMS 35 static struct { @@ -27,6 +27,10 @@ static struct { } received_conf_items[N_CONFIG_ITEMS]; static size_t n_received_conf_items = 0; +static char USER_ENV[] = "USER=rabbit"; +static char COMPRESS_1_ENV[] = "CCACHE_COMPRESS=1"; +static char NOCOMPRESS_1_ENV[] = "CCACHE_NOCOMPRESS=1"; + static void conf_item_receiver(const char *descr, const char *origin, void *context) { @@ -94,7 +98,7 @@ TEST(conf_read_valid_config) { struct conf *conf = conf_create(); char *errmsg, *user; - putenv("USER=rabbit"); + putenv(USER_ENV); user = getenv("USER"); CHECK_STR_EQ("rabbit", user); create_file( @@ -314,6 +318,7 @@ TEST(conf_read_missing_config_file) char *errmsg; CHECK(!conf_read(conf, "ccache.conf", &errmsg)); CHECK_INT_EQ(errno, ENOENT); + conf_free(conf); } TEST(verify_absolute_base_dir) @@ -356,12 +361,12 @@ TEST(conf_update_from_environment) struct conf *conf = conf_create(); char *errmsg; - putenv("CCACHE_COMPRESS=1"); + putenv(COMPRESS_1_ENV); CHECK(conf_update_from_environment(conf, &errmsg)); CHECK(conf->compression); x_unsetenv("CCACHE_COMPRESS"); - putenv("CCACHE_NOCOMPRESS=1"); + putenv(NOCOMPRESS_1_ENV); CHECK(conf_update_from_environment(conf, &errmsg)); CHECK(!conf->compression); @@ -456,60 +461,59 @@ TEST(conf_print_unknown_value) TEST(conf_print_items) { - size_t i; - struct conf conf = { - "bd", - "cd", - 7, - "c", - "cc", - true, - 8, - "ce", - false, - true, - false, - true, - "efth", - .file_clone = true, - true, - .hash_dir = false, - "ihim", - true, - 0.0, - "lf", - 4711, - 98.7 * 1000 * 1000, - "p", - true, - "pc", - "pcc", - true, - true, - true, - .run_second_cpp = false, - SLOPPY_FILE_MACRO|SLOPPY_INCLUDE_FILE_MTIME| - SLOPPY_INCLUDE_FILE_CTIME|SLOPPY_TIME_MACROS| - SLOPPY_FILE_STAT_MATCHES|SLOPPY_FILE_STAT_MATCHES_CTIME| - SLOPPY_PCH_DEFINES|SLOPPY_SYSTEM_HEADERS|SLOPPY_CLANG_INDEX_STORE, - false, - "td", - 022, - true, - NULL - }; - size_t n = 0; - - conf.item_origins = x_malloc(N_CONFIG_ITEMS * sizeof(char *)); - for (i = 0; i < N_CONFIG_ITEMS; ++i) { + struct conf* conf = conf_create(); + conf->base_dir = x_strdup("bd"); + conf->cache_dir = x_strdup("cd"); + conf->cache_dir_levels = 7; + conf->compiler = x_strdup("c"); + conf->compiler_check = x_strdup("cc"); + conf->compression = true; + conf->compression_level = 8; + conf->cpp_extension = x_strdup("ce"); + conf->debug = false; + conf->depend_mode = true; + conf->direct_mode = false; + conf->disable = true; + conf->extra_files_to_hash = x_strdup("efth"); + conf->file_clone = true; + conf->hard_link = true; + conf->hash_dir = false; + conf->ignore_headers_in_manifest = x_strdup("ihim"); + conf->keep_comments_cpp = true; + conf->limit_multiple = 0.0; + conf->log_file = x_strdup("lf"); + conf->max_files = 4711; + conf->max_size = 98.7 * 1000 * 1000; + conf->path = x_strdup("p"); + conf->pch_external_checksum = true; + conf->prefix_command = x_strdup("pc"); + conf->prefix_command_cpp = x_strdup("pcc"); + conf->read_only = true; + conf->read_only_direct = true; + conf->recache = true; + conf->run_second_cpp = false; + conf->sloppiness = + SLOPPY_FILE_MACRO | SLOPPY_INCLUDE_FILE_MTIME | SLOPPY_INCLUDE_FILE_CTIME + | SLOPPY_TIME_MACROS | SLOPPY_FILE_STAT_MATCHES + | SLOPPY_FILE_STAT_MATCHES_CTIME | SLOPPY_PCH_DEFINES + | SLOPPY_SYSTEM_HEADERS | SLOPPY_CLANG_INDEX_STORE; + conf->stats = false; + conf->temporary_dir = x_strdup("td"); + conf->umask = 022; + conf->unify = true; + + conf->item_origins = + static_cast(x_malloc(N_CONFIG_ITEMS * sizeof(char *))); + for (size_t i = 0; i < N_CONFIG_ITEMS; ++i) { #ifndef __MINGW32__ - conf.item_origins[i] = format("origin%zu", i); + conf->item_origins[i] = format("origin%zu", i); #else - conf.item_origins[i] = format("origin%u", (unsigned) i); + conf->item_origins[i] = format("origin%u", (unsigned) i); #endif } - conf_print_items(&conf, conf_item_receiver, NULL); + size_t n = 0; + conf_print_items(conf, conf_item_receiver, NULL); CHECK_INT_EQ(N_CONFIG_ITEMS, n_received_conf_items); CHECK_STR_EQ("base_dir = bd", received_conf_items[n++].descr); CHECK_STR_EQ("cache_dir = cd", received_conf_items[n++].descr); @@ -552,7 +556,7 @@ TEST(conf_print_items) CHECK_STR_EQ("umask = 022", received_conf_items[n++].descr); CHECK_STR_EQ("unify = true", received_conf_items[n++].descr); - for (i = 0; i < N_CONFIG_ITEMS; ++i) { + for (size_t i = 0; i < N_CONFIG_ITEMS; ++i) { #ifndef __MINGW32__ char *expected = format("origin%zu", i); #else @@ -562,7 +566,7 @@ TEST(conf_print_items) } free_received_conf_items(); - free(conf.item_origins); + conf_free(conf); } TEST_SUITE_END diff --git a/unittest/test_counters.c b/unittest/test_counters.cpp similarity index 90% rename from unittest/test_counters.c rename to unittest/test_counters.cpp index 9bbf5496b..7f07006da 100644 --- a/unittest/test_counters.c +++ b/unittest/test_counters.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2010-2018 Joel Rosdahl and other contributors +// Copyright (C) 2010-2019 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -16,10 +16,10 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "../src/ccache.h" -#include "../src/counters.h" -#include "framework.h" -#include "util.h" +#include "../src/ccache.hpp" +#include "../src/counters.hpp" +#include "framework.hpp" +#include "util.hpp" TEST_SUITE(counters) diff --git a/unittest/test_hash.c b/unittest/test_hash.cpp similarity index 97% rename from unittest/test_hash.c rename to unittest/test_hash.cpp index e25250afb..df3bc8b92 100644 --- a/unittest/test_hash.c +++ b/unittest/test_hash.cpp @@ -18,9 +18,9 @@ // This file contains tests for functions in hash.c. -#include "../src/ccache.h" -#include "../src/hash.h" -#include "framework.h" +#include "../src/ccache.hpp" +#include "../src/hash.hpp" +#include "framework.hpp" TEST_SUITE(hash) diff --git a/unittest/test_hashutil.c b/unittest/test_hashutil.cpp similarity index 98% rename from unittest/test_hashutil.c rename to unittest/test_hashutil.cpp index cbbfeaa3d..a7432281b 100644 --- a/unittest/test_hashutil.c +++ b/unittest/test_hashutil.cpp @@ -18,10 +18,10 @@ // This file contains tests for functions in hashutil.c. -#include "../src/ccache.h" -#include "../src/hashutil.h" -#include "framework.h" -#include "util.h" +#include "../src/ccache.hpp" +#include "../src/hashutil.hpp" +#include "framework.hpp" +#include "util.hpp" TEST_SUITE(hashutil) diff --git a/unittest/test_lockfile.c b/unittest/test_lockfile.cpp similarity index 93% rename from unittest/test_lockfile.c rename to unittest/test_lockfile.cpp index 3b8cfba1d..f75adf36a 100644 --- a/unittest/test_lockfile.c +++ b/unittest/test_lockfile.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2010-2018 Joel Rosdahl and other contributors +// Copyright (C) 2010-2019 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -18,9 +18,9 @@ // This file contains tests for functions in lockfile.c. -#include "../src/ccache.h" -#include "framework.h" -#include "util.h" +#include "../src/ccache.hpp" +#include "framework.hpp" +#include "util.hpp" TEST_SUITE(lockfile) diff --git a/unittest/test_stats.c b/unittest/test_stats.cpp similarity index 88% rename from unittest/test_stats.c rename to unittest/test_stats.cpp index df6ea30f5..02a284142 100644 --- a/unittest/test_stats.c +++ b/unittest/test_stats.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2010-2018 Joel Rosdahl and other contributors +// Copyright (C) 2010-2019 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -18,10 +18,10 @@ // This file contains tests for statistics handling. -#include "../src/ccache.h" -#include "../src/counters.h" -#include "framework.h" -#include "util.h" +#include "../src/ccache.hpp" +#include "../src/counters.hpp" +#include "framework.hpp" +#include "util.hpp" TEST_SUITE(stats) diff --git a/unittest/test_util.c b/unittest/test_util.cpp similarity index 94% rename from unittest/test_util.c rename to unittest/test_util.cpp index dabbd614a..c16c4663d 100644 --- a/unittest/test_util.c +++ b/unittest/test_util.cpp @@ -18,8 +18,10 @@ // This file contains tests for functions in util.c. -#include "../src/ccache.h" -#include "framework.h" +#include "../src/ccache.hpp" +#include "framework.hpp" + +static char FOO_ENV[] = "FOO=bar"; TEST_SUITE(util) @@ -91,28 +93,24 @@ TEST(subst_env_in_string) { char *errmsg; - putenv("FOO=bar"); + putenv(FOO_ENV); CHECK_STR_EQ_FREE2("bar", subst_env_in_string("$FOO", &errmsg)); CHECK(!errmsg); - errmsg = ""; CHECK_STR_EQ_FREE2("$", subst_env_in_string("$", &errmsg)); CHECK(!errmsg); - errmsg = ""; CHECK_STR_EQ_FREE2("bar bar:bar", subst_env_in_string("$FOO $FOO:$FOO", &errmsg)); CHECK(!errmsg); - errmsg = ""; CHECK_STR_EQ_FREE2("xbar", subst_env_in_string("x$FOO", &errmsg)); CHECK(!errmsg); - errmsg = ""; CHECK_STR_EQ_FREE2("barx", subst_env_in_string("${FOO}x", &errmsg)); CHECK(!errmsg); @@ -165,17 +163,16 @@ TEST(parse_size_with_suffix) {"78k", 78 * 1000}, {"78K", 78 * 1000}, - {"1.1 M", 1.1 * 1000 * 1000}, - {"438.55M", 438.55 * 1000 * 1000}, + {"1.1 M", (int64_t)(1.1 * 1000 * 1000)}, + {"438.55M", (int64_t)(438.55 * 1000 * 1000)}, {"1 G", 1 * 1000 * 1000 * 1000}, {"2T", (int64_t)2 * 1000 * 1000 * 1000 * 1000}, {"78 Ki", 78 * 1024}, - {"1.1Mi", 1.1 * 1024 * 1024}, - {"438.55 Mi", 438.55 * 1024 * 1024}, + {"1.1Mi", (int64_t)(1.1 * 1024 * 1024)}, + {"438.55 Mi", (int64_t)(438.55 * 1024 * 1024)}, {"1Gi", 1 * 1024 * 1024 * 1024}, {"2 Ti", (int64_t)2 * 1024 * 1024 * 1024 * 1024}, - }; for (i = 0; i < ARRAY_SIZE(sizes); ++i) { @@ -186,17 +183,16 @@ TEST(parse_size_with_suffix) TEST(format_command) { - char *argv[] = {"foo", "bar", NULL}; + const char *argv[] = {"foo", "bar", NULL}; CHECK_STR_EQ_FREE2("foo bar\n", format_command(argv)); - } TEST(format_hex) { uint8_t none[] = ""; uint8_t text[4] = "foo"; // incl. NUL - uint8_t data[4] = "\x00\x01\x02\x03"; + uint8_t data[4] = {0, 1, 2, 3}; char result[2 * sizeof(data) + 1] = "."; format_hex(none, 0, result); diff --git a/unittest/util.c b/unittest/util.cpp similarity index 91% rename from unittest/util.c rename to unittest/util.cpp index 5c364b1e7..af4515861 100644 --- a/unittest/util.c +++ b/unittest/util.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2010-2018 Joel Rosdahl and other contributors +// Copyright (C) 2010-2019 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -16,8 +16,8 @@ // this program; if not, write to the Free Software Foundation, Inc., 51 // Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "../src/system.h" -#include "util.h" +#include "../src/system.hpp" +#include "util.hpp" #ifdef _WIN32 # define lstat(a, b) stat(a, b) diff --git a/unittest/util.h b/unittest/util.hpp similarity index 100% rename from unittest/util.h rename to unittest/util.hpp