insert_final_newline = true
charset = utf-8
-[*.{c,h}]
+[*.{c,cpp,h,hpp}]
indent_style = tab
indent_size = 2
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
#!/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
-language: c
+language: cpp
dist: xenial
script:
# 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:
# 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:
# 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:
# 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:
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
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
-------------------------------------------------------------------------------
+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 <bkoz@redhat.com>
+ Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
+ Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
+ Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
+ Copyright (c) 2015 Paul Norman <penorman@mac.com>
+ Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
+ Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com>
+ Copyright (c) 2019 Enji Cooper <yaneurabeya@gmail.com>
+
+ 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
~~~~~~~~~~~~~~~~~~~~
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@
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 \
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)
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 $@")
[ ! -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 \
.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)
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' >$@
$(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@
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
# 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,
[enable more compiler warnings])])
if test x${enable_more_warnings} = xyes; then
CFLAGS="$CFLAGS $more_warnings"
+ CXXFLAGS="$CXXFLAGS $more_warnings"
fi
AC_HEADER_DIRENT
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)
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
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
all_cflags += -Werror
all_cppflags += -MD -MP -MF .deps/$(subst .._,,$(subst /,_,$(subst $(srcdir)/,,$<))).d
+all_cxxflags += -Werror
A2X = a2x
ASCIIDOC = asciidoc
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 = \
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
$(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
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
$(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)
$(Q)$(ASCIIDOC) -a revnumber=$(version) -d manpage -b docbook -o - $< | \
perl -pe 's!<literal>(.*?)</literal>!<emphasis role="strong">\1</emphasis>!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 $@")
.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
.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)
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
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
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.
--- /dev/null
+# ===========================================================================
+# 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 <bkoz@redhat.com>
+# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
+# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
+# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
+# Copyright (c) 2015 Paul Norman <penorman@mac.com>
+# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
+# Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com>
+# Copyright (c) 2019 Enji Cooper <yaneurabeya@gmail.com>
+#
+# 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 <typename T>
+ 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<void> single_type;
+ typedef check<check<void>> double_type;
+ typedef check<check<check<void>>> triple_type;
+ typedef check<check<check<check<void>>>> 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<T, T>
+ {
+ 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<int, decltype(0)>::value == true, "");
+ static_assert(is_same<int, decltype(c)>::value == false, "");
+ static_assert(is_same<int, decltype(v)>::value == false, "");
+ auto ac = c;
+ auto av = v;
+ auto sumi = ac + av + 'x';
+ auto sumf = ac + av + 1.0;
+ static_assert(is_same<int, decltype(ac)>::value == true, "");
+ static_assert(is_same<int, decltype(av)>::value == true, "");
+ static_assert(is_same<int, decltype(sumi)>::value == true, "");
+ static_assert(is_same<int, decltype(sumf)>::value == false, "");
+ static_assert(is_same<int, decltype(add(c, v))>::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 <int...>
+ struct sum;
+
+ template <int N0, int... N1toN>
+ struct sum<N0, N1toN...>
+ {
+ static constexpr auto value = N0 + sum<N1toN...>::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<typename T>
+ using member = typename T::member_type;
+
+ template<typename T>
+ void func(...) {}
+
+ template<typename T>
+ void func(member<T>*) {}
+
+ void test();
+
+ void test() { func<foo>(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<T, T>
+ {
+ static constexpr auto value = true;
+ };
+
+ int
+ test()
+ {
+ auto x = 0;
+ static_assert(is_same<int, decltype(f(x))>::value, "");
+ static_assert(is_same<int&, decltype(g(x))>::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 <initializer_list>
+#include <utility>
+#include <type_traits>
+
+namespace cxx17
+{
+
+ namespace test_constexpr_lambdas
+ {
+
+ constexpr int foo = [](){return 42;}();
+
+ }
+
+ namespace test::nested_namespace::definitions
+ {
+
+ }
+
+ namespace test_fold_expression
+ {
+
+ template<typename... Args>
+ int multiply(Args... args)
+ {
+ return (args * ... * 1);
+ }
+
+ template<typename... Args>
+ 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<std::initializer_list<int>, decltype(foo)>::value);
+ static_assert(std::is_same<int, decltype(bar)>::value);
+ }
+
+ namespace test_typename_in_template_template_parameter
+ {
+
+ template<template<typename> 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 <bool cond>
+ 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 <typename T1, typename T2>
+ 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 <auto n>
+ struct B
+ {};
+
+ B<5> b1;
+ B<'a'> b2;
+
+ }
+
+ namespace test_structured_bindings
+ {
+
+ int arr[2] = { 1, 2 };
+ std::pair<int, int> pr = { 1, 2 };
+
+ auto f1() -> int(&)[2]
+ {
+ return arr;
+ }
+
+ auto f2() -> std::pair<int, int>&
+ {
+ 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<typename T>
+ Bad
+ f(T*, T*);
+
+ template<typename T1, typename T2>
+ Good
+ f(T1*, T2*);
+
+ static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
+
+ }
+
+ namespace test_inline_variables
+ {
+
+ template<class T> void f(T)
+ {}
+
+ template<class T> inline T g(T)
+ {
+ return T{};
+ }
+
+ template<> inline void f<>(int)
+ {}
+
+ template<> int g<>(int)
+ {
+ return 5;
+ }
+
+ }
+
+} // namespace cxx17
+
+#endif // __cplusplus < 201703L
+
+]])
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
// 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.
//
// 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;
struct args *args = args_init(0, NULL);
char *pos = argtext;
- char *argbuf = x_malloc(strlen(argtext) + 1);
+ char* argbuf = static_cast<char*>(x_malloc(strlen(argtext) + 1));
char *argpos = argbuf;
// Used to track quoting state; if \0, we are not inside quotes. Otherwise
// 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<char*>(x_malloc(size + 1));
int pos = 0;
for (char **p = args->argv; *p; p++) {
pos += sprintf(&result[pos], "%s ", *p);
// 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;
// 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 <getopt.h>
#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)
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;
add_pending_tmp_file(const char *path)
{
block_signals();
- struct pending_tmp_file *e = x_malloc(sizeof(*e));
+ auto e = static_cast<pending_tmp_file*>(x_malloc(sizeof(pending_tmp_file)));
e->path = x_strdup(path);
e->next = pending_tmp_files;
pending_tmp_files = e;
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] == '>')) {
}
#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
}
// 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;
+ }
}
}
// 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);
}
}
- struct digest *d = x_malloc(sizeof(*d));
+ auto d = static_cast<digest*>(x_malloc(sizeof(digest)));
hash_result_as_bytes(fhash, d);
hashtable_insert(included_files, path, d);
path = NULL; // Ownership transferred to included_files.
{
struct hashtable_itr *iter = hashtable_iterator(included_files);
do {
- char *path = hashtable_iterator_key(iter);
+ char* path = static_cast<char*>(hashtable_iterator_key(iter));
fprintf(fp, "%s\n", path);
} while (hashtable_iterator_advance(iter));
}
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<char**>(
+ x_realloc(ignore_headers, (ignore_headers_len+1) * sizeof(char *)));
ignore_headers[ignore_headers_len++] = x_strdup(header);
q = NULL;
}
print_included_files(stdout);
}
- struct digest *digest = x_malloc(sizeof(*digest));
- hash_result_as_bytes(hash, digest);
- return digest;
+ auto d = static_cast<digest*>(x_malloc(sizeof(digest)));
+ hash_result_as_bytes(hash, d);
+ return d;
}
// Send cached stderr, if any, to stderr.
hash_string(hash, "false");
}
- struct digest *name = x_malloc(sizeof(*name));
+ auto name = static_cast<digest*>(x_malloc(sizeof(digest)));
hash_result_as_bytes(hash, name);
return name;
}
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<char*>(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) {
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<char**>(
+ 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]);
continue;
}
if (str_startswith(argv[i], "-fsanitize-blacklist=")) {
- sanitize_blacklists = x_realloc(
- sanitize_blacklists,
- (sanitize_blacklists_len + 1) * sizeof(char *));
+ sanitize_blacklists = static_cast<char**>(
+ 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;
// 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);
+ }
}
}
}
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:
configuration_printer(const char *descr, const char *origin, void *context)
{
assert(context);
- fprintf(context, "(%s) %s\n", origin, descr);
+ auto f = static_cast<FILE*>(context);
+ fprintf(f, "(%s) %s\n", origin, descr);
}
// The main program when not doing a compile.
#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__
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);
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
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
// 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 <math.h>
// 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(
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;
#ifndef COMMON_HEADER_H
#define COMMON_HEADER_H
-#include "compression.h"
+#include "compression.hpp"
#include "third_party/xxhash.h"
#define COMMON_HEADER_SIZE 15
// 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)
{
struct compopt key;
key.name = option;
- return bsearch(
+ void* result = bsearch(
&key, compopts, ARRAY_SIZE(compopts), sizeof(compopts[0]),
compare_compopts);
+ return static_cast<compopt*>(result);
}
static const struct compopt *
{
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<compopt*>(result);
}
// Runs fn on the first two characters of option.
#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);
// 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;
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<struct state*>(malloc(sizeof(struct state)));
state->output = output;
state->checksum = checksum;
(void)level;
// 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 <zstd.h>
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<struct state*>(malloc(sizeof(struct state)));
state->output = output;
state->checksum = checksum;
state->stream = ZSTD_createCStream();
// 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(
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) {
} else {
incompr_size += st->st_size;
}
-
-out:
- free(p);
}
// Process up all cache subdirectories.
// 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;
#ifndef COMPRESSION_H
#define COMPRESSION_H
-#include "system.h"
+#include "system.hpp"
#include "third_party/xxhash.h"
struct compr_state;
// 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,
struct conf *
conf_create(void)
{
- struct conf *conf = x_malloc(sizeof(*conf));
+ auto conf = static_cast<struct conf*>(x_malloc(sizeof(struct conf)));
conf->base_dir = x_strdup("");
conf->cache_dir = format("%s/.ccache", get_home_directory());
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<const char**>(
+ x_malloc(confitems_count() * sizeof(char *)));
for (size_t i = 0; i < confitems_count(); ++i) {
conf->item_origins[i] = "default";
}
#ifndef CONF_H
#define CONF_H
-#include "system.h"
+#include "system.hpp"
struct conf {
char *base_dir;
// 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)
%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) \
#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);
// 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<counters*>(x_malloc(sizeof(counters)));
c->data = NULL;
c->size = 0;
c->allocated = 0;
realloc = true;
}
if (realloc) {
- c->data = x_realloc(c->data, c->allocated * sizeof(c->data[0]));
+ c->data = static_cast<unsigned*>(
+ x_realloc(c->data, c->allocated * sizeof(c->data[0])));
}
for (size_t i = c->size; i < new_size; i++) {
c->data[i] = 0;
// 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;
static struct decompr_state *
decompr_none_init(FILE *input, XXH64_state_t *checksum)
{
- struct state *state = malloc(sizeof(struct state));
+ auto state = static_cast<struct state*>(malloc(sizeof(struct state)));
state->input = input;
state->checksum = checksum;
state->failed = false;
// 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 <zstd.h>
static struct decompr_state *
decompr_zstd_init(FILE *input, XXH64_state_t *checksum)
{
- struct state *state = malloc(sizeof(struct state));
+ auto state = static_cast<struct state*>(malloc(sizeof(struct state)));
state->input = input;
state->checksum = checksum;
%define slot-name env_name
%define initializer-suffix ,""
%{
-#include "envtoconfitems.h"
+#include "envtoconfitems.hpp"
%}
struct env_to_conf_item;
%%
-// 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.
//
#ifndef ENVTOCONFITEMS_H
#define ENVTOCONFITEMS_H
-#include "system.h"
+#include "system.hpp"
struct env_to_conf_item {
const char *env_name;
};
const struct env_to_conf_item *envtoconfitems_get(const char *str, size_t len);
+
size_t envtoconfitems_count(void);
#endif
// 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;
k += (bs << 1) + 3;
} while ((arg = argv[i++]));
- char *ptr = malloc(k + 1);
+ char *ptr = static_cast<char*>(malloc(k + 1));
char *str = ptr;
if (!str) {
*length = 0;
case '\\':
bs++;
break;
+ // Fallthrough.
case '"':
bs = (bs << 1) + 1;
+ // Fallthrough.
default:
while (bs && bs--) {
*ptr++ = '\\';
}
char *
-format_command(char **argv)
+format_command(const char* const* argv)
{
size_t len = 0;
for (int i = 0; argv[i]; i++) {
len += strlen(argv[i]);
}
len += 1;
- char *buf = x_malloc(len + 1);
+ char *buf = static_cast<char*>(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;
}
}
-// 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.
//
// 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 *);
void
exitfn_add_nullary(void (*function)(void))
{
- struct nullary_exit_function *p = x_malloc(sizeof(*p));
- p->function = function;
+ auto p = static_cast<exit_function*>(x_malloc(sizeof(exit_function)));
+ p->function = reinterpret_cast<void (*)(void*)>(function);
exitfn_add(call_nullary_exit_function, p);
}
void
exitfn_add(void (*function)(void *), void *context)
{
- struct exit_function *p = x_malloc(sizeof(*p));
+ auto p = static_cast<exit_function*>(x_malloc(sizeof(exit_function)));
p->function = function;
p->context = context;
p->next = exit_functions;
void
exitfn_add_last(void (*function)(void *), void *context)
{
- struct exit_function *p = x_malloc(sizeof(*p));
+ auto p = static_cast<exit_function*>(x_malloc(sizeof(exit_function)));
p->function = function;
p->context = context;
p->next = NULL;
// 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 <blake2.h>
#define HASH_DELIMITER "\000cCaChE"
struct hash *
hash_init(void)
{
- struct hash *hash = malloc(sizeof(struct hash));
+ auto hash = static_cast<struct hash*>(malloc(sizeof(struct hash)));
blake2b_init(&hash->state, DIGEST_SIZE);
hash->debug_binary = NULL;
hash->debug_text = NULL;
struct hash *
hash_copy(struct hash *hash)
{
- struct hash *result = malloc(sizeof(struct hash));
+ auto result = static_cast<struct hash*>(malloc(sizeof(struct hash)));
result->state = hash->state;
result->debug_binary = NULL;
result->debug_text = NULL;
#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)
// 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
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);
#ifndef HASHUTIL_H
#define HASHUTIL_H
-#include "conf.h"
-#include "hash.h"
+#include "conf.hpp"
+#include "hash.hpp"
#include <inttypes.h>
unsigned hash_from_string(void *str);
// 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).
-// 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.
//
// 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
}
free(content);
const size_t bufsize = 1024;
- content = x_malloc(bufsize);
+ content = static_cast<char*>(x_malloc(bufsize));
int len = read(fd, content, bufsize - 1);
if (len == -1) {
cc_log("lockfile_acquire: read %s: %s", lockfile, strerror(errno));
// 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
// 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;
#define READ_STR(str_var, len_var) \
do { \
READ_UINT16(len_var); \
- (str_var) = x_malloc(len_var + 1); \
+ (str_var) = static_cast<char*>(x_malloc(len_var + 1)); \
READ_BYTES(str_var, len_var); \
str_var[len_var] = '\0'; \
} while (false)
static struct manifest *
create_empty_manifest(void)
{
- struct manifest *mf = x_malloc(sizeof(*mf));
+ auto mf = static_cast<manifest*>(x_malloc(sizeof(manifest)));
mf->n_files = 0;
mf->files = NULL;
mf->n_file_infos = 0;
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) {
}
READ_UINT32(mf->n_files);
- mf->files = x_calloc(mf->n_files, sizeof(*mf->files));
+ mf->files = static_cast<file*>(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<file_info*>(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);
}
READ_UINT32(mf->n_results);
- mf->results = x_calloc(mf->n_results, sizeof(*mf->results));
+ mf->results = static_cast<result*>(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<uint32_t*>(
+ 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;
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;
}
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<file_stats*>(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<file_stats*>(x_malloc(sizeof(file_stats)));
st->size = file_stat.st_size;
st->mtime = file_stat.st_mtime;
st->ctime = file_stat.st_ctime;
}
}
- struct digest *actual = hashtable_search(hashed_files, path);
+ auto actual = static_cast<digest*>(hashtable_search(hashed_files, path));
if (!actual) {
struct hash *hash = hash_init();
int ret = hash_source_code_file(conf, hash, path);
return false;
}
- actual = malloc(sizeof(*actual));
+ actual = static_cast<digest*>(malloc(sizeof(digest)));
hash_result_as_bytes(hash, actual);
hashtable_insert(hashed_files, x_strdup(path), actual);
hash_free(hash);
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<uint32_t*>(x_malloc(sizeof(uint32_t)));
*index = i;
hashtable_insert(h, x_strdup(files[i].path), index);
}
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<file_info*>(x_malloc(sizeof(file_info)));
*fi = infos[i];
- uint32_t *index = x_malloc(sizeof(*index));
+ uint32_t *index = static_cast<uint32_t*>(x_malloc(sizeof(uint32_t)));
*index = i;
hashtable_insert(h, fi, index);
}
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<uint32_t*>(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<file*>(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);
fi.fsize = 0;
}
- uint32_t *fi_index = hashtable_search(mf_file_infos, &fi);
+ auto fi_index = static_cast<uint32_t*>(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<file_info*>(
+ x_realloc(mf->file_infos, (n + 1) * sizeof(file_info)));
mf->n_file_infos++;
mf->file_infos[n] = fi;
return n;
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<char*>(hashtable_iterator_key(iter));
+ auto digest = static_cast<struct digest*>(hashtable_iterator_value(iter));
indexes[i] = get_file_info_index(mf, path, digest, mf_files,
mf_file_infos);
i++;
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<result*>(
+ 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<uint32_t*>(
+ x_malloc(n_fii * sizeof(uint32_t)));
add_file_info_indexes(result->file_info_indexes, n_fii, mf, included_files);
result->name = *result_digest;
}
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<digest*>(x_malloc(sizeof(digest)));
*name = mf->results[i - 1].name;
goto out;
}
#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];
// 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
// ==================
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.
struct result_files *
result_files_init(void)
{
- struct result_files *list = x_malloc(sizeof(*list));
+ auto list = static_cast<result_files*>(x_malloc(sizeof(result_files)));
list->n_files = 0;
list->files = NULL;
list->sizes = NULL;
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<result_file*>(
+ x_realloc(list->files, (n + 1) * sizeof(result_file)));
+ list->sizes = static_cast<uint64_t*>(
+ x_realloc(list->sizes, (n + 1) * sizeof(uint64_t)));
struct result_file *f = &list->files[list->n_files];
list->n_files++;
FILE *dump_stream)
{
(void)result_path_in_cache;
-
+ bool found = false;
bool success = false;
FILE *subfile = NULL;
uint64_t file_len;
READ_UINT64(file_len);
- bool found = false;
if (dump_stream) {
fprintf(
dump_stream,
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;
}
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:
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",
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) {
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",
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,
? 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;
}
}
{
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);
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
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;
#ifndef RESULT_H
#define RESULT_H
-#include "conf.h"
+#include "conf.hpp"
extern const char RESULT_MAGIC[4];
#define RESULT_VERSION 1
// 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 <sys/types.h>
#include <sys/stat.h>
#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
#define ESTALE -1
#endif
+extern "C" {
+
#if !HAVE_VSNPRINTF
int rpl_vsnprintf(char *, size_t, const char *, va_list);
#define vsnprintf rpl_vsnprintf
#define asprintf rpl_asprintf
#endif
+} // extern "C"
+
#endif // CCACHE_SYSTEM_H
#include "config.h"
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
struct hashtable;
/* Example of use:
void
hashtable_destroy(struct hashtable *h, int free_values);
+#if defined (__cplusplus)
+}
+#endif
+
#endif /* HASHTABLE_CWC22_H */
/*
#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. */
return (hashtable_iterator_search(i,h,k)); \
}
-
+#if defined (__cplusplus)
+}
+#endif
#endif /* HASHTABLE_ITR_CWC22_H */
#include "hashtable.h"
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
/*****************************************************************************/
struct entry
{
/*****************************************************************************/
+#if defined (__cplusplus)
+}
+#endif
+
#endif /* HASHTABLE_PRIVATE_CWC22_H */
/*
(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 *);
}
return (failed == 0) ? 0 : 1;
}
+
+#if defined (__cplusplus)
+}
+#endif
+
#endif /* TEST_SNPRINTF */
/* vim: set joinspaces textwidth=80: */
// 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;
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<unsigned char>('\'')].type |= C_QUOTE;
+ tokens[static_cast<unsigned char>('"')].type |= C_QUOTE;
+ tokens[static_cast<unsigned char>('l')].type |= C_FLOAT;
+ tokens[static_cast<unsigned char>('L')].type |= C_FLOAT;
+ tokens[static_cast<unsigned char>('f')].type |= C_FLOAT;
+ tokens[static_cast<unsigned char>('F')].type |= C_FLOAT;
+ tokens[static_cast<unsigned char>('U')].type |= C_FLOAT;
+ tokens[static_cast<unsigned char>('u')].type |= C_FLOAT;
- tokens['-'].type |= C_SIGN;
- tokens['+'].type |= C_SIGN;
+ tokens[static_cast<unsigned char>('-')].type |= C_SIGN;
+ tokens[static_cast<unsigned char>('+')].type |= C_SIGN;
for (int i = 0; s_tokens[i]; i++) {
unsigned char c = s_tokens[i][0];
#ifndef UNIFY_H
#define UNIFY_H
-#include "hash.h"
+#include "hash.hpp"
int unify_hash(struct hash *hash, const char *fname, bool print);
// 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 <pwd.h>
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<char*>(x_malloc(debug_log_buffer_capacity));
debug_log_size = 0;
}
if (str_eq(conf->log_file, "")) {
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<char*>(
+ x_realloc(debug_log_buffer, debug_log_buffer_capacity));
}
memcpy(debug_log_buffer + debug_log_size, s, len);
debug_log_size += len;
#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
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;
errno = EEXIST;
goto error;
}
- FILE *f = fopen(filename, "w");
+
+ f = fopen(filename, "w");
if (!f) {
goto error;
}
while (m < n && s[m]) {
m++;
}
- char *ret = malloc(m + 1);
+ char *ret = static_cast<char*>(malloc(m + 1));
if (ret) {
memcpy(ret, s, m);
ret[m] = '\0';
char *
x_basename(const char *path)
{
- char *p = strrchr(path, '/');
+ const char *p = strrchr(path, '/');
if (p) {
path = p + 1;
}
TEXT("%s%s"),
drive,
filename+name_len);
- _tcsncpy(filename, temp_file, _tcslen(temp_file));
+ strcpy(filename, temp_file);
}
}
}
x_realpath(const char *path)
{
long maxlen = path_max(path);
- char *ret = x_malloc(maxlen);
+ char *ret = static_cast<char*>(x_malloc(maxlen));
char *p;
#if HAVE_REALPATH
}
}
-#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)
{
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",
#endif
free(*fname);
- *fname = template;
+ *fname = tmpl;
return fd;
}
x_readlink(const char *path)
{
long maxlen = path_max(path);
- char *buf = x_malloc(maxlen);
+ char *buf = static_cast<char*>(x_malloc(maxlen));
ssize_t len = readlink(path, buf, maxlen-1);
if (len == -1) {
free(buf);
return false;
}
size_t allocated = size_hint;
- *data = x_malloc(allocated);
+ *data = static_cast<char*>(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<char*>(x_realloc(*data, allocated));
}
ret = read(fd, *data + pos, allocated - pos);
if (ret == 0 || (ret == -1 && errno != EINTR)) {
size_t size;
char *data;
if (read_file(path, size_hint, &data, &size)) {
- data = x_realloc(data, size + 1);
+ data = static_cast<char*>(x_realloc(data, size + 1));
data[size] = '\0';
return data;
} else {
// 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 <float.h>
#include <math.h>
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 : "")
cct_chdir(name);
current_test = name;
- putenv("CCACHE_CONFIG_PATH=/dev/null");
+ putenv(CONFIG_PATH_ENV);
cc_reset();
}
}
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<char*>(x_malloc(2 * size + 1));
+ char *act_str = static_cast<char*>(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);
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;
}
if (free1) {
- free(expected);
+ free(const_cast<char*>(expected));
}
if (free2) {
- free(actual);
+ free(const_cast<char*>(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;
}
if (free1) {
- args_free(expected);
+ args_free(const_cast<struct args*>(expected));
}
if (free2) {
- args_free(actual);
+ args_free(const_cast<struct args*>(actual));
}
return result;
}
-// 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.
//
#ifndef TEST_FRAMEWORK_H
#define TEST_FRAMEWORK_H
-#include "../src/ccache.h"
+#include "../src/ccache.hpp"
// ============================================================================
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);
// 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 <getopt.h>
#else
// *INDENT-OFF* disable uncrustify
#define SUITE(name) unsigned suite_ ## name(unsigned);
-#include "suites.h"
+#include "suites.hpp"
#undef SUITE
// *INDENT-ON* enable uncrustify
{
suite_fn suites[] = {
#define SUITE(name) &suite_ ## name,
-#include "suites.h"
+#include "suites.hpp"
#undef SUITE
NULL
};
-// 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.
//
// 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)
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);
// 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;
-// 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.
//
// 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)
// 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)
// 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)
// 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 {
} 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)
{
{
struct conf *conf = conf_create();
char *errmsg, *user;
- putenv("USER=rabbit");
+ putenv(USER_ENV);
user = getenv("USER");
CHECK_STR_EQ("rabbit", user);
create_file(
char *errmsg;
CHECK(!conf_read(conf, "ccache.conf", &errmsg));
CHECK_INT_EQ(errno, ENOENT);
+ conf_free(conf);
}
TEST(verify_absolute_base_dir)
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);
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<const char**>(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);
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
}
free_received_conf_items();
- free(conf.item_origins);
+ conf_free(conf);
}
TEST_SUITE_END
-// 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.
//
// 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)
// 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)
// 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)
-// 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.
//
// 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)
-// 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.
//
// 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)
// 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)
{
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);
{"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) {
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);
-// 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.
//
// 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)