diff --git a/.clang-tidy b/.clang-tidy index b83436861bd..aa361594f56 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -18,6 +18,7 @@ Checks: > -objc-*, -openmp-*, -zircon-*, + cppcoreguidelines-avoid-const-or-ref-data-members, cppcoreguidelines-pro-type-static-cast-downcast, cppcoreguidelines-rvalue-reference-param-not-moved, google-explicit-constructor, diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 84d37423d2e..4fe5620680d 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -42,6 +42,9 @@ jobs: uses: github/codeql-action/init@v4 with: languages: ${{ matrix.language }} + config: | + paths-ignore: + - gui/manualtest - name: Build cppcheck if: matrix.language == 'cpp' diff --git a/Makefile b/Makefile index e51cd58ced7..daed0997479 100644 --- a/Makefile +++ b/Makefile @@ -338,6 +338,7 @@ TESTOBJ = test/fixture.o \ test/testpreprocessor.o \ test/testprocessexecutor.o \ test/testprogrammemory.o \ + test/testrefthunk.o \ test/testregex.o \ test/testsarifreport.o \ test/testsettings.o \ @@ -483,43 +484,43 @@ check-nonneg: ###### Build -$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/analyzer.h lib/astutils.h lib/calculate.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkuninitvar.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyzers.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h +$(libcppdir)/valueflow.o: lib/valueflow.cpp lib/analyzer.h lib/astutils.h lib/calculate.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkuninitvar.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/forwardanalyzer.h lib/infer.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/refthunk.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyzers.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp -$(libcppdir)/tokenize.o: lib/tokenize.cpp externals/simplecpp/simplecpp.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/tokenize.o: lib/tokenize.cpp externals/simplecpp/simplecpp.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/tokenize.cpp -$(libcppdir)/symboldatabase.o: lib/symboldatabase.cpp lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/keywords.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/symboldatabase.o: lib/symboldatabase.cpp lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/keywords.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/symboldatabase.cpp $(libcppdir)/addoninfo.o: lib/addoninfo.cpp externals/picojson/picojson.h lib/addoninfo.h lib/config.h lib/json.h lib/path.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/addoninfo.cpp -$(libcppdir)/analyzerinfo.o: lib/analyzerinfo.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/mathlib.h lib/path.h lib/platform.h lib/standards.h lib/utils.h lib/xml.h +$(libcppdir)/analyzerinfo.o: lib/analyzerinfo.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/standards.h lib/utils.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/analyzerinfo.cpp -$(libcppdir)/astutils.o: lib/astutils.cpp lib/astutils.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/findtoken.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/astutils.o: lib/astutils.cpp lib/astutils.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/findtoken.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/astutils.cpp -$(libcppdir)/check64bit.o: lib/check64bit.cpp lib/check.h lib/check64bit.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/check64bit.o: lib/check64bit.cpp lib/check.h lib/check64bit.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/check64bit.cpp -$(libcppdir)/checkassert.o: lib/checkassert.cpp lib/astutils.h lib/check.h lib/checkassert.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkassert.o: lib/checkassert.cpp lib/astutils.h lib/check.h lib/checkassert.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkassert.cpp -$(libcppdir)/checkautovariables.o: lib/checkautovariables.cpp lib/astutils.h lib/check.h lib/checkautovariables.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkautovariables.o: lib/checkautovariables.cpp lib/astutils.h lib/check.h lib/checkautovariables.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkautovariables.cpp -$(libcppdir)/checkbool.o: lib/checkbool.cpp lib/astutils.h lib/check.h lib/checkbool.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkbool.o: lib/checkbool.cpp lib/astutils.h lib/check.h lib/checkbool.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbool.cpp -$(libcppdir)/checkbufferoverrun.o: lib/checkbufferoverrun.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/checkimpl.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vfvalue.h lib/xml.h +$(libcppdir)/checkbufferoverrun.o: lib/checkbufferoverrun.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/checkimpl.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbufferoverrun.cpp -$(libcppdir)/checkclass.o: lib/checkclass.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/checkclass.o: lib/checkclass.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkclass.cpp -$(libcppdir)/checkcondition.o: lib/checkcondition.cpp lib/astutils.h lib/check.h lib/checkcondition.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkcondition.o: lib/checkcondition.cpp lib/astutils.h lib/check.h lib/checkcondition.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkcondition.cpp $(libcppdir)/checkers.o: lib/checkers.cpp lib/checkers.h lib/config.h @@ -528,79 +529,79 @@ $(libcppdir)/checkers.o: lib/checkers.cpp lib/checkers.h lib/config.h $(libcppdir)/checkersidmapping.o: lib/checkersidmapping.cpp lib/checkers.h lib/config.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkersidmapping.cpp -$(libcppdir)/checkersreport.o: lib/checkersreport.cpp lib/addoninfo.h lib/checkers.h lib/checkersreport.h lib/config.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h +$(libcppdir)/checkersreport.o: lib/checkersreport.cpp lib/addoninfo.h lib/checkers.h lib/checkersreport.h lib/config.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkersreport.cpp -$(libcppdir)/checkexceptionsafety.o: lib/checkexceptionsafety.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkexceptionsafety.o: lib/checkexceptionsafety.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkexceptionsafety.cpp -$(libcppdir)/checkfunctions.o: lib/checkfunctions.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkfunctions.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkfunctions.o: lib/checkfunctions.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkfunctions.h lib/checkimpl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkfunctions.cpp -$(libcppdir)/checkimpl.o: lib/checkimpl.cpp lib/checkers.h lib/checkimpl.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkimpl.o: lib/checkimpl.cpp lib/checkers.h lib/checkimpl.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkimpl.cpp -$(libcppdir)/checkinternal.o: lib/checkinternal.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkinternal.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkinternal.o: lib/checkinternal.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkinternal.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkinternal.cpp -$(libcppdir)/checkio.o: lib/checkio.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkio.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkio.o: lib/checkio.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkio.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkio.cpp -$(libcppdir)/checkleakautovar.o: lib/checkleakautovar.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkleakautovar.h lib/checkmemoryleak.h lib/checknullpointer.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkleakautovar.o: lib/checkleakautovar.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkleakautovar.h lib/checkmemoryleak.h lib/checknullpointer.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkleakautovar.cpp -$(libcppdir)/checkmemoryleak.o: lib/checkmemoryleak.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkmemoryleak.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkmemoryleak.o: lib/checkmemoryleak.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkmemoryleak.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkmemoryleak.cpp -$(libcppdir)/checknullpointer.o: lib/checknullpointer.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checknullpointer.o: lib/checknullpointer.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/findtoken.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checknullpointer.cpp -$(libcppdir)/checkother.o: lib/checkother.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkother.o: lib/checkother.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkother.cpp -$(libcppdir)/checkpostfixoperator.o: lib/checkpostfixoperator.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkpostfixoperator.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkpostfixoperator.o: lib/checkpostfixoperator.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkpostfixoperator.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkpostfixoperator.cpp -$(libcppdir)/checks.o: lib/checks.cpp lib/check.h lib/check64bit.h lib/checkassert.h lib/checkautovariables.h lib/checkbool.h lib/checkbufferoverrun.h lib/checkclass.h lib/checkcondition.h lib/checkexceptionsafety.h lib/checkfunctions.h lib/checkimpl.h lib/checkinternal.h lib/checkio.h lib/checkleakautovar.h lib/checkmemoryleak.h lib/checknullpointer.h lib/checkother.h lib/checkpostfixoperator.h lib/checks.h lib/checksizeof.h lib/checkstl.h lib/checkstring.h lib/checktype.h lib/checkuninitvar.h lib/checkunusedvar.h lib/checkvaarg.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/standards.h lib/vfvalue.h +$(libcppdir)/checks.o: lib/checks.cpp lib/check.h lib/check64bit.h lib/checkassert.h lib/checkautovariables.h lib/checkbool.h lib/checkbufferoverrun.h lib/checkclass.h lib/checkcondition.h lib/checkexceptionsafety.h lib/checkfunctions.h lib/checkimpl.h lib/checkinternal.h lib/checkio.h lib/checkleakautovar.h lib/checkmemoryleak.h lib/checknullpointer.h lib/checkother.h lib/checkpostfixoperator.h lib/checks.h lib/checksizeof.h lib/checkstl.h lib/checkstring.h lib/checktype.h lib/checkuninitvar.h lib/checkunusedvar.h lib/checkvaarg.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/refthunk.h lib/standards.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checks.cpp -$(libcppdir)/checksizeof.o: lib/checksizeof.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checksizeof.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checksizeof.o: lib/checksizeof.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checksizeof.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checksizeof.cpp -$(libcppdir)/checkstl.o: lib/checkstl.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/checkstl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/pathanalysis.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkstl.o: lib/checkstl.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/checkstl.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/pathanalysis.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkstl.cpp -$(libcppdir)/checkstring.o: lib/checkstring.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstring.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkstring.o: lib/checkstring.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstring.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkstring.cpp -$(libcppdir)/checktype.o: lib/checktype.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checktype.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checktype.o: lib/checktype.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checktype.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checktype.cpp -$(libcppdir)/checkuninitvar.o: lib/checkuninitvar.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/checkuninitvar.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkuninitvar.o: lib/checkuninitvar.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/checkuninitvar.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkuninitvar.cpp -$(libcppdir)/checkunusedfunctions.o: lib/checkunusedfunctions.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/astutils.h lib/checkers.h lib/checkunusedfunctions.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/checkunusedfunctions.o: lib/checkunusedfunctions.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/astutils.h lib/checkers.h lib/checkunusedfunctions.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedfunctions.cpp -$(libcppdir)/checkunusedvar.o: lib/checkunusedvar.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkunusedvar.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/checkunusedvar.o: lib/checkunusedvar.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkunusedvar.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedvar.cpp -$(libcppdir)/checkvaarg.o: lib/checkvaarg.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkvaarg.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/checkvaarg.o: lib/checkvaarg.cpp lib/astutils.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkvaarg.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkvaarg.cpp -$(libcppdir)/clangimport.o: lib/clangimport.cpp lib/clangimport.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/clangimport.o: lib/clangimport.cpp lib/clangimport.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/refthunk.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/clangimport.cpp $(libcppdir)/color.o: lib/color.cpp lib/color.h lib/config.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/color.cpp -$(libcppdir)/cppcheck.o: lib/cppcheck.cpp externals/picojson/picojson.h externals/simplecpp/simplecpp.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checks.h lib/checkunusedfunctions.h lib/clangimport.h lib/color.h lib/config.h lib/cppcheck.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/regex.h lib/rule.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/version.h lib/vfvalue.h +$(libcppdir)/cppcheck.o: lib/cppcheck.cpp externals/picojson/picojson.h externals/simplecpp/simplecpp.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checks.h lib/checkunusedfunctions.h lib/clangimport.h lib/color.h lib/config.h lib/cppcheck.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/refthunk.h lib/regex.h lib/rule.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/timer.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/version.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/cppcheck.cpp -$(libcppdir)/ctu.o: lib/ctu.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/ctu.o: lib/ctu.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/check.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/refthunk.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/ctu.cpp -$(libcppdir)/errorlogger.o: lib/errorlogger.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/errorlogger.o: lib/errorlogger.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/suppressions.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/errorlogger.cpp $(libcppdir)/errortypes.o: lib/errortypes.cpp lib/config.h lib/errortypes.h lib/utils.h @@ -609,10 +610,10 @@ $(libcppdir)/errortypes.o: lib/errortypes.cpp lib/config.h lib/errortypes.h lib/ $(libcppdir)/findtoken.o: lib/findtoken.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/findtoken.h lib/library.h lib/mathlib.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/findtoken.cpp -$(libcppdir)/forwardanalyzer.o: lib/forwardanalyzer.cpp lib/analyzer.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/forwardanalyzer.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/forwardanalyzer.o: lib/forwardanalyzer.cpp lib/analyzer.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/forwardanalyzer.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/forwardanalyzer.cpp -$(libcppdir)/fwdanalysis.o: lib/fwdanalysis.cpp lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h +$(libcppdir)/fwdanalysis.o: lib/fwdanalysis.cpp lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/fwdanalysis.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/fwdanalysis.cpp $(libcppdir)/importproject.o: lib/importproject.cpp externals/picojson/picojson.h externals/tinyxml2/tinyxml2.h lib/checkers.h lib/config.h lib/filesettings.h lib/importproject.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h @@ -624,7 +625,7 @@ $(libcppdir)/infer.o: lib/infer.cpp lib/calculate.h lib/config.h lib/errortypes. $(libcppdir)/keywords.o: lib/keywords.cpp lib/config.h lib/keywords.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/keywords.cpp -$(libcppdir)/library.o: lib/library.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/library.o: lib/library.cpp externals/tinyxml2/tinyxml2.h lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/refthunk.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/library.cpp $(libcppdir)/mathlib.o: lib/mathlib.cpp externals/simplecpp/simplecpp.h lib/config.h lib/errortypes.h lib/mathlib.h lib/smallvector.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h @@ -633,7 +634,7 @@ $(libcppdir)/mathlib.o: lib/mathlib.cpp externals/simplecpp/simplecpp.h lib/conf $(libcppdir)/path.o: lib/path.cpp externals/simplecpp/simplecpp.h lib/config.h lib/path.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/path.cpp -$(libcppdir)/pathanalysis.o: lib/pathanalysis.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/pathanalysis.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h +$(libcppdir)/pathanalysis.o: lib/pathanalysis.cpp lib/astutils.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/pathanalysis.h lib/refthunk.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/pathanalysis.cpp $(libcppdir)/pathmatch.o: lib/pathmatch.cpp lib/config.h lib/path.h lib/pathmatch.h lib/standards.h @@ -642,19 +643,19 @@ $(libcppdir)/pathmatch.o: lib/pathmatch.cpp lib/config.h lib/path.h lib/pathmatc $(libcppdir)/platform.o: lib/platform.cpp externals/tinyxml2/tinyxml2.h lib/config.h lib/mathlib.h lib/path.h lib/platform.h lib/standards.h lib/utils.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/platform.cpp -$(libcppdir)/preprocessor.o: lib/preprocessor.cpp externals/simplecpp/simplecpp.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h +$(libcppdir)/preprocessor.o: lib/preprocessor.cpp externals/simplecpp/simplecpp.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/preprocessor.cpp -$(libcppdir)/programmemory.o: lib/programmemory.cpp lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/programmemory.o: lib/programmemory.cpp lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/infer.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/programmemory.cpp $(libcppdir)/regex.o: lib/regex.cpp lib/config.h lib/regex.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/regex.cpp -$(libcppdir)/reverseanalyzer.o: lib/reverseanalyzer.cpp lib/analyzer.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/forwardanalyzer.h lib/library.h lib/mathlib.h lib/platform.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueptr.h lib/vfvalue.h +$(libcppdir)/reverseanalyzer.o: lib/reverseanalyzer.cpp lib/analyzer.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/forwardanalyzer.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/reverseanalyzer.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueptr.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/reverseanalyzer.cpp -$(libcppdir)/sarifreport.o: lib/sarifreport.cpp externals/picojson/picojson.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/platform.h lib/sarifreport.h lib/settings.h lib/standards.h lib/utils.h +$(libcppdir)/sarifreport.o: lib/sarifreport.cpp externals/picojson/picojson.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/sarifreport.h lib/settings.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/sarifreport.cpp $(libcppdir)/settings.o: lib/settings.cpp externals/picojson/picojson.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/rule.h lib/settings.h lib/standards.h lib/summaries.h lib/suppressions.h lib/utils.h lib/vfvalue.h @@ -663,34 +664,34 @@ $(libcppdir)/settings.o: lib/settings.cpp externals/picojson/picojson.h lib/addo $(libcppdir)/standards.o: lib/standards.cpp externals/simplecpp/simplecpp.h lib/config.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/standards.cpp -$(libcppdir)/summaries.o: lib/summaries.cpp lib/analyzerinfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/summaries.o: lib/summaries.cpp lib/analyzerinfo.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/summaries.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/summaries.cpp -$(libcppdir)/suppressions.o: lib/suppressions.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h +$(libcppdir)/suppressions.o: lib/suppressions.cpp externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/suppressions.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h lib/xml.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/suppressions.cpp -$(libcppdir)/templatesimplifier.o: lib/templatesimplifier.cpp lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/templatesimplifier.o: lib/templatesimplifier.cpp lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/templatesimplifier.cpp $(libcppdir)/timer.o: lib/timer.cpp lib/config.h lib/timer.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/timer.cpp -$(libcppdir)/token.o: lib/token.cpp externals/simplecpp/simplecpp.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/valueflow.h lib/vfvalue.h +$(libcppdir)/token.o: lib/token.cpp externals/simplecpp/simplecpp.h lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/valueflow.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/token.cpp -$(libcppdir)/tokenlist.o: lib/tokenlist.cpp externals/simplecpp/simplecpp.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/keywords.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h +$(libcppdir)/tokenlist.o: lib/tokenlist.cpp externals/simplecpp/simplecpp.h lib/astutils.h lib/checkers.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/keywords.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/tokenlist.cpp $(libcppdir)/utils.o: lib/utils.cpp lib/config.h lib/utils.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/utils.cpp -$(libcppdir)/vf_analyzers.o: lib/vf_analyzers.cpp lib/analyzer.h lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyzers.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h +$(libcppdir)/vf_analyzers.o: lib/vf_analyzers.cpp lib/analyzer.h lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/programmemory.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/valueptr.h lib/vf_analyzers.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_analyzers.cpp -$(libcppdir)/vf_common.o: lib/vf_common.cpp lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h +$(libcppdir)/vf_common.o: lib/vf_common.cpp lib/astutils.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_common.cpp -$(libcppdir)/vf_settokenvalue.o: lib/vf_settokenvalue.cpp lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h +$(libcppdir)/vf_settokenvalue.o: lib/vf_settokenvalue.cpp lib/astutils.h lib/calculate.h lib/checkers.h lib/config.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/valueflow.h lib/vf_common.h lib/vf_settokenvalue.h lib/vfvalue.h $(CXX) ${INCLUDE_FOR_LIB} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_settokenvalue.cpp $(libcppdir)/vfvalue.o: lib/vfvalue.cpp lib/config.h lib/errortypes.h lib/mathlib.h lib/smallvector.h lib/templatesimplifier.h lib/token.h lib/utils.h lib/vfvalue.h @@ -699,13 +700,13 @@ $(libcppdir)/vfvalue.o: lib/vfvalue.cpp lib/config.h lib/errortypes.h lib/mathli frontend/frontend.o: frontend/frontend.cpp frontend/frontend.h lib/checkers.h lib/config.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_FE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ frontend/frontend.cpp -cli/cmdlineparser.o: cli/cmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/filelister.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/regex.h lib/rule.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h +cli/cmdlineparser.o: cli/cmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/filelister.h externals/tinyxml2/tinyxml2.h lib/addoninfo.h lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/refthunk.h lib/regex.h lib/rule.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h lib/xml.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/cmdlineparser.cpp -cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/sehwrapper.h cli/signalhandler.h cli/singleexecutor.h cli/threadexecutor.h externals/picojson/picojson.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/sarifreport.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h +cli/cppcheckexecutor.o: cli/cppcheckexecutor.cpp cli/cmdlinelogger.h cli/cmdlineparser.h cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/sehwrapper.h cli/signalhandler.h cli/singleexecutor.h cli/threadexecutor.h externals/picojson/picojson.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/json.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/sarifreport.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/cppcheckexecutor.cpp -cli/executor.o: cli/executor.cpp cli/executor.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h +cli/executor.o: cli/executor.cpp cli/executor.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/executor.cpp cli/filelister.o: cli/filelister.cpp cli/filelister.h lib/config.h lib/filesettings.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/standards.h lib/utils.h @@ -714,7 +715,7 @@ cli/filelister.o: cli/filelister.cpp cli/filelister.h lib/config.h lib/filesetti cli/main.o: cli/main.cpp cli/cppcheckexecutor.h lib/config.h lib/filesettings.h lib/mathlib.h lib/path.h lib/platform.h lib/standards.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/main.cpp -cli/processexecutor.o: cli/processexecutor.cpp cli/executor.h cli/processexecutor.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h +cli/processexecutor.o: cli/processexecutor.cpp cli/executor.h cli/processexecutor.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/processexecutor.cpp cli/sehwrapper.o: cli/sehwrapper.cpp cli/sehwrapper.h lib/config.h lib/utils.h @@ -729,241 +730,244 @@ cli/singleexecutor.o: cli/singleexecutor.cpp cli/executor.h cli/singleexecutor.h cli/stacktrace.o: cli/stacktrace.cpp cli/stacktrace.h lib/config.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/stacktrace.cpp -cli/threadexecutor.o: cli/threadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h +cli/threadexecutor.o: cli/threadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/check.h lib/checkers.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/utils.h $(CXX) ${INCLUDE_FOR_CLI} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ cli/threadexecutor.cpp -test/fixture.o: test/fixture.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h test/options.h test/redirect.h +test/fixture.o: test/fixture.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h test/options.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/fixture.cpp test/helpers.o: test/helpers.cpp cli/filelister.h externals/simplecpp/simplecpp.h externals/tinyxml2/tinyxml2.h lib/checkers.h lib/config.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/helpers.cpp -test/main.o: test/main.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h +test/main.o: test/main.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/preprocessor.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/main.cpp test/options.o: test/options.cpp lib/config.h lib/timer.h test/options.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/options.cpp -test/test64bit.o: test/test64bit.cpp lib/check.h lib/check64bit.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/test64bit.o: test/test64bit.cpp lib/check.h lib/check64bit.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/test64bit.cpp -test/testanalyzerinformation.o: test/testanalyzerinformation.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h +test/testanalyzerinformation.o: test/testanalyzerinformation.cpp externals/tinyxml2/tinyxml2.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testanalyzerinformation.cpp -test/testassert.o: test/testassert.cpp lib/check.h lib/checkassert.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testassert.o: test/testassert.cpp lib/check.h lib/checkassert.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testassert.cpp -test/testastutils.o: test/testastutils.cpp lib/astutils.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testastutils.o: test/testastutils.cpp lib/astutils.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testastutils.cpp -test/testautovariables.o: test/testautovariables.cpp lib/check.h lib/checkautovariables.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testautovariables.o: test/testautovariables.cpp lib/check.h lib/checkautovariables.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testautovariables.cpp -test/testbool.o: test/testbool.cpp lib/check.h lib/checkbool.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testbool.o: test/testbool.cpp lib/check.h lib/checkbool.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testbool.cpp -test/testbufferoverrun.o: test/testbufferoverrun.cpp lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testbufferoverrun.o: test/testbufferoverrun.cpp lib/check.h lib/checkbufferoverrun.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testbufferoverrun.cpp -test/testcharvar.o: test/testcharvar.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testcharvar.o: test/testcharvar.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcharvar.cpp -test/testcheck.o: test/testcheck.cpp lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testcheck.o: test/testcheck.cpp lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcheck.cpp -test/testcheckersreport.o: test/testcheckersreport.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testcheckersreport.o: test/testcheckersreport.cpp lib/addoninfo.h lib/check.h lib/checkers.h lib/checkersreport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcheckersreport.cpp -test/testclangimport.o: test/testclangimport.cpp lib/check.h lib/checkers.h lib/clangimport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h +test/testclangimport.o: test/testclangimport.cpp lib/check.h lib/checkers.h lib/clangimport.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testclangimport.cpp -test/testclass.o: test/testclass.cpp lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testclass.o: test/testclass.cpp lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testclass.cpp -test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/regex.h lib/rule.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testcmdlineparser.o: test/testcmdlineparser.cpp cli/cmdlinelogger.h cli/cmdlineparser.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/regex.h lib/rule.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcmdlineparser.cpp -test/testcolor.o: test/testcolor.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testcolor.o: test/testcolor.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcolor.cpp -test/testcondition.o: test/testcondition.cpp lib/check.h lib/checkcondition.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testcondition.o: test/testcondition.cpp lib/check.h lib/checkcondition.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcondition.cpp -test/testconstructors.o: test/testconstructors.cpp lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testconstructors.o: test/testconstructors.cpp lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testconstructors.cpp -test/testcppcheck.o: test/testcppcheck.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testcppcheck.o: test/testcppcheck.cpp externals/simplecpp/simplecpp.h lib/addoninfo.h lib/analyzerinfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testcppcheck.cpp -test/testerrorlogger.o: test/testerrorlogger.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h +test/testerrorlogger.o: test/testerrorlogger.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/xml.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testerrorlogger.cpp -test/testexceptionsafety.o: test/testexceptionsafety.cpp lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testexceptionsafety.o: test/testexceptionsafety.cpp lib/check.h lib/checkers.h lib/checkexceptionsafety.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testexceptionsafety.cpp -test/testexecutor.o: test/testexecutor.cpp cli/executor.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testexecutor.o: test/testexecutor.cpp cli/executor.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testexecutor.cpp -test/testfilelister.o: test/testfilelister.cpp cli/filelister.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testfilelister.o: test/testfilelister.cpp cli/filelister.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfilelister.cpp -test/testfilesettings.o: test/testfilesettings.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testfilesettings.o: test/testfilesettings.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfilesettings.cpp -test/testfrontend.o: test/testfrontend.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testfrontend.o: test/testfrontend.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfrontend.cpp -test/testfunctions.o: test/testfunctions.cpp lib/check.h lib/checkers.h lib/checkfunctions.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testfunctions.o: test/testfunctions.cpp lib/check.h lib/checkers.h lib/checkfunctions.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testfunctions.cpp -test/testgarbage.o: test/testgarbage.cpp lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testgarbage.o: test/testgarbage.cpp lib/check.h lib/checkers.h lib/checks.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testgarbage.cpp -test/testimportproject.o: test/testimportproject.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testimportproject.o: test/testimportproject.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/importproject.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testimportproject.cpp -test/testincompletestatement.o: test/testincompletestatement.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testincompletestatement.o: test/testincompletestatement.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testincompletestatement.cpp -test/testinternal.o: test/testinternal.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkinternal.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testinternal.o: test/testinternal.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkinternal.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testinternal.cpp -test/testio.o: test/testio.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkio.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testio.o: test/testio.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkio.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testio.cpp -test/testleakautovar.o: test/testleakautovar.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkleakautovar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testleakautovar.o: test/testleakautovar.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkleakautovar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testleakautovar.cpp -test/testlibrary.o: test/testlibrary.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testlibrary.o: test/testlibrary.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testlibrary.cpp -test/testmathlib.o: test/testmathlib.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h +test/testmathlib.o: test/testmathlib.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testmathlib.cpp -test/testmemleak.o: test/testmemleak.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkmemoryleak.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testmemleak.o: test/testmemleak.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkmemoryleak.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testmemleak.cpp -test/testnullpointer.o: test/testnullpointer.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testnullpointer.o: test/testnullpointer.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checknullpointer.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testnullpointer.cpp -test/testoptions.o: test/testoptions.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h +test/testoptions.o: test/testoptions.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h test/options.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testoptions.cpp -test/testother.o: test/testother.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testother.o: test/testother.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkother.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testother.cpp -test/testpath.o: test/testpath.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testpath.o: test/testpath.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpath.cpp -test/testpathmatch.o: test/testpathmatch.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testpathmatch.o: test/testpathmatch.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/pathmatch.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpathmatch.cpp -test/testplatform.o: test/testplatform.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h +test/testplatform.o: test/testplatform.cpp externals/tinyxml2/tinyxml2.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h lib/xml.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testplatform.cpp -test/testpostfixoperator.o: test/testpostfixoperator.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkpostfixoperator.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testpostfixoperator.o: test/testpostfixoperator.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkpostfixoperator.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpostfixoperator.cpp -test/testpreprocessor.o: test/testpreprocessor.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testpreprocessor.o: test/testpreprocessor.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testpreprocessor.cpp -test/testprocessexecutor.o: test/testprocessexecutor.cpp cli/executor.h cli/processexecutor.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testprocessexecutor.o: test/testprocessexecutor.cpp cli/executor.h cli/processexecutor.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testprocessexecutor.cpp -test/testprogrammemory.o: test/testprogrammemory.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testprogrammemory.o: test/testprogrammemory.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/programmemory.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testprogrammemory.cpp -test/testregex.o: test/testregex.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testrefthunk.o: test/testrefthunk.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h + $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testrefthunk.cpp + +test/testregex.o: test/testregex.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/regex.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testregex.cpp -test/testsarifreport.o: test/testsarifreport.cpp externals/picojson/picojson.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/platform.h lib/sarifreport.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testsarifreport.o: test/testsarifreport.cpp externals/picojson/picojson.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/json.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/sarifreport.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsarifreport.cpp -test/testsettings.o: test/testsettings.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testsettings.o: test/testsettings.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsettings.cpp -test/testsimplifytemplate.o: test/testsimplifytemplate.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsimplifytemplate.o: test/testsimplifytemplate.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifytemplate.cpp -test/testsimplifytokens.o: test/testsimplifytokens.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsimplifytokens.o: test/testsimplifytokens.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifytokens.cpp -test/testsimplifytypedef.o: test/testsimplifytypedef.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsimplifytypedef.o: test/testsimplifytypedef.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifytypedef.cpp -test/testsimplifyusing.o: test/testsimplifyusing.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsimplifyusing.o: test/testsimplifyusing.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsimplifyusing.cpp -test/testsingleexecutor.o: test/testsingleexecutor.cpp cli/executor.h cli/singleexecutor.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testsingleexecutor.o: test/testsingleexecutor.cpp cli/executor.h cli/singleexecutor.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsingleexecutor.cpp -test/testsizeof.o: test/testsizeof.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checksizeof.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testsizeof.o: test/testsizeof.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checksizeof.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsizeof.cpp -test/teststandards.o: test/teststandards.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/teststandards.o: test/teststandards.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststandards.cpp -test/teststl.o: test/teststl.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/teststl.o: test/teststl.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststl.cpp -test/teststring.o: test/teststring.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstring.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/teststring.o: test/teststring.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkstring.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/teststring.cpp -test/testsummaries.o: test/testsummaries.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/summaries.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testsummaries.o: test/testsummaries.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/summaries.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsummaries.cpp -test/testsuppressions.o: test/testsuppressions.cpp cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/singleexecutor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testsuppressions.o: test/testsuppressions.cpp cli/cppcheckexecutor.h cli/executor.h cli/processexecutor.h cli/singleexecutor.h cli/threadexecutor.h lib/addoninfo.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsuppressions.cpp -test/testsymboldatabase.o: test/testsymboldatabase.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testsymboldatabase.o: test/testsymboldatabase.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testsymboldatabase.cpp -test/testthreadexecutor.o: test/testthreadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h +test/testthreadexecutor.o: test/testthreadexecutor.cpp cli/executor.h cli/threadexecutor.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/cppcheck.h lib/errorlogger.h lib/errortypes.h lib/filesettings.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/suppressions.h lib/timer.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testthreadexecutor.cpp -test/testtimer.o: test/testtimer.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/timer.h lib/utils.h test/fixture.h test/redirect.h +test/testtimer.o: test/testtimer.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/timer.h lib/utils.h test/fixture.h test/redirect.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtimer.cpp -test/testtoken.o: test/testtoken.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtoken.o: test/testtoken.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtoken.cpp -test/testtokenize.o: test/testtokenize.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtokenize.o: test/testtokenize.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenize.cpp -test/testtokenlist.o: test/testtokenlist.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtokenlist.o: test/testtokenlist.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenlist.cpp -test/testtokenrange.o: test/testtokenrange.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testtokenrange.o: test/testtokenrange.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/sourcelocation.h lib/standards.h lib/symboldatabase.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/tokenrange.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtokenrange.cpp -test/testtype.o: test/testtype.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checktype.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testtype.o: test/testtype.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checktype.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testtype.cpp -test/testuninitvar.o: test/testuninitvar.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkuninitvar.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testuninitvar.o: test/testuninitvar.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkuninitvar.h lib/color.h lib/config.h lib/ctu.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testuninitvar.cpp -test/testunusedfunctions.o: test/testunusedfunctions.cpp lib/check.h lib/checkers.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testunusedfunctions.o: test/testunusedfunctions.cpp lib/check.h lib/checkers.h lib/checkunusedfunctions.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedfunctions.cpp -test/testunusedprivfunc.o: test/testunusedprivfunc.cpp lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testunusedprivfunc.o: test/testunusedprivfunc.cpp lib/check.h lib/checkclass.h lib/checkers.h lib/checkimpl.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedprivfunc.cpp -test/testunusedvar.o: test/testunusedvar.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkunusedvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testunusedvar.o: test/testunusedvar.cpp externals/simplecpp/simplecpp.h lib/check.h lib/checkers.h lib/checkimpl.h lib/checkunusedvar.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/preprocessor.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testunusedvar.cpp -test/testutils.o: test/testutils.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h +test/testutils.o: test/testutils.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testutils.cpp -test/testvaarg.o: test/testvaarg.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkvaarg.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h +test/testvaarg.o: test/testvaarg.cpp lib/check.h lib/checkers.h lib/checkimpl.h lib/checkvaarg.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/tokenize.h lib/tokenlist.h lib/utils.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvaarg.cpp -test/testvalueflow.o: test/testvalueflow.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testvalueflow.o: test/testvalueflow.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvalueflow.cpp -test/testvarid.o: test/testvarid.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h +test/testvarid.o: test/testvarid.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/path.h lib/platform.h lib/refthunk.h lib/settings.h lib/smallvector.h lib/standards.h lib/templatesimplifier.h lib/token.h lib/tokenize.h lib/tokenlist.h lib/utils.h lib/vfvalue.h test/fixture.h test/helpers.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvarid.cpp -test/testvfvalue.o: test/testvfvalue.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/settings.h lib/standards.h lib/utils.h lib/vfvalue.h test/fixture.h +test/testvfvalue.o: test/testvfvalue.cpp lib/check.h lib/checkers.h lib/color.h lib/config.h lib/errorlogger.h lib/errortypes.h lib/library.h lib/mathlib.h lib/platform.h lib/refthunk.h lib/settings.h lib/standards.h lib/utils.h lib/vfvalue.h test/fixture.h $(CXX) ${INCLUDE_FOR_TEST} ${CFLAGS_FOR_TEST} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ test/testvfvalue.cpp externals/simplecpp/simplecpp.o: externals/simplecpp/simplecpp.cpp externals/simplecpp/simplecpp.h diff --git a/addons/threadsafety.py b/addons/threadsafety.py index 390a245d4e1..25b2c16abe3 100755 --- a/addons/threadsafety.py +++ b/addons/threadsafety.py @@ -91,7 +91,6 @@ 'race:stdin', 'race:stdout', 'race:streams', - 'race:strerror', 'race:strsignal', 'race:strtok', 'race:tmbuf', @@ -261,7 +260,6 @@ 'siginterrupt', 'sleep', 'srand48', - 'strerror', 'strsignal', 'strtok', 'tmpnam', diff --git a/cfg/gnu.cfg b/cfg/gnu.cfg index 9a0b1652d32..af2fff93e59 100644 --- a/cfg/gnu.cfg +++ b/cfg/gnu.cfg @@ -650,7 +650,7 @@ - + @@ -659,12 +659,12 @@ - + - + diff --git a/cfg/std.cfg b/cfg/std.cfg index 6dcf0f9f6b3..99377575428 100644 --- a/cfg/std.cfg +++ b/cfg/std.cfg @@ -3928,7 +3928,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + @@ -3974,12 +3974,12 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + - + @@ -4016,12 +4016,12 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + - + @@ -4081,13 +4081,13 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + - + @@ -4141,7 +4141,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun - + diff --git a/clang-tidy.md b/clang-tidy.md index f00a39cde12..fe6a6eb7140 100644 --- a/clang-tidy.md +++ b/clang-tidy.md @@ -138,7 +138,6 @@ Does not improve the readability. To be evaluated (need to remove exclusion). `cppcoreguidelines-missing-std-forward`
-`cppcoreguidelines-avoid-const-or-ref-data-members`
`cppcoreguidelines-macro-usage`
`cppcoreguidelines-pro-type-member-init`
`cppcoreguidelines-prefer-member-initializer`
diff --git a/cli/cmdlineparser.h b/cli/cmdlineparser.h index 54e7ae4b0aa..e712c3035ff 100644 --- a/cli/cmdlineparser.h +++ b/cli/cmdlineparser.h @@ -56,6 +56,8 @@ class CmdLineParser { * @param suppressions Suppressions instance that keeps the suppressions */ CmdLineParser(CmdLineLogger &logger, Settings &settings, Suppressions &suppressions); + CmdLineParser(const CmdLineParser &) = delete; + CmdLineParser &operator=(const CmdLineParser &) = delete; enum class Result : std::uint8_t { Success, Exit, Fail }; @@ -152,10 +154,10 @@ class CmdLineParser { void outputFormatOptionMixingError() const; - CmdLineLogger &mLogger; + CmdLineLogger& mLogger; - Settings &mSettings; - Suppressions &mSuppressions; + Settings& mSettings; + Suppressions& mSuppressions; protected: std::vector mPathNames; diff --git a/cli/processexecutor.cpp b/cli/processexecutor.cpp index 959d16d37ec..f0f01bcffe7 100644 --- a/cli/processexecutor.cpp +++ b/cli/processexecutor.cpp @@ -96,7 +96,7 @@ namespace { { if (suppr.isInline) writeToPipe(REPORT_SUPPR_INLINE, suppressionToString(suppr)); - else if (suppr.checked) + else if (suppr.checked && suppr.hash == 0) writeToPipe(REPORT_SUPPR, suppressionToString(suppr)); } } @@ -172,8 +172,8 @@ namespace { writeToPipeInternal(type, data.c_str(), len); } - const int mWpipe; - const bool mDebug; + int mWpipe; + bool mDebug; }; } diff --git a/gui/checkthread.cpp b/gui/checkthread.cpp index 07ca4e77ed2..2b4c9ba654f 100644 --- a/gui/checkthread.cpp +++ b/gui/checkthread.cpp @@ -113,13 +113,15 @@ CheckThread::CheckThread(ThreadResult &result, int threadIndex) void CheckThread::setSettings(const Settings &settings, std::shared_ptr supprs) { mFiles.clear(); + mFileSettings.clear(); mSettings = settings; // this is a copy mSuppressions = std::move(supprs); } -void CheckThread::analyseWholeProgram(const std::list &files, const std::string& ctuInfo) +void CheckThread::analyseWholeProgram(const std::list &files, const std::list &fileSettings, const std::string& ctuInfo) { mFiles = files; + mFileSettings = fileSettings; mAnalyseWholeProgram = true; mCtuInfo = ctuInfo; start(); @@ -136,8 +138,9 @@ void CheckThread::run() std::string ctuInfo; ctuInfo.swap(mCtuInfo); qDebug() << "Whole program analysis"; - cppcheck.analyseWholeProgram(mSettings.buildDir, mFiles, {}, ctuInfo); + cppcheck.analyseWholeProgram(mSettings.buildDir, mFiles, mFileSettings, ctuInfo); mFiles.clear(); + mFileSettings.clear(); emit done(); return; } diff --git a/gui/checkthread.h b/gui/checkthread.h index a630ef7fc13..74eb292e6e2 100644 --- a/gui/checkthread.h +++ b/gui/checkthread.h @@ -69,10 +69,11 @@ class CheckThread : public QThread { /** * @brief Run whole program analysis - * @param files All files - * @param ctuInfo Ctu info for addons + * @param files All files + * @param fileSettings All files of the project + * @param ctuInfo Ctu info for addons */ - void analyseWholeProgram(const std::list &files, const std::string& ctuInfo); + void analyseWholeProgram(const std::list &files, const std::list &fileSettings, const std::string& ctuInfo); void setAddonsAndTools(const QStringList &addonsAndTools) { mAddonsAndTools = addonsAndTools; @@ -153,6 +154,7 @@ class CheckThread : public QThread { bool isSuppressed(const SuppressionList::ErrorMessage &errorMessage) const; std::list mFiles; + std::list mFileSettings; bool mAnalyseWholeProgram{}; std::string mCtuInfo; QStringList mAddonsAndTools; diff --git a/gui/cppcheck_de.ts b/gui/cppcheck_de.ts index f89eb60e4a8..ee401f8c2a4 100644 --- a/gui/cppcheck_de.ts +++ b/gui/cppcheck_de.ts @@ -5,27 +5,32 @@ About + About Cppcheck Über Cppcheck + Version %1 Version %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - Ein Werkzeug zur statischen C/C++-Code-Analyse. + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. Copyright © 2007-%1 Cppcheck-Team. + This program is licensed under the terms of the GNU General Public License version 3 Dieses Programm ist unter den Bedingungen @@ -33,11 +38,13 @@ der GNU General Public License Version 3 lizenziert + Visit Cppcheck homepage at %1 Besuchen Sie die Cppcheck-Homepage unter %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> <html><head/><body><p>Vielen Dank den Bibliotheken die wir nutzen:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> @@ -47,11 +54,13 @@ der GNU General Public License Version 3 lizenziert ApplicationDialog + Add an application Anwendung hinzufügen + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -78,21 +87,25 @@ Parameter: -l(line) (file) + &Name: &Name: + &Executable: &Ausführbare Datei: + &Parameters: &Parameter: + Browse Suchen @@ -188,16 +201,19 @@ Parameter: -l(line) (file) HelpDialog + Cppcheck GUI help Cppcheck GUI Hilfe + Contents Inhalt + Index Index @@ -215,16 +231,19 @@ Parameter: -l(line) (file) LibraryAddFunctionDialog + Add function Funktion hinzufügen + Function name(s) Funktionsname(n) + Number of arguments Anzahl Argumente @@ -233,86 +252,103 @@ Parameter: -l(line) (file) LibraryDialog + Library Editor Bibliothekseditor + Open Öffnen + Save Speichern + Save as Speichern unter + Functions Funktionen + Sort Sortiere + Add Hinzufügen + Filter: Filter: + Comments Kommentare + noreturn Zurückkehrend + False Ja + True Nein + Unknown Unbekannt + return value must be used Rückgabewert muss genutzt werden + ignore function in leaks checking Ignoriere Funktion in Speicherleck-Prüfung + Arguments Argumente + Edit Bearbeiten @@ -356,11 +392,13 @@ Parameter: -l(line) (file) LibraryEditArgDialog + Edit argument Argument bearbeiten + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -376,11 +414,13 @@ Parameter: -l(line) (file) + Not bool Nicht boolsch + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -396,78 +436,99 @@ Parameter: -l(line) (file) + Not null Nicht Null + Not uninit Nicht uninitialisiert + String String + Format string Formatstring + Min size of buffer Minimale Puffergröße + + Type Typ + + None Keine + + argvalue Argumentwert + + mul Multiplikation + + strlen strlen + + Arg Argument 1 + + Arg2 Argument 2 + and und + Valid values Zulässige Werte @@ -480,506 +541,611 @@ Parameter: -l(line) (file) + Standard Standard + &File &Datei + &View &Ansicht + &Toolbars &Symbolleisten + A&nalyze A&nalysieren + C++ standard C++-Standard + &C standard &C-Standard + &Edit &Bearbeiten + &License... &Lizenz... + A&uthors... &Autoren... + &About... Ü&ber... + &Files... &Dateien... + + Analyze files Analysiere Dateien + Ctrl+F Strg+F + &Directory... &Verzeichnis... + + Analyze directory Analysiere Verzeichnis + Ctrl+D Strg+D + Ctrl+R Strg+R + &Stop &Stoppen + + Stop analysis Analyse abbrechen + Esc Esc + &Save results to file... &Ergebnisse in Datei speichern... + Ctrl+S Strg+S + &Quit &Beenden + &Clear results Ergebnisse &löschen + &Preferences &Einstellungen - + + + Show errors Zeige Fehler - + + + Show warnings Zeige Warnungen + + Show performance warnings Zeige Performance-Warnungen + Show &hidden Zeige &versteckte - - + + Information Information + Show information messages Zeige Informationsmeldungen + Show portability warnings Zeige Portabilitätswarnungen + Show Cppcheck results Zeige Cppcheck-Ergebnisse + Clang Clang + Show Clang results Zeige Clang-Ergebnisse + &Filter &Filter + Filter results Gefilterte Ergebnisse + Windows 32-bit ANSI Windows 32-bit, ANSI + Windows 32-bit Unicode Windows 32-bit, Unicode + Unix 32-bit Unix 32-bit + Unix 64-bit Unix 64-bit + Windows 64-bit Windows 64-bit + &Print... Drucken... + Print the Current Report Aktuellen Bericht ausdrucken + Print Pre&view... Druckvorschau + Open a Print Preview Dialog for the Current Results Druckvorschaudialog für aktuelle Ergebnisse öffnen + Open library editor Bibliothekseditor öffnen + &Check all Alle &auswählen + Checking for updates + Hide Verstecken + + Report + Filter Filter + &Reanalyze modified files Veränderte Dateien neu analysieren + Reanal&yze all files Alle Dateien erneut anal&ysieren + Ctrl+Q + Style war&nings Stilwar&nungen + E&rrors F&ehler + &Uncheck all Alle a&bwählen + Collapse &all Alle &reduzieren + &Expand all Alle &erweitern + &Standard &Standard + Standard items Standardeinträge + Toolbar Symbolleiste + &Categories &Kategorien + Error categories Fehler-Kategorien + &Open XML... Öffne &XML... + Open P&roject File... Pr&ojektdatei öffnen... + Ctrl+Shift+O + Sh&ow Scratchpad... &Zeige Schmierzettel... + &New Project File... &Neue Projektdatei... + Ctrl+Shift+N + &Log View &Loganzeige + Log View Loganzeige + C&lose Project File Projektdatei &schließen + &Edit Project File... Projektdatei &bearbeiten... + &Statistics &Statistik + &Warnings &Warnungen + Per&formance warnings Per&formance-Warnungen + &Information &Information + &Portability &Portabilität + P&latforms P&lattformen + C++&11 C++&11 + C&99 C&99 + &Posix Posix + C&11 C&11 + &C89 &C89 + &C++03 &C++03 + &Library Editor... &Bibliothekseditor + &Auto-detect language Sprache &automatisch erkennen + &Enforce C++ C++ &erzwingen + E&nforce C C e&rzwingen + C++14 C++14 + Reanalyze and check library Neu analysieren und Bibliothek prüfen + Check configuration (defines, includes) Prüfe Konfiguration (Definitionen, Includes) + C++17 C++17 + C++20 C++20 + Compliance report... + Normal @@ -997,68 +1163,84 @@ Parameter: -l(line) (file) + Autosar + EULA... + Thread Details + Show thread details + &Contents &Inhalte + Categories Kategorien + + Show style warnings Zeige Stilwarnungen + Open the help contents Öffnet die Hilfe-Inhalte + F1 F1 + &Help &Hilfe - - + + Quick Filter: Schnellfilter: - + + None of the selected files is part of the project, nothing to analyze. + + + + Select configuration Konfiguration wählen - + Found project file: %1 Do you want to load this project file instead? @@ -1067,102 +1249,102 @@ Do you want to load this project file instead? Möchten Sie stattdessen diese öffnen? - + File not found Datei nicht gefunden - + Bad XML Fehlerhaftes XML - + Missing attribute Fehlendes Attribut - + Bad attribute value Falscher Attributwert - + Duplicate platform type Plattformtyp doppelt - + Platform type redefined Plattformtyp neu definiert - + Duplicate define - + Failed to load the selected library '%1'. %2 Laden der ausgewählten Bibliothek '%1' schlug fehl. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License Lizenz - + Authors Autoren - + Save the report file Speichert die Berichtdatei - - + + XML files (*.xml) XML-Dateien (*.xml) - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -1171,32 +1353,32 @@ This is probably because the settings were changed between the Cppcheck versions Dies wurde vermutlich durch einen Wechsel der Cppcheck-Version hervorgerufen. Bitte prüfen (und korrigieren) Sie die Einstellungen, andernfalls könnte die Editor-Anwendung nicht korrekt starten. - + You must close the project file before selecting new files or directories! Sie müssen die Projektdatei schließen, bevor Sie neue Dateien oder Verzeichnisse auswählen! - + The library '%1' contains unknown elements: %2 Die Bibliothek '%1' enthält unbekannte Elemente: %2 - + Unsupported format Nicht unterstütztes Format - + Unknown element Unbekanntes Element - - - - + + + + Error Fehler @@ -1205,50 +1387,50 @@ Dies wurde vermutlich durch einen Wechsel der Cppcheck-Version hervorgerufen. Bi Laden von %1 fehlgeschlagen. Ihre Cppcheck-Installation ist defekt. Sie können --data-dir=<Verzeichnis> als Kommandozeilenparameter verwenden, um anzugeben, wo die Datei sich befindet. Bitte beachten Sie, dass --data-dir in Installationsroutinen genutzt werden soll, und die GUI bei dessen Nutzung nicht startet, sondern die Einstellungen konfiguriert. - + Open the report file Berichtdatei öffnen - + Text files (*.txt) Textdateien (*.txt) - + CSV files (*.csv) CSV-Dateien (*.csv) - + Project files (*.cppcheck);;All files(*.*) Projektdateien (*.cppcheck);;Alle Dateien(*.*) - + Select Project File Projektdatei auswählen - - - - + + + + Project: Projekt: - + No suitable files found to analyze! Keine passenden Dateien für Analyse gefunden! - + C/C++ Source C/C++-Quellcode - + Compile database Compilerdatenbank @@ -1261,22 +1443,22 @@ Dies wurde vermutlich durch einen Wechsel der Cppcheck-Version hervorgerufen. Bi Borland C++-Builder 6 - + Select files to analyze Dateien für Analyse auswählen - + Select directory to analyze Verzeichnis für Analyse auswählen - + Select the configuration that will be analyzed Zu analysierende Konfiguration auswählen - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? @@ -1285,7 +1467,7 @@ Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1296,7 +1478,7 @@ Eine neue XML-Datei zu öffnen wird die aktuellen Ergebnisse löschen Möchten sie fortfahren? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1305,104 +1487,104 @@ Do you want to stop the analysis and exit Cppcheck? Wollen sie die Analyse abbrechen und Cppcheck beenden? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML-Dateien (*.xml);;Textdateien (*.txt);;CSV-Dateien (*.csv) - + Build dir '%1' does not exist, create it? Erstellungsverzeichnis '%1' existiert nicht. Erstellen? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1411,22 +1593,22 @@ Analysis is stopped. Import von '%1' fehlgeschlagen; Analyse wurde abgebrochen. - + Project files (*.cppcheck) Projektdateien (*.cppcheck) - + Select Project Filename Projektnamen auswählen - + No project file loaded Keine Projektdatei geladen - + The project file %1 @@ -1443,12 +1625,12 @@ Do you want to remove the file from the recently used projects -list? Möchten Sie die Datei von der Liste der zuletzt benutzten Projekte entfernen? - + Install - + New version available: %1. %2 @@ -1493,26 +1675,31 @@ Options: NewSuppressionDialog + New suppression Neue Fehlerunterdrückung + Error ID Fehler-ID + File name Dateiname + Line number Zeilennummer + Symbol name Symbolname @@ -1554,26 +1741,31 @@ Options: ProjectFile + Project File Projektdatei + Paths and Defines Pfade und Definitionen + Import Project (Visual studio / compile database/ Borland C++ Builder 6) Importiere Projekt (Visual Studio / Compile-Datenbank / Borland C++-Builder 6) + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int Definitionen müssen mit einem Semikolon getrennt werden. Beispiel: DEF1;DEF2=5;DEF3=int + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. Hinweis: Legen Sie eigene .cfg-Dateien in den Ordner der Projektdatei. Dann sollten sie oben sichtbar werden. @@ -1583,48 +1775,59 @@ Options: + MISRA rule texts MISRA-Regeltexte + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> <html><head/><body><p>Text aus Anhang A &quot;Summary of guidelines&quot; aus der MISRA-C-2012-PDF in eine Textdatei einfügen.</p></body></html> + ... ... + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> <html><head/><body><p>Sie haben die Auswahl:</p><p> * Alle Debug- und Release-Konfigurationen analysieren</p><p> * Nur die erste passende Debug-Konfiguration analysieren</p><p><br/></p></body></html> + + Browse... Durchsuchen... + Analyze all Visual Studio configurations Alle Visual-Studio-Konfigurationen analysieren + Selected VS Configurations Ausgewählte VS-Konfiguration + Paths: Pfade: + + Add... Hinzufügen... @@ -1632,6 +1835,9 @@ Options: + + + Edit Bearbeiten @@ -1640,300 +1846,365 @@ Options: + + + + Remove Entfernen + Undefines: Un-Definitionen: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 Un-Definitionen müssen Semikolon-getrennt sein. Beispiel: UNDEF1;UNDEF2;UNDEF3 + Include Paths: Includepfade: + Up Auf + Down Ab + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + Platform Plattform + + Analysis Analyse + This is a workfolder that Cppcheck will use for various purposes. + Clang (experimental) + Check level + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) Prüfe Code in ungenutzten Templates (normalerweise AN, theoretisch können Warnungen in ungenutzten Templates gefahrlos ignoriert werden) + Max CTU depth Maximale CTU-Tiefe + Max recursion in template instantiation + Warning options Warnoptionen + Root path: Wurzelverzeichnis: + Filepaths in warnings will be relative to this path + Warning tags (separated by semicolon) Warnungs-Tags (Semikolon-getrennt) + Enable inline suppressions Inline-Fehlerunterdrückung aktivieren + 2025 + Misra C++ + 2008 + Cert C Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + Autosar + Safety profiles (defined in C++ core guidelines) + Bug hunting + External tools Externe Werkzeuge + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) Cppcheck-Arbeitsverzeichnis (Vollständige Programmanalyse, inkrementelle Analyse, Statistiken, etc.) + Types and Functions + Libraries Bibliotheken + Parser + Cppcheck (built in) + Check that each class has a safe public interface + Limit analysis + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. + Exclude source files + Exclude folder... + Exclude file... + Suppressions Fehlerunterdrückungen + Add Hinzufügen + + Addons Add-Ons + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. + Y2038 Y2038 + Thread safety Threadsicherheit + Coding standards Programmierstandards + Misra C Misra C + 2012 + + 2023 + Cert C++ Cert C++ + Bug hunting (Premium) @@ -1947,6 +2218,7 @@ Options: + Defines: Definitionen: @@ -2565,21 +2837,25 @@ Legen Sie unter dem Menü Ansicht fest, welche Arten von Fehlern angezeigt werde + Results Berichte + Critical errors Kritische Fehler + Analysis Log Analyseprotokoll + Warning Details Warnungs-Details @@ -2588,26 +2864,31 @@ Legen Sie unter dem Menü Ansicht fest, welche Arten von Fehlern angezeigt werde ScratchPad + Scratchpad Schmierzettel + Copy or write some C/C++ code here: Kopieren oder schreiben Sie C/C++-Code hierher: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": Optional einen Dateinamen (hauptsächlich für automatische Spracherkennung) eingeben und auf "Prüfe" klicken: + filename Dateiname + Check Prüfe @@ -2616,21 +2897,25 @@ Legen Sie unter dem Menü Ansicht fest, welche Arten von Fehlern angezeigt werde Settings + Preferences Einstellungen + General Allgemein + Add... Hinzufügen... + Number of threads: Anzahl der Threads: @@ -2640,56 +2925,67 @@ Legen Sie unter dem Menü Ansicht fest, welche Arten von Fehlern angezeigt werde + Force checking all #ifdef configurations Erzwinge Prüfung aller #ifdef-Konfigurationen + Show full path of files Vollständigen Dateipfad anzeigen + Show "No errors found" message when no errors found "Keine Fehler gefunden"-Meldung anzeigen, wenn keine Fehler gefunden werden + Display error Id in column "Id" Zeige Meldungs-Id in Spalte "Id" + Enable inline suppressions Inline-Fehlerunterdrückung aktivieren + Check for inconclusive errors also Auch nach unklaren Fehlern suchen + Show statistics on check completion Zeige Statistiken nach Prüfungsabschluss + Check for updates Auf Updates prüfen + Show internal warnings in log Interne Warnungen im Log anzeigen + Addons Add-Ons + Python binary (leave this empty to use python in the PATH) Python-Binärdatei (Python aus PATH wird genutzt, wenn leer) @@ -2697,117 +2993,143 @@ Legen Sie unter dem Menü Ansicht fest, welche Arten von Fehlern angezeigt werde + + + ... ... + MISRA addon MISRA-Addon + MISRA rule texts file MISRA-Regeltext-Datei + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> <html><head/><body><p>Text aus Anhang A &quot;Summary of guidelines&quot; aus der MISRA-C-2012-PDF in eine Textdatei einfügen.</p></body></html> + Clang Clang + Clang path (leave empty to use system PATH) Clang-Verzeichnis (PATH wird genutzt, wenn leer) + Visual Studio headers Visual-Studio-Header + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> <html><head/><body><p>Pfade zu Visual-Studio-Headern, Semikolon-getrennt.</p><p>Sie können eine Visual-Studio-Kommandozeile öffnen, &quot;SET INCLUDE&quot; eingeben und dann die Pfade hier reinkopieren.</p></body></html> + Code Editor Code-Editor + Code Editor Style Code-Editor-Stil + System Style Systemstil + Default Light Style Heller Standardstil + Default Dark Style Dunkler Standardstil + Custom Benutzerdefiniert + Remove Entfernen + Max count: Maximalzahl: + Applications Anwendungen + + Edit... Bearbeiten... + Set as default Als Standard festlegen + Reports Berichte + Save all errors when creating report Alle Fehler beim Erstellen von Berichten speichern + Save full path to files in reports Vollständigen Dateipfad in Berichten speichern + Language Sprache @@ -2864,6 +3186,8 @@ Legen Sie unter dem Menü Ansicht fest, welche Arten von Fehlern angezeigt werde + + Statistics @@ -2871,113 +3195,135 @@ Legen Sie unter dem Menü Ansicht fest, welche Arten von Fehlern angezeigt werde + Project Projekt + Project: Projekt: + Paths: Pfade: + Include paths: Include-Pfade: + Defines: Definitionen: + Undefines: Un-Definitionen: + Previous Scan Vorherige Prüfung + Path Selected: Ausgewählte Pfade: + Number of Files Scanned: Anzahl der geprüften Dateien: + Scan Duration: Prüfungsdauer: + Errors: Fehler: + Warnings: Warnungen: + Stylistic warnings: Stilwarnungen: + Portability warnings: Portabilitätswarnungen: + Performance issues: Performance-Probleme: + Information messages: Informationsmeldungen: + Active checkers: Aktive Checker: + Checkers Checker + History Verlauf + File: Datei: + Copy to Clipboard In die Zwischenablage kopieren + Pdf Export PDF-Export @@ -3127,6 +3473,7 @@ Legen Sie unter dem Menü Ansicht fest, welche Arten von Fehlern angezeigt werde ThreadDetails + Thread Details diff --git a/gui/cppcheck_es.ts b/gui/cppcheck_es.ts index 0230aaa69e4..b2080055651 100644 --- a/gui/cppcheck_es.ts +++ b/gui/cppcheck_es.ts @@ -5,38 +5,45 @@ About + About Cppcheck Acerca de Cppcheck + Version %1 Versión %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - Una utilidad para el análisis estático de código C/C++. + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. Copyright © 2007-2021 el equipo de cppcheck. + This program is licensed under the terms of the GNU General Public License version 3 Este programa está licenciado bajo los términos de GNU General Public License versión 3 + Visit Cppcheck homepage at %1 Visita el sitio de Cppcheck en %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> @@ -46,11 +53,13 @@ of the GNU General Public License version 3 ApplicationDialog + Add an application Añade una aplicación + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -66,21 +75,25 @@ Parameters: -l(line) (file) + &Name: &Nombre: + &Executable: &Ejecutable: + &Parameters: &Parámetros: + Browse Buscar @@ -125,16 +138,19 @@ Parameters: -l(line) (file) HelpDialog + Cppcheck GUI help + Contents + Index @@ -152,16 +168,19 @@ Parameters: -l(line) (file) LibraryAddFunctionDialog + Add function Añadir función + Function name(s) Nombre(s) de la función + Number of arguments Número de argumentos @@ -170,86 +189,103 @@ Parameters: -l(line) (file) LibraryDialog + Library Editor Editor de bibliotecas + Open Abrir + Save Guardar + Save as + Functions Funciones + Sort + Add Añadir + Filter: + Comments + noreturn + False Falso + True Verdadero + Unknown Desconocido + return value must be used + ignore function in leaks checking + Arguments Argumentos + Edit Editar @@ -295,11 +331,13 @@ Parameters: -l(line) (file) LibraryEditArgDialog + Edit argument Editar argumento + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -310,11 +348,13 @@ Parameters: -l(line) (file) + Not bool No bool + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -325,78 +365,99 @@ Parameters: -l(line) (file) + Not null No null + Not uninit No uninit + String String + Format string + Min size of buffer + + Type Tipo + + None Ninguno + + argvalue + + mul + + strlen + + Arg + + Arg2 + and + Valid values Valores válidos @@ -409,684 +470,800 @@ Parameters: -l(line) (file) + &File &Archivo + &View &Ver + &Toolbars &Herramientas + &Help &Ayuda + C++ standard C++ estándar + &C standard C standard C estándar + &Edit &Editar + Standard Estándar + Categories Categorías + &License... &Licencia... + A&uthors... A&utores... + &About... &Acerca de... + &Files... &Ficheros... + + Analyze files Check files Comprobar archivos + Ctrl+F Ctrl+F + &Directory... &Carpeta... + + Analyze directory Check directory Comprobar carpeta + Ctrl+D Ctrl+D + Ctrl+R Ctrl+R + &Stop &Detener + + Stop analysis Stop checking Detener comprobación + Esc Esc + &Save results to file... &Guardar los resultados en el fichero... + Ctrl+S Ctrl+S + &Quit &Salir + &Clear results &Limpiar resultados + &Preferences &Preferencias + + Show style warnings Mostrar advertencias de estilo - + + + Show errors Mostrar errores - - + + Information Información + Show information messages Mostrar mensajes de información + Show portability warnings Mostrar advertencias de portabilidad + Show Cppcheck results + Clang + Show Clang results + &Filter &Filtro + Filter results Resultados del filtro + Windows 32-bit ANSI Windows 32-bit ANSI + Windows 32-bit Unicode Windows 32-bit Unicode + Unix 32-bit Unix 32-bit + Unix 64-bit Unix 64-bit + Windows 64-bit Windows 64-bit + &Print... Im&primir... + Print the Current Report Imprimir el informe actual + Print Pre&view... Pre&visualización de impresión... + Open a Print Preview Dialog for the Current Results Abre el diálogo de previsualización de impresión para el informe actual + Open library editor Abrir el editor de bibliotecas + &Check all &Seleccionar todo + Checking for updates + Hide Ocultar + + Report + A&nalyze + Filter Filtro + &Reanalyze modified files &Recheck modified files + Reanal&yze all files + Ctrl+Q + Style war&nings + E&rrors + &Uncheck all &Deseleccionar todo + Collapse &all Contraer &todo + &Expand all &Expandir todo + &Standard &Estándar + Standard items Elementos estándar + &Contents &Contenidos + Open the help contents Abrir la ayuda de contenidos + F1 F1 + Toolbar Barra de herramientas + &Categories &Categorías + Error categories Categorías de error + &Open XML... &Abrir XML... + Open P&roject File... Abrir P&royecto... + Ctrl+Shift+O + Sh&ow Scratchpad... + &New Project File... &Nuevo Proyecto... + Ctrl+Shift+N + &Log View &Visor del log + Log View Visor del log + C&lose Project File C&errar Proyecto + &Edit Project File... &Editar Proyecto... + &Statistics &Estadísticas + &Warnings + Per&formance warnings + &Information + &Portability + P&latforms + C++&11 + C&99 + &Posix + C&11 + &C89 + &C++03 + &Library Editor... + &Auto-detect language + &Enforce C++ + E&nforce C + C++14 C++14 + Reanalyze and check library + Check configuration (defines, includes) + C++17 C++17 + C++20 C++20 + Compliance report... + Normal + Autosar + EULA... + Thread Details + Show thread details - + + + Show warnings Mostrar advertencias + + Show performance warnings Mostrar advertencias de rendimiento + Show &hidden Mostrar &ocultos - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. - + You must close the project file before selecting new files or directories! ¡Tienes que cerrar el proyecto antes de seleccionar nuevos ficheros o carpetas! - + Select configuration - + File not found Archivo no encontrado - + Bad XML XML malformado - + Missing attribute Falta el atributo - + Bad attribute value - + Unsupported format Formato no soportado - + Duplicate define - + Failed to load the selected library '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - - + + XML files (*.xml) Archivos XML (*.xml) - + Open the report file Abrir informe - + License Licencia - + Authors Autores - + Save the report file Guardar informe - - + + Quick Filter: Filtro rápido: - + Found project file: %1 Do you want to load this project file instead? @@ -1095,102 +1272,107 @@ Do you want to load this project file instead? ¿Quiere cargar este fichero de proyecto en su lugar? - + The library '%1' contains unknown elements: %2 La biblioteca '%1' contiene elementos deconocidos: %2 - + Duplicate platform type - + Platform type redefined - + Unknown element - - - - + + + + Error Error - + Text files (*.txt) Ficheros de texto (*.txt) - + CSV files (*.csv) Ficheros CVS (*.cvs) - + Project files (*.cppcheck);;All files(*.*) Ficheros de proyecto (*.cppcheck;;Todos los ficheros (*.*) - + Select Project File Selecciona el archivo de proyecto - - - - + + + + Project: Proyecto: - + + None of the selected files is part of the project, nothing to analyze. + + + + No suitable files found to analyze! - + C/C++ Source - + Compile database - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1198,76 +1380,76 @@ Do you want to proceed? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + Build dir '%1' does not exist, create it? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Project files (*.cppcheck) - + Select Project Filename Selecciona el nombre del proyecto - + No project file loaded No hay ningún proyecto cargado - + The project file %1 @@ -1284,67 +1466,67 @@ Do you want to remove the file from the recently used projects -list? ¿Quiere eliminar el fichero de la lista de proyectos recientes? - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1388,26 +1570,31 @@ Options: NewSuppressionDialog + New suppression + Error ID + File name + Line number + Symbol name @@ -1449,111 +1636,135 @@ Options: ProjectFile + Project File Archivo de proyecto + Paths and Defines + Import Project (Visual studio / compile database/ Borland C++ Builder 6) Import Project (Visual studio / compile database) + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int Defines must be separated by a semicolon ';' + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. Nota: Ponga sus propios archivos .cfg en la misma carpeta que el proyecto. Debería verlos arriba. + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. + Exclude source files + Exclude folder... + Exclude file... + Misra C + 2012 + + 2023 + MISRA rule texts + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + ... + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> + + Browse... + Analyze all Visual Studio configurations + Selected VS Configurations + Paths: Rutas: + + Add... Añadir... @@ -1561,6 +1772,9 @@ Options: + + + Edit Editar @@ -1569,269 +1783,327 @@ Options: + + + + Remove Eliminar + Undefines: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 + Include Paths: + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + Types and Functions + + Analysis + This is a workfolder that Cppcheck will use for various purposes. + Parser + Cppcheck (built in) + Check level + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + Check that each class has a safe public interface + Limit analysis + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) + Max CTU depth + Enable inline suppressions Habilitar supresiones inline + 2025 + Misra C++ + 2008 + Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + Autosar + Safety profiles (defined in C++ core guidelines) + Bug hunting + External tools + Up Subir + Down Bajar + Platform + Clang (experimental) + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) + Max recursion in template instantiation + Warning options + Root path: + Filepaths in warnings will be relative to this path + Warning tags (separated by semicolon) + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) + Libraries + Suppressions Supresiones + Add Añadir + + Addons + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. + Y2038 + Thread safety + Coding standards + Cert C++ + Bug hunting (Premium) + Defines: Definiciones: @@ -2354,21 +2626,25 @@ Por favor comprueba que la ruta a la aplicación y los parámetros son correctos ResultsView + Results Resultados + Critical errors + Analysis Log + Warning Details @@ -2475,26 +2751,31 @@ Para cambiar el tipo de comportamiento, abra el menú Ver. ScratchPad + Scratchpad Scratchpad + Copy or write some C/C++ code here: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": + filename nombre de archivo + Check Comprobar @@ -2503,11 +2784,13 @@ Para cambiar el tipo de comportamiento, abra el menú Ver. Settings + Preferences Preferencias + General General @@ -2517,46 +2800,55 @@ Para cambiar el tipo de comportamiento, abra el menú Ver. + Force checking all #ifdef configurations Forzar comprobación de todas las configuraciones #ifdef + Display error Id in column "Id" Mostrar el Id del error en la columna "Id" + Enable inline suppressions Habilitar supresiones inline + Check for inconclusive errors also + Show statistics on check completion + Check for updates + Show internal warnings in log + Addons + Python binary (leave this empty to use python in the PATH) @@ -2564,137 +2856,167 @@ Para cambiar el tipo de comportamiento, abra el menú Ver. + + + ... + MISRA addon + MISRA rule texts file + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Clang + Clang path (leave empty to use system PATH) + Visual Studio headers + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> + Code Editor + Code Editor Style + System Style + Default Light Style + Default Dark Style + Custom + Add... Añadir... + Max count: + + Edit... Editar... + Set as default Definir por defecto + Language Idioma + Number of threads: Número de hilos: + Show full path of files Mostrar la ruta completa de los ficheros + Show "No errors found" message when no errors found Mostrar el mensaje "No se han encontrado errores" + Remove Eliminar + Applications Aplicaciones + Reports Informes + Save all errors when creating report Guardar todos los errores cuando se cree el informe + Save full path to files in reports Guardar la ruta completa en los ficheros de informes @@ -2751,6 +3073,8 @@ Para cambiar el tipo de comportamiento, abra el menú Ver. + + Statistics @@ -2758,113 +3082,135 @@ Para cambiar el tipo de comportamiento, abra el menú Ver. + Project Proyecto + Project: Proyecto: + Paths: Rutas: + Include paths: Incluye las rutas: + Defines: Definiciones: + Undefines: + Previous Scan Análisis anterior + Path Selected: Ruta seleccionada: + Number of Files Scanned: Número de archivos analizados: + Scan Duration: Duración del análisis: + Errors: Errores: + Warnings: Advertencias: + Stylistic warnings: Advertencias de estilo: + Portability warnings: Advertencias de portabilidad: + Performance issues: Problemas de rendimiento: + Information messages: Mensajes de información: + Active checkers: + Checkers + History + File: + Copy to Clipboard Copiar al portapapeles + Pdf Export @@ -3014,6 +3360,7 @@ Para cambiar el tipo de comportamiento, abra el menú Ver. ThreadDetails + Thread Details diff --git a/gui/cppcheck_fi.ts b/gui/cppcheck_fi.ts index 8bdd6fd1671..0600febbd04 100644 --- a/gui/cppcheck_fi.ts +++ b/gui/cppcheck_fi.ts @@ -5,27 +5,32 @@ About + About Cppcheck Tietoa ohjelmasta Cppcheck + Version %1 Versio %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - Työkalu C/C++ koodin staattiseen analysointiin. + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. Copyright (C) 2007-2021 Daniel Marjamäki ja cppcheck tiimi. + This program is licensed under the terms of the GNU General Public License version 3 Tämä ohjelma on lisensoitu GNU General @@ -33,11 +38,13 @@ Public lisenssin version 3 alaisuuteen + Visit Cppcheck homepage at %1 Cppcheckin kotisivu löytyy osoitteesta %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> @@ -47,11 +54,13 @@ Public lisenssin version 3 alaisuuteen ApplicationDialog + Add an application Lisää uusi ohjelma + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -67,21 +76,25 @@ Parameters: -l(line) (file) + &Name: + &Executable: + &Parameters: + Browse Selaa @@ -128,16 +141,19 @@ Parameters: -l(line) (file) HelpDialog + Cppcheck GUI help + Contents + Index @@ -155,16 +171,19 @@ Parameters: -l(line) (file) LibraryAddFunctionDialog + Add function + Function name(s) + Number of arguments @@ -173,86 +192,103 @@ Parameters: -l(line) (file) LibraryDialog + Library Editor + Open + Save + Save as + Functions + Sort + Add + Filter: + Comments + noreturn + False + True + Unknown + return value must be used + ignore function in leaks checking + Arguments + Edit @@ -298,11 +334,13 @@ Parameters: -l(line) (file) LibraryEditArgDialog + Edit argument + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -313,11 +351,13 @@ Parameters: -l(line) (file) + Not bool + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -328,78 +368,99 @@ Parameters: -l(line) (file) + Not null + Not uninit + String + Format string + Min size of buffer + + Type + + None + + argvalue + + mul + + strlen + + Arg + + Arg2 + and + Valid values @@ -412,785 +473,906 @@ Parameters: -l(line) (file) + A&nalyze + Standard Vakio + &File &Tiedosto + &View &Näytä + &Toolbars + C++ standard + &C standard C standard + &Edit &Muokkaa + &License... &Lisenssi... + A&uthors... &Tekijät... + &About... &Tietoa ohjelmasta Cppcheck... + &Files... &Tiedostot... + + Analyze files Check files + Ctrl+F Ctrl+F + &Directory... &Hakemisto... + + Analyze directory Check directory + Ctrl+D Ctrl+D + Ctrl+R Ctrl+R + &Stop &Pysäytä + + Stop analysis Stop checking + Esc Esc + &Save results to file... &Tallenna tulokset tiedostoon... + Ctrl+S Ctrl+S + &Quit &Lopeta + &Clear results &Tyhjennä tulokset + &Preferences &Asetukset - + + + Show errors - + + + Show warnings + + Show performance warnings + Show &hidden - - + + Information + Show information messages + Show portability warnings + Show Cppcheck results + Clang + Show Clang results + &Filter + Filter results + Windows 32-bit ANSI + Windows 32-bit Unicode + Unix 32-bit + Unix 64-bit + Windows 64-bit + &Print... + Print the Current Report + Print Pre&view... + Open a Print Preview Dialog for the Current Results + Open library editor + &Check all &Valitse kaikki + Checking for updates + Hide + + Report + Filter + &Reanalyze modified files &Recheck modified files + Reanal&yze all files + Ctrl+Q + Style war&nings + E&rrors + &Uncheck all &Poista kaikista valinta + Collapse &all &Pienennä kaikki + &Expand all &Laajenna kaikki + &Standard + Standard items + Toolbar + &Categories + Error categories + &Open XML... + Open P&roject File... + Ctrl+Shift+O + Sh&ow Scratchpad... + &New Project File... + Ctrl+Shift+N + &Log View + Log View + C&lose Project File + &Edit Project File... + &Statistics + &Warnings + Per&formance warnings + &Information + &Portability + P&latforms + C++&11 + C&99 + &Posix + C&11 + &C89 + &C++03 + &Library Editor... + &Auto-detect language + &Enforce C++ + E&nforce C + C++14 + Reanalyze and check library + Check configuration (defines, includes) + C++17 + C++20 + Compliance report... + Normal + Autosar + EULA... + Thread Details + Show thread details + &Contents + Categories + + Show style warnings + Open the help contents + F1 + &Help &Ohje - - + + Quick Filter: - + Select configuration - + Found project file: %1 Do you want to load this project file instead? - + File not found - + Bad XML - + Missing attribute - + Bad attribute value - + Duplicate define - + Failed to load the selected library '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License Lisenssi - + Authors Tekijät - + Save the report file Tallenna raportti - - + + XML files (*.xml) XML-tiedostot (*xml) - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. - + You must close the project file before selecting new files or directories! - + The library '%1' contains unknown elements: %2 - + Unsupported format - + Duplicate platform type - + Platform type redefined - + Unknown element - - - - + + + + Error - + Open the report file - + Text files (*.txt) Tekstitiedostot (*.txt) - + CSV files (*.csv) - + Project files (*.cppcheck);;All files(*.*) - + Select Project File - - - - + + + + Project: - + + None of the selected files is part of the project, nothing to analyze. + + + + No suitable files found to analyze! - + C/C++ Source - + Compile database - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1198,76 +1380,76 @@ Do you want to proceed? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + Build dir '%1' does not exist, create it? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Project files (*.cppcheck) - + Select Project Filename - + No project file loaded - + The project file %1 @@ -1278,67 +1460,67 @@ Do you want to remove the file from the recently used projects -list? - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1382,26 +1564,31 @@ Options: NewSuppressionDialog + New suppression + Error ID + File name + Line number + Symbol name @@ -1423,75 +1610,91 @@ Options: ProjectFile + Project File + Paths and Defines + Import Project (Visual studio / compile database/ Borland C++ Builder 6) Import Project (Visual studio / compile database) + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int Defines must be separated by a semicolon ';' + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. + MISRA rule texts + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + ... + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> + + Browse... + Analyze all Visual Studio configurations + Selected VS Configurations + Paths: + + Add... @@ -1499,6 +1702,9 @@ Options: + + + Edit @@ -1507,305 +1713,371 @@ Options: + + + + Remove + Undefines: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 + Include Paths: + Up + Down + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + Platform + + Analysis + This is a workfolder that Cppcheck will use for various purposes. + Clang (experimental) + Check level + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) + Max CTU depth + Max recursion in template instantiation + Warning options + Root path: + Filepaths in warnings will be relative to this path + Warning tags (separated by semicolon) + Enable inline suppressions + 2025 + Misra C++ + 2008 + Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + Autosar + Safety profiles (defined in C++ core guidelines) + Bug hunting + External tools + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) + Types and Functions + Libraries + Parser + Cppcheck (built in) + Check that each class has a safe public interface + Limit analysis + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. + Exclude source files + Exclude folder... + Exclude file... + Suppressions + Add + + Addons + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. + Y2038 + Thread safety + Coding standards + Misra C + 2012 + + 2023 + Cert C++ + Bug hunting (Premium) + Defines: @@ -2412,21 +2684,25 @@ Määrittääksesi minkä tyyppisiä virheitä näytetään, avaa näkymä valik + Results Tulokset + Critical errors + Analysis Log + Warning Details @@ -2435,26 +2711,31 @@ Määrittääksesi minkä tyyppisiä virheitä näytetään, avaa näkymä valik ScratchPad + Scratchpad + Copy or write some C/C++ code here: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": + filename + Check @@ -2463,77 +2744,92 @@ Määrittääksesi minkä tyyppisiä virheitä näytetään, avaa näkymä valik Settings + Preferences Asetukset + General Yleiset + Add... + Number of threads: Säikeiden lukumäärä: + Force checking all #ifdef configurations Check all #ifdef configurations Tarkista kaikki #ifdef kombinaatiot + Show full path of files Näytä tiedostojen täysi polku + Show "No errors found" message when no errors found Näytä "virheitä ei löytynyt"-viesti jos virheitä ei löydy + Display error Id in column "Id" + Enable inline suppressions + Check for inconclusive errors also + Show statistics on check completion + Check for updates + Show internal warnings in log + Addons + Python binary (leave this empty to use python in the PATH) @@ -2541,117 +2837,143 @@ Määrittääksesi minkä tyyppisiä virheitä näytetään, avaa näkymä valik + + + ... + MISRA addon + MISRA rule texts file + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Clang + Clang path (leave empty to use system PATH) + Visual Studio headers + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> + Code Editor + Code Editor Style + System Style + Default Light Style + Default Dark Style + Custom + Remove + Max count: + Applications Ohjelmat + + Edit... + Set as default + Reports Raportit + Save all errors when creating report Tallenna kaikki virheet raporttia luodessa + Save full path to files in reports Tallenna tiedostojen koko polku raportteihin + Language @@ -2704,6 +3026,8 @@ Määrittääksesi minkä tyyppisiä virheitä näytetään, avaa näkymä valik + + Statistics @@ -2711,113 +3035,135 @@ Määrittääksesi minkä tyyppisiä virheitä näytetään, avaa näkymä valik + Project + Project: + Paths: + Include paths: + Defines: + Undefines: + Previous Scan + Path Selected: + Number of Files Scanned: + Scan Duration: + Errors: + Warnings: + Stylistic warnings: + Portability warnings: + Performance issues: + Information messages: + Active checkers: + Checkers + History + File: + Copy to Clipboard + Pdf Export @@ -2967,6 +3313,7 @@ Määrittääksesi minkä tyyppisiä virheitä näytetään, avaa näkymä valik ThreadDetails + Thread Details diff --git a/gui/cppcheck_fr.ts b/gui/cppcheck_fr.ts index ca25352e60c..7ac6f3ae89a 100644 --- a/gui/cppcheck_fr.ts +++ b/gui/cppcheck_fr.ts @@ -5,21 +5,25 @@ About + About Cppcheck A propos + Version %1 Version %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - Un outil d'analyse statique de code C/C++. + This program is licensed under the terms of the GNU General Public License version 3 Ce programme est sous licence GNU @@ -27,17 +31,20 @@ General Public License version 3 + Visit Cppcheck homepage at %1 Visitez le site Cppcheck : %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. @@ -47,11 +54,13 @@ General Public License version 3 ApplicationDialog + Add an application Ajouter une application + Browse Parcourir @@ -67,16 +76,19 @@ General Public License version 3 + &Executable: &Exécutable : + &Parameters: &Paramètres : + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -102,6 +114,7 @@ Paramètres : -l(ligne) (fichier) + &Name: &Nom : @@ -128,16 +141,19 @@ Paramètres : -l(ligne) (fichier) HelpDialog + Cppcheck GUI help + Contents + Index @@ -151,16 +167,19 @@ Paramètres : -l(ligne) (fichier) LibraryAddFunctionDialog + Add function Ajouter une fonction + Function name(s) Nom(s) de la fonction + Number of arguments Nombre d'arguments @@ -169,66 +188,79 @@ Paramètres : -l(ligne) (fichier) LibraryDialog + Library Editor + Open + Save Sauvegarder + Functions + Add Ajouter + noreturn + False + True + Unknown + return value must be used + ignore function in leaks checking + Arguments + Edit Editer @@ -245,21 +277,25 @@ Paramètres : -l(ligne) (fichier) + Sort + Filter: + Comments + Save as @@ -288,11 +324,13 @@ Paramètres : -l(ligne) (fichier) LibraryEditArgDialog + Edit argument + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -303,11 +341,13 @@ Paramètres : -l(ligne) (fichier) + Not bool + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -318,78 +358,99 @@ Paramètres : -l(ligne) (fichier) + Not null + Not uninit + String + Format string + Min size of buffer + + Type + + None + + argvalue + + mul + + strlen + + Arg + + Arg2 + and + Valid values @@ -398,472 +459,535 @@ Paramètres : -l(ligne) (fichier) MainWindow + Checking for updates + Hide Cacher + &File &Fichier + &View &Affichage + + Report + &Help &Aide + &Edit &Édition + Standard Standard + &License... &Licence... + A&uthors... A&uteurs... + &About... À &Propos... + &Files... &Fichiers... + Ctrl+F + &Directory... &Répertoires... + Ctrl+D + Ctrl+R + &Stop &Arrêter + Esc + &Save results to file... &Sauvegarder les résultats dans un fichier... + Ctrl+S + &Quit &Quitter + &Clear results &Effacer les résultats + &Preferences &Préférences + &Check all &Tout cocher + &Uncheck all &Tout décocher + Collapse &all &Tout réduire + &Expand all &Tout dérouler + &Contents &Contenus + Open the help contents Ouvir l'aide + F1 + Compliance report... + Normal + Autosar + EULA... + Thread Details + Show thread details - + License Licence - + Authors Auteurs - + Save the report file Sauvegarder le rapport - - + + XML files (*.xml) Fichiers XML (*.xml) - + About - + Text files (*.txt) Fichiers Texte (*.txt) - + CSV files (*.csv) Fichiers CSV (*.csv) + &Toolbars &Boite à outils + Categories Catégories + + Show style warnings Afficher les avertissements de style - + + + Show errors Afficher les erreurs + &Standard + Standard items + Toolbar + &Categories + Error categories + &Open XML... &Ouvrir un fichier XML... + Open P&roject File... Ouvrir un P&rojet... + &New Project File... &Nouveau Projet... + &Log View &Journal + Log View Journal + C&lose Project File F&ermer le projet + &Edit Project File... &Editer le projet + &Statistics Statistiques - + + + Show warnings Afficher les avertissements + + Show performance warnings Afficher les avertissements de performance + Show &hidden - - + + Information Information + Show information messages Afficher les messages d'information + Show portability warnings Afficher les problèmes de portabilité - + You must close the project file before selecting new files or directories! Vous devez d'abord fermer le projet avant de choisir des fichiers/répertoires - + Open the report file Ouvrir le rapport - + Project files (*.cppcheck);;All files(*.*) - + Select Project File - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Select Project Filename - + No project file loaded - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -871,37 +995,39 @@ This is probably because the settings were changed between the Cppcheck versions + &Filter &Filtre + Filter results - - + + Quick Filter: Filtre rapide : - + Found project file: %1 Do you want to load this project file instead? - - - - + + + + Project: Projet : - + The project file %1 @@ -913,31 +1039,37 @@ Do you want to remove the file from the recently used projects -list? + Filter Filtre + Windows 32-bit ANSI + Windows 32-bit Unicode + Unix 32-bit + Unix 64-bit + Windows 64-bit @@ -948,98 +1080,104 @@ Do you want to remove the file from the recently used projects -list? + C++ standard - - - - + + + + Error Erreur - + File not found Fichier introuvable - + Bad XML Mauvais fichier XML - + Missing attribute Attribut manquant - + Bad attribute value Mauvaise valeur d'attribut - + Failed to load the selected library '%1'. %2 Echec lors du chargement de la bibliothèque '%1'. %2 - + Unsupported format Format non supporté - + The library '%1' contains unknown elements: %2 La bibliothèque '%1' contient des éléments inconnus: %2 - + Duplicate platform type - + Platform type redefined + &Print... &Imprimer... + Print the Current Report Imprimer le rapport + Print Pre&view... Apercu d'impression... + Open a Print Preview Dialog for the Current Results + Open library editor - + Unknown element - + Select configuration @@ -1062,104 +1200,116 @@ Options: - + Build dir '%1' does not exist, create it? + + Analyze files + + Analyze directory + &Reanalyze modified files + + Stop analysis - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + No suitable files found to analyze! - + + None of the selected files is part of the project, nothing to analyze. + + + + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Duplicate define - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1167,181 +1317,213 @@ Do you want to stop the analysis and exit Cppcheck? + A&nalyze + &C standard + Reanal&yze all files + Ctrl+Q + Style war&nings + E&rrors + Ctrl+Shift+O + Sh&ow Scratchpad... + Ctrl+Shift+N + &Warnings + Per&formance warnings + &Information + &Portability + Show Cppcheck results + Clang + Show Clang results + P&latforms + C++&11 + C&99 + &Posix + C&11 + &C89 + &C++03 + &Library Editor... + &Auto-detect language + &Enforce C++ + E&nforce C + C++14 - + Project files (*.cppcheck) + Reanalyze and check library + Check configuration (defines, includes) + C++17 + C++20 - + C/C++ Source - + Compile database - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1353,26 +1535,31 @@ Do you want to proceed? NewSuppressionDialog + New suppression + Error ID + File name + Line number + Symbol name @@ -1394,22 +1581,27 @@ Do you want to proceed? ProjectFile + Project File Fichier Projet + Paths: Chemins : + Defines: + + Add... Ajouter... @@ -1417,6 +1609,9 @@ Do you want to proceed? + + + Edit Editer @@ -1425,356 +1620,433 @@ Do you want to proceed? + + + + Remove Supprimer + Up Monter + Down Descendre + Suppressions Suppressions + Add Ajouter + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. + ... + Include Paths: + Paths and Defines + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> + Analyze all Visual Studio configurations + Root path: + Warning tags (separated by semicolon) + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) + Selected VS Configurations + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + Types and Functions + Libraries + Parser + Cppcheck (built in) + Check that each class has a safe public interface + Limit analysis + + Addons + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. + Y2038 + Thread safety + Coding standards + Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + Autosar + Bug hunting + + Browse... + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int + Platform + This is a workfolder that Cppcheck will use for various purposes. + Clang (experimental) + Check level + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) + Max recursion in template instantiation + Warning options + Filepaths in warnings will be relative to this path + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. + Exclude source files + Exclude folder... + Exclude file... + Enable inline suppressions + Misra C + 2012 + + 2023 + 2025 + MISRA rule texts + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Misra C++ + 2008 + Cert C++ + Safety profiles (defined in C++ core guidelines) + Bug hunting (Premium) + External tools + Import Project (Visual studio / compile database/ Borland C++ Builder 6) + Undefines: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 + + Analysis + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) + Max CTU depth @@ -2291,6 +2563,7 @@ Please select the default editor application in preferences/Applications.ResultsView + Results Résultats @@ -2375,16 +2648,19 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage. + Critical errors + Analysis Log + Warning Details @@ -2408,26 +2684,31 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage.ScratchPad + Scratchpad + filename + Check + Copy or write some C/C++ code here: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": @@ -2436,122 +2717,147 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage.Settings + Preferences Préférences + General Général + Number of threads: Nombre de fils : + Max count: + Show full path of files Montrer le chemin complet des fichiers + Show "No errors found" message when no errors found Afficher un message "Pas d'erreur trouvée" lorsque aucune erreur est trouvée + Check for updates + Applications Applications + Reports Rapports + Save all errors when creating report Sauvegarder toutes les erreurs lorsqu'un rapport est créé + Save full path to files in reports Sauvegarder le chemin complet des fichiers dans les rapports + Add... Ajouter... + Force checking all #ifdef configurations + Enable inline suppressions + Language Langue + Remove Supprimer + + Edit... Editer... + Set as default + Display error Id in column "Id" Afficher l'identifiant d'erreur Id dans la colonne "Id" + Check for inconclusive errors also + Show internal warnings in log Montrer les avertissements internes dans le journal + Show statistics on check completion + Addons + Python binary (leave this empty to use python in the PATH) @@ -2559,71 +2865,87 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage. + + + ... + Clang + Clang path (leave empty to use system PATH) + Visual Studio headers + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> + MISRA addon + MISRA rule texts file + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Code Editor + Code Editor Style + Default Light Style + Default Dark Style + Custom + System Style @@ -2676,6 +2998,8 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage. + + Statistics @@ -2683,93 +3007,111 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage. + Project Projet + Project: Projet : + Paths: Chemins : + Include paths: Inclure les chemins : + Defines: + Previous Scan Analyse précédente + Path Selected: Chemin sélectionné : + Number of Files Scanned: Nombre de fichiers analysés : + Scan Duration: Durée de l'analyse : + Errors: Erreurs : + Warnings: Avertissements + Stylistic warnings: Avertissements de style + Portability warnings: Avertissements de portabilité + Performance issues: Problème de performance + Information messages: Messages d'information : + Active checkers: + Checkers + Copy to Clipboard Copier vers le presse-papier @@ -2896,6 +3238,7 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage. + Pdf Export @@ -2906,11 +3249,13 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage. + History + File: @@ -2926,6 +3271,7 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage. + Undefines: @@ -2939,6 +3285,7 @@ Pour configurer les erreurs affichées, ouvrez le menu d'affichage.ThreadDetails + Thread Details diff --git a/gui/cppcheck_it.ts b/gui/cppcheck_it.ts index 243b0be7d51..4d0823a7053 100644 --- a/gui/cppcheck_it.ts +++ b/gui/cppcheck_it.ts @@ -5,27 +5,32 @@ About + About Cppcheck Informazioni su Cppcheck + Version %1 Versione %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - Uno strumento per l'analisi statica di codice C/C++ + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. Copyright © 2007-2021 il team Cppcheck. + This program is licensed under the terms of the GNU General Public License version 3 Questo programma è rilasciato sotto i termini @@ -33,11 +38,13 @@ della GNU General Public License versione 3 + Visit Cppcheck homepage at %1 Visita la pagina iniziale di Cppcheck all'indirizzo: %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> @@ -47,11 +54,13 @@ della GNU General Public License versione 3 ApplicationDialog + Add an application Aggiungi un'applicazione + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -78,21 +87,25 @@ Parametri: -l(line) (file) + &Name: &Nome: + &Executable: &Eseguibile: + &Parameters: &Parametri: + Browse Esplora @@ -137,16 +150,19 @@ Parametri: -l(line) (file) HelpDialog + Cppcheck GUI help + Contents + Index @@ -164,16 +180,19 @@ Parametri: -l(line) (file) LibraryAddFunctionDialog + Add function + Function name(s) + Number of arguments @@ -182,86 +201,103 @@ Parametri: -l(line) (file) LibraryDialog + Library Editor + Open + Save + Save as + Functions + Sort + Add + Filter: + Comments + noreturn + False + True + Unknown + return value must be used + ignore function in leaks checking + Arguments + Edit Modifica @@ -307,11 +343,13 @@ Parametri: -l(line) (file) LibraryEditArgDialog + Edit argument + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -322,11 +360,13 @@ Parametri: -l(line) (file) + Not bool + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -337,78 +377,99 @@ Parametri: -l(line) (file) + Not null + Not uninit + String + Format string + Min size of buffer + + Type + + None + + argvalue + + mul + + strlen + + Arg + + Arg2 + and + Valid values @@ -421,578 +482,694 @@ Parametri: -l(line) (file) + A&nalyze + Standard Standard + &File &File + &View &Visualizza + &Toolbars &Barre degli strumenti + C++ standard + &C standard C standard + &Edit &Modifica + &License... &Licenza... + A&uthors... A&utori... + &About... I&nformazioni su... + &Files... &File... + + Analyze files Check files Scansiona i file + Ctrl+F Ctrl+F + &Directory... &Cartella... + + Analyze directory Check directory Scansiona la cartella + Ctrl+D Ctrl+D + Ctrl+R Ctrl+R + &Stop &Ferma + + Stop analysis Stop checking Ferma la scansione + Esc Esc + &Save results to file... &Salva i risultati nel file... + Ctrl+S Ctrl+S + &Quit &Esci + &Clear results &Cancella i risultati + &Preferences &Preferenze - + + + Show errors Mostra gli errori - + + + Show warnings Mostra gli avvisi + + Show performance warnings Mostra gli avvisi sulle prestazioni + Show &hidden Mostra &i nascosti - - + + Information Informazione + Show information messages Mostra messaggi di informazione + Show portability warnings Mostra gli avvisi sulla portabilità + Show Cppcheck results + Clang + Show Clang results + &Filter &Filtro + Filter results Filtra i risultati + Windows 32-bit ANSI Windows 32-bit, ANSI + Windows 32-bit Unicode Windows 32-bit, Unicode + Unix 32-bit Unix 32-bit + Unix 64-bit Unix 64-bit + Windows 64-bit Windows 64-bit + &Print... + Print the Current Report + Print Pre&view... + Open a Print Preview Dialog for the Current Results + Open library editor + &Check all &Seleziona tutto + Checking for updates + Hide Nascondi + + Report + Filter Filtro + &Reanalyze modified files &Recheck modified files + Reanal&yze all files + Ctrl+Q + Style war&nings + E&rrors + &Uncheck all &Deseleziona tutto + Collapse &all Riduci &tutto + &Expand all &Espandi tutto + &Standard &Standard + Standard items Oggetti standard + Toolbar Barra degli strumenti + &Categories &Categorie + Error categories Categorie di errore + &Open XML... &Apri XML... + Open P&roject File... Apri file di p&rogetto... + Ctrl+Shift+O + Sh&ow Scratchpad... + &New Project File... &Nuovo file di progetto... + Ctrl+Shift+N + &Log View &Visualizza il rapporto + Log View Visualizza il rapporto + C&lose Project File C&hiudi il file di progetto + &Edit Project File... &Modifica il file di progetto... + &Statistics &Statistiche + &Warnings + Per&formance warnings + &Information + &Portability + P&latforms + C++&11 + C&99 + &Posix + C&11 + &C89 + &C++03 + &Library Editor... + &Auto-detect language + &Enforce C++ + E&nforce C + C++14 C++14 + Reanalyze and check library + Check configuration (defines, includes) + C++17 C++17 + C++20 C++20 + Compliance report... + Normal + Autosar + EULA... + Thread Details + Show thread details + &Contents &Contenuti + Categories Categorie + + Show style warnings Mostra gli avvisi sullo stile + Open the help contents Apri i contenuti di aiuto + F1 F1 + &Help &Aiuto - - + + Quick Filter: Rapido filtro: - + Select configuration - + Found project file: %1 Do you want to load this project file instead? @@ -1001,96 +1178,96 @@ Do you want to load this project file instead? Vuoi piuttosto caricare questo file di progetto? - + File not found - + Bad XML - + Missing attribute - + Bad attribute value - + Unsupported format - + Duplicate define - + Failed to load the selected library '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License Licenza - + Authors Autori - + Save the report file Salva il file di rapporto - - + + XML files (*.xml) File XML (*.xml) - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -1099,111 +1276,116 @@ This is probably because the settings were changed between the Cppcheck versions Probabilmente ciò è avvenuto perché le impostazioni sono state modificate tra le versioni di Cppcheck. Per favore controlla (e sistema) le impostazioni delle applicazioni editor, altrimenti il programma editor può non partire correttamente. - + You must close the project file before selecting new files or directories! Devi chiudere il file di progetto prima di selezionare nuovi file o cartelle! - + The library '%1' contains unknown elements: %2 - + Duplicate platform type - + Platform type redefined - + Unknown element - - - - + + + + Error - + Open the report file Apri il file di rapporto - + Text files (*.txt) File di testo (*.txt) - + CSV files (*.csv) Files CSV (*.csv) - + Project files (*.cppcheck);;All files(*.*) Files di progetto (*.cppcheck);;Tutti i files(*.*) - + Select Project File Seleziona il file di progetto - - - - + + + + Project: Progetto: - + + None of the selected files is part of the project, nothing to analyze. + + + + No suitable files found to analyze! - + C/C++ Source - + Compile database - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1211,76 +1393,76 @@ Do you want to proceed? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + Build dir '%1' does not exist, create it? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Project files (*.cppcheck) - + Select Project Filename Seleziona il nome del file di progetto - + No project file loaded Nessun file di progetto caricato - + The project file %1 @@ -1297,67 +1479,67 @@ Do you want to remove the file from the recently used projects -list? Vuoi rimuovere il file dalla lista dei progetti recentemente usati? - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1401,26 +1583,31 @@ Options: NewSuppressionDialog + New suppression + Error ID + File name + Line number + Symbol name @@ -1462,111 +1649,135 @@ Options: ProjectFile + Project File File di progetto + Paths and Defines + Import Project (Visual studio / compile database/ Borland C++ Builder 6) Import Project (Visual studio / compile database) + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int Defines must be separated by a semicolon ';' + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. + Exclude source files + Exclude folder... + Exclude file... + Misra C + 2012 + + 2023 + MISRA rule texts + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + ... + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> + + Browse... + Analyze all Visual Studio configurations + Selected VS Configurations + Paths: Percorsi: + + Add... Aggiungi... @@ -1574,6 +1785,9 @@ Options: + + + Edit Modifica @@ -1582,269 +1796,327 @@ Options: + + + + Remove Rimuovi + Undefines: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 + Include Paths: + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + Types and Functions + + Analysis + This is a workfolder that Cppcheck will use for various purposes. + Parser + Cppcheck (built in) + Check level + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + Check that each class has a safe public interface + Limit analysis + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) + Max CTU depth + Enable inline suppressions Abilita le soppressioni + 2025 + Misra C++ + 2008 + Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + Autosar + Safety profiles (defined in C++ core guidelines) + Bug hunting + External tools + Up Su + Down Giù + Platform + Clang (experimental) + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) + Max recursion in template instantiation + Warning options + Root path: + Filepaths in warnings will be relative to this path + Warning tags (separated by semicolon) + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) + Libraries + Suppressions + Add + + Addons + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. + Y2038 + Thread safety + Coding standards + Cert C++ + Bug hunting (Premium) + Defines: Definizioni: @@ -2464,21 +2736,25 @@ Per vedere il tipo di errori che sono mostrati, apri il menu Visualizza. + Results Risultati + Critical errors + Analysis Log + Warning Details @@ -2487,26 +2763,31 @@ Per vedere il tipo di errori che sono mostrati, apri il menu Visualizza.ScratchPad + Scratchpad Blocchetto per appunti + Copy or write some C/C++ code here: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": + filename Nome file + Check Scansiona @@ -2515,21 +2796,25 @@ Per vedere il tipo di errori che sono mostrati, apri il menu Visualizza.Settings + Preferences Preferenze + General Generale + Add... Aggiungi... + Number of threads: Numero di threads: @@ -2539,56 +2824,67 @@ Per vedere il tipo di errori che sono mostrati, apri il menu Visualizza. + Force checking all #ifdef configurations Forza la scansione di tutte le configurazioni #ifdef + Show full path of files Mostra tutto il percorso dei files + Show "No errors found" message when no errors found Mostra il messaggio "Nessun errore trovato" quando nessun errore è stato trovato + Display error Id in column "Id" Mostra l'id dell'errore nella colonna "Id" + Enable inline suppressions Abilita le soppressioni + Check for inconclusive errors also + Show statistics on check completion + Check for updates + Show internal warnings in log + Addons + Python binary (leave this empty to use python in the PATH) @@ -2596,117 +2892,143 @@ Per vedere il tipo di errori che sono mostrati, apri il menu Visualizza. + + + ... + MISRA addon + MISRA rule texts file + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Clang + Clang path (leave empty to use system PATH) + Visual Studio headers + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> + Code Editor + Code Editor Style + System Style + Default Light Style + Default Dark Style + Custom + Remove Rimuovi + Max count: + Applications Applicazioni + + Edit... Modifica... + Set as default Imposta come predefinito + Reports Rapporti + Save all errors when creating report Salva tutti gli errori quando viene creato il rapporto + Save full path to files in reports Salva tutto il percorso ai files nei rapporti + Language Lingua @@ -2763,6 +3085,8 @@ Per vedere il tipo di errori che sono mostrati, apri il menu Visualizza. + + Statistics @@ -2770,113 +3094,135 @@ Per vedere il tipo di errori che sono mostrati, apri il menu Visualizza. + Project Progetto + Project: Progetto: + Paths: Percorsi: + Include paths: Percorsi di inclusione: + Defines: Definizioni: + Undefines: + Previous Scan Precedente Scansione + Path Selected: Selezionato percorso: + Number of Files Scanned: Numero di Files Scansionati: + Scan Duration: Durata della scansione: + Errors: Errori: + Warnings: Avvisi: + Stylistic warnings: Avvisi sullo stile: + Portability warnings: Avvisi sulla portabilità: + Performance issues: Casi sulla performance: + Information messages: Messaggi di informazione: + Active checkers: + Checkers + History + File: + Copy to Clipboard Copia negli Appunti + Pdf Export @@ -3026,6 +3372,7 @@ Per vedere il tipo di errori che sono mostrati, apri il menu Visualizza.ThreadDetails + Thread Details diff --git a/gui/cppcheck_ja.ts b/gui/cppcheck_ja.ts index dcbe8418942..75b2bad9985 100644 --- a/gui/cppcheck_ja.ts +++ b/gui/cppcheck_ja.ts @@ -5,38 +5,45 @@ About + About Cppcheck cppcheckについて + Version %1 Version %1 + Cppcheck - A tool for static C/C++ code analysis. CppcheckはC/C++ 静的コード解析ツールです. + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. Copyright © 2007-%1 Cppcheck team. + This program is licensed under the terms of the GNU General Public License version 3 本ソフトウェアはGNU General Public License Version3 ライセンスの元で配布されます + Visit Cppcheck homepage at %1 Cppcheckのホームページはこちら %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> <html><head/><body><p>ライブラリの開発者に感謝を捧げます:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> @@ -46,11 +53,13 @@ of the GNU General Public License version 3 ApplicationDialog + Add an application アプリケーションの追加 + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -77,21 +86,25 @@ Parameters: -l(line) (file) + &Name: 表示名(&N): + &Executable: 実行ファイルのパス(&E): + &Parameters: パラメータ(&P): + Browse 参照 @@ -191,16 +204,19 @@ Parameters: -l(line) (file) HelpDialog + Cppcheck GUI help Cppcheck GUI ヘルプ + Contents 目次 + Index インデックス @@ -218,16 +234,19 @@ Parameters: -l(line) (file) LibraryAddFunctionDialog + Add function 関数の追加 + Function name(s) 関数の名称 + Number of arguments 引数の数 @@ -236,86 +255,103 @@ Parameters: -l(line) (file) LibraryDialog + Library Editor ライブラリエディタ + Open 開く + Save 保存する + Save as 別名で保存する + Functions 関数 + Sort ソート + Add 追加 + Filter: フィルタ: + Comments コメント + noreturn noreturn(返り値なし) + False False(偽) + True True(真) + Unknown Unknown(不明) + return value must be used 返り値は使用されなければならない + ignore function in leaks checking リークの解析中に無視する関数 + Arguments Arguments(引数) + Edit 編集 @@ -361,11 +397,13 @@ Parameters: -l(line) (file) LibraryEditArgDialog + Edit argument 引数の編集 + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -381,12 +419,14 @@ Parameters: -l(line) (file) + Not bool 非ブール型 非bool値 + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -402,78 +442,99 @@ Parameters: -l(line) (file) + Not null 非NULL + Not uninit 未初期化 + String 文字列 + Format string フォーマット文字列 + Min size of buffer バッファの最小サイズ + + Type Type(型) + + None None(無) + + argvalue argvalue(引数の値) + + mul mul(積) + + strlen strlen(文字数) + + Arg Arg(引数) + + Arg2 Arg2(第二引数) + and and(和) + Valid values 妥当な値 @@ -486,542 +547,654 @@ Parameters: -l(line) (file) + &File ファイル(&F) + &View 表示(&V) + &Toolbars ツールバー(&T) + &Help ヘルプ(&H) + C++ standard C++標準 + &C standard C standard &C標準 + &Edit 編集(&E) + Standard 言語規格 + Categories カテゴリ + &License... ライセンス(&L)... + A&uthors... 作者(&u)... + &About... Cppcheckについて(&A)... + &Files... ファイル選択(&F)... + + Analyze files Check files ファイルをチェックする + Ctrl+F Ctrl+F + &Directory... ディレクトリ選択(&D)... + + Analyze directory Check directory ディレクトリをチェックする + Ctrl+D Ctrl+D + Ctrl+R Ctrl+R + &Stop 停止(&S) + + Stop analysis Stop checking チェックを停止する + Esc Esc + &Save results to file... 結果をファイルに保存(&S)... + Ctrl+S Ctrl+S + &Quit 終了(&Q) + &Clear results 結果をクリア(&C) + &Preferences 設定(&P) + + Show style warnings スタイル警告を表示 - + + + Show errors エラーを表示 - - + + Information 情報 + Show information messages 情報メッセージを表示 + Show portability warnings 移植可能性の問題を表示 + Show Cppcheck results Cppcheck結果を表示する + Clang Clang + Show Clang results Clangの結果を表示 + &Filter フィルター(&F) + Filter results フィルタ結果 + Windows 32-bit ANSI Windows 32-bit ANSIエンコード + Windows 32-bit Unicode Windows 32-bit Unicode + Unix 32-bit Unix 32-bit + Unix 64-bit Unix 64-bit + Windows 64-bit Windows 64-bit + &Print... 印刷(&P)... + Print the Current Report 現在のレポートを印刷 + Print Pre&view... 印刷プレビュー(&v)... + Open a Print Preview Dialog for the Current Results 現在のレポートをプレビュー表示 + Open library editor ライブラリエディタを開く + C&lose Project File プロジェクトを閉じる(&l) + &Edit Project File... プロジェクトの編集(&E)... + &Statistics 統計情報(&S) - + + + Show warnings 警告を表示 + + Show performance warnings パフォーマンス警告を表示 + Show &hidden 非表示を表示(&h) + &Check all すべてのエラーを表示(&C) + Checking for updates 更新の確認 + Hide 非表示 + + Report レポート + A&nalyze チェック(&n) + Filter フィルター + &Reanalyze modified files &Recheck modified files 変更ありファイルを再解析(&R) + Reanal&yze all files 全ファイル再解析(&y) + Ctrl+Q Ctrl+Q + Style war&nings スタイル警告(&n) + E&rrors エラー(&r) + &Uncheck all すべてのエラーを非表示(&U) + Collapse &all ツリーを折り畳む(&a) + &Expand all ツリーを展開(&E) + &Standard 言語規格(&S) + Standard items 標準項目 + &Contents コンテンツ(&C) + Open the help contents ヘルプファイルを開く + F1 F1 + Toolbar ツールバー + &Categories カテゴリ(&C) + Error categories エラーカテゴリ + &Open XML... XMLを開く(&O)... + Open P&roject File... プロジェクトを開く(&R)... + Ctrl+Shift+O Ctrl+Shift+O + Sh&ow Scratchpad... スクラッチパッドを表示(&o)... + &New Project File... 新規プロジェクト(&N)... + Ctrl+Shift+N Ctrl+Shift+N + &Log View ログを表示(&L) + Log View ログ表示 + &Warnings 警告(&W) + Per&formance warnings パフォーマンス警告(&f) + &Information 情報(&I) + &Portability 移植可能性(&P) + P&latforms プラットフォーム(&l) + C++&11 C++11(&1) + C&99 C99(&9) + &Posix Posix(&P) + C&11 C11(&1) + &C89 C89(&C) + &C++03 C++03(&C) + &Library Editor... ライブラリエディタ(&L)... + &Auto-detect language 自動言語検出(&A) + &Enforce C++ C++ 強制(&E) + E&nforce C C 強制(&n) + C++14 C++14 + Reanalyze and check library ライブラリを再チェックする + Check configuration (defines, includes) チェックの設定(define、インクルード) + C++17 C++17 + C++20 C++20 + Compliance report... コンプライアンスレポート... + Normal ノーマル @@ -1047,26 +1220,30 @@ Parameters: -l(line) (file) + Autosar AUTOSAR + EULA... EULA... + Thread Details スレッド詳細 + Show thread details スレッド詳細を表示 - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -1075,23 +1252,28 @@ This is probably because the settings were changed between the Cppcheck versions Cppcheckの古いバージョンの設定には互換性がありません。エディタアプリケーションの設定を確認して修正してください、そうしないと正しく起動できないかもしれません。 - + You must close the project file before selecting new files or directories! 新しいファイル/ディレクトリをチェックするには現在のプロジェクトを閉じてください! - - + + Quick Filter: クイックフィルタ: - + + None of the selected files is part of the project, nothing to analyze. + + + + Select configuration コンフィグレーションの選択 - + Found project file: %1 Do you want to load this project file instead? @@ -1100,64 +1282,64 @@ Do you want to load this project file instead? 現在のプロジェクトの代わりにこのプロジェクトファイルを読み込んでもかまいませんか? - + The library '%1' contains unknown elements: %2 このライブラリ '%1' には次の不明な要素が含まれています。 %2 - + File not found ファイルがありません - + Bad XML 不正なXML - + Missing attribute 属性がありません - + Bad attribute value 不正な属性があります - + Unsupported format サポートされていないフォーマット - + Duplicate platform type プラットフォームの種類が重複しています - + Platform type redefined プラットフォームの種類が再定義されました - + Unknown element 不明な要素 - + Failed to load the selected library '%1'. %2 選択したライブラリの読み込みに失敗しました '%1' %2 - - - - + + + + Error エラー @@ -1170,38 +1352,38 @@ Do you want to load this project file instead? %1 - %2 の読み込みに失敗 - - + + XML files (*.xml) XML ファイル (*.xml) - + Open the report file レポートを開く - + License ライセンス - + Authors 作者 - + Save the report file レポートを保存 - + Text files (*.txt) テキストファイル (*.txt) - + CSV files (*.csv) CSV形式ファイル (*.csv) @@ -1210,32 +1392,32 @@ Do you want to load this project file instead? コンプライアンスレポートをすぐに生成できません。解析が完了し成功していなければなりません。コードを再解析して、致命的なエラーがないことを確認してください。 - + Project files (*.cppcheck);;All files(*.*) プロジェクトファイル (*.cppcheck);;すべてのファイル(*.*) - + Select Project File プロジェクトファイルを選択 - + Failed to open file ファイルを開くのに失敗しました - + Unknown project file format プロジェクトファイルの形式が不明です - + Failed to import project file プロジェクトファイルのインポートに失敗しました - + Failed to import '%1': %2 Analysis is stopped. @@ -1244,40 +1426,40 @@ Analysis is stopped. 解析を停止しました。 - + Failed to import '%1' (%2), analysis is stopped '%1' (%2) のインポートに失敗しました。解析は停止 - + Install インストール - + New version available: %1. %2 新しいバージョンが利用可能です。: %1. %2 - - - - + + + + Project: プロジェクト: - + No suitable files found to analyze! チェック対象のファイルがみつかりません! - + C/C++ Source C/C++のソースコード - + Compile database コンパイルデータベース @@ -1290,22 +1472,22 @@ Analysis is stopped. Borland C++ Builder 6 - + Select files to analyze チェック対象のファイルを選択 - + Select directory to analyze チェックするディレクトリを選択してください - + Select the configuration that will be analyzed チェックの設定を選択 - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? @@ -1314,37 +1496,37 @@ Do you want to proceed analysis without using any of these project files? - + Duplicate define 重複した定義 - + File not found: '%1' ファイルがありません: '%1' - + Failed to load/setup addon %1: %2 アドオンの読み込みまたは設定に失敗 %1 - %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. %1のロードに失敗しました。あなたの Cppcheck は正しくインストールされていません。あなたは --data-dir=<directory> コマンドラインオプションを使ってこのファイルの場所を指定できます。ただし、この --data-dir はインストールスクリプトによって使用されていなければなりません。またGUI版はこれを使用しません。さらに、全ての設定は調整済みでなければなりません。 - + Failed to load %1 - %2 Analysis is aborted. 読み込みに失敗 %1 - %2 - - + + %1 Analysis is aborted. @@ -1353,7 +1535,7 @@ Analysis is aborted. 解析は中止した。 - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1363,7 +1545,7 @@ Do you want to proceed? 新しくXMLファイルを開くと現在の結果が削除されます。実行しますか? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1372,77 +1554,77 @@ Do you want to stop the analysis and exit Cppcheck? チェックを中断して、Cppcheckを終了しますか? - + About CppCheckについて - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML ファイル (*.xml);;テキストファイル (*.txt);;CSVファイル (*.csv) - + Build dir '%1' does not exist, create it? ビルドディレクトリ'%1'がありません。作成しますか? - + To check the project using addons, you need a build directory. アドオンを使用してプロジェクトをチェックするためには、ビルドディレクトリが必要です。 - + Show Mandatory 必須を表示 - + Show Required 要求を表示 - + Show Advisory 推奨を表示 - + Show Document ドキュメントを表示 - + Show L1 L1を表示 - + Show L2 L2を表示 - + Show L3 L3を表示 - + Show style スタイルを表示 - + Show portability 移植可能性を表示 - + Show performance パフォーマンスを表示 - + Show information 情報を表示 @@ -1451,22 +1633,22 @@ Do you want to stop the analysis and exit Cppcheck? '%1'のインポートに失敗しました。(チェック中断) - + Project files (*.cppcheck) プロジェクトファイル (*.cppcheck) - + Select Project Filename プロジェクトファイル名を選択 - + No project file loaded プロジェクトファイルが読み込まれていません - + The project file %1 @@ -1528,26 +1710,31 @@ Options: NewSuppressionDialog + New suppression 新しい指摘の抑制 + Error ID エラーID + File name ファイル名 + Line number 行数 + Symbol name シンボル名 @@ -1589,28 +1776,33 @@ Options: ProjectFile + Project File プロジェクトファイル + Paths and Defines パスと定義 + Import Project (Visual studio / compile database/ Borland C++ Builder 6) Import Project (Visual studio / compile database) プロジェクトのインポート(Visual studio / compile database Borland C++ Builder 6)) + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int Defines must be separated by a semicolon ';' 定義(Define)はセミコロン';'で区切る必要があります。 例: DEF1;DEF2=5;DEF3=int + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. カスタマイズした cfgファイルを同じフォルダにプロジェクトファイルとして保存してください。ここに表示できるようになります。 @@ -1620,48 +1812,59 @@ Options: + MISRA rule texts MISRA ルールテキスト + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> <html><head/><body><p>MISRA C 2012 pdfのAppendix A &quot;Summary of guidelines&quot; からテキストをコピーペーストしてください。</p></body></html> + ... ... + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> <html><head/><body><p>選択済み:</p><p> * 全Debug と Release設定をチェックする</p><p> * 最初にマッチした Debug 設定のみチェックする</p><p><br/></p></body></html> + + Browse... 参照... + Analyze all Visual Studio configurations Visual Studioの全ての設定をチェックする + Selected VS Configurations 選択したVS設定 + Paths: パス: + + Add... 追加... @@ -1669,6 +1872,9 @@ Options: + + + Edit 編集 @@ -1677,87 +1883,108 @@ Options: + + + + Remove 取り除く + Undefines: 定義取り消し(Undefines): + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 定義の取り消しはセミコロンで区切ります。例: UNDEF1;UNDEF2;UNDEF3 + Include Paths: インクルードパス: + Include file インクルードファイル + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">ヘッダファイルを強制的にインクルードします</span></p></body></html> + Browse.. ブラウズ.. + Types and Functions 型と関数 + + Analysis チェック + This is a workfolder that Cppcheck will use for various purposes. Cppcheckがさまざまな目的で使用するワークディレクトリ。 + Parser パーサー + Cppcheck (built in) Cppcheckビルトイン + Check level チェックレベル + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. #R 限定的 -- 開発者が直接的に結果を得るための解析を意味します。解析は限定的で高速ですがより少ない結果になります。 + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. #N 通常 -- CIでの通常の解析を意味します。解析が合理的な時間内に完了すべきです。 + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). #E 徹底的 -- ナイトリービルド等を意味します。解析時間はより長くなることがあります (コンパイルの10倍以上時間がかかってもよい)。 + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) ヘッダファイルのコードもチェック (通常はONにしてください、制限するときのみOFF) @@ -1767,194 +1994,234 @@ Options: + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. タグが追加された場合、警告上で右クリックしてそれらのタグの中の一つを設定できます。警告を分類できます。 + Exclude source files 除外するソースファイル + Exclude folder... フォルダで除外... + Exclude file... ファイルで除外... + Check that each class has a safe public interface クラスが安全で公開されたインターフェースをもっているか確認 + Limit analysis 解析の制限 + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) 未使用テンプレートのコードもチェック (解析に時間がかかり、また正確性は低い) + Max CTU depth CTUの最大深さ + Enable inline suppressions inline抑制を有効にする + Misra C MISRA C + 2012 2012 + + 2023 2023 + 2025 2025 + Misra C++ MISRA C++ + 2008 2008 + Cert C++ Cert C++ + Safety profiles (defined in C++ core guidelines) 安全性プロファイル(C++コアガイドラインで定義) + Bug hunting (Premium) バグハンティング(プレミアム) + External tools 外部ツール + Up 上 + Down 下 + Platform プラットフォーム + Clang (experimental) Clang (実験的) + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. 可能な限りクラスが柔軟であり堅牢であることを望む場合、公開されたインターフェースが非常に堅牢です。Cppcheckは引数があらゆる値をとりうると仮定します。 + Max recursion in template instantiation テンプレートインスタンス化の最大再帰回数 + Warning options 警告オプション + Root path: ルートパス: + Filepaths in warnings will be relative to this path 警告中のファイルパスはこのパスからの相対パスになります + Warning tags (separated by semicolon) 警告タグ(セミコロン区切り) + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) Cppcheck ビルドディレクトリ (全プログラムチェック, 差分チェック, 統計等) + Libraries ライブラリ + Suppressions 指摘の抑制 + Add 追加 + + Addons アドオン + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. 注意: アドオンには<a href="https://www.python.org/">Python</a>が必要です。 + Y2038 Y2038 + Thread safety スレッドセーフ + Coding standards コーディング標準 @@ -1964,11 +2231,13 @@ Options: + Cert C CERT C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) CERT-INT35-C: int型の精度 (もしサイズが精度と一致する場合空のままにしてください) @@ -1978,11 +2247,13 @@ Options: + Autosar AUTOSAR + Bug hunting バグハント @@ -1996,6 +2267,7 @@ Options: + Defines: 定義(Defines): @@ -2550,21 +2822,25 @@ Please check the application path and parameters are correct. ResultsView + Results 結果 + Critical errors 致命的なエラー + Analysis Log チェックログ + Warning Details 警告の詳細 @@ -2674,26 +2950,31 @@ To toggle what kind of errors are shown, open view menu. ScratchPad + Scratchpad スクラッチパッド + Copy or write some C/C++ code here: ここに C/C++のコードをコピーペーストまたは記入してください: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": オプション: ファイル名を入力(言語は自動判定)して"チェック"をクリックしてください: + filename ファイル名 + Check チェック @@ -2702,21 +2983,25 @@ To toggle what kind of errors are shown, open view menu. Settings + Preferences 設定 + General 全般 + Add... 追加... + Number of threads: 解析用のスレッド数: @@ -2726,57 +3011,68 @@ To toggle what kind of errors are shown, open view menu. + Force checking all #ifdef configurations Check all #ifdef configurations すべての #ifdef をチェックする + Show full path of files ファイルのフルパスを表示 + Show "No errors found" message when no errors found エラーが無いときは"エラーなし"を表示 + Display error Id in column "Id" エラーIDを "Id" に表示する + Enable inline suppressions inline抑制を有効にする + Check for inconclusive errors also 結論のでない指摘もチェックする + Show statistics on check completion チェック完了時に統計情報を表示する + Check for updates 更新の確認 + Show internal warnings in log ログの内部警告も表示する + Addons アドオン + Python binary (leave this empty to use python in the PATH) Pythonインタプリタの場所(空白の場合システムのPATHから検索) @@ -2784,117 +3080,143 @@ To toggle what kind of errors are shown, open view menu. + + + ... ... + MISRA addon MISRAアドオン + MISRA rule texts file MISRA ルールテキストファイル + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> <html><head/><body><p>Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdfのテキストをテキストファイルにコピー</p></body></html> + Clang Clang + Clang path (leave empty to use system PATH) Clangの場所(空白の場合システムのPATHから検索) + Visual Studio headers Visual Studioのヘッダ + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> <html><head/><body><p>Visual Studioのヘッダーファイル(セミコロン区切り';')。</p><p>Visual Studio コマンドプロンプトを開き、 &quot;SET INCLUDE&quot;. と入力後、そのパスをコピーペーストしてください。</p></body></html> + Code Editor コードエディタ + Code Editor Style コードエディタスタイル + System Style システムのデフォルトのスタイル + Default Light Style ライトスタイルをデフォルトに + Default Dark Style ダークスタイルをデフォルトに + Custom カスタム + Remove 削除 + Max count: #M 最大数: + Applications アプリケーション + + Edit... 編集... + Set as default デフォルトとして設定 + Reports レポート + Save all errors when creating report レポート作成時にすべての警告/エラーを保存 + Save full path to files in reports レポートにファイルのフルパスを保存 + Language 言語 @@ -2951,6 +3273,8 @@ To toggle what kind of errors are shown, open view menu. + + Statistics @@ -2958,113 +3282,135 @@ To toggle what kind of errors are shown, open view menu. + Project プロジェクト + Project: プロジェクト: + Paths: パス: + Include paths: インクルードパス: + Defines: 定義(define): + Undefines: 定義取り消し(undef): + Previous Scan 前回の解析 + Path Selected: ディレクトリ選択: + Number of Files Scanned: 解析済みファイル数: + Scan Duration: 解析にかかった時間: + Errors: エラー: + Warnings: 警告: + Stylistic warnings: スタイル警告: + Portability warnings: 移植可能性の警告: + Performance issues: パフォーマンス警告: + Information messages: 情報メッセージ: + Active checkers: 有効なチェッカー: + Checkers チェッカー + History ヒストリー + File: ファイル: + Copy to Clipboard クリップボードにコピー + Pdf Export PDF エクスポート @@ -3214,6 +3560,7 @@ To toggle what kind of errors are shown, open view menu. ThreadDetails + Thread Details スレッド詳細 diff --git a/gui/cppcheck_ka.ts b/gui/cppcheck_ka.ts index 7464052e694..97fe21d6f96 100644 --- a/gui/cppcheck_ka.ts +++ b/gui/cppcheck_ka.ts @@ -5,27 +5,32 @@ About + About Cppcheck Cppcheck-ის შესახებ + Version %1 ვერსია %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - ხელსაწყო სტატიკური C/C++ კოდის ანალიზისთვის. + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. Copyright © 2007-%1 Cppcheck-ის გუნდი. ყველა უფლება დაცულია. + This program is licensed under the terms of the GNU General Public License version 3 ვრცელდება GNU-ის საჯარო ლიცენზიის, @@ -33,11 +38,13 @@ of the GNU General Public License version 3 + Visit Cppcheck homepage at %1 ეწვიეთ Cppcheck-ის ვებგვერდს მისამართზე %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> <html><head/><body><p>დიდი მადლობა ამ ბიბლიოთეკებს, რომლებსაც ვიყენებთ::</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> @@ -47,11 +54,13 @@ of the GNU General Public License version 3 ApplicationDialog + Add an application აპლიკაციის დამატება + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -67,21 +76,25 @@ Parameters: -l(line) (file) + &Name: &სახელი: + &Executable: &გამშვები ფაილი: + &Parameters: &პარამეტრები: + Browse დათვალიერება @@ -179,16 +192,19 @@ Parameters: -l(line) (file) HelpDialog + Cppcheck GUI help Cppcheck-ის გრაფიკული ინტერფეისის დახმარება + Contents შემცველობა + Index ინდექსი @@ -206,16 +222,19 @@ Parameters: -l(line) (file) LibraryAddFunctionDialog + Add function ფუნქციის დამატება + Function name(s) ფუნქციის სახელ(ებ)-ი + Number of arguments არგუმენტების რაოდენობა @@ -224,86 +243,103 @@ Parameters: -l(line) (file) LibraryDialog + Library Editor ბიბლიოთეკის რედაქტორი + Open გახსნა + Save შენახვა + Save as შენახვა, როგორც + Functions ფუნქციები + Sort დალაგება + Add დამატება + Filter: ფილტრი: + Comments კომენტარები + noreturn noreturn + False მცდარი + True სიმართლე + Unknown უცნობი + return value must be used უნდა გამოიყენოთ დაბრუნებული მნიშვნელობა + ignore function in leaks checking ფუნქციების გამოტოვება გაჟონვები შემოწმებისას + Arguments არგუმენტები + Edit ჩასწორება @@ -348,11 +384,13 @@ Parameters: -l(line) (file) LibraryEditArgDialog + Edit argument არგუმენტის ჩასწორება + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -363,11 +401,13 @@ Parameters: -l(line) (file) + Not bool ლოგიკური მნ. არაა + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -378,78 +418,99 @@ Parameters: -l(line) (file) + Not null ნულოვანი არაა + Not uninit Uninit არაა + String სტრიქონი + Format string სტრიქონის ფორმატი + Min size of buffer ბუფერის მინ. ზომა + + Type ტიპი + + None არაფერი + + argvalue argvalue + + mul mul + + strlen strlen + + Arg არგ + + Arg2 Arg2 + and და + Valid values სწორი მნიშვნელობები @@ -462,511 +523,616 @@ Parameters: -l(line) (file) + A&nalyze ა&ნალიზი + Standard სტანდარტული + &File &ფაილი + &View &ხედი + &Toolbars &ხელსაწყოთა ზოლები + C++ standard C++-ის სტანდარტი + &C standard C standard &C-ის სტანდარტი + &Edit &ჩასწორება + &License... &ლიცენზია... + A&uthors... &ავტორები... + &About... &შესახებ... + &Files... ფაილ&ები... + + Analyze files Check files ფაილების ანალიზი + Ctrl+F Ctrl+F + &Directory... &საქაღალდე.... + + Analyze directory Check directory საქაღალდის ანალიზი + Ctrl+D Ctrl+D + Ctrl+R Ctrl+R + &Stop &გაჩერება + + Stop analysis Stop checking ანალიზის გაჩერება + Esc Esc + &Save results to file... შედეგები&ს შენახვა ფაილში.... + Ctrl+S Ctrl+S + &Quit გამოსვლა + &Clear results შედეგების &გასუფთავება + &Preferences &გამართვა - + + + Show errors შეცდომების ჩვენება - + + + Show warnings გაფრთხილების ჩვენება + + Show performance warnings წარმადობის გაფრთხილებების ჩვენება + Show &hidden დამალულის &ჩვენება - - + + Information ინფორმაცია + Show information messages ინფორმაციის შეტყობინებების ჩვენება + Show portability warnings გადატანადობის გაფრთხილებების ჩვენება + Show Cppcheck results Cppcheck-ის შედეგები ჩვენება + Clang Clang + Show Clang results Clang-ის შედეგები ჩვენება + &Filter &ფილტრი + Filter results შედეგების გაფილტვრა + Windows 32-bit ANSI Windows 32-bit ANSI + Windows 32-bit Unicode Windows 32-bit Unicode + Unix 32-bit Unix 32-bit + Unix 64-bit Unix 64-bit + Windows 64-bit Windows 64-bit + &Print... &ბეჭდვა… + Print the Current Report მიმდინარე ანგარიშის დაბეჭდვა + Print Pre&view... საბეჭდის &გადახედვა... + Open a Print Preview Dialog for the Current Results მიმდინარე შედეგების დაბეჭდვის მინიატურის დიალოგის ჩვენება + Open library editor ბიბლიოთეკის რედაქტორის გახსნა + &Check all &ყველას ჩართვა + Checking for updates განახლებების შემოწმება + Hide დამალვა + + Report + Filter ფილტრი + &Reanalyze modified files &Recheck modified files ყველა შეცვლილი ფაილის თავიდან ანალი&ზი + Reanal&yze all files &ყველა ფაილის თავიდან ანალიზი + Ctrl+Q Ctrl+Q + Style war&nings ს&ტილის გაფრთხილებები + E&rrors &შეცდომები + &Uncheck all ყველას ჩამოყ&რა + Collapse &all ყველას ჩაკეცვ&ა + &Expand all &ყველას ამოკეცვა + &Standard &სტანდარტული + Standard items სტანდარტული ელემენტები + Toolbar ხელსაწყოთა ზოლი + &Categories &კატეგორიები + Error categories შეცდომის კატეგორიები + &Open XML... &XML-ის გახსნა... + Open P&roject File... პ&პროექტის ფაილის გახსნა... + Ctrl+Shift+O Ctrl+Shift+O + Sh&ow Scratchpad... ბლ&ოკნოტის ჩვენება... + &New Project File... &ახალი პროექტის ფაილი... + Ctrl+Shift+N Ctrl+Shift+N + &Log View ჟურნა&ლის ხედი + Log View ჟურნალის ხედი + C&lose Project File პროექტის ფაი&ლის დახურვა + &Edit Project File... პროექტის ფაილის ჩასწორ&ება... + &Statistics &სტატისტიკა + &Warnings &გაფრთხილებები + Per&formance warnings წარმატების გა&ფრთხილებები + &Information &ინფორმაცია + &Portability &გადატანადობა + P&latforms პ&ლატფორმები + C++&11 C++&11 + C&99 C&99 + &Posix &Posix + C&11 C&11 + &C89 &C89 + &C++03 &C++03 + &Library Editor... ბიბ&ლიოთეკის რედაქტორი... + &Auto-detect language ენის &ავტოდადგენა + &Enforce C++ ძ&ალით C++ + E&nforce C ძა&ლით C + C++14 C++14 + Reanalyze and check library ბიბლიოთეკის თავიდან ანალიზი და შემოწმება + Check configuration (defines, includes) კონფიგურაციის შემოწმება (defines, includes) + C++17 C++17 + C++20 C++20 + Compliance report... შესაბამისობის ანგარიში... + Normal ნორმალური @@ -984,68 +1150,84 @@ Parameters: -l(line) (file) + Autosar + EULA... + Thread Details + Show thread details + &Contents &შემცველობა + Categories კატეგორიები + + Show style warnings სტილის გაფრთხილების ჩვენება + Open the help contents დახმარების შემცველობის გახსნა + F1 F1 + &Help &დახმარება - - + + Quick Filter: სწრაფი ფილტრი: - + + None of the selected files is part of the project, nothing to analyze. + + + + Select configuration აირჩიეთ კონფიგურაცია - + Found project file: %1 Do you want to load this project file instead? @@ -1054,61 +1236,61 @@ Do you want to load this project file instead? გნებავთ, სამაგიეროდ, ეს პროექტის ფაილი ჩატვირთოთ? - + File not found ფაილი ნაპოვნი არაა - + Bad XML არასწორი XML - + Missing attribute აკლია ატრიბუტი - + Bad attribute value არასწორი ატრიბუტის მნიშვნელობა - + Unsupported format მხარდაუჭერელი ფორმატი - + Duplicate define გამეორებული აღწერა - + Failed to load the selected library '%1'. %2 ჩავარდა ჩატვირთვა მონიშნული ბიბლიოთეკისთვის '%1'. %2 - + File not found: '%1' ფაილი ვერ ვიპოვე: '%1' - + Failed to load/setup addon %1: %2 დამატების (%1) ჩატვირთვა/მორგება ჩავარდა: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. @@ -1117,8 +1299,8 @@ Analysis is aborted. ანალიზი შეწყდა. - - + + %1 Analysis is aborted. @@ -1127,113 +1309,113 @@ Analysis is aborted. ანალიზი შეწყვეტილია. - + License ლიცენზია - + Authors ავტორები - + Save the report file ანგარიშის ფაილში ჩაწერა - - + + XML files (*.xml) XML ფაილები (*.xml) - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. - + You must close the project file before selecting new files or directories! ახალი ფაილების ან საქაღალდეების არჩევამდე პრორექტის ფაილი უნდა დახუროთ! - + The library '%1' contains unknown elements: %2 ბიბლიოთეკა '%1' უცნობ ელემენტებს შეიცავს: %2 - + Duplicate platform type გამეორებული პლატფორმის ტიპი - + Platform type redefined პლატფორმის ტიპი თავდან აღიწერა - + Unknown element უცნობი ელემენტი - - - - + + + + Error შეცდომა - + Open the report file ანგარიშის ფაილის გახსნა - + Text files (*.txt) ტექსტური ფაილები (*.txt) - + CSV files (*.csv) CSV ფაილები (*.csv) - + Project files (*.cppcheck);;All files(*.*) პროექტის ფაილები (*.cppcheck);;ყველა ფაილი(*.*) - + Select Project File აირჩიეთ პროექტის ფაილი - - - - + + + + Project: პროექტი: - + No suitable files found to analyze! ანალიზისათვის შესაფერისი ფაილები აღმოჩენილი არაა! - + C/C++ Source C/C++ საწყისი კოდი - + Compile database მონაცემთა ბაზის კომპილაცია @@ -1246,22 +1428,22 @@ This is probably because the settings were changed between the Cppcheck versions Borland C++ Builder 6 - + Select files to analyze აირჩეთ ფაილები ანალიზისთვის - + Select directory to analyze აირჩიეთ საქაღალდე ანალიზისთვის - + Select the configuration that will be analyzed აირჩიეთ კონფიგურაცია ანალიზისთვის - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? @@ -1270,7 +1452,7 @@ Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1281,7 +1463,7 @@ Do you want to proceed? გნებავთ, გააგრძელოთ? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1290,12 +1472,12 @@ Do you want to stop the analysis and exit Cppcheck? გნებავთ, გააჩეროთ ანალიზი და გახვიდეთ Cppcheck-დან? - + About შესახებ - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML ფაილები (*.xml);;ტექსტური ფაილები (*.txt);;CSV ფაილები (*.csv) @@ -1304,32 +1486,32 @@ Do you want to stop the analysis and exit Cppcheck? შესაბამისობის ანგარიშის გენერაცია ახლა შეუძლებელია, რადგან ჯერ ანალიზი წარმატებით უნდა დასრულდეს. სცადეთ, კოდის ანალიზი თავიდან გაუშვათ და დარწმუნდეთ, რომ კრიტიკული შეცდომები არ არსებობს. - + Build dir '%1' does not exist, create it? აგების საქაღალდე (%1) არ არსებობს. შევქმნა? - + To check the project using addons, you need a build directory. პროექტის დამატებებით შესამოწმებლად აგების საქაღალდე გჭირდებათ. - + Failed to open file ფაილის გახსნის შეცდომა - + Unknown project file format უცნობი პროექტის ფაილის ფორმატი - + Failed to import project file პროექტის ფაილის შემოტანა ჩავარდა - + Failed to import '%1': %2 Analysis is stopped. @@ -1338,27 +1520,27 @@ Analysis is stopped. ანალიზი შეწყდა. - + Failed to import '%1' (%2), analysis is stopped '%1'-ის (%2) შემოტანა ჩავარდა. ანალიზი შეწყდა - + Project files (*.cppcheck) პროექტის ფაილები (*.cppcheck) - + Select Project Filename აირჩიეთ პროექტის ფაილის სახელი - + No project file loaded პროექტის ფაილი ჩატვირთული არაა - + The project file %1 @@ -1375,67 +1557,67 @@ Do you want to remove the file from the recently used projects -list? გნებავთ წაშალოთ ეს ფაილი ახლახან გამოყენებული პროექტების სიიდან? - + Install დაყენება - + New version available: %1. %2 ხელმისაწვდომია ახალი ვერსია: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1492,26 +1674,31 @@ Options: NewSuppressionDialog + New suppression ახალი ჩახშობა + Error ID შეცდომის ID + File name ფაილის სახელი + Line number ხაზის ნომერი + Symbol name სიმბოლოს სახელი @@ -1553,120 +1740,145 @@ Options: ProjectFile + Project File პროექტის ფაილი + Paths and Defines ბილიკები და აღწერები + Import Project (Visual studio / compile database/ Borland C++ Builder 6) Import Project (Visual studio / compile database) პროექტის შემოტანა (Visual studio / მონაცემთა ბაზი კომპილაცია / Borland C++ Builder 6) + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int Defines must be separated by a semicolon ';' აღწერები წერტილმძიმით უნდა იყოს გამოყოფილი. მაგ: DEF1;DEF2=5;DEF3=int + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. შენიშვნა: ჩადეთ თქვენი .cfg ფაილები იგივე საქაღალდეში, სადაც პროექტის ფაილია. მათ ზემოთ დაინახავთ. + Clang (experimental) Clang (ექსპერიმენტული) + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) თავსართის ფაილებში არსებული კოდის შეწმება (ნაგულისხმევად, ეს ჩართულია. თუ გნებავთ შეზღუდული სწრაფი ანალიზი, მაშინ გამორთეთ ეს) + Max recursion in template instantiation + Filepaths in warnings will be relative to this path ფაილის ბილიკები ამ ბილიკის ფარდობითი იქნება + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. თუ ჭდეები დამატებულია, შეგიძლიათ, გაფრთხილებებზე მარჯვენა ღილაკით დააწკაპუნოთ და დააყენოთ ერთ-ერთი ჭდე. გაფრთხილებების კატეგორიებად დალაგება ხელით შეგიძლიათ. + Exclude source files კოდის ფაილების ამოღება + Exclude folder... საქაღალდის ამოღება... + Exclude file... ფაილის ამოღება... + MISRA rule texts MISRA-ის წესის ტექსტები + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + ... ... + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> + + Browse... ნუსხა... + Analyze all Visual Studio configurations ყველა Visual Studio-ის კონფიგურაციის ანალიზი + Selected VS Configurations არჩეული VS-ის კონფიგურაციები + Paths: ბილიკები: + + Add... დამატება... @@ -1674,6 +1886,9 @@ Options: + + + Edit ჩასწორება @@ -1682,255 +1897,311 @@ Options: + + + + Remove წაშლა + Undefines: წაშლილი მაკროაღწერები: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 წაშლილი მაკროაღწერები წერტილმძიმით უნდა იყოს გამოყოფილი. მაგ: UNDEF1;UNDEF2;UNDEF3 + Include Paths: ჩასმის ბილიკები: + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + Types and Functions ტიპები და ფუნქციები + + Analysis ანალიზი + This is a workfolder that Cppcheck will use for various purposes. ეს სამუშაო საქაღალდეა, რომელსაც Cppcheck სხვადასხვა მიზნებისთვის გამოიყენებს. + Parser ანალიზატორი + Cppcheck (built in) Cppcheck (ჩაშენებული) + Check level შემოწმების დონე + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. ნორმალური -- ნიშნავს ნორმალურ ანალიზს CI-ში. ანალიზი მისაღებ დროში დასრულდება. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). ამომწურავი -- განკუთვნილია ღამის აგებებისთვის და ა.შ. ანალიზის დრო, შეიძლება, უფრო მეტიც იყოს (კომპილაციაზე 10x მეტი დრო ჩვეულებრივი ამბავია). + Check that each class has a safe public interface შემოწმება, აქვს თუ არა ყველა კლასს უსაფრთხო საჯარო ინტერფეისი + Limit analysis ანალიზის შეზღუდვა + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) + Max CTU depth CTU-ის მაქსიმალური სიღრმე + Enable inline suppressions შეცდომების ხაზშივე ჩახშობის ჩართვა + 2025 2025 + Misra C++ Misra C++ + 2008 2008 + Cert C Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) CERT-INT35-C: მთელი რიცხვის სიზუსტე (თუ ზომა სიზუსტეს ემთხვევა, შეგიძლიათ, ცარიელი დატოვოთ) + Autosar + Safety profiles (defined in C++ core guidelines) + Bug hunting შეცდომებზე ნადირობა + External tools გარე ხელსაწყოები + Up მაღლა + Down ქვემოთ + Platform პლატფორმა + Warning options გაფრთხილების მორგება + Root path: Root ბილიკი: + Warning tags (separated by semicolon) გაფრთხილების ჭდეები (წერტილმძიმით გამოყოფილი) + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) Cppcheck-ის აგების საქაღალდე (მთელი პროგრამის ანალიზი, ინკრემენტული ანალიზი, სტატისტიკა და ა.შ.) + Libraries ბიბლიოთეკები + Suppressions ჩახშობები + Add დამატება + + Addons დამატებები + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. შენიშვნა: დამატებას დაყენებული <a href="https://www.python.org/">Python</a> სჭირდება. + Y2038 Y2038 + Thread safety ნაკადების უსაფრთხოება + Coding standards კოდირების სტანდარტები + Misra C Misra C + 2012 2012 + + 2023 2023 + Cert C++ Cert C++ + Bug hunting (Premium) შეცდომებზე ნადირობა (ფასიანი) @@ -1944,6 +2215,7 @@ Options: + Defines: მაკროაღწრები: @@ -2590,21 +2862,25 @@ To toggle what kind of errors are shown, open view menu. + Results შედეგები + Critical errors კრიტიკული შეცდომები + Analysis Log ანალიზის ჟურნალი + Warning Details გაფრთხილების დეტალები @@ -2613,26 +2889,31 @@ To toggle what kind of errors are shown, open view menu. ScratchPad + Scratchpad მონახაზი + Copy or write some C/C++ code here: დააკოპირეთ ან დაწერეთ C/C++ კოდი აქ: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": შეიყვანეთ არასავალდებულო ფაილის სახელი (ძირითადად ავტომატური ენის დადგენისთვის) და დააწკაპუნეთ ღილაკზე "შემოწმება": + filename ფაილის სახელი + Check შემოწმება @@ -2641,21 +2922,25 @@ To toggle what kind of errors are shown, open view menu. Settings + Preferences მორგება + General ზოგადი + Add... დამატება... + Number of threads: ნაკადების რაოდენობა: @@ -2665,57 +2950,68 @@ To toggle what kind of errors are shown, open view menu. + Force checking all #ifdef configurations Check all #ifdef configurations ყველა #ifdef კონფიგურაციის ნაძალადევი შემოწმება + Show full path of files ფაილების სრული ბილიკის ჩვენება + Show "No errors found" message when no errors found "შეცდომები ნაპოვნი არაა" შეტყობინების ჩვენება, როცა შეცდომები აღმოჩენილი არა + Display error Id in column "Id" სვეტში "Id" შეცდომის Id-ის ჩვენება + Enable inline suppressions შეცდომების ხაზშივე ჩახშობის ჩართვა + Check for inconclusive errors also ასევე, ნაჩვენები იქნება საკამათო შეცდომებიც + Show statistics on check completion სტატისტიკის ჩვენება შემოწმების დასრულებისას + Check for updates განახლებების შემოწმება + Show internal warnings in log ჟურნალში შიდა გაფრთხილებების ჩვენება + Addons დამატებები + Python binary (leave this empty to use python in the PATH) ბილიკი python-ის ინტერპრეტატორამდე. (PATH-ში არსებული python-ის გამოსაყენებლად ცარიელი დატოვეთ) @@ -2723,117 +3019,143 @@ To toggle what kind of errors are shown, open view menu. + + + ... ... + MISRA addon MISRA-ის დამატება + MISRA rule texts file MISRA-ის წესის ტექსტების ფაილი + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Clang Clang + Clang path (leave empty to use system PATH) ბილიკი Clang-ის ინტერპრეტატორამდე. (PATH-ში არსებულის გამოსაყენებლად ცარიელი დატოვეთ) + Visual Studio headers Visual Studio-ის თავსართები + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> + Code Editor კოდის რედაქტორი + Code Editor Style კოდის რედაქტორის სტილი + System Style სისტემის მიყოლა + Default Light Style ნაგულისხმევი ღია სტილი + Default Dark Style ნაგულისხმევი მუქი სტილი + Custom მომხმარებლის + Remove წაშლა + Max count: + Applications აპლიკაციები + + Edit... რედაქტირება... + Set as default ნაგულისხმებად დაყენება + Reports ანგარიში + Save all errors when creating report ყველა შეცდომის შენახვა ანგარიშის შექმნისას + Save full path to files in reports ფაილების სრული ბილიკის ჩვენება ანგარიშებში + Language ენა @@ -2890,6 +3212,8 @@ To toggle what kind of errors are shown, open view menu. + + Statistics @@ -2897,113 +3221,135 @@ To toggle what kind of errors are shown, open view menu. + Project პროექტი + Project: პროექტი: + Paths: ბილიკები: + Include paths: თავსართის ფაილის ბილიკები: + Defines: მაკროაღწრები: + Undefines: წაშლილი მაკროაღწერები: + Previous Scan წინა სკანირება + Path Selected: არჩეული ბილიკი: + Number of Files Scanned: დასკანერებულია ფაილების რაოდენობა: + Scan Duration: სკანირების ხანგრძლივობა: + Errors: შეცდომები: + Warnings: გაფრთხილებები: + Stylistic warnings: სტილისტური გაფრთხილებები: + Portability warnings: გადატანადობის გაფრთხილებები: + Performance issues: წარმადობის პრობლემები: + Information messages: ინფორმაციის შეტყობინებები: + Active checkers: აქტიური შემმოწმებლები: + Checkers შაში + History ისტორია + File: ფაილი: + Copy to Clipboard ბუფერში კოპირება + Pdf Export PDF-ად გატანა @@ -3153,6 +3499,7 @@ To toggle what kind of errors are shown, open view menu. ThreadDetails + Thread Details diff --git a/gui/cppcheck_ko.ts b/gui/cppcheck_ko.ts index a7bae5f31f4..09f564e6380 100644 --- a/gui/cppcheck_ko.ts +++ b/gui/cppcheck_ko.ts @@ -5,21 +5,25 @@ About + About Cppcheck Cppcheck 정보 + Version %1 버전 %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - 정적 C/C++ 코드 분석 도구. + This program is licensed under the terms of the GNU General Public License version 3 이 프로그램은 GNU General Public License version 3을 @@ -27,17 +31,20 @@ of the GNU General Public License version 3 + Visit Cppcheck homepage at %1 Cppcheck 홈페이지(%1)를 방문해보세요 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. @@ -47,11 +54,13 @@ of the GNU General Public License version 3 ApplicationDialog + Add an application 응용 프로그램 추가 + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -77,21 +86,25 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: + &Name: 이름(&N): + &Executable: 실행 파일(&E): + &Parameters: 명령행 인자(&P): + Browse 찾기 @@ -136,16 +149,19 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: HelpDialog + Cppcheck GUI help + Contents + Index @@ -163,16 +179,19 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: LibraryAddFunctionDialog + Add function + Function name(s) + Number of arguments @@ -181,66 +200,79 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: LibraryDialog + Library Editor + Open + Save + Functions + Add + noreturn + False + True + Unknown + return value must be used + ignore function in leaks checking + Arguments + Edit 편집 @@ -257,21 +289,25 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: + Sort + Filter: + Comments + Save as @@ -304,11 +340,13 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: LibraryEditArgDialog + Edit argument + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -319,11 +357,13 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: + Not bool + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -334,78 +374,99 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: + Not null + Not uninit + String + Format string + Min size of buffer + + Type + + None + + argvalue + + mul + + strlen + + Arg + + Arg2 + and + Valid values @@ -418,355 +479,426 @@ Kate로 파일을 열고, 해당 행으로 이동하는 예제: + Checking for updates + Hide 숨기기 + &File 파일(&F) + &View 보기(&V) + &Toolbars 도구바(&T) + + Report + &Help 도움말(&H) + &Edit 편집(&E) + Standard 표준 도구 + Categories 분류 도구 + Filter 필터 도구 + &License... 저작권(&L)... + A&uthors... 제작자(&u)... + &About... 정보(&A)... + &Files... 파일(&F)... + Ctrl+F Ctrl+F + &Directory... 디렉토리(&D)... + Ctrl+D Ctrl+D + Ctrl+R Ctrl+R + &Stop 중지(&S) + Esc Esc + &Save results to file... 결과를 파일에 저장(&S)... + Ctrl+S Ctrl+S + &Quit 종료(&Q) + &Clear results 결과 지우기(&C) + &Preferences 설정(&P) + + Show style warnings 스타일 경고 표시 - + + + Show errors 애러 표시 + &Check all 전체 선택(&C) + &Uncheck all 전체 해제(&U) + Collapse &all 전체 접기(&A) + &Expand all 전체 펼치기(&E) + &Standard 표준 도구(&S) + Standard items 표준 아이템 + &Contents 내용(&C) + Open the help contents 도움말을 엽니다 + F1 F1 + Toolbar 도구바 + &Categories 분류 도구(&C) + Error categories 에러 종류 + &Open XML... XML 열기(&O)... + Open P&roject File... 프로젝트 파일 열기(&R)... + &New Project File... 새 프로젝트 파일(&N)... + &Log View 로그 보기(&L) + Log View 로그 보기 + C&lose Project File 프로젝트 파일 닫기(&L) + &Edit Project File... 프로젝트 파일 편집(&E)... + &Statistics 통계 보기(&S) - + + + Show warnings 경고 표시 + + Show performance warnings 성능 경고 표시 + Show &hidden 숨기기 보기(&H) + Compliance report... + Normal + Autosar + EULA... + Thread Details + Show thread details - - + + Information 정보 + Show information messages 정보 표시 + Show portability warnings 이식성 경고 표시 + &Filter 필터 도구(&F) + Filter results 필터링 결과 + Windows 32-bit ANSI Windows 32-bit ANSI + Windows 32-bit Unicode Windows 32-bit Unicode + Unix 32-bit Unix 32-bit + Unix 64-bit Unix 64-bit + Windows 64-bit Windows 64-bit - - + + Quick Filter: 빠른 필터: - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -775,12 +907,17 @@ This is probably because the settings were changed between the Cppcheck versions Cppcheck 버전간 설정 방법 차이때문인 것으로 보입니다. 편집기 설정을 검사(및 수정)해주세요, 그렇지 않으면 편집기가 제대로 시작하지 않습니다. - + + None of the selected files is part of the project, nothing to analyze. + + + + You must close the project file before selecting new files or directories! 새로운 파일이나 디렉토리를 선택하기 전에 프로젝트 파일을 닫으세요! - + Found project file: %1 Do you want to load this project file instead? @@ -789,210 +926,210 @@ Do you want to load this project file instead? 이 프로젝트 파일을 불러오겠습니까? - - + + XML files (*.xml) XML 파일 (*.xml) - + Open the report file 보고서 파일 열기 - + License 저작권 - + Authors 제작자 - + Save the report file 보고서 파일 저장 - + Text files (*.txt) 텍스트 파일 (*.txt) - + CSV files (*.csv) CSV 파일 (*.csv) - + Project files (*.cppcheck);;All files(*.*) 프로젝트 파일 (*.cppcheck);;모든 파일(*.*) - + Select Project File 프로젝트 파일 선택 - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information - - - - + + + + Project: 프로젝트: - + Duplicate define - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + About - + To check the project using addons, you need a build directory. - + Select Project Filename 프로젝트 파일이름 선택 - + No project file loaded 프로젝트 파일 불러오기 실패 - + The project file %1 @@ -1015,96 +1152,102 @@ Do you want to remove the file from the recently used projects -list? + C++ standard - - - - + + + + Error - + File not found - + Bad XML - + Missing attribute - + Bad attribute value - + Failed to load the selected library '%1'. %2 - + Unsupported format - + The library '%1' contains unknown elements: %2 - + Duplicate platform type - + Platform type redefined + &Print... + Print the Current Report + Print Pre&view... + Open a Print Preview Dialog for the Current Results + Open library editor - + Unknown element - + Select configuration @@ -1127,67 +1270,74 @@ Options: - + Build dir '%1' does not exist, create it? + + Analyze files + + Analyze directory + &Reanalyze modified files + + Stop analysis - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + No suitable files found to analyze! - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1195,181 +1345,213 @@ Do you want to stop the analysis and exit Cppcheck? + A&nalyze + &C standard + Reanal&yze all files + Ctrl+Q + Style war&nings + E&rrors + Ctrl+Shift+O + Sh&ow Scratchpad... + Ctrl+Shift+N + &Warnings + Per&formance warnings + &Information + &Portability + Show Cppcheck results + Clang + Show Clang results + P&latforms + C++&11 + C&99 + &Posix + C&11 + &C89 + &C++03 + &Library Editor... + &Auto-detect language + &Enforce C++ + E&nforce C + C++14 C++14 - + Project files (*.cppcheck) + Reanalyze and check library + Check configuration (defines, includes) + C++17 C++17 + C++20 C++20 - + C/C++ Source - + Compile database - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1381,26 +1563,31 @@ Do you want to proceed? NewSuppressionDialog + New suppression + Error ID + File name + Line number + Symbol name @@ -1442,22 +1629,27 @@ Do you want to proceed? ProjectFile + Project File 프로젝트 파일 + Defines: Defines: + Paths: 경로: + + Add... 추가... @@ -1465,6 +1657,9 @@ Do you want to proceed? + + + Edit 편집 @@ -1473,356 +1668,433 @@ Do you want to proceed? + + + + Remove 제거 + Up 위로 + Down 아래로 + Suppressions + Add + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. + ... + Include Paths: + Paths and Defines + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> + Analyze all Visual Studio configurations + Root path: + Warning tags (separated by semicolon) + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) + Selected VS Configurations + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + Types and Functions + Libraries + Parser + Cppcheck (built in) + Check that each class has a safe public interface + Limit analysis + + Addons + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. + Y2038 + Thread safety + Coding standards + Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + Autosar + Bug hunting + + Browse... + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int + Platform + This is a workfolder that Cppcheck will use for various purposes. + Clang (experimental) + Check level + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) + Max recursion in template instantiation + Warning options + Filepaths in warnings will be relative to this path + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. + Exclude source files + Exclude folder... + Exclude file... + Enable inline suppressions Inline suppression 사용 + Misra C + 2012 + + 2023 + 2025 + MISRA rule texts + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Misra C++ + 2008 + Cert C++ + Safety profiles (defined in C++ core guidelines) + Bug hunting (Premium) + External tools + Import Project (Visual studio / compile database/ Borland C++ Builder 6) + Undefines: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 + + Analysis + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) + Max CTU depth @@ -2339,6 +2611,7 @@ Please check the application path and parameters are correct. ResultsView + Results 결과 @@ -2427,16 +2700,19 @@ To toggle what kind of errors are shown, open view menu. + Critical errors + Analysis Log + Warning Details @@ -2460,26 +2736,31 @@ To toggle what kind of errors are shown, open view menu. ScratchPad + Scratchpad + filename + Check 검사 + Copy or write some C/C++ code here: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": @@ -2488,16 +2769,19 @@ To toggle what kind of errors are shown, open view menu. Settings + Preferences 설정 + General 일반 + Number of threads: 쓰레드 수: @@ -2507,107 +2791,129 @@ To toggle what kind of errors are shown, open view menu. + Force checking all #ifdef configurations 모든 #ifdef 설정을 강제로 검사 + Show full path of files 파일의 전체 경로 표시 + Show "No errors found" message when no errors found 에러가 발견되지 않는 경우 "에러가 없습니다." 메시지 표시 + Enable inline suppressions Inline suppression 사용 + Check for updates + Add... 추가... + Remove 제거 + Applications 응용 프로그램 + + Edit... 편집... + Set as default 기본으로 지정 + Reports 보고서 + Save all errors when creating report 보고서 생성 시 모든 에러 저장 + Save full path to files in reports 보고서에 파일의 전체 경로 저장 + Language 언어 + Display error Id in column "Id" + Check for inconclusive errors also + Show internal warnings in log + Show statistics on check completion + Max count: + Addons + Python binary (leave this empty to use python in the PATH) @@ -2615,71 +2921,87 @@ To toggle what kind of errors are shown, open view menu. + + + ... + Clang + Clang path (leave empty to use system PATH) + Visual Studio headers + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> + MISRA addon + MISRA rule texts file + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Code Editor + Code Editor Style + Default Light Style + Default Dark Style + Custom + System Style @@ -2736,6 +3058,8 @@ To toggle what kind of errors are shown, open view menu. + + Statistics @@ -2743,93 +3067,111 @@ To toggle what kind of errors are shown, open view menu. + Project 프로젝트 + Project: 프로젝트: + Paths: 경로: + Include paths: Include 경로: + Defines: Defines: + Previous Scan 직전 검사 + Path Selected: 선택된 경로: + Number of Files Scanned: 검사된 파일 수: + Scan Duration: 검사 시간: + Errors: 에러: + Warnings: 경고: + Stylistic warnings: 스타일 경고: + Portability warnings: 이식성 경고: + Performance issues: 성능 경고: + Information messages: 정보 메시지: + Active checkers: + Checkers + Copy to Clipboard 클립보드에 복사 @@ -2956,6 +3298,7 @@ To toggle what kind of errors are shown, open view menu. + Pdf Export @@ -2966,11 +3309,13 @@ To toggle what kind of errors are shown, open view menu. + History + File: @@ -2986,6 +3331,7 @@ To toggle what kind of errors are shown, open view menu. + Undefines: @@ -2999,6 +3345,7 @@ To toggle what kind of errors are shown, open view menu. ThreadDetails + Thread Details diff --git a/gui/cppcheck_nl.ts b/gui/cppcheck_nl.ts index 0c390ff245c..3bab077e6e3 100644 --- a/gui/cppcheck_nl.ts +++ b/gui/cppcheck_nl.ts @@ -5,27 +5,32 @@ About + About Cppcheck Over Cppcheck + Version %1 Versie %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - Een tool voor statische C/C++ code analyse. + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. Copyright © 2007-2021 het cppcheck team. + This program is licensed under the terms of the GNU General Public License version 3 Dit programma is beschikbaar onder te termen @@ -33,11 +38,13 @@ van de GNU General Public License versie 3 + Visit Cppcheck homepage at %1 Bezoek de Cppcheck homepage op %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> @@ -47,11 +54,13 @@ van de GNU General Public License versie 3 ApplicationDialog + Add an application Voeg een nieuwe applicatie toe + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -77,21 +86,25 @@ Parameters: -l(lijn) (bestand) + &Name: &Naam: + &Executable: &Uitvoerbaar: + &Parameters: + Browse Bladeren @@ -138,16 +151,19 @@ Parameters: -l(lijn) (bestand) HelpDialog + Cppcheck GUI help + Contents + Index @@ -165,16 +181,19 @@ Parameters: -l(lijn) (bestand) LibraryAddFunctionDialog + Add function + Function name(s) + Number of arguments @@ -183,86 +202,103 @@ Parameters: -l(lijn) (bestand) LibraryDialog + Library Editor + Open + Save Opslaan + Save as + Functions + Sort + Add + Filter: + Comments + noreturn + False + True + Unknown + return value must be used + ignore function in leaks checking + Arguments + Edit Bewerk @@ -308,11 +344,13 @@ Parameters: -l(lijn) (bestand) LibraryEditArgDialog + Edit argument + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -323,11 +361,13 @@ Parameters: -l(lijn) (bestand) + Not bool + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -338,78 +378,99 @@ Parameters: -l(lijn) (bestand) + Not null + Not uninit + String + Format string + Min size of buffer + + Type + + None + + argvalue + + mul + + strlen + + Arg + + Arg2 + and + Valid values @@ -422,578 +483,694 @@ Parameters: -l(lijn) (bestand) + A&nalyze + Standard Standaard + &File &Bestand + &View &Weergave + &Toolbars &Werkbalken + C++ standard C++standaard + &C standard C standard C standaard + &Edit Be&werken + &License... &Licentie... + A&uthors... A&uteurs... + &About... &Over... + &Files... &Bestanden... + + Analyze files Check files Controleer bestanden + Ctrl+F Ctrl+F + &Directory... &Mappen... + + Analyze directory Check directory Controleer Map + Ctrl+D Ctrl+D + Ctrl+R Ctrl+R + &Stop &Stop + + Stop analysis Stop checking Stop controle + Esc Esc + &Save results to file... &Resultaten opslaan... + Ctrl+S Ctrl+S + &Quit &Afsluiten + &Clear results &Resultaten wissen + &Preferences &Voorkeuren - + + + Show errors Toon fouten - + + + Show warnings Toon waarschuwingen + + Show performance warnings Toon presentatie waarschuwingen + Show &hidden Toon &verborgen - - + + Information Informatie + Show information messages Toon informatie bericht + Show portability warnings Toon portabiliteit waarschuwingen + Show Cppcheck results + Clang + Show Clang results + &Filter &Filter + Filter results Filter resultaten + Windows 32-bit ANSI Windows 32-bit ANSI + Windows 32-bit Unicode + Unix 32-bit + Unix 64-bit + Windows 64-bit + &Print... + Print the Current Report + Print Pre&view... + Open a Print Preview Dialog for the Current Results + Open library editor + &Check all &Controleer alles + Checking for updates + Hide Verberg + + Report + Filter + &Reanalyze modified files &Recheck modified files + Reanal&yze all files + Ctrl+Q + Style war&nings + E&rrors + &Uncheck all Selecteer &niets + Collapse &all Alles Inkl&appen + &Expand all Alles &Uitklappen + &Standard &Standaard + Standard items Standaard items + Toolbar Werkbalk + &Categories &Categorieën + Error categories Foute Categorieën + &Open XML... + Open P&roject File... Open P&oject bestand... + Ctrl+Shift+O + Sh&ow Scratchpad... + &New Project File... &Nieuw Project Bestand... + Ctrl+Shift+N + &Log View &Log weergave + Log View Log weergave + C&lose Project File &Sluit Project Bestand + &Edit Project File... &Bewerk Project Bestand... + &Statistics &Statistieken + &Warnings + Per&formance warnings + &Information + &Portability + P&latforms + C++&11 + C&99 + &Posix + C&11 + &C89 + &C++03 + &Library Editor... + &Auto-detect language + &Enforce C++ + E&nforce C + C++14 + Reanalyze and check library + Check configuration (defines, includes) + C++17 + C++20 + Compliance report... + Normal + Autosar + EULA... + Thread Details + Show thread details + &Contents &Inhoud + Categories Categorieën + + Show style warnings Toon stijl waarschuwingen + Open the help contents Open de help inhoud + F1 + &Help &Help - - + + Quick Filter: Snel Filter: - + Select configuration - + Found project file: %1 Do you want to load this project file instead? @@ -1001,91 +1178,91 @@ Do you want to load this project file instead? Wilt u dit project laden in plaats van? - + File not found - + Bad XML - + Missing attribute - + Bad attribute value - + Duplicate define - + Failed to load the selected library '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License Licentie - + Authors Auteurs - + Save the report file Rapport opslaan - - + + XML files (*.xml) XML bestanden (*.xml) - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -1094,116 +1271,121 @@ This is probably because the settings were changed between the Cppcheck versions Dit is waarschijnlijk omdat de instellingen zijn gewijzigd tussen de versies van cppcheck. Controleer (en maak) de bewerker instellingen, anders zal de bewerker niet correct starten. - + You must close the project file before selecting new files or directories! Je moet project bestanden sluiten voordat je nieuwe bestanden of mappen selekteerd! - + The library '%1' contains unknown elements: %2 - + Unsupported format - + Duplicate platform type - + Platform type redefined - + Unknown element - - - - + + + + Error - + Open the report file Open het rapport bestand - + Text files (*.txt) Tekst bestanden (*.txt) - + CSV files (*.csv) CSV bestanden (*.csv) - + Project files (*.cppcheck);;All files(*.*) Project bestanden (*.cppcheck);;Alle bestanden(*.*) - + Select Project File Selecteer project bestand - - - - + + + + Project: Project: - + + None of the selected files is part of the project, nothing to analyze. + + + + No suitable files found to analyze! - + C/C++ Source - + Compile database - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1211,76 +1393,76 @@ Do you want to proceed? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + Build dir '%1' does not exist, create it? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Project files (*.cppcheck) - + Select Project Filename Selecteer project bestandsnaam - + No project file loaded Geen project bestand geladen - + The project file %1 @@ -1296,67 +1478,67 @@ Kan niet worden gevonden! Wilt u het bestand van de onlangs gebruikte project verwijderen -lijst? - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1400,26 +1582,31 @@ Options: NewSuppressionDialog + New suppression + Error ID + File name + Line number + Symbol name @@ -1441,111 +1628,135 @@ Options: ProjectFile + Project File Project Bestand + Paths and Defines + Import Project (Visual studio / compile database/ Borland C++ Builder 6) Import Project (Visual studio / compile database) + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int Defines must be separated by a semicolon ';' + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. + Exclude source files + Exclude folder... + Exclude file... + Misra C + 2012 + + 2023 + MISRA rule texts + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + ... + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> + + Browse... + Analyze all Visual Studio configurations + Selected VS Configurations + Paths: Paden: + + Add... Toevoegen... @@ -1553,6 +1764,9 @@ Options: + + + Edit Bewerk @@ -1561,269 +1775,327 @@ Options: + + + + Remove Verwijder + Undefines: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 + Include Paths: + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + Types and Functions + + Analysis + This is a workfolder that Cppcheck will use for various purposes. + Parser + Cppcheck (built in) + Check level + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + Check that each class has a safe public interface + Limit analysis + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) + Max CTU depth + Enable inline suppressions Schakel inline suppressies in + 2025 + Misra C++ + 2008 + Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + Autosar + Safety profiles (defined in C++ core guidelines) + Bug hunting + External tools + Up Omhoog + Down Omlaag + Platform + Clang (experimental) + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) + Max recursion in template instantiation + Warning options + Root path: + Filepaths in warnings will be relative to this path + Warning tags (separated by semicolon) + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) + Libraries + Suppressions + Add + + Addons + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. + Y2038 + Thread safety + Coding standards + Cert C++ + Bug hunting (Premium) + Defines: Omschrijft: @@ -2445,21 +2717,25 @@ Gebruik het uitzicht menu om te selecteren welke fouten getoond worden. + Results Resultaten + Critical errors + Analysis Log + Warning Details @@ -2468,26 +2744,31 @@ Gebruik het uitzicht menu om te selecteren welke fouten getoond worden.ScratchPad + Scratchpad Scratchpad + Copy or write some C/C++ code here: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": + filename bestandsnaam + Check Controleer @@ -2496,21 +2777,25 @@ Gebruik het uitzicht menu om te selecteren welke fouten getoond worden.Settings + Preferences Instellingen + General Algemeen + Add... Toevoegen... + Number of threads: Aantal threads: @@ -2520,57 +2805,68 @@ Gebruik het uitzicht menu om te selecteren welke fouten getoond worden. + Force checking all #ifdef configurations Check all #ifdef configurations Controleer alle #ifdef combinaties + Show full path of files Toon het volledige pad van bestanden + Show "No errors found" message when no errors found Toon "Geen fouten gevonden" indien geen fouten gevonden werden + Display error Id in column "Id" Toon fout ld in kolom "Id" + Enable inline suppressions Schakel inline suppressies in + Check for inconclusive errors also + Show statistics on check completion + Check for updates + Show internal warnings in log + Addons + Python binary (leave this empty to use python in the PATH) @@ -2578,117 +2874,143 @@ Gebruik het uitzicht menu om te selecteren welke fouten getoond worden. + + + ... + MISRA addon + MISRA rule texts file + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Clang + Clang path (leave empty to use system PATH) + Visual Studio headers + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> + Code Editor + Code Editor Style + System Style + Default Light Style + Default Dark Style + Custom + Remove Verwijder + Max count: + Applications Applicaties + + Edit... Bewerk... + Set as default Instellen als standaard + Reports Rapporten + Save all errors when creating report Alle fouten opslaan + Save full path to files in reports Volledig pad opslaan + Language Taal @@ -2741,6 +3063,8 @@ Gebruik het uitzicht menu om te selecteren welke fouten getoond worden. + + Statistics @@ -2748,113 +3072,135 @@ Gebruik het uitzicht menu om te selecteren welke fouten getoond worden. + Project Project + Project: Project: + Paths: Paden: + Include paths: Bevat paden: + Defines: Omschrijft: + Undefines: + Previous Scan Vorige scan + Path Selected: Pad Geselekteerd: + Number of Files Scanned: Aantal bestanden gescanned: + Scan Duration: Scan tijd: + Errors: Fouten: + Warnings: Waarschuwingen: + Stylistic warnings: Stilistisch waarschuwingen: + Portability warnings: Portabiliteit waarschuwingen: + Performance issues: Presentatie problemen: + Information messages: Informatie bericht: + Active checkers: + Checkers + History + File: + Copy to Clipboard Kopieer naar Clipbord + Pdf Export @@ -3004,6 +3350,7 @@ Gebruik het uitzicht menu om te selecteren welke fouten getoond worden.ThreadDetails + Thread Details diff --git a/gui/cppcheck_ru.ts b/gui/cppcheck_ru.ts index 2eec05aa1b6..d9a1a27c0a2 100644 --- a/gui/cppcheck_ru.ts +++ b/gui/cppcheck_ru.ts @@ -5,27 +5,32 @@ About + About Cppcheck О Cppcheck + Version %1 Версия %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - программа для статического анализа кода на языках С/С++. + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. Copyright © 2007-2021 Cppcheck team. + This program is licensed under the terms of the GNU General Public License version 3 Эта программа распространяется на @@ -33,11 +38,13 @@ of the GNU General Public License version 3 + Visit Cppcheck homepage at %1 Посетите домашнюю страницу: %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> @@ -47,11 +54,13 @@ of the GNU General Public License version 3 ApplicationDialog + Add an application Добавление приложения + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -77,21 +86,25 @@ Parameters: -l(line) (file) + &Name: &Название: + &Executable: &Программа: + &Parameters: &Параметры: + Browse Просмотреть @@ -138,16 +151,19 @@ Parameters: -l(line) (file) HelpDialog + Cppcheck GUI help + Contents + Index @@ -165,16 +181,19 @@ Parameters: -l(line) (file) LibraryAddFunctionDialog + Add function Добавить функцию + Function name(s) Имя(имена) функции + Number of arguments Количество аргументов @@ -183,86 +202,103 @@ Parameters: -l(line) (file) LibraryDialog + Library Editor Редактор библиотек + Open Открыть + Save Сохранить + Save as Сохранить как + Functions Функции + Sort Сортировать + Add Добавить + Filter: Фильтр: + Comments Комментарии + noreturn + False + True + Unknown + return value must be used должно быть использовано возвращаемое значение + ignore function in leaks checking пропускать функцию при проверке на утечки + Arguments Аргументы + Edit Изменить @@ -308,11 +344,13 @@ Parameters: -l(line) (file) LibraryEditArgDialog + Edit argument Редактировать аргумент + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -323,11 +361,13 @@ Parameters: -l(line) (file) + Not bool + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -338,78 +378,99 @@ Parameters: -l(line) (file) + Not null + Not uninit + String + Format string + Min size of buffer + + Type + + None + + argvalue + + mul + + strlen + + Arg + + Arg2 + and + Valid values @@ -422,578 +483,699 @@ Parameters: -l(line) (file) + A&nalyze Анализ + Standard Стандартные + &File &Файл + &View &Вид + &Toolbars &Панель инструментов + C++ standard Стандарт C++ + &C standard C standard &Стандарт C + &Edit &Правка + &License... &Лицензия... + A&uthors... &Авторы... + &About... &О программе... + &Files... &Файлы... + + Analyze files Check files Проверить файлы + Ctrl+F Ctrl+F + &Directory... &Каталог... + + Analyze directory Check directory Проверка каталога + Ctrl+D Ctrl+D + Ctrl+R Ctrl+R + &Stop Остановить + + Stop analysis Stop checking Остановить проверку + Esc Esc + &Save results to file... Сохранить отчёт в файл... + Ctrl+S Ctrl+S + &Quit Выход + &Clear results Очистить отчёт + &Preferences Параметры - + + + Show errors Показать ошибки - + + + Show warnings Показать предупреждения + + Show performance warnings Показать предупреждения производительности + Show &hidden Показать скрытые - - + + Information Информационные сообщения + Show information messages Показать информационные сообщения + Show portability warnings Показать предупреждения переносимости + Show Cppcheck results Просмотр результатов Cppcheck + Clang Clang + Show Clang results Просмотр результатов Clang + &Filter Фильтр + Filter results Результаты фильтрации + Windows 32-bit ANSI Windows 32-bit ANSI + Windows 32-bit Unicode Windows 32-bit Unicode + Unix 32-bit Unix 32-bit + Unix 64-bit Unix 64-bit + Windows 64-bit Windows 64-bit + &Print... Печать... + Print the Current Report Напечатать текущий отчет + Print Pre&view... Предварительный просмотр... + Open a Print Preview Dialog for the Current Results Открыть диалог печати для текущих результатов + Open library editor Открыть редактор библиотек + &Check all Отметить все + Checking for updates + Hide Скрыть + + Report + Filter Фильтр + &Reanalyze modified files &Recheck modified files Заново проверить измененные файлы + Reanal&yze all files Заново проверить все файлы + Ctrl+Q + Style war&nings Стилистические предупреждения + E&rrors Ошибки + &Uncheck all Сбросить все + Collapse &all Свернуть все + &Expand all Развернуть все + &Standard Стандартные + Standard items Стандартные элементы + Toolbar Панель инструментов + &Categories Категории + Error categories Категории ошибок + &Open XML... &Открыть XML... + Open P&roject File... Открыть файл &проекта... + Ctrl+Shift+O + Sh&ow Scratchpad... Показать Блокнот + &New Project File... &Новый файл проекта... + Ctrl+Shift+N + &Log View Посмотреть &лог + Log View Посмотреть лог + C&lose Project File &Закрыть файл проекта + &Edit Project File... &Изменить файл проекта... + &Statistics &Статистика + &Warnings Предупреждения + Per&formance warnings Предупреждения производительности + &Information Информационные предупреждения + &Portability Предупреждения переносимости + P&latforms Платформы + C++&11 + C&99 + &Posix + C&11 + &C89 + &C++03 + &Library Editor... Редактор библиотеки + &Auto-detect language Автоматическое определение языка + &Enforce C++ Принудительно C++ + E&nforce C Принудительно C + C++14 C++14 + Reanalyze and check library Повторный анализ библиотеки + Check configuration (defines, includes) Проверить конфигурацию (defines, includes) + C++17 C++17 + C++20 C++20 + Compliance report... + Normal + Autosar + EULA... + Thread Details + Show thread details + &Contents Помощь + Categories Категории + + Show style warnings Показать стилистические предупреждения + Open the help contents Открыть помощь + F1 F1 + &Help Помощь - - + + Quick Filter: Быстрый фильтр: - + + None of the selected files is part of the project, nothing to analyze. + + + + Select configuration Выбор конфигурации - + Found project file: %1 Do you want to load this project file instead? @@ -1002,97 +1184,97 @@ Do you want to load this project file instead? Вы хотите загрузить этот проект? - + File not found Файл не найден - + Bad XML Некорректный XML - + Missing attribute Пропущен атрибут - + Bad attribute value Некорректное значение атрибута - + Unsupported format Неподдерживаемый формат - + Duplicate define - + Failed to load the selected library '%1'. %2 Не удалось загрузить выбранную библиотеку '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License Лицензия - + Authors Авторы - + Save the report file Сохранить файл с отчетом - - + + XML files (*.xml) XML-файлы (*.xml) - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -1101,37 +1283,37 @@ This is probably because the settings were changed between the Cppcheck versions Возможно, это связано с изменениями в версии программы. Пожалуйста, проверьте (и исправьте) настройки приложения. - + You must close the project file before selecting new files or directories! Вы должны закрыть проект перед выбором новых файлов или каталогов! - + The library '%1' contains unknown elements: %2 Библиотека '%1' содержит неизвестные элементы: %2 - + Duplicate platform type Дубликат типа платформы - + Platform type redefined Переобъявление типа платформы - + Unknown element Неизвестный элемент - - - - + + + + Error Ошибка @@ -1140,50 +1322,50 @@ This is probably because the settings were changed between the Cppcheck versions Невозможно загрузить %1. Cppcheck установлен некорректно. Вы можете использовать --data-dir=<directory> в командной строке для указания расположения файлов конфигурации. Обратите внимание, что --data-dir предназначен для использования сценариями установки. При включении данной опции, графический интерфейс пользователя не запускается. - + Open the report file Открыть файл с отчетом - + Text files (*.txt) Текстовые файлы (*.txt) - + CSV files (*.csv) CSV файлы(*.csv) - + Project files (*.cppcheck);;All files(*.*) Файлы проекта (*.cppcheck);;Все файлы(*.*) - + Select Project File Выберите файл проекта - - - - + + + + Project: Проект: - + No suitable files found to analyze! Не найдено подходящих файлов для анализа - + C/C++ Source Исходный код C/C++ - + Compile database @@ -1196,22 +1378,22 @@ This is probably because the settings were changed between the Cppcheck versions Borland C++ Builder 6 - + Select files to analyze Выбор файлов для анализа - + Select directory to analyze Выбор каталога для анализа - + Select the configuration that will be analyzed Выбор используемой конфигурации - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? @@ -1220,7 +1402,7 @@ Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1231,7 +1413,7 @@ Do you want to proceed? Вы хотите продолжить? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1240,104 +1422,104 @@ Do you want to stop the analysis and exit Cppcheck? Вы хотите остановить анализ и выйти из Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML файлы (*.xml);;Текстовые файлы (*.txt);;CSV файлы (*.csv) - + Build dir '%1' does not exist, create it? Директория для сборки '%1' не существует, создать? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1346,22 +1528,22 @@ Analysis is stopped. Невозможно импортировать '%1', анализ остановлен - + Project files (*.cppcheck) Файлы проекта (*.cppcheck) - + Select Project Filename Выберите имя файла для проекта - + No project file loaded Файл с проектом не загружен - + The project file %1 @@ -1377,12 +1559,12 @@ Do you want to remove the file from the recently used projects -list? Хотите удалить его из списка проектов? - + Install - + New version available: %1. %2 @@ -1439,26 +1621,31 @@ Options: NewSuppressionDialog + New suppression Новое подавление + Error ID ID + File name Имя файла + Line number Номер строки + Symbol name Имя символа @@ -1500,73 +1687,87 @@ Options: ProjectFile + Project File Файл проекта + Paths and Defines Каталоги и определения + Import Project (Visual studio / compile database/ Borland C++ Builder 6) Import Project (Visual studio / compile database) Импорт проекта (Visual studio / compile database/ Borland C++ Builder 6) + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int Defines must be separated by a semicolon ';' Defines должны быть разделены точкой с запятой ';' + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. Положите свои .cfg-файлы в один каталог с файлом проекта. Вы увидите их сверху. + Clang (experimental) + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) + Max recursion in template instantiation + Filepaths in warnings will be relative to this path + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. + Exclude source files + Exclude folder... + Exclude file... @@ -1576,48 +1777,59 @@ Options: + MISRA rule texts Файл с текстами правил MISRA + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> <html><head/><body><p>Скопируйте текст из Appendix A &quot;Summary of guidelines&quot; из фала правил MISRA C 2012 pdf в текстовый файл.</p></body></html> + ... ... + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> <html><head/><body><p>Выберите:</p><p> * Анализ всех конфигураций Debug и Release</p><p> * Анализ только первой подходящей конфигурации Debug</p><p><br/></p></body></html> + + Browse... Обзор... + Analyze all Visual Studio configurations Анализировать все конфигурации Visual Studio + Selected VS Configurations + Paths: Пути: + + Add... Добавить... @@ -1625,6 +1837,9 @@ Options: + + + Edit Изменить @@ -1633,260 +1848,317 @@ Options: + + + + Remove Удалить + Undefines: Удаленные макроопределения: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 Удаленные макроопределения должны быть разделены точкой с запятой, например: UNDEF1;UNDEF2;UNDEF3 + Include Paths: Пути заголовочных файлов: + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + Types and Functions + + Analysis Анализ + This is a workfolder that Cppcheck will use for various purposes. + Parser + Cppcheck (built in) + Check level + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + Check that each class has a safe public interface + Limit analysis + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) Проверить код в неиспользуемых шаблонах + Max CTU depth Максимальная глубина CTU + Enable inline suppressions Включить inline-подавление ошибок + 2025 + Misra C++ + 2008 + Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + Autosar + Safety profiles (defined in C++ core guidelines) + Bug hunting + External tools Внешние инструменты + Up Вверх + Down Вниз + Platform Платформа + Warning options Опции предупреждений + Root path: Корневой каталог: + Warning tags (separated by semicolon) Теги предупреждений (через ';') + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) Каталог сборки Cppcheck + Libraries Библиотеки + Suppressions Подавления + Add Добавить + + Addons Дополнения + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. + Y2038 + Thread safety + Coding standards Стандарты кодирования + Misra C + 2012 + + 2023 + Cert C++ + Bug hunting (Premium) + Defines: Объявленные макроопределения: @@ -2526,21 +2798,25 @@ To toggle what kind of errors are shown, open view menu. + Results Результаты + Critical errors + Analysis Log Лог анализа + Warning Details Детали предупреждения @@ -2549,26 +2825,31 @@ To toggle what kind of errors are shown, open view menu. ScratchPad + Scratchpad Блокнот + Copy or write some C/C++ code here: Исходный код C/C++: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": При необходимости введите имя файла и нажмите "Проверить": + filename имя файла + Check Проверить @@ -2577,21 +2858,25 @@ To toggle what kind of errors are shown, open view menu. Settings + Preferences Параметры + General Общие + Add... Добавить... + Number of threads: Количество потоков исполнения: @@ -2601,57 +2886,68 @@ To toggle what kind of errors are shown, open view menu. + Force checking all #ifdef configurations Check all #ifdef configurations Проверять все варианты #ifdef конфигураций + Show full path of files Показывать полные пути к файлам + Show "No errors found" message when no errors found Показывать сообщение, если ошибок не найдено + Display error Id in column "Id" Отображать номер ошибки в колонке "id" + Enable inline suppressions Включить inline-подавление ошибок + Check for inconclusive errors also Показывать также спорные ошибки + Show statistics on check completion Показывать статистику после завершения проверки + Check for updates + Show internal warnings in log Показывать внутренние предупреждения в логе + Addons Дополнения + Python binary (leave this empty to use python in the PATH) Python (оставьте пустым для использования python из PATH) @@ -2659,117 +2955,143 @@ To toggle what kind of errors are shown, open view menu. + + + ... ... + MISRA addon Дополнение MISRA + MISRA rule texts file Файл с текстами правил MISRA: + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> <html><head/><body><p>Скопируйте текст из Appendix A &quot;Summary of guidelines&quot; из фала правил MISRA C 2012 pdf в текстовый файл.</p></body></html> + Clang Clang + Clang path (leave empty to use system PATH) Clang (оставьте пустым для использования clang из PATH) + Visual Studio headers Заголовочные файлы Visual Studio + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> <html><head/><body><p>Путь до заголовочных файлов Visual Studio headers, разделенных символом ';'.</p><p>Вы можете открыть командную строку Visual Studio, ввести &quot;SET INCLUDE&quot; и скопировать пути.</p></body></html> + Code Editor Редактор + Code Editor Style Оформление + System Style + Default Light Style + Default Dark Style + Custom + Remove Удалить + Max count: + Applications Приложения + + Edit... Изменить... + Set as default Установить по умолчанию + Reports Отчёты + Save all errors when creating report Сохранять все ошибки при создании отчёта + Save full path to files in reports Сохранять полные пути к файлам в отчётах + Language Язык @@ -2826,6 +3148,8 @@ To toggle what kind of errors are shown, open view menu. + + Statistics @@ -2833,113 +3157,135 @@ To toggle what kind of errors are shown, open view menu. + Project Проект + Project: Проект: + Paths: Пути: + Include paths: Включенные пути: + Defines: Объявленные макроопределения: + Undefines: Удаленные макроопределения: + Previous Scan Последнее сканирование + Path Selected: Выбранный путь: + Number of Files Scanned: Количество просканированных файлов: + Scan Duration: Продолжительность сканирования: + Errors: Ошибки: + Warnings: Предупреждения: + Stylistic warnings: Стилистические предупреждения: + Portability warnings: Предупреждения переносимости: + Performance issues: Проблемы с производительностью: + Information messages: Информационные сообщения: + Active checkers: + Checkers + History История + File: Файл: + Copy to Clipboard Скопировать в буфер обмена + Pdf Export Экспорт PDF @@ -3089,6 +3435,7 @@ To toggle what kind of errors are shown, open view menu. ThreadDetails + Thread Details diff --git a/gui/cppcheck_sr.ts b/gui/cppcheck_sr.ts index 9579d88b695..81da0d77edf 100644 --- a/gui/cppcheck_sr.ts +++ b/gui/cppcheck_sr.ts @@ -5,27 +5,32 @@ About + About Cppcheck About Cppcheck + Version %1 Version %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - A tool for static C/C++ code analysis. + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. + This program is licensed under the terms of the GNU General Public License version 3 This program is licensed under the terms @@ -33,11 +38,13 @@ of the GNU General Public License version 3 + Visit Cppcheck homepage at %1 Visit Cppcheck homepage at %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> @@ -47,11 +54,13 @@ of the GNU General Public License version 3 ApplicationDialog + Add an application Add a new application + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -67,21 +76,25 @@ Parameters: -l(line) (file) + &Name: + &Executable: + &Parameters: + Browse Browse @@ -126,16 +139,19 @@ Parameters: -l(line) (file) HelpDialog + Cppcheck GUI help + Contents + Index @@ -153,16 +169,19 @@ Parameters: -l(line) (file) LibraryAddFunctionDialog + Add function + Function name(s) + Number of arguments @@ -171,86 +190,103 @@ Parameters: -l(line) (file) LibraryDialog + Library Editor + Open + Save + Save as + Functions + Sort + Add + Filter: + Comments + noreturn + False + True + Unknown + return value must be used + ignore function in leaks checking + Arguments + Edit @@ -296,11 +332,13 @@ Parameters: -l(line) (file) LibraryEditArgDialog + Edit argument + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -311,11 +349,13 @@ Parameters: -l(line) (file) + Not bool + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -326,78 +366,99 @@ Parameters: -l(line) (file) + Not null + Not uninit + String + Format string + Min size of buffer + + Type + + None + + argvalue + + mul + + strlen + + Arg + + Arg2 + and + Valid values @@ -410,785 +471,906 @@ Parameters: -l(line) (file) + A&nalyze + Standard Standard + &File &File + &View &View + &Toolbars + C++ standard + &C standard C standard + &Edit &Edit + &License... &License... + A&uthors... A&uthors... + &About... &About... + &Files... &Files... + + Analyze files Check files + Ctrl+F Ctrl+F + &Directory... &Directory... + + Analyze directory Check directory + Ctrl+D Ctrl+D + Ctrl+R Ctrl+R + &Stop &Stop + + Stop analysis Stop checking + Esc Esc + &Save results to file... &Save results to file... + Ctrl+S Ctrl+S + &Quit &Quit + &Clear results &Clear results + &Preferences &Preferences - + + + Show errors - + + + Show warnings + + Show performance warnings + Show &hidden - - + + Information + Show information messages + Show portability warnings + Show Cppcheck results + Clang + Show Clang results + &Filter + Filter results + Windows 32-bit ANSI Windows 32-bit ANSI + Windows 32-bit Unicode Windows 32-bit Unicode + Unix 32-bit Unix 32-bit + Unix 64-bit Unix 64-bit + Windows 64-bit Windows 64-bit + &Print... + Print the Current Report + Print Pre&view... + Open a Print Preview Dialog for the Current Results + Open library editor + &Check all &Check all + Checking for updates + Hide + + Report + Filter + &Reanalyze modified files &Recheck modified files + Reanal&yze all files + Ctrl+Q + Style war&nings + E&rrors + &Uncheck all &Uncheck all + Collapse &all Collapse &all + &Expand all &Expand all + &Standard + Standard items + Toolbar + &Categories + Error categories + &Open XML... + Open P&roject File... + Ctrl+Shift+O + Sh&ow Scratchpad... + &New Project File... + Ctrl+Shift+N + &Log View + Log View + C&lose Project File + &Edit Project File... + &Statistics + &Warnings + Per&formance warnings + &Information + &Portability + P&latforms + C++&11 + C&99 + &Posix + C&11 + &C89 + &C++03 + &Library Editor... + &Auto-detect language + &Enforce C++ + E&nforce C + C++14 C++14 + Reanalyze and check library + Check configuration (defines, includes) + C++17 C++17 + C++20 C++20 + Compliance report... + Normal + Autosar + EULA... + Thread Details + Show thread details + &Contents + Categories + + Show style warnings + Open the help contents + F1 F1 + &Help &Help - - + + Quick Filter: - + Select configuration - + Found project file: %1 Do you want to load this project file instead? - + File not found - + Bad XML - + Missing attribute - + Bad attribute value - + Duplicate define - + Failed to load the selected library '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License License - + Authors Authors - + Save the report file Save the report file - - + + XML files (*.xml) XML files (*.xml) - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. - + You must close the project file before selecting new files or directories! - + The library '%1' contains unknown elements: %2 - + Unsupported format - + Duplicate platform type - + Platform type redefined - + Unknown element - - - - + + + + Error - + Open the report file - + Text files (*.txt) Text files (*.txt) - + CSV files (*.csv) - + Project files (*.cppcheck);;All files(*.*) - + Select Project File - - - - + + + + Project: - + + None of the selected files is part of the project, nothing to analyze. + + + + No suitable files found to analyze! - + C/C++ Source - + Compile database - + Select files to analyze - + Select directory to analyze - + Select the configuration that will be analyzed - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1196,76 +1378,76 @@ Do you want to proceed? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) - + Build dir '%1' does not exist, create it? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Project files (*.cppcheck) - + Select Project Filename - + No project file loaded - + The project file %1 @@ -1276,67 +1458,67 @@ Do you want to remove the file from the recently used projects -list? - + Install - + New version available: %1. %2 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1380,26 +1562,31 @@ Options: NewSuppressionDialog + New suppression + Error ID + File name + Line number + Symbol name @@ -1441,75 +1628,91 @@ Options: ProjectFile + Project File + Paths and Defines + Import Project (Visual studio / compile database/ Borland C++ Builder 6) Import Project (Visual studio / compile database) + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int Defines must be separated by a semicolon ';' + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. + MISRA rule texts + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + ... + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> + + Browse... + Analyze all Visual Studio configurations + Selected VS Configurations + Paths: + + Add... @@ -1517,6 +1720,9 @@ Options: + + + Edit @@ -1525,305 +1731,371 @@ Options: + + + + Remove + Undefines: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 + Include Paths: + Up + Down + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + Platform + + Analysis + This is a workfolder that Cppcheck will use for various purposes. + Clang (experimental) + Check level + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) + Max CTU depth + Max recursion in template instantiation + Warning options + Root path: + Filepaths in warnings will be relative to this path + Warning tags (separated by semicolon) + Enable inline suppressions + 2025 + Misra C++ + 2008 + Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + Autosar + Safety profiles (defined in C++ core guidelines) + Bug hunting + External tools + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) + Types and Functions + Libraries + Parser + Cppcheck (built in) + Check that each class has a safe public interface + Limit analysis + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. + Exclude source files + Exclude folder... + Exclude file... + Suppressions + Add + + Addons + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. + Y2038 + Thread safety + Coding standards + Misra C + 2012 + + 2023 + Cert C++ + Bug hunting (Premium) + Defines: @@ -2427,21 +2699,25 @@ To toggle what kind of errors are shown, open view menu. + Results Results + Critical errors + Analysis Log + Warning Details @@ -2450,26 +2726,31 @@ To toggle what kind of errors are shown, open view menu. ScratchPad + Scratchpad + Copy or write some C/C++ code here: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": + filename + Check @@ -2478,76 +2759,91 @@ To toggle what kind of errors are shown, open view menu. Settings + Preferences Preferences + General General + Add... + Number of threads: Number of threads: + Force checking all #ifdef configurations Check all #ifdef configurations + Show full path of files Show full path of files + Show "No errors found" message when no errors found Show "No errors found" message when no errors found + Display error Id in column "Id" + Enable inline suppressions + Check for inconclusive errors also + Show statistics on check completion + Check for updates + Show internal warnings in log + Addons + Python binary (leave this empty to use python in the PATH) @@ -2555,117 +2851,143 @@ To toggle what kind of errors are shown, open view menu. + + + ... + MISRA addon + MISRA rule texts file + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Clang + Clang path (leave empty to use system PATH) + Visual Studio headers + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> + Code Editor + Code Editor Style + System Style + Default Light Style + Default Dark Style + Custom + Remove + Max count: + Applications Applications + + Edit... + Set as default + Reports Reports + Save all errors when creating report Save all errors when creating report + Save full path to files in reports Save full path to files in reports + Language @@ -2718,6 +3040,8 @@ To toggle what kind of errors are shown, open view menu. + + Statistics @@ -2725,113 +3049,135 @@ To toggle what kind of errors are shown, open view menu. + Project + Project: + Paths: + Include paths: + Defines: + Undefines: + Previous Scan + Path Selected: + Number of Files Scanned: + Scan Duration: + Errors: + Warnings: + Stylistic warnings: + Portability warnings: + Performance issues: + Information messages: + Active checkers: + Checkers + History + File: + Copy to Clipboard + Pdf Export @@ -2981,6 +3327,7 @@ To toggle what kind of errors are shown, open view menu. ThreadDetails + Thread Details diff --git a/gui/cppcheck_sv.ts b/gui/cppcheck_sv.ts index 79bc48d06fc..80726023e09 100644 --- a/gui/cppcheck_sv.ts +++ b/gui/cppcheck_sv.ts @@ -5,27 +5,32 @@ About + About Cppcheck Om Cppcheck + Version %1 Version %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - Ett verktyg för statisk analys av C/C++ kod. + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. Copyright © 2007-2021 Cppcheck team. + This program is licensed under the terms of the GNU General Public License version 3 This program is licensed under the terms @@ -33,11 +38,13 @@ of the GNU General Public License version 3 + Visit Cppcheck homepage at %1 Hemsida: %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> @@ -47,11 +54,13 @@ of the GNU General Public License version 3 ApplicationDialog + Add an application Lägg till program + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -77,21 +86,25 @@ Parametrar: -l(line) (file) + &Name: Namn: + &Executable: Körbar fil: + &Parameters: Parametrar: + Browse Bläddra @@ -138,16 +151,19 @@ Parametrar: -l(line) (file) HelpDialog + Cppcheck GUI help + Contents + Index @@ -165,16 +181,19 @@ Parametrar: -l(line) (file) LibraryAddFunctionDialog + Add function Lägg till funktion + Function name(s) Funktion namn + Number of arguments Antal argument @@ -183,86 +202,103 @@ Parametrar: -l(line) (file) LibraryDialog + Library Editor Library Editor + Open Öppna + Save Spara + Save as Spara som + Functions Funktioner + Sort Sortera + Add Lägg till + Filter: Filter: + Comments Kommentar + noreturn noreturn + False False + True True + Unknown Vet ej + return value must be used retur värde måste användas + ignore function in leaks checking Ignorera funktionen när cppcheck letar efter läckor + Arguments Argument + Edit Redigera @@ -308,11 +344,13 @@ Parametrar: -l(line) (file) LibraryEditArgDialog + Edit argument Konfigurera argument + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -326,11 +364,13 @@ Exempel: + Not bool Ej bool + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -344,78 +384,99 @@ Exempel: + Not null Ej null + Not uninit Ej uninit + String Sträng + Format string Format sträng + Min size of buffer Minsta storlek för buffer + + Type Typ + + None Ingen + + argvalue argvalue + + mul mul + + strlen strlen + + Arg Arg + + Arg2 Arg2 + and och + Valid values Tillåtna värden @@ -428,579 +489,700 @@ Exempel: + A&nalyze Analysera + Standard Standard + &File &Arkiv + &View &Visa + &Toolbars Verktygsfält + C++ standard C++ standard + &C standard C standard C standard + &Edit &Redigera + &License... &Licens... + A&uthors... &Utvecklat av... + &About... &Om... + &Files... &Filer... + + Analyze files Check files Analysera filer + Ctrl+F Ctrl+F + &Directory... &Katalog... + + Analyze directory Check directory Analysera mapp + Ctrl+D Ctrl+D + Ctrl+R Ctrl+R + &Stop &Stoppa + + Stop analysis Stop checking Stoppa analys + Esc Esc + &Save results to file... &Spara resultat till fil... + Ctrl+S Ctrl+S + &Quit &Avsluta + &Clear results &Töm resultat + &Preferences &Inställningar - + + + Show errors Visa fel - + + + Show warnings Visa varningar + + Show performance warnings Visa prestanda varningar + Show &hidden Visa dolda - - + + Information Information + Show information messages Visa informations meddelanden + Show portability warnings Visa portabilitets varningar + Show Cppcheck results Visa Cppcheck resultat + Clang Clang + Show Clang results Visa Clang resultat + &Filter &Filter + Filter results Filtrera resultat + Windows 32-bit ANSI Windows 32-bit ANSI + Windows 32-bit Unicode Windows 32-bit Unicode + Unix 32-bit Unix 32-bit + Unix 64-bit Unix 64-bit + Windows 64-bit Windows 64-bit + &Print... Skriv ut... + Print the Current Report Skriv ut aktuell rapport + Print Pre&view... Förhandsgranska utskrift... + Open a Print Preview Dialog for the Current Results Öppnar förhandsgranskning för nuvarande resultat + Open library editor Öppna library editor + &Check all &Kryssa alla + Checking for updates + Hide Dölj + + Report + Filter Filter + &Reanalyze modified files &Recheck modified files Analysera om ändrade filer + Reanal&yze all files Analysera om alla filer + Ctrl+Q + Style war&nings Style varningar + E&rrors Fel + &Uncheck all Kryssa &ur alla + Collapse &all Ingen bra översättning! &Fäll ihop alla + &Expand all &Expandera alla + &Standard &Standard + Standard items Standard poster + Toolbar Verktygsfält + &Categories &Kategorier + Error categories Fel kategorier + &Open XML... &Öppna XML... + Open P&roject File... Öppna Projektfil... + Ctrl+Shift+O + Sh&ow Scratchpad... Visa Scratchpad... + &New Project File... Ny projektfil... + Ctrl+Shift+N + &Log View + Log View Logg vy + C&lose Project File Stäng projektfil + &Edit Project File... Redigera projektfil... + &Statistics Statistik + &Warnings Varningar + Per&formance warnings Optimerings varningar + &Information Information + &Portability Portabilitet + P&latforms Plattformar + C++&11 C++11 + C&99 C99 + &Posix Posix + C&11 C11 + &C89 C89 + &C++03 C++03 + &Library Editor... Library Editor... + &Auto-detect language Detektera språk automatiskt + &Enforce C++ Tvinga C++ + E&nforce C Tvinga C + C++14 C++14 + Reanalyze and check library + Check configuration (defines, includes) + C++17 C++17 + C++20 C++20 + Compliance report... + Normal + Autosar + EULA... + Thread Details + Show thread details + &Contents &Innehåll + Categories Kategorier + + Show style warnings Visa stil varningar + Open the help contents Öppna hjälp + F1 F1 + &Help &Hjälp - - + + Quick Filter: Snabbfilter: - + + None of the selected files is part of the project, nothing to analyze. + + + + Select configuration Välj konfiguration - + Found project file: %1 Do you want to load this project file instead? @@ -1009,97 +1191,97 @@ Do you want to load this project file instead? Vill du ladda denna projektfil istället? - + File not found Filen hittades ej - + Bad XML Ogiltig XML - + Missing attribute Attribut finns ej - + Bad attribute value Ogiltigt attribut värde - + Unsupported format Format stöds ej - + Duplicate define - + Failed to load the selected library '%1'. %2 Misslyckades att ladda valda library '%1'. %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + License Licens - + Authors Utvecklare - + Save the report file Spara rapport - - + + XML files (*.xml) XML filer (*.xml) - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -1108,37 +1290,37 @@ This is probably because the settings were changed between the Cppcheck versions En trolig orsak är att inställningarna ändrats för olika Cppcheck versioner. Kontrollera programinställningarna. - + You must close the project file before selecting new files or directories! Du måste stänga projektfilen innan nya filer eller sökvägar kan väljas! - + The library '%1' contains unknown elements: %2 Library filen '%1' har element som ej hanteras: %2 - + Duplicate platform type Dubbel plattformstyp - + Platform type redefined Plattformstyp definieras igen - + Unknown element Element hanteras ej - - - - + + + + Error Fel @@ -1147,50 +1329,50 @@ En trolig orsak är att inställningarna ändrats för olika Cppcheck versioner. Misslyckades att ladda %1. Din Cppcheck installation är ej komplett. Du kan använda --data-dir<directory> på kommandoraden för att specificera var denna fil finns. Det är meningen att --data-dir kommandot skall köras under installationen,så GUIt kommer ej visas när --data-dir används allt som händer är att en inställning görs. - + Open the report file Öppna rapportfilen - + Text files (*.txt) Text filer (*.txt) - + CSV files (*.csv) CSV filer (*.csv) - + Project files (*.cppcheck);;All files(*.*) Projektfiler (*.cppcheck);;Alla filer(*.*) - + Select Project File Välj projektfil - - - - + + + + Project: Projekt: - + No suitable files found to analyze! Inga filer hittades att analysera! - + C/C++ Source - + Compile database @@ -1199,22 +1381,22 @@ En trolig orsak är att inställningarna ändrats för olika Cppcheck versioner. Visual Studio - + Select files to analyze Välj filer att analysera - + Select directory to analyze Välj mapp att analysera - + Select the configuration that will be analyzed Välj konfiguration som kommer analyseras - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? @@ -1223,7 +1405,7 @@ Do you want to proceed analysis without using any of these project files? - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1231,7 +1413,7 @@ Do you want to proceed? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1240,104 +1422,104 @@ Do you want to stop the analysis and exit Cppcheck? Vill du stoppa analysen och avsluta Cppcheck? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML filer (*.xml);;Text filer (*.txt);;CSV filer (*.csv) - + Build dir '%1' does not exist, create it? Build dir '%1' existerar ej, skapa den? - + To check the project using addons, you need a build directory. - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1346,22 +1528,22 @@ Analysis is stopped. Misslyckades att importera '%1', analysen stoppas - + Project files (*.cppcheck) Projekt filer (*.cppcheck) - + Select Project Filename Välj Projektfil - + No project file loaded Inget projekt laddat - + The project file %1 @@ -1378,12 +1560,12 @@ Do you want to remove the file from the recently used projects -list? Vill du ta bort filen från 'senast använda projekt'-listan? - + Install - + New version available: %1. %2 @@ -1440,26 +1622,31 @@ Options: NewSuppressionDialog + New suppression + Error ID + File name + Line number + Symbol name @@ -1501,65 +1688,79 @@ Options: ProjectFile + Project File Projektfil + Paths and Defines Sökvägar och defines + Import Project (Visual studio / compile database/ Borland C++ Builder 6) Import Project (Visual studio / compile database) Importera Projekt (Visual Studio / compile database) + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int Defines must be separated by a semicolon ';' Defines separeras med semicolon ';' + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. Obs: Lägg dina egna .cfg filer i samma folder som projekt filen. De skall isåfall visas ovan. + ... ... + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> <html><head/><body><p>Du har ett val:</p><p> * Analysera alla Debug och Release konfigurationer</p><p> * Analysera bara den första matchande Debug konfigurationen</p><p><br/></p></body></html> + + Browse... + Analyze all Visual Studio configurations Analysera alla Visual Studio konfigurationer + Selected VS Configurations + Paths: Sökvägar: + + Add... Lägg till... @@ -1567,6 +1768,9 @@ Options: + + + Edit Redigera @@ -1575,310 +1779,377 @@ Options: + + + + Remove Ta bort + Undefines: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 + Include Paths: Include sökvägar: + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + This is a workfolder that Cppcheck will use for various purposes. + Clang (experimental) + Check level + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) + Max recursion in template instantiation + Filepaths in warnings will be relative to this path + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. + Exclude source files + Exclude folder... + Exclude file... + Enable inline suppressions Använd inline suppressions + Misra C + 2012 + + 2023 + 2025 + MISRA rule texts + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Misra C++ + 2008 + Cert C++ + Safety profiles (defined in C++ core guidelines) + Bug hunting (Premium) + External tools + Up Upp + Down Ned + Platform + + Analysis + Parser + Cppcheck (built in) + Check that each class has a safe public interface + Limit analysis + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) + Max CTU depth + Warning options + Root path: Bas sökväg: + Warning tags (separated by semicolon) Varnings taggar (separerade med semikolon) + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) Cppcheck build dir (whole program analys, incremental analys, statistik, etc) + Types and Functions + Libraries Libraries + Suppressions Suppressions + Add Lägg till + + Addons Addons + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. + Y2038 Y2038 + Thread safety Tråd säkerhet + Coding standards Kodstandarder + Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + Autosar + Bug hunting @@ -1892,6 +2163,7 @@ Options: + Defines: Defines: @@ -2530,21 +2802,25 @@ För att ställa in vilka fel som skall visas använd visa menyn. + Results Resultat + Critical errors + Analysis Log Analys Log + Warning Details Varningsdetaljer @@ -2553,26 +2829,31 @@ För att ställa in vilka fel som skall visas använd visa menyn. ScratchPad + Scratchpad Scratchpad + Copy or write some C/C++ code here: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": + filename Filnamn + Check Analysera @@ -2581,21 +2862,25 @@ För att ställa in vilka fel som skall visas använd visa menyn. Settings + Preferences Inställningar + General Allmänt + Add... Lägg till... + Number of threads: Antal trådar: @@ -2605,57 +2890,68 @@ För att ställa in vilka fel som skall visas använd visa menyn. + Force checking all #ifdef configurations Check all #ifdef configurations Kontrollera alla #ifdef konfigurationer + Show full path of files Visa den fulla sökvägen för filer + Show "No errors found" message when no errors found Visa "Inga fel hittades" meddelande när inga fel hittas + Display error Id in column "Id" Visa meddelande id i kolumn "Id" + Enable inline suppressions Använd inline suppressions + Check for inconclusive errors also Kör inconclusive analys + Show statistics on check completion Visa statistik när analys är klar + Check for updates + Show internal warnings in log Visa interna fel i loggen + Addons Addons + Python binary (leave this empty to use python in the PATH) Python binär fil (lämna tom för att använda python i PATH) @@ -2663,117 +2959,143 @@ För att ställa in vilka fel som skall visas använd visa menyn. + + + ... ... + MISRA addon + MISRA rule texts file + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Clang Clang + Clang path (leave empty to use system PATH) Clang sökväg (lämna tom för att använda PATH) + Visual Studio headers Visual Studio headers + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> <html><head/><body><p>Sökvägar till Visual Studio headers, separerade med semikolon ';'.</p><p>Du kan öppna en Visual Studio command prompt, och skriva &quot;SET INCLUDE&quot;. Sedan kopiera och klistra in sökvägarna.</p></body></html> + Code Editor + Code Editor Style + System Style + Default Light Style + Default Dark Style + Custom + Remove Ta bort + Max count: + Applications Program + + Edit... Redigera... + Set as default Sätt förvald + Reports Rapporter + Save all errors when creating report Spara alla fel + Save full path to files in reports Spara fulla sökvägar + Language Språk @@ -2830,6 +3152,8 @@ För att ställa in vilka fel som skall visas använd visa menyn. + + Statistics @@ -2837,113 +3161,135 @@ För att ställa in vilka fel som skall visas använd visa menyn. + Project Projekt + Project: Projekt: + Paths: Sökvägar: + Include paths: Include sökvägar: + Defines: Defines: + Undefines: + Previous Scan Föregående analys + Path Selected: Vald sökväg: + Number of Files Scanned: Antal analyserade filer: + Scan Duration: Analys tid: + Errors: Fel: + Warnings: Varningar: + Stylistic warnings: Stil varningar: + Portability warnings: Portabilitets varningar: + Performance issues: Prestanda varningar: + Information messages: Informations meddelanden: + Active checkers: + Checkers + History Historik + File: Fil: + Copy to Clipboard Kopiera + Pdf Export Pdf Export @@ -3093,6 +3439,7 @@ För att ställa in vilka fel som skall visas använd visa menyn. ThreadDetails + Thread Details diff --git a/gui/cppcheck_zh_CN.ts b/gui/cppcheck_zh_CN.ts index 17a85231255..3bc2a493818 100644 --- a/gui/cppcheck_zh_CN.ts +++ b/gui/cppcheck_zh_CN.ts @@ -5,38 +5,45 @@ About + About Cppcheck 关于 Cppcheck + Version %1 版本 %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - C/C++ 静态代码分析工具。 + Copyright © 2007-%1 Cppcheck team. Copyright © 2007-2021 Cppcheck team. 版权所有 © 2007-%1 Cppcheck 团队。 + This program is licensed under the terms of the GNU General Public License version 3 该程序在 GNU 通用公共授权版本 3 的条款下发布 + Visit Cppcheck homepage at %1 访问 Cppcheck 主页: %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> @@ -46,11 +53,13 @@ of the GNU General Public License version 3 ApplicationDialog + Add an application 添加应用程序 + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -76,21 +85,25 @@ Parameters: -l(line) (file) + &Name: 名称(&N): + &Executable: 可执行文件(&E): + &Parameters: 参数(&P): + Browse 浏览 @@ -135,16 +148,19 @@ Parameters: -l(line) (file) HelpDialog + Cppcheck GUI help Cppcheck GUI 帮助 + Contents 内容 + Index 索引 @@ -162,16 +178,19 @@ Parameters: -l(line) (file) LibraryAddFunctionDialog + Add function 添加函数 + Function name(s) 函数名 + Number of arguments 参数个数 @@ -180,86 +199,103 @@ Parameters: -l(line) (file) LibraryDialog + Library Editor 库编辑器 + Open 打开 + Save 保存 + Save as 另存为 + Functions 函数 + Sort 排序 + Add 添加 + Filter: 过滤: + Comments 注释 + noreturn 无返回 + False 否 + True 是 + Unknown 未知 + return value must be used 返回值必须被使用 + ignore function in leaks checking 在泄漏检查中忽略函数 + Arguments 参数 + Edit 编辑 @@ -305,11 +341,13 @@ Parameters: -l(line) (file) LibraryEditArgDialog + Edit argument 编辑参数 + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -325,11 +363,13 @@ Parameters: -l(line) (file) + Not bool 非布尔值 + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -345,78 +385,99 @@ Parameters: -l(line) (file) + Not null 非空 + Not uninit 非未初始化 + String 字符串 + Format string 格式化字符串 + Min size of buffer 最小缓冲区大小 + + Type 类型 + + None 无 + + argvalue argvalue + + mul mul + + strlen strlen + + Arg 参数1 + + Arg2 参数2 + and 并且 + Valid values 有效值 @@ -429,567 +490,683 @@ Parameters: -l(line) (file) + &File 文件(&F) + &View 查看(&V) + &Toolbars 工具栏(&T) + &Help 帮助(&H) + C++ standard C++ 标准 + &C standard C standard &C 标准 + &Edit 编辑(&E) + Standard 标准 + Categories 分类 + &License... 许可证(&L)... + A&uthors... 作者(&U)... + &About... 关于(&A)... + &Files... 文件(&F)... + + Analyze files Check files 分析文件 + Ctrl+F Ctrl+F + &Directory... 目录(&D)... + + Analyze directory Check directory 分析目录 + Ctrl+D Ctrl+D + Ctrl+R Ctrl+R + &Stop 停止(&S) + + Stop analysis Stop checking 停止分析 + Esc Esc + &Save results to file... 保存结果到文件(&S)... + Ctrl+S Ctrl+S + &Quit 退出(&Q) + &Clear results 清空结果(&C) + &Preferences 首选项(&P) + + Show style warnings 显示风格警告 - + + + Show errors 显示错误 - - + + Information 信息 + Show information messages 显示信息消息 + Show portability warnings 显示可移植性警告 + Show Cppcheck results 显示 Cppcheck 结果 + Clang Clang + Show Clang results 显示 Clang 结果 + &Filter 滤器(&F) + Filter results 过滤结果 + Windows 32-bit ANSI + Windows 32-bit Unicode + Unix 32-bit + Unix 64-bit + Windows 64-bit + &Print... 打印(&P)... + Print the Current Report 打印当前报告 + Print Pre&view... 打印预览(&v)... + Open a Print Preview Dialog for the Current Results 打开当前结果的打印预览窗口 + Open library editor 打开库编辑器 + C&lose Project File 关闭项目文件(&L) + &Edit Project File... 编辑项目文件(&E)... + &Statistics 统计(&S) - + + + Show warnings 显示警告 + + Show performance warnings 显示性能警告 + Show &hidden 显示隐藏项(&H) + &Check all 全部选中(&C) + Checking for updates + Hide 隐藏 + + Report + A&nalyze 分析(&A) + Filter 滤器 + &Reanalyze modified files &Recheck modified files 重新分析已修改的文件(&R) + Reanal&yze all files 重新分析全部文件(&y) + Ctrl+Q Ctrl+Q + Style war&nings 风格警告(&n) + E&rrors 编辑(&r) + &Uncheck all 全部取消选中(&U) + Collapse &all 全部折叠(&A) + &Expand all 全部展开(&E) + &Standard 标准(&S) + Standard items 标准项 + &Contents 内容(&C) + Open the help contents 打开帮助内容 + F1 F1 + Toolbar 工具栏 + &Categories 分类(&C) + Error categories 错误分类 + &Open XML... 打开 XML (&O)... + Open P&roject File... 打开项目文件(&R)... + Ctrl+Shift+O Ctrl+Shift+O + Sh&ow Scratchpad... 显示便条(&o)... + &New Project File... 新建项目文件(&N)... + Ctrl+Shift+N Ctrl+Shift+N + &Log View 日志视图(&L) + Log View 日志视图 + &Warnings 警告(&W) + Per&formance warnings 性能警告(&f) + &Information 信息(&I) + &Portability 可移植性(&P) + P&latforms 平台(&l) + C++&11 C++&11 + C&99 C&99 + &Posix &Posix + C&11 C&11 + &C89 &C89 + &C++03 &C++03 + &Library Editor... 库编辑器(&L)... + &Auto-detect language 自动检测语言(&A) + &Enforce C++ &Enforce C++ + E&nforce C E&nforce C + C++14 C++14 + Reanalyze and check library 重新分析并检查库 + Check configuration (defines, includes) 检查配置(defines, includes) + C++17 C++17 + C++20 C++20 + Compliance report... + Normal 常规 + Autosar + EULA... + Thread Details + Show thread details - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. @@ -998,23 +1175,28 @@ This is probably because the settings were changed between the Cppcheck versions 这可能是因为 Cppcheck 不同版本间的设置有所不同。请检查(并修复)编辑器应用程序设置,否则编辑器程序可能不会正确启动。 - + You must close the project file before selecting new files or directories! 在选择新的文件或目录之前,你必须先关闭此项目文件! - - + + Quick Filter: 快速滤器: - + + None of the selected files is part of the project, nothing to analyze. + + + + Select configuration 选择配置 - + Found project file: %1 Do you want to load this project file instead? @@ -1023,64 +1205,64 @@ Do you want to load this project file instead? 你是否想加载该项目文件? - + The library '%1' contains unknown elements: %2 库 '%1' 包含未知元素: %2 - + File not found 文件未找到 - + Bad XML 无效的 XML - + Missing attribute 缺失属性 - + Bad attribute value 无效的属性值 - + Unsupported format 不支持的格式 - + Duplicate platform type 重复的平台类型 - + Platform type redefined 平台类型重定义 - + Unknown element 位置元素 - + Failed to load the selected library '%1'. %2 选择的库 '%1' 加载失败。 %2 - - - - + + + + Error 错误 @@ -1089,108 +1271,108 @@ Do you want to load this project file instead? 加载 %1 失败。您的 Cppcheck 安装已损坏。您可以在命令行添加 --data-dir=<目录> 参数来指定文件位置。请注意,'--data-dir' 参数应当由安装脚本使用,因此,当使用此参数时,GUI不会启动,所发生的一切只是配置了设置。 - - + + XML files (*.xml) XML 文件(*.xml) - + Open the report file 打开报告文件 - + License 许可证 - + Authors 作者 - + Save the report file 保存报告文件 - + Text files (*.txt) 文本文件(*.txt) - + CSV files (*.csv) CSV 文件(*.csv) - + Project files (*.cppcheck);;All files(*.*) 项目文件(*.cppcheck);;所有文件(*.*) - + Select Project File 选择项目文件 - + Failed to open file - + Unknown project file format - + Failed to import project file - + Failed to import '%1': %2 Analysis is stopped. - + Failed to import '%1' (%2), analysis is stopped - + Install - + New version available: %1. %2 - - - - + + + + Project: 项目: - + No suitable files found to analyze! 没有找到合适的文件来分析! - + C/C++ Source C/C++ 源码 - + Compile database Compile database @@ -1203,22 +1385,22 @@ Analysis is stopped. Borland C++ Builder 6 - + Select files to analyze 选择要分析的文件 - + Select directory to analyze 选择要分析的目录 - + Select the configuration that will be analyzed 选择要分析的配置 - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? @@ -1227,44 +1409,44 @@ Do you want to proceed analysis without using any of these project files? - + Duplicate define - + File not found: '%1' - + Failed to load/setup addon %1: %2 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1275,7 +1457,7 @@ Do you want to proceed? 你想继续吗? - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1284,77 +1466,77 @@ Do you want to stop the analysis and exit Cppcheck? 您想停止分析并退出 Cppcheck 吗? - + About - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML 文件 (*.xml);;文本文件 (*.txt);;CSV 文件 (*.csv) - + Build dir '%1' does not exist, create it? 构建文件夹 '%1' 不能存在,创建它吗? - + To check the project using addons, you need a build directory. 要使用插件检查项目,您需要一个构建目录。 - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1363,22 +1545,22 @@ Do you want to stop the analysis and exit Cppcheck? 导入 '%1' 失败,分析已停止 - + Project files (*.cppcheck) 项目文件 (*.cppcheck) - + Select Project Filename 选择项目文件名 - + No project file loaded 项目文件未加载 - + The project file %1 @@ -1446,26 +1628,31 @@ Options: NewSuppressionDialog + New suppression 新建抑制 + Error ID 错误 ID + File name 文件名 + Line number 行号 + Symbol name 符号名 @@ -1487,48 +1674,57 @@ Options: ProjectFile + Project File 项目文件 + Paths and Defines 路径和定义 + Import Project (Visual studio / compile database/ Borland C++ Builder 6) Import Project (Visual studio / compile database) 导入项目 (Visual studio / compile database/ Borland C++ Builder 6) + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int Defines must be separated by a semicolon ';' 定义必须用分号分隔。例如:DEF1;DEF2=5;DEF3=int + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. 注意:把你自己的 .cfg 文件放在和项目文件相同的文件夹中。你应该在上面看到它们。 + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. 如果添加了标记,您将能够右键单击警告并设置其中一个标记。您可以手动对警告进行分类。 + Exclude source files 排除源文件 + Exclude folder... 排除文件夹... + Exclude file... 排除文件... @@ -1538,48 +1734,59 @@ Options: + MISRA rule texts MISRA 规则文本 + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> <html><head/><body><p>从 MISRA C 2012 PDF 的附录 A &quot;指南摘要&quot; 复制/粘贴文本到一个文本文件。</p></body></html> + ... ... + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> <html><head/><body><p>您有一个选择:</p><p> * 分析所有的 Debug 和 Release 配置</p><p> * 只分析第一个匹配的 Debug 配置</p><p><br/></p></body></html> + + Browse... 浏览... + Analyze all Visual Studio configurations 分析全部 Visual Studio 配置 + Selected VS Configurations 已选择的 VS 配置 + Paths: 路径: + + Add... 添加... @@ -1587,6 +1794,9 @@ Options: + + + Edit 编辑 @@ -1595,280 +1805,341 @@ Options: + + + + Remove 移除 + Undefines: 未定义: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 未定义必须用分号分隔。例如:UNDEF1;UNDEF2;UNDEF3 + Include Paths: 包含目录: + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + Types and Functions 类型和函数 + + Analysis 分析 + This is a workfolder that Cppcheck will use for various purposes. 这是一个 Cppcheck 将用于各种目的的工作文件夹。 + Parser 解析器 + Cppcheck (built in) Cppcheck (内建) + Check level + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + Check that each class has a safe public interface 检查每个类是否有一个安全的公共接口 + Limit analysis 极限分析 + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) Check code in unused templates (slower and less accurate analysis) 检查未使用模板中的代码(正常情况下应该是打开,但理论上可以忽略未使用模板中的警告) + Max CTU depth 最大 CTU 深度 + Enable inline suppressions 启用内联方案 + 2025 + Misra C++ + 2008 + Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + Autosar + Safety profiles (defined in C++ core guidelines) + Bug hunting + External tools 外部工具 + Up 向上 + Down 向下 + Platform 平台 + Clang (experimental) Clang (实验性的) + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. 如果你想要设计你的类尽可能的灵活和健壮,那么公共接口必须非常健壮。Cppcheck 将假设参数可以取 *任何* 值。 + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) 检查头文件中的代码(通常应该是打开的。如果您想要一个有限的快速分析,那么关掉它)) + Max recursion in template instantiation 模板实例化中的最大递归 + Warning options 警告选项 + Root path: 根路径: + Filepaths in warnings will be relative to this path 警告中的文件路径将相对于此路径 + Warning tags (separated by semicolon) 警告标志(用分号隔开) + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) Cppcheck 构建目录 (整个程序分析、增量分析、统计数据等) + Libraries 库 + Suppressions 抑制 + Add 添加 + + Addons 插件 + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. 注意:插件需要安装 <a href="https://www.python.org/">Python</a>。 + Y2038 Y2038 + Thread safety 线程安全 + Coding standards 编码标准 + Misra C + 2012 + + 2023 + Cert C++ + Bug hunting (Premium) @@ -1882,6 +2153,7 @@ Options: + Defines: 定义: @@ -2424,21 +2696,25 @@ Please check the application path and parameters are correct. ResultsView + Results 结果 + Critical errors + Analysis Log 分析日志 + Warning Details 警告详情 @@ -2549,26 +2825,31 @@ To toggle what kind of errors are shown, open view menu. ScratchPad + Scratchpad 便条 + Copy or write some C/C++ code here: 在这里复制或输入一些 C/C++ 代码: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": 可选择输入文件名 (主要用来自动语言检测) 然后点击 "检查": + filename 文件名 + Check 检查 @@ -2577,21 +2858,25 @@ To toggle what kind of errors are shown, open view menu. Settings + Preferences 首选项 + General 常规 + Add... 添加... + Number of threads: 线程个数: @@ -2601,57 +2886,68 @@ To toggle what kind of errors are shown, open view menu. + Force checking all #ifdef configurations Check all #ifdef configurations 强制检查所有 #ifdef 配置 + Show full path of files 显示文件的完整路径 + Show "No errors found" message when no errors found 当未找到错误,显示“未发现错误”消息 + Display error Id in column "Id" 在列“Id”中显示错误 Id + Enable inline suppressions 启用内联方案 + Check for inconclusive errors also 检查不确定的错误 + Show statistics on check completion 检查完成后显示统计数据 + Check for updates + Show internal warnings in log 在日志中显示内建警告 + Addons 插件 + Python binary (leave this empty to use python in the PATH) Python 二进制 (留空将使用 PATH 路径中的 python) @@ -2659,117 +2955,143 @@ To toggle what kind of errors are shown, open view menu. + + + ... ... + MISRA addon MISRA 插件 + MISRA rule texts file MISRA 规则文本文件 + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> <html><head/><body><p>从 MISRA C 2012 PDF 的附录 A &quot;指南摘要&quot; 复制/粘贴文本到一个文本文件。</p></body></html> + Clang Clang + Clang path (leave empty to use system PATH) Clang 路径 (留空将使用系统 PATH 路径) + Visual Studio headers Visual Studio 头文件 + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> <html><head/><body><p>Visual Studio 头文件路径,用分号 ';' 分割。</p><p>你可以打开一个 Visual Studio 命令提示符,输入 &quot;SET INCLUDE&quot;。然后复制/粘贴路径。</p></body></html> + Code Editor 代码编辑器 + Code Editor Style 代码编辑器风格 + System Style 系统风格 + Default Light Style 默认浅色风格 + Default Dark Style 默认深色风格 + Custom 自定义 + Remove 移除 + Max count: + Applications 应用程序 + + Edit... 编辑... + Set as default 设为默认 + Reports 报告 + Save all errors when creating report 创建报告时,保存所有错误 + Save full path to files in reports 在报告中保存文件的完整路径 + Language 语言 @@ -2826,6 +3148,8 @@ To toggle what kind of errors are shown, open view menu. + + Statistics @@ -2833,113 +3157,135 @@ To toggle what kind of errors are shown, open view menu. + Project 项目 + Project: 项目: + Paths: 路径: + Include paths: 包含路径: + Defines: 定义: + Undefines: 未定义: + Previous Scan 上一次扫描 + Path Selected: 选中的路径: + Number of Files Scanned: 扫描的文件数: + Scan Duration: 扫描时间: + Errors: 错误: + Warnings: 警告: + Stylistic warnings: Stylistic 警告: + Portability warnings: 可移植性警告: + Performance issues: 性能警告: + Information messages: 信息: + Active checkers: + Checkers + History 历史 + File: 文件: + Copy to Clipboard 复制到剪贴板 + Pdf Export 导出 PDF @@ -3089,6 +3435,7 @@ To toggle what kind of errors are shown, open view menu. ThreadDetails + Thread Details diff --git a/gui/cppcheck_zh_TW.ts b/gui/cppcheck_zh_TW.ts index 6be1247835e..b1951e9f29f 100644 --- a/gui/cppcheck_zh_TW.ts +++ b/gui/cppcheck_zh_TW.ts @@ -5,26 +5,31 @@ About + About Cppcheck 關於 Cppcheck + Version %1 版本 %1 + Cppcheck - A tool for static C/C++ code analysis. Cppcheck - 一款靜態 C/C++ 程式碼分析工具。 + Copyright © 2007-%1 Cppcheck team. 著作權 © 2007-%1 Cppcheck 團隊。 + This program is licensed under the terms of the GNU General Public License version 3 該程式是根據 GNU 通用公眾授權條款第 3 版 @@ -32,11 +37,13 @@ of the GNU General Public License version 3 + Visit Cppcheck homepage at %1 訪問 Cppcheck 主頁: %1 + <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PCRE</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">PicoJSON</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">TinyXML2</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Boost</li></ul></body></html> <html><head/><body><p>Many thanks to these libraries that we use:</p><ul style="margin-top: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; -qt-list-indent: 1;"><li style=" margin-top:12px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">pcre</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">picojson</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">qt</li><li style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">tinyxml2</li></ul></body></html> @@ -46,11 +53,13 @@ of the GNU General Public License version 3 ApplicationDialog + Add an application 新增應用程式 + Here you can add an application that can open error files. Specify a name for the application, the application executable and command line parameters for the application. The following texts in parameters are replaced with appropriate values when application is executed: @@ -66,21 +75,25 @@ Parameters: -l(line) (file) + &Name: 名稱(&N): + &Executable: 執行檔(&E): + &Parameters: 參數(&P): + Browse 瀏覽 @@ -140,16 +153,19 @@ Parameters: -l(line) (file) HelpDialog + Cppcheck GUI help Cppcheck GUI 幫助 + Contents 內容 + Index 索引 @@ -167,16 +183,19 @@ Parameters: -l(line) (file) LibraryAddFunctionDialog + Add function 新增函式 + Function name(s) 函式名稱 + Number of arguments 引數數量 @@ -185,86 +204,103 @@ Parameters: -l(line) (file) LibraryDialog + Library Editor 程式庫編輯器 + Open 開啟 + Save 儲存 + Save as 另存為 + Functions 函式 + Sort 排序 + Add 新增 + Filter: + Comments 註釋 + noreturn + False + True + Unknown 未知 + return value must be used + ignore function in leaks checking + Arguments 引數 + Edit 編輯 @@ -308,11 +344,13 @@ Parameters: -l(line) (file) LibraryEditArgDialog + Edit argument 編輯引數 + <html><head/><body> <p>Is bool value allowed? For instance result from comparison or from '!' operator.</p> <p>Typically, set this if the argument is a pointer, size, etc.</p> @@ -323,11 +361,13 @@ Parameters: -l(line) (file) + Not bool + <html><head/><body> <p>Is a null parameter value allowed?</p> <p>Typically this should be used on any pointer parameter that does not allow null.</p> @@ -338,78 +378,99 @@ Parameters: -l(line) (file) + Not null + Not uninit + String 字串 + Format string + Min size of buffer + + Type 型別 + + None + + argvalue + + mul + + strlen + + Arg + + Arg2 + and + Valid values 有效值 @@ -422,532 +483,644 @@ Parameters: -l(line) (file) + Checking for updates 檢查更新 + Hide 隱藏 + &File 檔案(&F) + &View 檢視(&V) + &Toolbars 工具條(&T) + + Report + &Help 幫助(&H) + A&nalyze 分析(&N) + C++ standard C++ 標準 + &C standard C 標準(&C) + &Edit 編輯(&E) + Standard 標準 + Categories 分類 + Filter 篩選 + &License... 授權(&L)... + A&uthors... 作者(&U)... + &About... 關於(&A)... + &Files... 檔案(&F)... + + Analyze files 分析檔案 + Ctrl+F Ctrl+F + &Directory... 目錄(&D)... + + Analyze directory 分析目錄 + Ctrl+D Ctrl+D + &Reanalyze modified files 重新分析已修改的檔案(&R) + Ctrl+R Ctrl+R + Reanal&yze all files 重新分析所有檔案(&Y) + &Stop 停止(&S) + + Stop analysis 停止分析 + Esc Esc + &Save results to file... 儲存結果為檔案(&S)... + Ctrl+S Ctrl+S + &Quit 退出(&Q) + Ctrl+Q Ctrl+Q + &Clear results 清除結果(&C) + &Preferences 偏好設定(&P) + Style war&nings 樣式警告(&N) + + Show style warnings 顯示樣式警告 + E&rrors 錯誤(&R) - + + + Show errors 顯示錯誤 + &Check all 全部檢查(&C) + &Uncheck all + Collapse &all 全部摺疊(&A) + &Expand all 全部展開(&E) + &Standard 標準(&S) + Standard items 標準項目 + &Contents 內容(&C) + Open the help contents 開啟幫助內容 + F1 F1 + Toolbar 工具條 + &Categories 分類(&C) + Error categories 錯誤分類 + &Open XML... 開啟 XML(&O)... + Open P&roject File... 開啟專案檔(&R)... + Ctrl+Shift+O Ctrl+Shift+O + Sh&ow Scratchpad... + &New Project File... 新增專案檔(&N)... + Ctrl+Shift+N Ctrl+Shift+N + &Log View 日誌檢視(&L) + Log View 日誌檢視 + C&lose Project File 關閉專案檔(&L) + &Edit Project File... 編輯專案檔(&E)... + &Statistics 統計資料(&S) + &Warnings 警告(&W) - + + + Show warnings 顯示警告 + Per&formance warnings 效能警告(&F) + + Show performance warnings 顯示下效能警告 + Show &hidden 顯示隱藏項目(&H) + &Information 資訊(&I) + Show information messages 顯示資訊訊息 + &Portability 可移植性(&P) + Show portability warnings 顯示可移植性警告 + Show Cppcheck results 顯示 Cppcheck 結果 + Clang Clang + Show Clang results 顯示 Clang 結果 + &Filter 篩選(&F) + Filter results 篩選結果 + Windows 32-bit ANSI Windows 32 位元 ANSI + Windows 32-bit Unicode Windows 32 位元 Unicode + Unix 32-bit Unix 32 位元 + Unix 64-bit Unix 64 位元 + Windows 64-bit Windows 64 位元 + P&latforms 平臺(&L) + C++&11 C++&11 + C&99 C&99 + &Posix + C&11 C&11 + &C89 &C89 + &C++03 &C++03 + &Print... 列印(&P)... + Print the Current Report 列印當前報告 + Print Pre&view... 列印預覽(&V)... + Open a Print Preview Dialog for the Current Results 開啟當前結果的列印預覽視窗 + &Library Editor... 程式庫編輯器(&L)... + Open library editor 開啟程式庫編輯器 + &Auto-detect language 自動偵測語言(&A) + &Enforce C++ + E&nforce C + C++14 C++14 + Reanalyze and check library 重新分析並檢查程式庫 + Check configuration (defines, includes) 檢查組態 (定義、包含) + C++17 C++17 + C++20 C++20 + Compliance report... + Normal @@ -961,21 +1134,25 @@ Parameters: -l(line) (file) + Autosar + EULA... + Thread Details + Show thread details @@ -1003,43 +1180,48 @@ Options: Cppcheck GUI - 命令行參數 - - + + Quick Filter: 快速篩選: - - - - + + + + Project: 專案: - + There was a problem with loading the editor application settings. This is probably because the settings were changed between the Cppcheck versions. Please check (and fix) the editor application settings, otherwise the editor program might not start correctly. - + + None of the selected files is part of the project, nothing to analyze. + + + + No suitable files found to analyze! 找不到適合的檔案來分析! - + You must close the project file before selecting new files or directories! 您必須在選取新檔案或目錄之前關閉該專案檔! - + C/C++ Source C/C++ 來源檔 - + Compile database 編譯資料庫 @@ -1052,145 +1234,145 @@ This is probably because the settings were changed between the Cppcheck versions Borland C++ Builder 6 - + Select files to analyze 選取要分析的檔案 - + Select directory to analyze 選取要分析的目錄 - + Select configuration 選取組態 - + Select the configuration that will be analyzed 選取要分析的組態 - + Found project file: %1 Do you want to load this project file instead? - + Found project files from the directory. Do you want to proceed analysis without using any of these project files? - - + + Information 資訊 - + The library '%1' contains unknown elements: %2 - + File not found 找不到檔案 - + Bad XML - + Missing attribute - + Bad attribute value - + Unsupported format 未支援的格式 - + Duplicate platform type 重複的平臺型別 - + Platform type redefined 平臺型別重定義 - + Duplicate define - + Unknown element 未知的元素 - + Failed to load the selected library '%1'. %2 無法載入選取的程式庫 '%1'。 %2 - + File not found: '%1' - + Failed to load/setup addon %1: %2 - - - - + + + + Error 錯誤 - + Failed to load %1. Your Cppcheck installation is broken. You can use --data-dir=<directory> at the command line to specify where this file is located. Please note that --data-dir is supposed to be used by installation scripts and therefore the GUI does not start when it is used, all that happens is that the setting is configured. Analysis is aborted. - + Failed to load %1 - %2 Analysis is aborted. - - + + %1 Analysis is aborted. - + Current results will be cleared. Opening a new XML file will clear current results. @@ -1198,18 +1380,18 @@ Do you want to proceed? - - + + XML files (*.xml) XML 檔案 (*.xml) - + Open the report file 開啟報告檔 - + Analyzer is running. Do you want to stop the analysis and exit Cppcheck? @@ -1218,77 +1400,77 @@ Do you want to stop the analysis and exit Cppcheck? 您想停止分析並離開 Cppcheck 嗎? - + About 關於 - + License 授權 - + Authors 作者 - + XML files (*.xml);;Text files (*.txt);;CSV files (*.csv) XML 檔案 (*.xml);;文字檔 (*.txt);;CSV 檔案 (*.csv) - + Save the report file 儲存報告檔 - + Text files (*.txt) 文字檔 (*.txt) - + CSV files (*.csv) CSV 檔案 (*.csv) - + Project files (*.cppcheck);;All files(*.*) 專案檔 (*.cppcheck);;所有檔案 (*.*) - + Select Project File 選取專案檔 - + Build dir '%1' does not exist, create it? 建置目錄 '%1' 不存在,是否建立它? - + To check the project using addons, you need a build directory. - + Failed to open file 無法開啟檔案 - + Unknown project file format 未知的專案檔格式 - + Failed to import project file 無法匯入專案檔 - + Failed to import '%1': %2 Analysis is stopped. @@ -1297,62 +1479,62 @@ Analysis is stopped. 停止分析。 - + Failed to import '%1' (%2), analysis is stopped - + Show Mandatory - + Show Required - + Show Advisory - + Show Document - + Show L1 - + Show L2 - + Show L3 - + Show style - + Show portability - + Show performance - + Show information @@ -1361,22 +1543,22 @@ Analysis is stopped. 無法匯入 '%1',停止分析 - + Project files (*.cppcheck) 專案檔 (*.cppcheck) - + Select Project Filename 選取專案檔案名稱 - + No project file loaded - + The project file %1 @@ -1393,12 +1575,12 @@ Do you want to remove the file from the recently used projects -list? 您要從最近使用的專案列表中移除該檔案嗎? - + Install 安章 - + New version available: %1. %2 可用的新版本: %1. %2 @@ -1407,26 +1589,31 @@ Do you want to remove the file from the recently used projects -list? NewSuppressionDialog + New suppression 新建抑制 + Error ID 錯誤 ID + File name 檔案名稱 + Line number 行號 + Symbol name 符號名稱 @@ -1468,48 +1655,59 @@ Do you want to remove the file from the recently used projects -list? ProjectFile + Project File 專案檔 + Paths and Defines 路徑與定義 + Import Project (Visual studio / compile database/ Borland C++ Builder 6) 匯入專案 (Visual Studio / 編譯資料庫 / Borland C++ Builder 6) + + Browse... 瀏覽... + <html><head/><body><p>You have a choice:</p><p> * Analyze all Debug and Release configurations</p><p> * Only analyze the first matching Debug configuration</p><p><br/></p></body></html> + Analyze all Visual Studio configurations 分析所有 Visual Studio 組態 + Selected VS Configurations 選取 VS 組態 + Paths: 路徑: + + Add... 新增... @@ -1517,6 +1715,9 @@ Do you want to remove the file from the recently used projects -list? + + + Edit 編輯 @@ -1525,274 +1726,334 @@ Do you want to remove the file from the recently used projects -list? + + + + Remove 移除 + Defines: 定義: + Defines must be separated by a semicolon. Example: DEF1;DEF2=5;DEF3=int + Undefines: 未定義: + Undefines must be separated by a semicolon. Example: UNDEF1;UNDEF2;UNDEF3 + Include Paths: 包含路徑: + Up + Down + Include file + <html><head/><body><p><span style=" font-family:'monospace'; color:#000000; background-color:#ffffff;">Force inclusion of a header file</span></p></body></html> + Browse.. + Types and Functions 型別與函式 + Platform 平臺 + Libraries 程式庫 + Note: Put your own custom .cfg files in the same folder as the project file. You should see them above. + + Analysis 分析 + Cppcheck build dir (whole program analysis, incremental analysis, statistics, etc) + This is a workfolder that Cppcheck will use for various purposes. + Parser 剖析器 + Cppcheck (built in) Cppcheck (內建) + Clang (experimental) + Check level + Reduced -- meant for usage where developer wants results directly. Limited and faster analysis with fewer results. + Normal -- meant for normal analysis in CI. Analysis should finish in reasonable time. + Exhaustive -- meant for nightly builds etc. Analysis time can be longer (10x slower than compilation is OK). + If you want to design your classes to be as flexible and robust as possible then the public interface must be very robust. Cppcheck will asumme that arguments can take *any* value. + Check that each class has a safe public interface + Limit analysis + Check code in headers (should be ON normally. if you want a limited quick analysis then turn this OFF) + Check code in unused templates (should be ON normally, however in theory you can safely ignore warnings in unused templates) + Max CTU depth + Max recursion in template instantiation + Warning options 警告選項 + Root path: 根路徑: + Filepaths in warnings will be relative to this path + Warning tags (separated by semicolon) 警告標記 (由分號分隔) + If tags are added, you will be able to right click on warnings and set one of these tags. You can manually categorize warnings. + Exclude source files 排除來源檔 + Exclude folder... 排除資料夾... + Exclude file... 排除檔案... + Suppressions 抑制 + Add 新增 + Enable inline suppressions + + Addons + Note: Addons require <a href="https://www.python.org/">Python</a> being installed. + Y2038 Y2038 + Thread safety 執行緒安全 + Coding standards + Misra C + 2012 + + 2023 + 2025 + Misra C++ + 2008 @@ -1802,16 +2063,19 @@ Do you want to remove the file from the recently used projects -list? + MISRA rule texts + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + ... ... @@ -1821,41 +2085,49 @@ Do you want to remove the file from the recently used projects -list? + Cert C + CERT-INT35-C: int precision (if size equals precision, you can leave empty) + Cert C++ + Autosar + Safety profiles (defined in C++ core guidelines) + Bug hunting (Premium) + Bug hunting + External tools 外部工具 @@ -2382,21 +2654,25 @@ Please check the application path and parameters are correct. ResultsView + Results 結果 + Critical errors + Analysis Log 分析日誌 + Warning Details 警告詳細資訊 @@ -2502,26 +2778,31 @@ To toggle what kind of errors are shown, open view menu. ScratchPad + Scratchpad + Copy or write some C/C++ code here: + Optionally enter a filename (mainly for automatic language detection) and click on "Check": + filename 檔案名稱 + Check @@ -2530,122 +2811,147 @@ To toggle what kind of errors are shown, open view menu. Settings + Preferences 偏好設定 + General 一般 + Number of threads: 執行緒數量: + Max count: + Force checking all #ifdef configurations + Show full path of files 顯示檔案的完整路徑 + Show "No errors found" message when no errors found + Display error Id in column "Id" + Enable inline suppressions + Check for inconclusive errors also + Show statistics on check completion + Check for updates 檢查更新 + Show internal warnings in log 顯示日誌中的內部警告 + Applications 應用程式 + Add... 新增... + + Edit... 編輯... + Remove 移除 + Set as default 設定為預設值 + Reports 報告 + Save all errors when creating report + Save full path to files in reports 在報告中儲存檔案的完整路徑 + Language 語言 + Addons + Python binary (leave this empty to use python in the PATH) @@ -2653,71 +2959,87 @@ To toggle what kind of errors are shown, open view menu. + + + ... ... + MISRA addon + MISRA rule texts file MISRA 規則文字檔 + <html><head/><body><p>Copy/paste the text from Appendix A &quot;Summary of guidelines&quot; from the MISRA C 2012 pdf to a text file.</p></body></html> + Clang Clang + Clang path (leave empty to use system PATH) + Visual Studio headers Visual Studio 標頭檔 + <html><head/><body><p>Paths to Visual Studio headers, separated by semicolon ';'.</p><p>You can open a Visual Studio command prompt, write &quot;SET INCLUDE&quot;. Then copy/paste the paths.</p></body></html> + Code Editor 程式碼編輯器 + Code Editor Style 程式碼編輯器樣式 + System Style 系統樣式 + Default Light Style + Default Dark Style + Custom 自訂 @@ -2770,6 +3092,8 @@ To toggle what kind of errors are shown, open view menu. + + Statistics @@ -2777,113 +3101,135 @@ To toggle what kind of errors are shown, open view menu. + Project 專案 + Project: 專案: + Paths: 路徑: + Include paths: 包含路徑: + Defines: 定義: + Undefines: 未定義: + Previous Scan 上一次掃描 + Path Selected: 選取的路徑: + Number of Files Scanned: 已掃描的檔案數量: + Scan Duration: 掃描時間: + Errors: 錯誤: + Warnings: 警告: + Stylistic warnings: + Portability warnings: 可移植性警告: + Performance issues: 效能議題: + Information messages: 資訊訊息: + Active checkers: + Checkers + History 歷史紀錄 + File: 檔案: + Copy to Clipboard 複製到剪貼簿 + Pdf Export Pdf 匯出 @@ -3033,6 +3379,7 @@ To toggle what kind of errors are shown, open view menu. ThreadDetails + Thread Details diff --git a/gui/help/commandline.html b/gui/help/commandline.html new file mode 100644 index 00000000000..d66d7fb598b --- /dev/null +++ b/gui/help/commandline.html @@ -0,0 +1,63 @@ + + +Command line options + + + + +

Command line options

+ +

The GUI can be started from a terminal or a shortcut with options:

+ +
cppcheck-gui [OPTIONS] [files or paths]
+ + + + + + + + + + +
OptionDescription
-p <file>Open the project file and analyze + it. If the project has a build dir with earlier results, these are shown + instead; click Reanalyze all files to analyze again.
-l <file>Open a results file in XML + format.
-d <directory>Used with -l: + the folder that was analyzed to create the results file. Relative paths in + the results file are relative to this folder. It is needed to show the + source code of the warnings.
-h, --helpShow a short description + of the options.
-v, --versionShow the version of + the GUI.
--data-dir=<directory>Meant for + installation scripts. Stores the folder where Cppcheck's data files + (translations, library configurations, platforms, addons) are installed. + The GUI is not started when this option is used.
files or pathsAnalyze these files and folders without + a project. If one of the arguments is a project file + (*.cppcheck), it is opened as with -p. If one of + them is an XML file, it is opened as a results file.
+ +

Examples

+ +

Open a project:

+
cppcheck-gui -p myproject.cppcheck
+

or simply:

+
cppcheck-gui myproject.cppcheck
+ +

Look at the results of a CI job. The job ran Cppcheck in the folder +/home/me/src/myproject and saved the results:

+
cppcheck-gui -l results.xml -d /home/me/src/myproject
+ +

Analyze a folder without a project:

+
cppcheck-gui src/
+ +

Starting without options

+ +

When the GUI is started without options, it opens the project that was open +when it was closed last time, and shows the results of the last analysis if +the project has a build dir.

+ + + + + diff --git a/gui/help/images/add-application.png b/gui/help/images/add-application.png new file mode 100644 index 00000000000..68e4b422ace Binary files /dev/null and b/gui/help/images/add-application.png differ diff --git a/gui/help/images/context-menu-tag.png b/gui/help/images/context-menu-tag.png new file mode 100644 index 00000000000..69c510f3d48 Binary files /dev/null and b/gui/help/images/context-menu-tag.png differ diff --git a/gui/help/images/context-menu.png b/gui/help/images/context-menu.png new file mode 100644 index 00000000000..6afa8f80542 Binary files /dev/null and b/gui/help/images/context-menu.png differ diff --git a/gui/help/images/index-mainwindow.png b/gui/help/images/index-mainwindow.png deleted file mode 100644 index aa67a5e836d..00000000000 Binary files a/gui/help/images/index-mainwindow.png and /dev/null differ diff --git a/gui/help/images/library-editor.png b/gui/help/images/library-editor.png new file mode 100644 index 00000000000..5bdf7db02ba Binary files /dev/null and b/gui/help/images/library-editor.png differ diff --git a/gui/help/images/main-window.png b/gui/help/images/main-window.png new file mode 100644 index 00000000000..e678199f2e0 Binary files /dev/null and b/gui/help/images/main-window.png differ diff --git a/gui/help/images/menu-analyze.png b/gui/help/images/menu-analyze.png new file mode 100644 index 00000000000..6aa110f8dd4 Binary files /dev/null and b/gui/help/images/menu-analyze.png differ diff --git a/gui/help/images/menu-edit.png b/gui/help/images/menu-edit.png new file mode 100644 index 00000000000..18b587ceb44 Binary files /dev/null and b/gui/help/images/menu-edit.png differ diff --git a/gui/help/images/menu-file.png b/gui/help/images/menu-file.png new file mode 100644 index 00000000000..4b7a3fcfd9f Binary files /dev/null and b/gui/help/images/menu-file.png differ diff --git a/gui/help/images/menu-help.png b/gui/help/images/menu-help.png new file mode 100644 index 00000000000..a76d218063b Binary files /dev/null and b/gui/help/images/menu-help.png differ diff --git a/gui/help/images/menu-view-report.png b/gui/help/images/menu-view-report.png new file mode 100644 index 00000000000..65050ce279c Binary files /dev/null and b/gui/help/images/menu-view-report.png differ diff --git a/gui/help/images/menu-view.png b/gui/help/images/menu-view.png new file mode 100644 index 00000000000..40d66eaf972 Binary files /dev/null and b/gui/help/images/menu-view.png differ diff --git a/gui/help/images/new-suppression.png b/gui/help/images/new-suppression.png new file mode 100644 index 00000000000..13c615172e4 Binary files /dev/null and b/gui/help/images/new-suppression.png differ diff --git a/gui/help/images/preferences-addons.png b/gui/help/images/preferences-addons.png new file mode 100644 index 00000000000..70eb0642256 Binary files /dev/null and b/gui/help/images/preferences-addons.png differ diff --git a/gui/help/images/preferences-applications.png b/gui/help/images/preferences-applications.png new file mode 100644 index 00000000000..41a94dcda32 Binary files /dev/null and b/gui/help/images/preferences-applications.png differ diff --git a/gui/help/images/preferences-clang.png b/gui/help/images/preferences-clang.png new file mode 100644 index 00000000000..bb00ea2d31c Binary files /dev/null and b/gui/help/images/preferences-clang.png differ diff --git a/gui/help/images/preferences-code-editor.png b/gui/help/images/preferences-code-editor.png new file mode 100644 index 00000000000..5edb3658d6d Binary files /dev/null and b/gui/help/images/preferences-code-editor.png differ diff --git a/gui/help/images/preferences-general.png b/gui/help/images/preferences-general.png new file mode 100644 index 00000000000..98f56728201 Binary files /dev/null and b/gui/help/images/preferences-general.png differ diff --git a/gui/help/images/preferences-language.png b/gui/help/images/preferences-language.png new file mode 100644 index 00000000000..32aa867fcb2 Binary files /dev/null and b/gui/help/images/preferences-language.png differ diff --git a/gui/help/images/preferences-reports.png b/gui/help/images/preferences-reports.png new file mode 100644 index 00000000000..d18a150ac5a Binary files /dev/null and b/gui/help/images/preferences-reports.png differ diff --git a/gui/help/images/projectfile-addons.png b/gui/help/images/projectfile-addons.png new file mode 100644 index 00000000000..9aa09829fbb Binary files /dev/null and b/gui/help/images/projectfile-addons.png differ diff --git a/gui/help/images/projectfile-analysis.png b/gui/help/images/projectfile-analysis.png new file mode 100644 index 00000000000..1d846829455 Binary files /dev/null and b/gui/help/images/projectfile-analysis.png differ diff --git a/gui/help/images/projectfile-import.png b/gui/help/images/projectfile-import.png new file mode 100644 index 00000000000..ae487d9bf3c Binary files /dev/null and b/gui/help/images/projectfile-import.png differ diff --git a/gui/help/images/projectfile-paths-and-defines.png b/gui/help/images/projectfile-paths-and-defines.png new file mode 100644 index 00000000000..a6ec3a4d2c8 Binary files /dev/null and b/gui/help/images/projectfile-paths-and-defines.png differ diff --git a/gui/help/images/projectfile-types-and-functions.png b/gui/help/images/projectfile-types-and-functions.png new file mode 100644 index 00000000000..4b2fb57f435 Binary files /dev/null and b/gui/help/images/projectfile-types-and-functions.png differ diff --git a/gui/help/images/projectfile-warning-options.png b/gui/help/images/projectfile-warning-options.png new file mode 100644 index 00000000000..779925309af Binary files /dev/null and b/gui/help/images/projectfile-warning-options.png differ diff --git a/gui/help/images/quick-filter.png b/gui/help/images/quick-filter.png new file mode 100644 index 00000000000..cefbe833e42 Binary files /dev/null and b/gui/help/images/quick-filter.png differ diff --git a/gui/help/images/report-misra.png b/gui/help/images/report-misra.png new file mode 100644 index 00000000000..30071346a44 Binary files /dev/null and b/gui/help/images/report-misra.png differ diff --git a/gui/help/images/scratchpad.png b/gui/help/images/scratchpad.png new file mode 100644 index 00000000000..ca1dd74ad3d Binary files /dev/null and b/gui/help/images/scratchpad.png differ diff --git a/gui/help/images/statistics-previous-scan.png b/gui/help/images/statistics-previous-scan.png new file mode 100644 index 00000000000..a2ec1c45157 Binary files /dev/null and b/gui/help/images/statistics-previous-scan.png differ diff --git a/gui/help/images/statistics-project.png b/gui/help/images/statistics-project.png new file mode 100644 index 00000000000..5e909732bf4 Binary files /dev/null and b/gui/help/images/statistics-project.png differ diff --git a/gui/help/images/statistics-statistics.png b/gui/help/images/statistics-statistics.png new file mode 100644 index 00000000000..1bbaddbe18f Binary files /dev/null and b/gui/help/images/statistics-statistics.png differ diff --git a/gui/help/images/toolbar.png b/gui/help/images/toolbar.png new file mode 100644 index 00000000000..41664a4edb2 Binary files /dev/null and b/gui/help/images/toolbar.png differ diff --git a/gui/help/images/walkthrough-analysis.png b/gui/help/images/walkthrough-analysis.png deleted file mode 100644 index 94efb2890d8..00000000000 Binary files a/gui/help/images/walkthrough-analysis.png and /dev/null differ diff --git a/gui/help/images/walkthrough-import-project.png b/gui/help/images/walkthrough-import-project.png deleted file mode 100644 index 44b18e7f6b2..00000000000 Binary files a/gui/help/images/walkthrough-import-project.png and /dev/null differ diff --git a/gui/help/images/walkthrough-library.png b/gui/help/images/walkthrough-library.png deleted file mode 100644 index fbb5ae14d09..00000000000 Binary files a/gui/help/images/walkthrough-library.png and /dev/null differ diff --git a/gui/help/images/walkthrough-new-project.png b/gui/help/images/walkthrough-new-project.png deleted file mode 100644 index 55bf7ce2f4f..00000000000 Binary files a/gui/help/images/walkthrough-new-project.png and /dev/null differ diff --git a/gui/help/images/walkthrough-toolbar-severities.png b/gui/help/images/walkthrough-toolbar-severities.png deleted file mode 100644 index f06e3aa41cf..00000000000 Binary files a/gui/help/images/walkthrough-toolbar-severities.png and /dev/null differ diff --git a/gui/help/images/walkthrough-warning-menu.png b/gui/help/images/walkthrough-warning-menu.png deleted file mode 100644 index 0154b5ccbc9..00000000000 Binary files a/gui/help/images/walkthrough-warning-menu.png and /dev/null differ diff --git a/gui/help/index.html b/gui/help/index.html index 4d2cd43f824..6272ec01151 100644 --- a/gui/help/index.html +++ b/gui/help/index.html @@ -1,21 +1,103 @@ Cppcheck GUI +

Cppcheck GUI

-

With the Cppcheck GUI you can analyze your code.

+

Cppcheck is a static analysis tool for C and C++ code. It looks for bugs +such as undefined behavior, memory leaks, buffer overruns, null pointer +dereferences and uninitialized variables, and it points out code that is +suspicious, slow or hard to maintain. Cppcheck tries hard to avoid false +positives: when it reports something there is usually a reason to look at +it.

+ +

The Cppcheck GUI is a graphical front end for Cppcheck. With the GUI you +can:

+
    +
  • create and edit project files that describe what code to analyze and how + to analyze it,
  • +
  • import Visual Studio solutions and projects, compile databases + (compile_commands.json) and Borland C++ Builder 6 projects,
  • +
  • run the analysis in several threads and watch the results come in,
  • +
  • browse the warnings, read the source code next to them and follow the + path that leads to each bug,
  • +
  • filter, hide, suppress and tag warnings,
  • +
  • open the code in your favorite editor,
  • +
  • save results as XML, text or CSV and print them,
  • +
  • try out small pieces of code in the scratchpad,
  • +
  • write configuration files for your own libraries.
  • +
+ +

Contents

-

If you want to get started, look at the walk through.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PageWhat you will find there
Getting startedA step by step walk through: create a project, run the analysis and + look at the first results. Start here if you are new to Cppcheck.
The main windowAll menus, toolbars and panels of the main window.
Analyzing without a projectQuick analysis of files and folders, and the settings in the + Analyze menu.
Project filesEvery option in the project file dialog explained in detail.
Investigating warningsHow to read the results list, the warning details and the code + view, and how to decide if a warning is a real bug.
Severities and report typesWhat error, warning, style, performance, portability and information + mean, and how the compliance report types classify warnings.
Hiding and suppressing warningsTemporary hiding, permanent suppressions in the project file, and + inline suppressions in the code.
Tagging warningsCategorize warnings with your own tags.
Results files, printing and statisticsSave and open results, print reports and view statistics.
Scratchpad, library editor and other toolsTools for trying out code and for describing your own libraries.
PreferencesEvery option in the preferences dialog.
Command line optionsHow to start the GUI with a project or a results file.
TroubleshootingAnswers to common questions and problems.
+ +

Projects or quick analysis?

+ +

There are two ways to use the GUI:

+
    +
  • With a project file (recommended). A project file + (*.cppcheck) stores where your code is, the include paths, + the preprocessor defines, the libraries you use, suppressions, tags and + much more. The analysis is more accurate when Cppcheck knows these + things, and you only configure them once. See + Getting started and + Project files.
  • +
  • Without a project file. Use Analyze > Files... or + Analyze > Directory... to analyze some code quickly. See + Analyzing without a project.
  • +
-

Example

+

More information

-
+

The Cppcheck manual describes the analysis itself in more detail, including +the command line tool, the configuration file format and addons. You can find +it at https://cppcheck.sourceforge.io/manual.pdf.

+ +

The Cppcheck home page is +https://cppcheck.sourceforge.io/. +There you can download new versions, read about the checks and report +problems.

+ + - diff --git a/gui/help/investigating-warnings.html b/gui/help/investigating-warnings.html index 5eec66bd054..d1275a8ba01 100644 --- a/gui/help/investigating-warnings.html +++ b/gui/help/investigating-warnings.html @@ -1,22 +1,183 @@ Investigating warnings +

Investigating warnings

-

When you have run the analysis it is time to look at the results.

+

When the analysis is done (or while it is still running) it is time to look +at the results. This page explains how to read a warning, how to decide if it +is a real bug, and what you can do with it.

-

If you click on a warning then the corresponding code will be shown in the -"Warning details" at the bottom.

+

Reading a warning

-

You can right click warnings to get options. The difference of -"hiding" a warning and "suppressing" a warning is that -the suppression is permanent and hiding the warning is only temporary. When -suppressing warning(s), that is saved in the project file. +

+

Click a warning in the results list. The lower part of the window then +shows:

+
    +
  • the id of the warning, for example arrayIndexOutOfBounds. + The id identifies the kind of problem. Search for it in the Cppcheck + documentation or on the internet to learn more about it,
  • +
  • the CWE number, if there is one. CWE (Common Weakness Enumeration) + is a standard list of software weaknesses. Look it up at + cwe.mitre.org for a general + description of the problem,
  • +
  • the full message. It can be longer than the summary in the list,
  • +
  • the source code with the line of the warning highlighted.
  • +
+ +

In the example above Cppcheck says that buf[16] is accessed at +index 16. The array has 16 elements, so the valid indexes are 0 to 15. The loop +condition i <= BUFFER_SIZE should be +i < BUFFER_SIZE.

+ +

Notes: the path to the bug

+ +

Many warnings have notes. Click the arrow in front of the warning to see +them. Notes show the steps that lead to the problem, in order, for +example:

+
Assuming that condition 'i<=16' is not redundant   (line 9)
+Array index out of bounds                         (line 10)
+ +

Click a note to show its line in the code view. For a bug that depends on +values, the notes usually tell you where the value comes from, which +conditions Cppcheck assumes, and where the bad value is used. Follow the notes +to understand the warning.

+ +

A note like Assuming that condition 'x' is not redundant means that +Cppcheck uses the condition in your code as a hint about possible values. For +example, if the code checks if (p == NULL) after it has already +used p, then either the check is not needed or the code can use a +null pointer. Cppcheck warns because one of them must be wrong.

+ +

Is it a real bug?

+ +

Cppcheck tries to avoid false warnings, but no static analysis tool is +perfect. To decide if a warning is right:

+
    +
  1. Read the message and the notes, and look at the code they point to.
  2. +
  3. Think about the values Cppcheck mentions. Can they really happen? Look at + the callers of the function if needed.
  4. +
  5. Check if Cppcheck may be missing information. Warnings in code that uses + macros or types that Cppcheck could not see, because an include path is + missing, can be wrong. Look for missingInclude information + messages and fix the include paths in the project.
  6. +
  7. Check if a library configuration is missing. If your code calls a + function that never returns (like a fatal error handler) and Cppcheck + does not know that, it may warn about code after the call. Select the + library in the project or write a configuration for your own functions. + See Libraries.
  8. +
+ +

Even if a warning is not a bug today, it can point to code that is hard to +understand or easy to break. Many developers prefer to change the code so that +the warning goes away, instead of suppressing it.

+ +

If you are sure Cppcheck is wrong, suppress the warning (see +Hiding and suppressing warnings). It is also +very helpful if you report the false warning, with a small code example, at +https://trac.cppcheck.net/ or in the +Cppcheck forum.

+ +

Inconclusive warnings

+ +

Sometimes Cppcheck finds something suspicious but can not be sure that it +is a bug. These inconclusive warnings are not shown by default. Enable +Check for inconclusive errors also in the +preferences to see them. An extra +Inconclusive column then marks them. Expect more false warnings among +them.

+ +

Where to start

+ +

The first analysis of a large project can give many warnings. Some +tips:

+
    +
  • Start with errors, then warnings. Use the + severity buttons in the toolbar to hide the + other severities.
  • +
  • Look at the information messages early. They are not bugs, but they + tell you about problems in the configuration, such as headers that can + not be found. Fixing them makes the other results better.
  • +
  • Sort by the Id column to handle one kind of warning at a time. If + one kind of warning is wrong everywhere, it may be a configuration + problem.
  • +
  • Use the quick filter to find warnings about a function, a variable or a + file.
  • +
  • With a build dir, sort by Since date to see the newest warnings + first. New warnings are the easiest to fix, because the code is fresh in + your mind.
  • +
  • Use tags to remember what you have looked + at.
  • +
+ +

Opening the code in an editor

+ +

Double-click a warning, or select it and press Enter, to open the file in +your default editor at the line of the warning. You can also right-click a +warning and choose an editor at the top of the context menu.

+ +

Editors are configured in the +preferences on the Applications tab. On some systems the GUI finds +installed editors automatically.

+ +

If the file is not found, for example because the results were loaded from +an XML file created on another computer, the GUI asks you to select the +folder where the file is.

+ + +

The context menu

+ +

Right-click one or more selected warnings to get the context menu. Select +several warnings with Ctrl+click or Shift+click.

+ +

+ + + + + + + + + + + +
CommandDescription
(editors)Open the file of the warning in this editor.
Recheck N file(s)Analyze the selected files again. Select + file items (the top level items in the list) to enable this. Useful after + you have fixed something in a file. Not available while an analysis is + running or for results loaded from an XML file.
CopyCopy the selected warnings, notes or file names to the + clipboard as text, in the format + file:line:column:severity: summary [id], followed by one line + for each note. Paste it in a bug report or a chat.
Hide N result(s)Hide the selected warnings until the next + analysis. See Hiding warnings.
Hide all with idHide all warnings with the same id as the + selected warning, until the next analysis.
Suppress selected id(s)Suppress all warnings with the ids of + the selected warnings, in all files. The suppression is saved in the + project file, so the warnings are not reported again. See + Hiding and suppressing warnings.
Open containing folderOpen the folder of the file in your + file manager.
TagGive the selected warnings a tag. Only shown if the + project has tags. See Tagging warnings.
+ +

Analyzing again

+ +

After you have changed the code:

+
    +
  • Right-click a file in the results list and choose Recheck to + analyze just that file again.
  • +
  • Use Reanalyze all files in the toolbar to analyze everything again. + With a build dir only changed files are analyzed again, so this is + fast.
  • +
  • Use Analyze > Reanalyze modified files (Ctrl+R) to analyze only + the files that changed since the last analysis. See + The main window for when this is + available.
  • +
+ + - diff --git a/gui/help/mainwindow.html b/gui/help/mainwindow.html new file mode 100644 index 00000000000..d12fe51c787 --- /dev/null +++ b/gui/help/mainwindow.html @@ -0,0 +1,293 @@ + + +The main window + + + + +

The main window

+ +

This page describes the parts of the main window and every command in the +menus and toolbars.

+ +

+ +

From top to bottom the main window has:

+
    +
  • the menu bar,
  • +
  • the toolbars: the standard toolbar, the severity toolbar and the + quick filter,
  • +
  • the progress bar, which is shown while an analysis is running,
  • +
  • the results list with all warnings,
  • +
  • the lower panel with two tabs: Warning Details (the message + and the source code of the selected warning) and Analysis Log.
  • +
+ +

The title bar shows the name of the project file that is open. You can drag +the bar between the results list and the lower panel to give more space to +either of them. The GUI remembers the window size, the column widths and the +position of the bar.

+ +

The results list

+ +

The results are grouped by file. Each file is a top level item; click the +arrow to expand it, or use View > Expand all. Each warning in a file +can have child items called notes, which describe the path through the +code that leads to the problem.

+ +

The columns are:

+ + + + + + + + + + + + + +
ColumnMeaning
FileThe file of the warning. By default the path is shown + relative to the project (see Show full path of files in the + preferences and Root path in the + project file).
LineThe line number.
Severityerror, warning, style, performance, portability, + information, or note for the notes. See + Severities. The icon in the File column + shows the severity too.
Classification, Level, Guideline, RuleOnly shown when a + compliance report type (Misra, Cert, Autosar) is selected in + View > Report. See Report + types.
InconclusiveShown when inconclusive warnings are enabled in + the preferences. Marks warnings where Cppcheck is not sure.
SummaryA short description of the problem.
IdThe id of the checker message, for example + nullPointer. You need it for suppressions. The column can be + turned off in the preferences.
Since dateThe date the warning was first seen. Only + available for projects with a build dir; the date is kept from analysis + to analysis as long as the warning is still there. This makes it easy to + see which warnings are new.
TagsYour own tag for the warning. See + Tagging.
CWEThe Common Weakness + Enumeration number of the problem, if there is one.
+ +

Click a column header to sort by that column. Drag the edge of a column +header to change its width.

+ +

Double-click a warning, or select it and press Enter, to open the file in +your default editor at the line of the warning. You must configure the editor +first in the preferences.

+ +

Right-click warnings to get a context menu. See +The context menu.

+ +

Warning Details and the code view

+ +

When you select a warning, the Warning Details tab shows the id, the +CWE number and the full message. Some messages are longer than the summary in +the list and explain the problem in more detail. If the file was included from +another file, it also shows which file included it.

+ +

Below the message, the code view shows the source file with the line of the +warning highlighted. Select a note to see the line of the note. The code view +is read only; use your editor to change the code. The colors of the code view +can be changed in the preferences.

+ +

Analysis Log

+ +

The Analysis Log tab shows which files were analyzed and with which +configuration: the preprocessor defines, undefines, include paths and +platform. Look here if the results are not what you expected, for example to +check that the right include paths are used. Right-click the log to clear it +or copy one or all entries.

+ +

If Show internal warnings in log is enabled in the preferences, +internal debug warnings are shown here too.

+ +

If a critical error happens, for example a syntax error that stops the +analysis of a file, a red message is shown above the results list.

+ +

Toolbars

+ +

+ +

The standard toolbar (left) has, from left to right: Open Project +File, Save results to file, Reanalyze all files, +Stop, Clear results, Preferences and About. These +commands are described with the menus below.

+ +

The severity toolbar (right) has one toggle button for each +severity: error, warning, style, portability, performance and information. +When a button is pressed, warnings with that severity are shown. Release it to +hide them. The last two buttons show or hide results from Cppcheck itself and +results from Clang tools (Clang-Tidy). When you select a compliance report +type, the buttons change to the classifications of that standard, for example +Mandatory, Required and Advisory for Misra.

+ +

The quick filter field shows only warnings that contain the text you +type. The text is searched (ignoring case) in the summary, the message, the id, +the classification and the files and texts of the notes. Click the small cross +in the field to clear the filter.

+ +

+ +

The toolbars can be turned on and off with View > Toolbars.

+ +

The File menu

+ +

+ + + + + + + + + + + + +
CommandDescription
Open XML...Open a results file in XML format that was saved + earlier by the GUI or created with the command line tool + (cppcheck --xml ...). The current results are cleared. See + Opening results.
New Project File...Create a new project file. First you + choose the file name, then the project + file dialog opens. When you click OK the analysis starts.
Open Project File...Open an existing project file + (*.cppcheck). If the project has a build dir with results + from an earlier analysis, those results are shown. Otherwise the analysis + starts.
Edit Project File...Change the settings of the open project. + When you click OK, the project file is saved and the code is analyzed + again.
Close Project FileClose the project and clear the results. + You must close the project before you can analyze files or folders + without a project.
(recent projects)The project files you opened recently. + Click one to open it.
Save results to file...Save the results as XML, text or CSV. + See Saving results.
Print Preview... / Print...Preview or print the results. + See Printing.
QuitClose the GUI. If an analysis is running, you are asked + if you want to stop it.
+ +

The Edit menu

+ +

+ + + + + +
CommandDescription
Clear resultsRemove all results from the list. If the + project has a build dir, the cached analysis results in the build dir are + deleted too, so the next analysis analyzes every file from scratch.
PreferencesOpen the preferences + dialog.
+ +

The View menu

+ +

+ + + + + + + + + + + + + +
CommandDescription
ToolbarsShow or hide the standard toolbar, the severity + toolbar (Categories) and the quick filter.
ReportChoose how warnings are classified: Normal + (Cppcheck severities) or according to a coding standard: Autosar, Cert C, + Cert C++, Misra C, Misra C++ 2008 or Misra C++ 2023. See + Report types.
Show errors ... Show informationThe same as the buttons in + the severity toolbar.
Check all / Uncheck allShow or hide all severities at + once.
Collapse all / Expand allCollapse or expand all files and + warnings in the results list.
Show hiddenShow the warnings again that you have hidden with + the context menu. Only enabled when there are hidden warnings.
Show Scratchpad...Open the + scratchpad, where you can type or paste code and analyze it.
StatisticsShow statistics + about the project and the last analysis.
Library Editor...Open the + library editor to create or change a library configuration (.cfg) + file.
Thread DetailsShow what each analysis thread is doing right + now. See Thread details.
+ +

The Analyze menu

+ +

+ + + + + + + + + + + + + +
CommandDescription
Files...Analyze one or more files without a project. You can + also select a compile database, a Visual Studio solution or project, or a + Borland C++ Builder 6 project here. See + Analyzing without a project.
Directory...Analyze all source files in a folder and its + subfolders, without a project.
Reanalyze modified filesAnalyze again only the files that + changed since the last analysis in this session, including files that + include a changed header. This works for files and folders you selected + with Files... or Directory... and for projects that list + their paths in the project file. For projects that import a compile + database or a Visual Studio project, use Reanalyze all files + instead.
Reanalyze all filesAnalyze all files again. For a project with + a build dir, unchanged files are not analyzed again; their cached results + are used.
Reanalyze and check libraryAnalyze the project again and + report functions and types for which Cppcheck has no configuration. Use it + to find out what is missing in your library configurations. See + Checking the library + configuration.
Check configuration (defines, includes)Analyze the project + again and report problems in the configuration, such as include files + that can not be found. Use it when you set up a new project.
StopStop the running analysis (Esc). Results found so far are + kept.
C standard / C++ standardThe language standard used for + files when the standard is not known in another way (for example from an + imported project).
Auto-detect language / Enforce C++ / Enforce CBy default the + language of each file is chosen from its file extension: .c + files are C and .cpp, .cc, .cxx and + similar are C++. Choose Enforce C++ or Enforce C to analyze + all files as that language, for example if your C++ code is in + .c files.
Native ... Windows 64-bitThe platform to use when the project + does not choose a platform, or when you analyze without a project. + Native is the platform you run Cppcheck on. See + Platform.
+ +

The Help menu

+ +

+ + + + + + + +
CommandDescription
ContentsOpen this help (F1).
License...Show the license of Cppcheck (GNU GPL v3).
Authors...Show the people who have contributed to + Cppcheck.
About...Show the version of Cppcheck.
+ +

Cppcheck Premium also shows EULA... in this menu.

+ +

Keyboard shortcuts

+ + + + + + + + + + + + + + +
ShortcutCommand
Ctrl+Shift+NNew Project File
Ctrl+Shift+OOpen Project File
Ctrl+SSave results to file
Ctrl+PPrint
Ctrl+QQuit
Ctrl+FAnalyze files
Ctrl+DAnalyze directory
Ctrl+RReanalyze modified files
EscStop the analysis
F1Help
EnterOpen the selected warning in the default editor
+ + + + + diff --git a/gui/help/manual.html b/gui/help/manual.html deleted file mode 100644 index a237cb8485b..00000000000 --- a/gui/help/manual.html +++ /dev/null @@ -1,947 +0,0 @@ - -Cppcheck 1.46

Chapter 1. Introduction

Cppcheck is an analysis tool for C/C++ code. Unlike C/C++ compilers - and many other analysis tools, it doesn't detect syntax errors. Cppcheck - only detects the types of bugs that the compilers normally fail to detect. - The goal is no false positives.

Supported code and platforms:

  • You can check non-standard code that includes various compiler - extensions, inline assembly code, etc.

  • Cppcheck should be compilable by any C++ compiler that handles - the latest C++ standard.

  • Cppcheck should work on any platform that has sufficient cpu and - memory.

Accuracy

Please understand that there are limits of Cppcheck. Cppcheck is - rarely wrong about reported errors. But there are many bugs that it - doesn't detect.

You will find more bugs in your software by testing your software - carefully, than by using Cppcheck. You will find more bugs in your - software by instrumenting your software, than by using Cppcheck. But - Cppcheck can still detect some of the bugs that you miss when testing and - instrumenting your software.


Chapter 2. Getting started

2.1. First test

Here is a simple code

int main()
-{
-    char a[10];
-    a[10] = 0;
-    return 0;
-}

If you save that into file1.c and - execute:

cppcheck file1.c

The output from cppcheck will then be:

Checking file1.c...
-[file1.c:4]: (error) Array 'a[10]' index 10 out of bounds

2.2. Checking all files in a folder

Normally a program has many sourcefiles. And you want to check - them all. Cppcheck can check all sourcefiles in a directory:

cppcheck path

If "path" is a folder then cppcheck will check all sourcefiles in - this folder.

Checking path/file1.cpp...
-1/2 files checked 50% done
-Checking path/file2.cpp...
-2/2 files checked 100% done

2.3. Excluding a file or folder from checking

There is no command to exclude a file or folder from checking. But - you can exclude a file or folder by being more careful when including - files and folders in the checking.

Imagine for example that the folder "src" contain the folders "a", - "b" and "c". To exclude "c" this command can be used:

cppcheck src/a src/b

All files under "src/a" and "src/b" are then checked.

The flag --file-list might also be - useful.


2.4. Severities

The possible severities for messages are:

error

used when bugs are found

warning

suggestions about defensive programming to prevent - bugs

style

stylistic issues related to code cleanup (unused functions, - redundant code, constness, and such)

performance

suggestions for making the code faster


2.5. Enable messages

By default only error messages are shown. - Through the --enable command more checks can be - enabled.


2.5.1. Stylistic issues

With --enable=style you enable most - warning, style and - performance messages.

Here is a simple code example:

void f(int x)
-{
-    int i;
-    if (x == 0)
-    {
-        i = 0;
-    }
-}

There are no bugs in that code so Cppcheck won't report anything - by default. To enable the stylistic messages, use the --enable=style - command:

cppcheck --enable=style file3.c

The output from Cppcheck is now:

Checking file3.c...
-[file3.c:3]: (style) Variable 'i' is assigned a value that is never used
-[file3.c:3]: (style) The scope of the variable i can be reduced


2.5.2. Unused functions

This check will try to find unused functions. It is best to use - this when the whole program is checked, so that all usages is seen by - cppcheck.

cppcheck --enable=unusedFunction path

2.5.3. Enable all checks

To enable all checks your can use the - --enable=all flag:

cppcheck --enable=all path

2.6. Saving results in file

Many times you will want to save the results in a file. You can - use the normal shell redirection for piping error output to a - file.

cppcheck file1.c 2> err.txt

2.7. Multithreaded checking

To use 4 threads to check the files in a folder:

cppcheck -j 4 path

Chapter 3. Preprocessor configurations

By default Cppcheck will check all preprocessor configurations - (except those that have #error in them). This is the recommended - behaviour.

But if you want to manually limit the checking you can do so with - -D.

Beware that only the macros, which are given here and the macros - defined in source files and known header files are considered. That - excludes all the macros defined in some system header files, which are by - default not examined by cppcheck.

The usage: if you, for example, want to limit the checking so the - only configuration to check should be "DEBUG=1;__cplusplus" then something - like this can be used:

cppcheck -DDEBUG=1 -D__cplusplus path

Chapter 4. XML output

Cppcheck can generate the output in XML format.

Use the --xml flag when you execute cppcheck:

cppcheck --xml file1.cpp

The xml format is:

<?xml version="1.0"?>
-<results>
-  <error file="file1.cpp" line="123" id="someError"
-               severity="error" msg="some error text"/>
-</results>

Attributes:

file

filename. Both relative and absolute paths are possible

line

a number

id

id of error. These are always valid symbolnames.

severity

either error or style. - warning and performance are - saved as style.

msg

the error message


Chapter 5. Reformatting the output

If you want to reformat the output so it looks different you can use - templates.

To get Visual Studio compatible output you can use "--template - vs":

cppcheck --template vs gui/test.cpp

This output will look like this:

Checking gui/test.cpp...
-gui/test.cpp(31): error: Memory leak: b
-gui/test.cpp(16): error: Mismatching allocation and deallocation: k

To get gcc compatible output you can use "--template gcc":

cppcheck --template gcc gui/test.cpp

The output will look like this:

Checking gui/test.cpp...
-gui/test.cpp:31: error: Memory leak: b
-gui/test.cpp:16: error: Mismatching allocation and deallocation: k

You can write your own pattern (for example a comma-separated - format):

cppcheck --template "{file},{line},{severity},{id},{message}" gui/test.cpp

The output will look like this:

Checking gui/test.cpp...
-gui/test.cpp,31,error,memleak,Memory leak: b
-gui/test.cpp,16,error,mismatchAllocDealloc,Mismatching allocation and deallocation: k


Chapter 6. Suppressions

If you want to filter out certain errors you can suppress these. - First you need to create a suppressions file. The format is:

[error id]:[filename]:[line]
-[error id]:[filename2]
-[error id]

The error id is the id that you want to suppress. - The easiest way to get it is to use the --xml command - line flag. Copy and paste the id string from the xml - output.

Here is an example:

memleak:file1.cpp
-exceptNew:file1.cpp
-uninitvar

You can then use the suppressions file:

cppcheck --suppressions suppressions.txt src/

-

Chapter 7. Exception safety

Cppcheck has a few checks that ensure that you don't break the basic - guarantee of exception safety. It doesn't have any checks for the strong - guarantee yet.

Example:

Fred::Fred() : a(new int[20]), b(new int[20])
-{
-}

By default cppcheck will not detect any problems in that - code.

To enable the exception safety checking you can use - --enable:

cppcheck --enable=exceptNew --enable=exceptRealloc fred.cpp

The output will be:

[fred.cpp:3]: (style) Upon exception there is memory leak: a

If an exception occurs when b is allocated, - a will leak.

Here is another example:

int *p;
-
-int a(int sz)
-{
-    delete [] p;
-    if (sz <= 0)
-        throw std::runtime_error("size <= 0");
-    p = new int[sz];
-}

Check that with Cppcheck:

cppcheck --enable=exceptNew --enable=exceptRealloc except2.cpp

The output from Cppcheck is:

[except2.cpp:7]: (error) Throwing exception in invalid state, p points at deallocated memory

Chapter 8. Html report

You can convert the xml output from cppcheck into a html report. - You'll need python and the pygments module - (http://pygments.org/) for this to work. In the Cppcheck source - tree there is a folder "htmlreport" that contains a script that transforms - a Cppcheck xml file into html output.

This command generates the help screen:

htmlreport/cppcheck-htmlreport -h

The output screen says:

Usage: cppcheck-htmlreport [options]
-
-Options:
-  -h, --help      show this help message and exit
-  --file=FILE     The cppcheck xml output file to read defects from.
-                  Default is reading from stdin.
-  --report-dir=REPORT_DIR
-                  The directory where the html report content is written.
-  --source-dir=SOURCE_DIR
-                  Base directory where source code files can be found.

An example usage:

./cppcheck gui/test.cpp --xml 2> err.xml
-htmlreport/cppcheck-htmlreport --file=err.xml --report-dir=test1 --source-dir=.

Chapter 9. Graphical user interface

9.1. Introduction

A Cppcheck GUI is available.

The main screen is shown immediately when the GUI is - started.


9.2. Check source code

Use the Check menu.


9.3. Inspecting results

The results are shown in a list.

You can show/hide certain types of messages through the - View menu.

Results can be saved to an xml file that can later be opened. See - Save results to file and Open - XML.


9.4. Settings

The language can be changed at any time by using the - Language menu.

More settings are available in - Edit>Preferences.


9.5. Project files

The project files are used to store project specific settings. - These settings are:

  • include folders

  • preprocessor defines

It isn't recommended to provide the paths to the standard C/C++ - headers - Cppcheck has internal knowledge about ANSI C/C++ and it isn't - recommended that this known functionality is redefined. But feel free to - try it.

As you can read in chapter 3 in this manual the default is that - Cppcheck checks all configurations. So only provide preprocessor defines - if you want to limit the checking.

diff --git a/gui/help/online-help.qhp b/gui/help/online-help.qhp index 23411d0f3b4..29f73530ca2 100644 --- a/gui/help/online-help.qhp +++ b/gui/help/online-help.qhp @@ -5,46 +5,136 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + style.css index.html - images/index-mainwindow.png - investigating-warnings.html - preferences.html + walkthrough.html + mainwindow.html + standalone-analysis.html projectfiledialog.html + investigating-warnings.html severities.html + suppressions.html + tagging.html + reports.html + tools.html + preferences.html + commandline.html + troubleshooting.html + images/add-application.png + images/context-menu-tag.png + images/context-menu.png + images/library-editor.png + images/main-window.png + images/menu-analyze.png + images/menu-edit.png + images/menu-file.png + images/menu-help.png + images/menu-view-report.png + images/menu-view.png + images/new-suppression.png + images/preferences-addons.png + images/preferences-applications.png + images/preferences-clang.png + images/preferences-code-editor.png + images/preferences-general.png + images/preferences-language.png + images/preferences-reports.png + images/projectfile-addons.png + images/projectfile-analysis.png + images/projectfile-import.png + images/projectfile-paths-and-defines.png + images/projectfile-types-and-functions.png + images/projectfile-warning-options.png + images/quick-filter.png + images/report-misra.png + images/scratchpad.png images/severities-error.png - images/severities-warning.png - images/severities-style.png + images/severities-information.png images/severities-performance.png images/severities-portability.png - images/severities-information.png - standalone-analysis.html - tagging.html - walkthrough.html - images/walkthrough-analysis.png - images/walkthrough-library.png - images/walkthrough-toolbar-severities.png - images/walkthrough-import-project.png - images/walkthrough-new-project.png - images/walkthrough-warning-menu.png + images/severities-style.png + images/severities-warning.png + images/statistics-previous-scan.png + images/statistics-project.png + images/statistics-statistics.png + images/toolbar.png diff --git a/gui/help/preferences.html b/gui/help/preferences.html index 5a591227b3c..4c298e59e14 100644 --- a/gui/help/preferences.html +++ b/gui/help/preferences.html @@ -1,74 +1,195 @@ Preferences +

Preferences

-

Number of threads
Number of threads to use in analysis. Each -thread checks its own source file.

- -

Force checking of all #ifdef configurations
Cppcheck try to check -all code and will therefore guess different preprocessor configurations. The -maximum number of configurations that is checked is 14 by default.

- -

Show full path of files
Show the full paths in the results.

- -

Show "No errors found" message when no errors found
-If you want to get a message box about this.

- -

Display error id column "Id"
Show error id in results

- -

Enable inline suppressions
You can suppress warnings with comments. -See the Cppcheck manual (https://cppcheck.sourceforge.io/manual.pdf) for more -information about inline suppressions.

- -

Check for inconclusive errors also
When full analysis of the code -can not determine if there should be a warning or not, it is inconclusive. -Normally Cppcheck does not warn then.

- -

Show statistics on check completion
Show statistics in a window -when analysis finish.

- -

Show internal warnings in log
Internal warnings (for debugging) is -shown in the Analysis log.

- -

Applications
Configure external editor to open from context menu -when you right click on a warning.

- -

Save all errors when creating report
If hidden warnings should be -saved or not.

- -

Save full path to files in report
If you use Root path the -warnings on the screen will not have the full path.

- -

Language
Configure language to use for GUI.

- -

Python binary
To be able to execute addons, Cppcheck needs to know -where python is. Unless you configure something, Cppcheck will try to execute -python in your PATH.

- -

MISRA rule texts
Only needed if you want to use the MISRA addon. -Cppcheck is not legally allowed to distribute the MISRA rule texts and these -must be provided by users. The MISRA rule texts are proprietary. An example -rule text file: -

Appendix A Summary of guidelines
-Rule 1.1
-Text of rule 1.1
-Rule 1.2
-Text of rule 1.2
-

- -

Clang path
The path to clang binary. If no path is provided -then system PATH is used.

- -

Visual studio headers
If you want to use the Visual Studio headers -in the analysis you can provide the path(s) here. Hint: Open a visual studio -command prompt and type SET INCLUDE. Then copy/paste the paths.

- -

Code editor style
The visual theme to use for the code editor that -is used when you investigate results.

+

Open the preferences with Edit > Preferences or the preferences +button in the toolbar. The preferences are your personal settings; they are +stored for your user account, not in the project file. Click OK to +apply the changes.

+ +

Some settings exist both here and in the project file, for example +Enable inline suppressions. When a project is open, the project +setting is used.

+ +

General

+ +

+ + + + + + + + + + + + + +
OptionDescription
Number of threadsHow many files are analyzed at the same time. + Each thread analyzes its own file. Max count shows the number of + processor cores of your computer, which is the highest value you can + enter. More threads make the analysis faster, but use more memory. A value + equal to the number of cores is usually a good choice.
Force checking all #ifdef configurationsBy default Cppcheck + analyzes at most 12 preprocessor configurations of each file. With this + option all configurations are analyzed. This finds more bugs in code with + many #ifdefs, but can be very slow. See + Defines.
Show full path of filesShow the full path of files in the + results list, instead of the path relative to the project.
Show "No errors found" message when no errors foundShow a + message box when an analysis finishes without warnings.
Display error Id in column "Id"Show the Id column in + the results list. The id is needed for suppressions.
Enable inline suppressionsAllow comments like + // cppcheck-suppress nullPointer in the code to suppress + warnings. Only used when no project is open; projects have their own + setting. See Inline + suppressions.
Check for inconclusive errors alsoAlso report warnings where + Cppcheck is not sure that there is a problem. These give more findings, but + also more false warnings. An Inconclusive column is added to the + results list.
Show statistics on check completionOpen the + statistics dialog when an analysis + finishes.
Check for updatesWhen the GUI starts, check on the Cppcheck + web site if there is a newer version. If there is, a message is shown at + the top of the main window. This needs an internet connection; nothing + else is sent.
Show internal warnings in logShow debug warnings from the + analysis in the Analysis Log. Only useful if you develop Cppcheck or + investigate a problem with the analysis.
+ + +

Applications

+ +

+ +

The editors (or other programs) that you can open a warning in. They are +shown at the top of the context menu of the results list. The default +application is used when you double-click a warning or press Enter.

+ +

On some systems the GUI finds installed editors automatically and adds them +to the list.

+ +
    +
  • Add...: add an application.
  • +
  • Edit...: change the selected application.
  • +
  • Remove: remove the selected application.
  • +
  • Set as default: make the selected application the default one.
  • +
+ +

+ +

For each application you enter a name for the menu, the executable and the +command line parameters. These texts in the parameters are replaced when the +application is started:

+ + + + + + + +
TextReplaced with
(file)The file name of the warning
(line)The line number
(message)The warning message
(severity)The severity
+ +

Examples for some common editors:

+ + + + + + + + + + + + + + + +
EditorExecutableParameters
Visual Studio Codecode--goto (file):(line)
Katekate-l(line) (file)
Qt Creatorqtcreator-client (file):(line)
Notepad++notepad++.exe-n(line) (file)
Vim (in a terminal)xterm-e vim +(line) (file)
Emacsemacs+(line) (file)
+ +

Reports

+ +

+ + + + + +
OptionDescription
Save all errors when creating reportAlso save hidden warnings + when you save the results to a file. By default only the visible warnings + are saved.
Save full path to files in reportsSave the full path of each + file. By default the path relative to the project (or the root + path) is saved.
+ +

See Results files, printing and statistics.

+ +

Language

+ +

+ +

The language of the user interface. The GUI is translated to several +languages; select one and click OK. This help is only available in +English.

+ + +

Addons

+ +

+ + + + + +
OptionDescription
Python binaryThe Python interpreter used to run addons. Leave + it empty to use the Python found in the PATH. If the file you enter does + not exist, a red warning is shown.
MISRA rule texts fileA text file with the MISRA C rule texts, + used by the Misra addon to show the rule texts in the warnings. Cppcheck is + not allowed to distribute the rule texts, so you must create the file from + your copy of the MISRA C document. See + Addons for the format. This is + the same setting as MISRA rule texts in the project dialog.
+ + +

Clang

+ +

+ + + + + +
OptionDescription
Clang pathThe folder where clang and + clang-tidy are installed. Used by the Clang parser and by + Clang-Tidy (see Analysis and + External tools in the project + dialog). Leave it empty to search the system PATH. On Windows, Clang is + also found in C:\Program Files\LLVM\bin.
Visual Studio headersPaths to the Visual Studio headers, + separated by semicolons. Clang needs them to parse code that uses the + Visual Studio libraries. To get the paths, open a Visual Studio command + prompt, type SET INCLUDE and copy/paste the paths.
+ + +

Code Editor

+ +

+ +

The colors of the code view in the lower part of the main window.

+
    +
  • System Style: use the colors of your desktop theme.
  • +
  • Default Light Style: dark text on a light background.
  • +
  • Default Dark Style: light text on a dark background.
  • +
  • Custom: your own colors. Click Edit... to choose the + foreground and background colors of the editor, the highlighted line and + the line numbers, and the color and font weight of keywords, class names, + strings, comments and symbols. A preview shows the result.
  • +
+ + diff --git a/gui/help/projectfiledialog.html b/gui/help/projectfiledialog.html index 52b4eba444f..e357ebbc91d 100644 --- a/gui/help/projectfiledialog.html +++ b/gui/help/projectfiledialog.html @@ -1,179 +1,474 @@ -Project File Dialog +Project files + -

Project File Dialog

+

Project files

-

The Project file dialog contains 4 tabs:

-
    -
  • Paths and defines; paths to check and basic preprocessor settings. -
  • Types and Functions; configuration of platform and 3rd party libraries -
  • Analysis; analysis options -
  • Warning options; formatting warnings, suppressing warnings, etc -
  • Addons; extra analysis with addons -
+

A project file (*.cppcheck) stores everything Cppcheck needs to +know to analyze your code: which files to analyze, include paths, defines, +libraries, platform, analysis options, suppressions, tags and addons. It is +an XML file, so you can put it in version control and share it with your +team. Paths in the project file are relative to the folder of the project +file.

-

Paths and defines

+

Create a project with File > New Project File... and change it +with File > Edit Project File.... Both open the Project file +dialog described on this page. When you click OK the project file is +saved and the analysis starts. Click Cancel to close the dialog without +saving.

-

It is recommended to import a project file.

+

The dialog has five tabs:

+
    +
  • Paths and Defines: what code to analyze and the + preprocessor settings,
  • +
  • Types and Functions: the platform and the libraries + your code uses,
  • +
  • Analysis: the build dir, the parser and options + that control how deep the analysis is,
  • +
  • Warning options: root path, tags, excluded + files and suppressions,
  • +
  • Addons: addons, coding standards and external + tools.
  • +
-

Import project

+ +

Paths and Defines

+ +

+ +

On this tab you tell Cppcheck what code to analyze. You can either import a +project from your build system, or enter the paths, defines and include paths +yourself. Importing is recommended: you get the exact include paths and +defines that the compiler uses, and you do not have to update the Cppcheck +project when the build changes.

+ + +

Import Project

+ +

Click Browse... to select the project to import. Supported +formats:

+ + + + + + + + + +
FormatNotes
Compile database
compile_commands.json
Contains the exact compiler command line of every source file. CMake + writes it when you configure with + -DCMAKE_EXPORT_COMPILE_COMMANDS=ON. Meson and Ninja write it + too, and for other build systems (for example make) you can create it + with tools such as Bear. When a compile database is imported, each + file is analyzed with just the configuration given on its command line.
Visual Studio
*.sln, *.slnx, + *.vcxproj
Cppcheck reads the source files, include paths and defines of each + configuration (such as Debug|Win32 or + Release|x64).
Borland C++ Builder 6
*.bpr
 
+ +

Click the brush button next to the field to remove the import.

+ +

When a project is imported, the Paths, Include Paths and +Undefines fields are disabled because the information comes from the +imported project. Defines and Include file can still be used; +they are added to what the imported project says.

+ +

Analyze all Visual Studio configurations and Selected VS +Configurations: only enabled when a Visual Studio solution or project is +imported. A Visual Studio project usually has several configurations, and +analyzing all of them takes time. Check Analyze all Visual Studio +configurations to analyze every Debug and Release configuration. +Otherwise check the configurations you want in the list. If you analyze +several configurations of a file, warnings that are the same in all of them +are only reported once.

+ +

Paths

+ +

The folders and files to analyze (only when no project is imported). +Click Add... to add a folder, select a path and click Edit to +change it, or Remove to remove it. All C and C++ source files in the +folders and their subfolders are analyzed (.c, +.cpp, .cxx, .cc, .c++, +.tpp, .txx, .ipp, .ixx). +Headers are analyzed when they are included from a source file.

+ +

To leave out some files or folders, use Exclude source +files on the Warning options tab.

+ + +

Defines

+ +

Preprocessor macros that are defined for the analysis, like the +-D option of a compiler. Separate them with semicolons, and give a +value with =:

+ +
DEBUG;VERSION=5;WORD=int
+ +

To understand when you need defines, you need to know how Cppcheck handles +preprocessor conditions. A compiler only sees one configuration of your code. +Cppcheck instead tries to analyze all configurations. Look at this code:

+ +
#ifdef A
+    code1
+#endif
+#ifdef B
+    code2
+#endif
-Project to import. Cppcheck will get: +

Cppcheck automatically analyzes the code both with and without +A and B defined, so bugs in both code1 +and code2 are found. You normally do not have to set defines. Use +them when:

    -
  • What files to check -
  • Preprocessor defines -
  • Preprocessor include paths -
  • Language standard if set +
  • a macro must always be defined for the code to make sense, for example + a macro that your build system always sets,
  • +
  • a macro has a value that matters, for example + BUFFER_SIZE=1024,
  • +
  • Cppcheck reports a syntax error because a macro it does not know is used + in a way that only works when the macro is defined.
-

Paths (If you do not import project)

+

By default at most 12 configurations are analyzed for each file. If there +are more, an information message tells you. Enable Force checking +all #ifdef configurations in the preferences +to analyze all of them, which can take a long time.

-

What paths to check.

+

Undefines

-

Defines (If you do not import project)

+

Macros that must never be defined, like the -U option of a +compiler. Separate them with semicolons:

-

Cppcheck automatically checks the code with different preprocessor -configurations.

+
A;C
-
#ifdef A
-code1
-#endif
-#ifdef B
-code2
-#endif
+

In the example above, if A is undefined, Cppcheck does not +analyze the configuration where A is defined. Use this for +configurations that are never used, for example code for a platform you do not +support. It makes the analysis faster and avoids warnings for code you do not +care about.

-

Cppcheck will automatically perform analysis both when A is defined and B is -defined. So any bugs in both code1 and code2 will be detected.

+ +

Include Paths

-

If you want to configure that A will always be defined in Cppcheck analysis -you can do that here.

+

The folders where Cppcheck looks for header files that are included with +#include "..." or #include <...>, like the +-I option of a compiler. Folders are searched in the order of the +list; use Up and Down to change the order.

-

Defines are separated by semicolon. So you can for instance write:

+

Add the folders of your own headers and of the headers of 3rd party +libraries that are part of your project. Cppcheck needs them to know your +types, macros, functions and classes. Without them, some bugs can not be found +and you may get false warnings.

-
A;B=3;C
+

Do not add the folders of the standard library and system headers +(for example /usr/include or the Visual Studio include +folders). Cppcheck has built-in knowledge of the standard library and of the +libraries you select on the Types and Functions tab, and analyzing the +system headers makes the analysis slow and can cause wrong results. That is +why the missingIncludeSystem information messages say that Cppcheck does +not need the standard headers.

-

Undefines (If you do not import project)

+

Include file

-

Cppcheck automatically checks the code with different preprocessor -configurations.

+

A header file that is included before every source file, like the +-include option of GCC or /FI of Visual Studio. Use +it if your build forces a header to be included, for example a configuration +header with macros that all files need.

-
#ifdef A
-code1
-#endif
-#ifdef B
-code2
-#endif
+ +

Types and Functions

-

Cppcheck will automatically perform analysis both when A is defined and B is -defined. So any bugs in both code1 and code2 will be detected.

+

-

If you want to configure that A is never defined in Cppcheck analysis you -can do that here.

+ +

Platform

-

Undefines are separated by semicolon. So you can for instance write:

+

The platform decides the sizes of the basic types (short, +int, long, long long, pointers, +size_t, wchar_t) and whether char is +signed. Cppcheck uses this, for example, to find integer overflows, buffer +overruns with sizeof and portability problems.

-
A;C
+

Choose one of the built-in platforms:

+
    +
  • Native: the computer you run Cppcheck on,
  • +
  • Windows 32-bit ANSI, Windows 32-bit Unicode, + Windows 64-bit,
  • +
  • Unix 32-bit, Unix 64-bit.
  • +
-

Include paths (If you do not import project)

+

For embedded targets and other special platforms, choose one of the +platform files (*.xml) in the list, for example +avr8.xml, arm32-wchar_t2.xml or +pic16.xml. You can write your own platform file and put it in the +folder of the project file; it then appears in the list. See the Cppcheck +manual for the format.

-

Specify include paths.

+

If you leave the platform empty, the platform selected in the +Analyze menu of the main window is used.

-

Types and Functions

+ +

Libraries

-

Cppcheck uses the Platform setting to determine size of -short/int/long/pointer/etc.

+

Check the libraries that your code uses. Each library has a configuration +file (.cfg) that describes its functions, types and macros, for +example:

+
    +
  • which functions allocate and free memory or other resources, so that + leaks and double frees can be found,
  • +
  • which arguments must not be null or uninitialized, and which values are + valid,
  • +
  • which functions never return (like exit()),
  • +
  • which return values must be used,
  • +
  • format strings, buffer sizes and so on.
  • +
-

Check the libraries that you use in the Libraries listbox.

+

The standard library (std.cfg) is always used. Some +commonly used libraries are posix (Linux and Unix APIs), +windows (Windows API), gnu, qt, boost, +wxwidgets, gtk, sdl, opengl, openssl, +sqlite3 and googletest.

+

If your code uses a library that is not in the list, or your own library, +you can write a configuration file for it. Put the .cfg file in +the same folder as the project file and it appears in the list. You can create +and edit configuration files with the library +editor. Use Analyze > Reanalyze and check library to find +functions that are not configured.

+ +

Analysis

+

+ +

Cppcheck build dir

-

This is a work-folder that Cppcheck uses. Each Cppcheck project should have -a separate build dir. It is used for:

+

A work folder for Cppcheck. Each project needs its own build dir; do not +share one build dir between projects. A new project automatically gets +<name>-cppcheck-build-dir next to the project file. If the +folder does not exist when the analysis starts, the GUI asks if it should +create it.

+ +

The build dir is optional, but strongly recommended. It is used for:

    -
  • whole program analysis -
  • debug output -
  • faster analysis (if a source file has changed check it, if source file is - not changed then reuse old results) -
  • statistics +
  • Incremental analysis. Cppcheck stores the results of each file. When + you analyze again, files that have not changed (including the headers they + include) are not analyzed again; their stored results are used. This makes + the second analysis of a large project much faster.
  • +
  • Whole program analysis. Some checks need information from all + files, for example finding functions that are never called + (unusedFunction) or bugs where a value is passed from one file to a + function in another file. These checks are only run when there is a build + dir.
  • +
  • Addons. Addons (Misra, Y2038, Thread safety) and Clang-Tidy need a + build dir.
  • +
  • Results history. The results of the last analysis are saved + (lastResults.xml) and shown when you open the project. The + Since date column shows when each warning was first seen.
  • +
  • Statistics of previous analyses.
+

Do not put the build dir in version control. Edit > Clear +results deletes the stored results in the build dir.

+

Parser

-

It is in general recommended to use Cppcheck parser. However you can choose -to use Clang parser; Clang will be executed with a command line flag that tells -it to dump its AST and Cppcheck will read that AST and convert it into a -corresponding Cppcheck AST and use that.

+

Cppcheck (built in) is recommended. Cppcheck has its own parser that +works well even if the code can not be compiled, if headers are missing or if +the code uses compiler extensions.

-

Analysis

+

Clang (experimental) uses Clang to parse the code. Clang is run with +a flag that makes it write its abstract syntax tree (AST); Cppcheck reads this +AST, converts it and runs its checks on it. Clang must be installed (see +Clang path in the preferences), and the +code must be correct enough for Clang to accept it. This is experimental and +not all checks work as well as with the built in parser.

-

Configure what kind of analysis you want.

+

Check level

-

The Normal analysis is recommended for most use cases. Especially if -you use Cppcheck in CI.

+

How much time Cppcheck may spend on the analysis. A higher level finds more +bugs but takes longer.

+
    +
  • Reduced: a limited and fast analysis, for when you want results + right away, for example while you are writing code.
  • +
  • Normal: the default. Meant for normal analysis in CI; it should + finish in reasonable time.
  • +
  • Exhaustive: a deeper analysis of the control flow and of values, + for nightly builds and similar. It can take much longer; up to 10 times + the compilation time is normal.
  • +
-

The Bug hunting can be used if you really want to find a bug in your -code and can invest time looking at bad results and providing extra -configuration.

+

Analysis

-

Limit analysis

+

Check that each class has a safe public interface: normally Cppcheck +only considers the values that are actually passed to a function. With this +option, Cppcheck assumes that the arguments of public member functions can +have any value, and warns if a function does not handle some value +safely, even if no caller passes that value today. Use it if you want your +classes to be robust against all possible use. It gives more warnings, and you +must decide for each of them if it matters.

-

You can turn off checking of headers. That could be interesting if Cppcheck -is very slow. But normally, you should check the code in headers.

+

Limit analysis

-

It is possible to check the code in unused templates. However the Cppcheck -AST will be incomplete/wrong. The recommendation is that you do not check -unused templates to avoid wrong warnings. The templates will be checked -properly when you do use them.

+

Check code in headers: should normally be on. If you turn it off, +Cppcheck does not report warnings in the code of header files and skips some +analysis of it. This can make the analysis much faster for code with large +headers, but you will miss bugs in headers.

-

Max CTU depth: How deep should the whole program analysis be. The risk with -a "too high" value is that Cppcheck will be slow.

+

Check code in unused templates: should normally be on. If it is off, +templates that are never instantiated are not analyzed. Cppcheck can not know +the template arguments in unused templates, so the analysis of them is less +precise. Templates that are used are always analyzed with the actual template +arguments.

-

Max recursion in template instantiation: Max recursion when Cppcheck -instantiates templates. The risk with a "too high" value is that -Cppcheck will be slow and can require much memory.

+

Max CTU depth: how deep the whole program analysis follows function +calls between files (CTU means "cross translation unit"). A higher value finds +bugs where values pass through more function calls, but makes the analysis +slower. The default is 2.

+

Max recursion in template instantiation: how deep recursive templates +are instantiated. Code that uses template metaprogramming can need a higher +value. A high value can make the analysis slow and use a lot of memory. The +default is 100.

+

Warning options

+

+ +

Root path

-

The root path for warnings. Cppcheck will strip away this part of the path -from warnings. For instance if there is a warning in -

../myproject/foo/bar/file.cpp
and the root path is -
../myproject/foo
then the path for the warning will be -
bar/file.cpp
.

+

File paths in warnings are shown relative to this path. If it is empty, the +folder of the project file is used. For example, if a warning is in

+
../myproject/foo/bar/file.cpp
+

and the root path is

+
../myproject/foo
+

then the warning is shown for

+
bar/file.cpp
-

Warning Tags

+

Warning tags

-

Tags allow you to manually categorize warnings.

+

Your own names for categories of warnings, separated by semicolons, for +example todo;false positive;fixed later. When you have entered +tags, you can right-click warnings and give them a tag. See +Tagging warnings. Only letters, digits and spaces +are allowed in tag names.

+

Exclude source files

-

Excluded source files will not be analyzed by Cppcheck.

+

Files and folders that should not be analyzed. Use it for generated code, +3rd party code that you do not maintain, test data and similar. Click +Exclude folder... or Exclude file... to add entries, Edit +to change the selected entry and Remove to remove it.

+

Excluding works for imported projects too. Note that an excluded header is +still read when it is included from a source file that is analyzed, because +Cppcheck needs it to understand that source file.

+ +

Suppressions

-

List of suppressions. These warnings will not be shown.

+

Warnings that should not be reported. Click Add to add a +suppression; double-click a suppression to edit it, and click Remove to +remove it.

-

Addons

+

+ +

A suppression has these fields:

+
    +
  • Error ID (required): the id of the warning, for example + nullPointer. You can select it from the list or type it. Use + * to suppress all warnings (for example for some file).
  • +
  • File name (optional): only suppress the warning in this file. You + can use the wildcards * and ?, for example + src/generated/*.
  • +
  • Line number (optional): only suppress the warning on this line. + This is fragile: when the code changes, the line number changes too. + Inline suppressions are better for single warnings.
  • +
  • Symbol name (optional): only suppress warnings about this + variable, function or other symbol.
  • +
+ +

You can also add suppressions from the results list with the context menu. +See Hiding and suppressing warnings.

-

Y2038
32-bit timers that count number of seconds since 1970 will -overflow in year 2038. Check that the code does not use such timers.

+

Enable inline suppressions

-

Thread safety
Check that the code is thread safe

+

When this is checked, comments in the code like

+
// cppcheck-suppress nullPointer
+

suppress warnings. See Inline +suppressions.

-

MISRA
Ensure that the MISRA coding standard is followed. Please -note you need to have a textfile with the misra rule texts to get proper -warning messages. Cppcheck is not legally allowed to distribute the misra -rule texts.

+ +

Addons

-

Clang-tidy
Run Clang-tidy

+

+ +

Addons are extra checkers, written in Python, that run after the normal +analysis. Addons need Python to be installed (see Python binary in the +preferences) and the project must have a +build dir. If an addon can not be found, it is shown as +(Not found) and can not be selected.

+ +

Addons

+ +

Y2038: on many 32-bit systems time_t is a signed 32-bit +integer that counts seconds since 1970. It overflows on 19 January 2038. This +addon warns about code that uses such 32-bit time values.

+ +

Thread safety: warns about code that is not safe to use from several +threads, for example local static variables and calls to functions that are +not thread safe.

+ +

Coding standards

+ +

Misra C: checks the code against the MISRA C guidelines, a coding +standard for safety critical C code. Open source Cppcheck has a Misra addon +that does not cover all rules.

+ +

The MISRA rule texts are copyrighted and Cppcheck is not allowed to +distribute them. Without them, Misra warnings only show the rule number. To +get the rule texts in the warnings, buy the MISRA C document, copy the text of +Appendix A "Summary of guidelines" to a text file, and select that file in +MISRA rule texts. The file should look like this:

+
Appendix A Summary of guidelines
+Rule 1.1
+Text of rule 1.1
+Rule 1.2
+Text of rule 1.2
+

The rule text file is a user setting; it is not stored in the project +file.

+ +

Misra C++, Cert C, Cert C++, Autosar and +Safety profiles are only available in Cppcheck Premium. Cppcheck +Premium also lets you choose the version of Misra C (2012, 2023 or 2025) and +Misra C++ (2008 or 2023). For Cert C you can give the precision of +int, which is used for rule INT35-C if the precision is not the +same as the size.

+ +

Bug hunting (Premium)

+ +

A very deep analysis that tries to find all bugs of some kinds, at the cost +of more false warnings and a longer analysis. Only available in Cppcheck +Premium.

+ +

External tools

+ +

Clang-Tidy: also run Clang-Tidy on the code and show its warnings +together with the Cppcheck warnings. Clang-Tidy must be installed. It is +searched for in the Clang path from the +preferences, or in the system PATH. If it is not found, the checkbox shows +(not found). Use the Clang button in the severity toolbar to show +or hide the Clang-Tidy results.

+ + - diff --git a/gui/help/reports.html b/gui/help/reports.html new file mode 100644 index 00000000000..7f9b0ab6124 --- /dev/null +++ b/gui/help/reports.html @@ -0,0 +1,125 @@ + + +Results files, printing and statistics + + + + +

Results files, printing and statistics

+ + +

Saving results

+ +

Select File > Save results to file... (Ctrl+S) or click the save +button in the toolbar. Choose a file name and a format:

+ + + + + + +
FormatContents
XML files (*.xml)All information about each warning: file, + line, column, severity, id, CWE, message, notes, tags and more. This is + the same XML format (version 2) as the command line tool writes with + --xml. The GUI can open it again, and many other tools, for + example CI systems and report generators, can read it. Use this format if + you want to keep the results.
Text files (*.txt)One line per warning, in the classic + Cppcheck text format:
+ [src/buffer.c:9] -> [src/buffer.c:10]: (error) Array 'buf[16]' + accessed at index 16, which is out of bounds.
+ The locations of the notes are listed first, connected with + ->.
CSV files (*.csv)One line per warning with the columns file, + line, severity, id and summary. Open it in a spreadsheet to sort, count + and filter warnings.
+ +

Two preferences on the Reports tab affect +what is saved:

+
    +
  • Save all errors when creating report: also save warnings that are + hidden. By default only the warnings you can see are saved, so you can use + the severity buttons, the quick filter and hiding to choose what goes in + the report.
  • +
  • Save full path to files in reports: save the full path of each + file instead of the path relative to the project.
  • +
+ + +

Opening results

+ +

Select File > Open XML... to open a results file in XML format. +The current results are cleared first. The file can come from the GUI or from +the command line tool, for example from a CI job:

+ +
cppcheck --project=compile_commands.json --xml 2> results.xml
+ +

When results are opened from a file, the GUI needs to find the source files +to show the code. If the paths in the file are relative, the GUI asks for the +folder they are relative to when you select a warning. You can also give the +folder on the command line with the -d option; see +Command line options.

+ +

XML files in the old version 1 format can not be opened. Use +--xml with a recent Cppcheck version to create files in the +version 2 format.

+ +

For results opened from a file, the code can not be analyzed again with +Recheck, because the GUI does not know how it was analyzed.

+ + +

Printing

+ +

Select File > Print... (Ctrl+P) to print the results, or File +> Print Preview... to see what will be printed first. The printout has +one line per warning with the file, line, severity and summary. Like saved +reports, only the warnings you can see are printed. You can print to a PDF +file if your system has a PDF printer.

+ + +

Statistics

+ +

Select View > Statistics to see statistics about the project and +the last analysis. Enable Show statistics on check completion in the +preferences to show the statistics +automatically after each analysis.

+ +

The statistics dialog has these tabs:

+ +

Project

+

The root path of the project, the paths that are analyzed, the include +paths, the defines and the undefines.

+

+ +

Previous Scan

+

The path that was analyzed, the number of files and how long the analysis +took.

+

+ +

Statistics

+

The number of warnings of each severity, and the number of active +checkers.

+

+ +

Checkers

+

A report of which checkers were active in the analysis and which were not. +Use it to see what was checked, for example to document the analysis for a +safety certification.

+ +

History

+

A chart of the number of warnings over time, read from the build dir of the +project. Only available if the GUI was built with Qt Charts and the project +has a build dir.

+ +

Click Copy to Clipboard to copy the statistics as text and HTML, for +example to paste them in an e-mail or a document. Click Pdf Export to +save them as a PDF file.

+ +

Note: the statistics count the warnings of the last +analysis in this session. When you open a project with a build dir, the +results of the previous session are shown, but they are not counted until you +analyze again.

+ + + + + diff --git a/gui/help/severities.html b/gui/help/severities.html index 791c78c68e6..7e9f9e66d5d 100644 --- a/gui/help/severities.html +++ b/gui/help/severities.html @@ -1,47 +1,188 @@ -Severities +Severities and report types + -

Severities

+

Severities and report types

-

error

+

Every warning has a severity that tells you what kind of problem it +is and how serious it is. The severity is shown in the Severity column +and as an icon in the results list. Use the buttons in the severity toolbar, +or the View menu, to show or hide each severity.

-
-

when code is executed there is some bad behavior (undefined behavior, leak)

+

error

-

warning

+

The code has a bug that causes bad behavior when it is executed: undefined +behavior, a crash, a memory or resource leak, and similar. Errors should +always be fixed.

-
-

when code is executed there might be undefined behavior

+

Examples: array index out of bounds (arrayIndexOutOfBounds), +null pointer dereference (nullPointer), use of an uninitialized +variable (uninitvar), memory leak (memleak), resource +leak (resourceLeak), use after free +(deallocuse), division by zero (zerodiv), +mismatching allocation and deallocation (mismatchAllocDealloc).

-

style

+
void f()
+{
+    char buf[10];
+    buf[10] = 0;     // error: arrayIndexOutOfBounds
+}
-
-

point out possible mistakes, and suggest more defensive programming. Examples: +

warning

+ +

The code can cause bad behavior in some situations, or there is code that is +almost certainly not doing what the programmer wanted. Warnings should be +looked at carefully; most of them are bugs.

+ +

Examples: a null pointer check after the pointer has already been used +(nullPointerRedundantCheck), not checking the result of +malloc() (nullPointerOutOfMemory), wrong argument type +for a printf format (invalidPrintfArgType_sint), assignment in a +condition where a comparison was meant, a member variable that is not +initialized in a constructor (uninitMemberVar).

+ +
void f(struct S *s)
+{
+    int x = s->x;
+    if (!s)          // warning: nullPointerRedundantCheck
+        return;
+}
+ +

style

+ +

The code is not wrong, but it can be improved: it is confusing, redundant, +or not as safe as it could be. Style warnings often point to real bugs, for +example a condition that is always true can mean that the wrong variable is +used. They also suggest more defensive programming.

+ +

Examples:

+
    +
  • unused variables, functions and code (unusedVariable, + unreadVariable, unusedFunction),
  • +
  • conditions that are always true or false + (knownConditionTrueFalse),
  • +
  • variables, parameters and member functions that can be const + (constVariable, constParameterPointer, + functionConst),
  • +
  • the scope of a variable can be reduced (variableScope),
  • +
  • duplicate code in if/else branches (duplicateBranch),
  • +
  • suspicious operator precedence (clarifyCalculation).
  • +
+ +
int f(int x)
+{
+    if (x > 0 && x > 10)   // style: the first condition is redundant
+        return 1;
+    return 0;
+}
+ +

performance

+ +

Suggestions to make the code faster. They are based on common knowledge +about what is slow. It is not certain that you get a measurable speed +improvement by fixing them; it depends on how often the code runs.

+ +

Examples: passing a large object by value instead of by const reference +(passedByValue), using it++ instead of +++it for iterators (postfixOperator), inefficient use +of STL containers.

+ +
void print(std::vector<std::string> names);   // performance: passedByValue
+ +

portability

+ +

The code may work on your platform but not on others: implementation +defined behavior, 64-bit problems, or undefined behavior that happens to work +"as you want" with your compiler.

+ +

Examples: storing a pointer in an int +(AssignmentAddressToInteger), shifting a negative value, casting +between incompatible pointer types (invalidPointerCast), assuming +the size of a type.

+ +

Some portability warnings depend on the platform you have selected; see +Platform.

+ +

information

+ +

Messages about the analysis itself, not about your code. If you get +information messages, your code may be fine but the Cppcheck configuration can +be improved. Fixing the configuration usually gives better results.

+ +

Examples:

    -
  • unused code/variables/functions -
  • conditions that are always true/false -
  • constness -
  • operator precedence +
  • missingInclude: an include file of your project was not + found. Add the folder to the + include paths.
  • +
  • missingIncludeSystem: a standard or system header was not + found. This is normal and you do not need to do anything; Cppcheck has + built-in knowledge of the standard library. You can hide these with the + severity toolbar or suppress the id.
  • +
  • toomanyconfigs: a file has more preprocessor configurations + than Cppcheck analyzes by default. See + Defines.
  • +
  • normalCheckLevelMaxBranches: the analysis of a function was + limited. Use the Exhaustive check level to analyze it fully.
  • +
  • messages from Analyze > Reanalyze and check library about + functions that are not configured.
-

-

performance

+

note

-
-

Suggestions for making the code faster. These suggestions are only based on common knowledge. It is not certain you'll get any measurable difference in speed by fixing these messages.

+

Notes are not warnings. They are shown as child items of a warning and +explain the path through the code that leads to it. See +Investigating warnings.

-

portability

+ +

Report types

+ +

If you work with a coding standard, you can show the results classified +according to that standard. Select the standard in View > Report:

+ +

+ + + + + + + + + + + + +
ReportClassificationsExtra columns
NormalThe Cppcheck severities described above. 
AutosarRequired, AdvisoryClassification, Guideline
Cert C, Cert C++L1, L2, L3 (the CERT priority levels; L1 is + the most severe)Level, Rule
Misra C, Misra C++ 2023Mandatory, Required, AdvisoryClassification, Guideline
Misra C++ 2008Required, Advisory, DocumentClassification, Guideline
+ +

With a compliance report type:

+
    +
  • Each warning is mapped to the guideline or rule of the standard that it + relates to. The Guideline or Rule column shows it, and the + Classification or Level column shows how strict the + guideline is.
  • +
  • The icons and the buttons in the severity toolbar follow the + classification: Mandatory and L1 use the error icon, Required and L2 the + warning icon, Advisory and L3 the style icon, and Document the + information icon.
  • +
  • Warnings that are not related to any guideline of the standard are not + shown.
  • +
-
-

portability warnings. Implementation defined behavior. 64-bit portability. Some undefined behavior that probably works "as you want". etc.

+

-

information

+

The report type only changes how results are shown; the analysis is the +same. To check the code against the rules of a coding standard, enable the +standard on the Addons tab of the +project. Open source Cppcheck has a Misra C addon; checking the other +standards needs Cppcheck Premium.

-
-

Configuration problems. If you get such output then your code is ok but your cppcheck configuration could be improved.

+ diff --git a/gui/help/standalone-analysis.html b/gui/help/standalone-analysis.html index ad7fae5fe55..bf7cc0096b3 100644 --- a/gui/help/standalone-analysis.html +++ b/gui/help/standalone-analysis.html @@ -1,17 +1,125 @@ - -Standalone analysis +Analyzing without a project + -

Standalone analysis

+

Analyzing without a project

+ +

You can analyze code quickly without creating a project file. This is +useful to try Cppcheck, or to look at a few files. For regular use a project +is better: with a properly configured project Cppcheck knows your include +paths, defines and libraries, and the analysis is more accurate. You also get +features that need a project, such as saved suppressions, tags and the build +dir. See Project files.

+ +

If a project is open, close it first with File > Close +Project File. The GUI does not let you analyze files or folders while a +project is open.

+ +

Analyzing files

+ +

Select Analyze > Files... (Ctrl+F) and select one or more source +files. The analysis starts at once.

+ +

In the same file dialog you can also select a project of your build +system. Cppcheck then analyzes the files of that project with its include +paths and defines, just as if you had imported it in a project file:

+
    +
  • a compile database (compile_commands.json),
  • +
  • a Visual Studio solution (*.sln, *.slnx) or + project (*.vcxproj). For a solution, a dialog asks which + configuration (for example Debug|x64) to analyze,
  • +
  • a Borland C++ Builder 6 project (*.bpr).
  • +
+ +

Analyzing a directory

+ +

Select Analyze > Directory... (Ctrl+D) and select a folder. +Cppcheck analyzes all source files in the folder and its subfolders. Files +with these extensions are analyzed: .c, .cpp, +.cxx, .cc, .c++, .tpp, +.txx, .ipp and .ixx.

+ +

Header files are not analyzed on their own. The code in a header is +analyzed when a source file includes it, as long as Cppcheck can find the +header.

+ +

If the folder contains a Cppcheck project file, the GUI asks if you want to +open that project instead. If there are several project files, it asks if you +want to continue without them.

+ +

Which settings are used

+ +

Without a project, the analysis uses:

+
    +
  • the preferences: number of threads, + Force checking all #ifdef configurations, Enable inline + suppressions, Check for inconclusive errors also,
  • +
  • the settings in the Analyze menu: the C and C++ standard, the + language (auto-detect, enforce C or enforce C++) and the platform.
  • +
+ +

The Analyze menu settings are remembered when you close the GUI.

+ +

Language standard

+ +

Analyze > C standard and Analyze > C++ standard select +the language version. It affects how some code is parsed and which checks +apply. For example, some functions are deprecated in newer standards, and +some library functions only exist in newer standards.

+ +

Language

+ +

With Auto-detect language the file extension decides if a file is C +or C++. Choose Enforce C or Enforce C++ to treat all files as +one language.

+ +

Platform

+ +

The platform decides the size of the basic types (short, +int, long, pointers, wchar_t and so on) +and whether char is signed. Choose the platform the code will run +on:

+
    +
  • Native: the computer you run Cppcheck on.
  • +
  • Unix 32-bit / Unix 64-bit: Linux, BSD, macOS and similar + on 32-bit or 64-bit processors.
  • +
  • Windows 32-bit ANSI / Windows 32-bit Unicode: 32-bit + Windows. In the ANSI variant the Windows "T" macros and types such as + TCHAR and _tcscpy mean the char + versions; in the Unicode variant they mean the wchar_t + versions.
  • +
  • Windows 64-bit: 64-bit Windows, with Unicode.
  • +
+ +

Limitations

+ +

Without a project:

+
    +
  • There are no include paths, so Cppcheck may not find your own headers. You + will see information messages about missing includes, and some + warnings can be missing because types and macros are unknown.
  • +
  • Suppressions made with the context menu can not be saved. The warnings + disappear from the list but are reported again in the next analysis. Use + inline suppressions in the code instead, or create a project. See + Hiding and suppressing warnings.
  • +
  • Warnings can not be tagged.
  • +
  • There is no build dir. Every analysis analyzes all files, the Since + date column is not available, and checks that need whole program + analysis, such as unused functions, are not run.
  • +
  • Addons and coding standards (Misra, Cert, ...) can not be used.
  • +
+ +

Analyzing again

-

It is possible to quickly analyze files. Open the Analyze menu and click on -either Files... or Directory....

+

After you change the code, use Analyze > Reanalyze modified files +(Ctrl+R) to analyze the files that changed, or Reanalyze all files to +analyze everything again.

-

It is recommended that you create a project for analysis. A properly configured -project will give you better analysis.

+ diff --git a/gui/help/style.css b/gui/help/style.css new file mode 100644 index 00000000000..126f42f3fe7 --- /dev/null +++ b/gui/help/style.css @@ -0,0 +1,68 @@ +/* Stylesheet for the Cppcheck GUI help. Qt's help browser only supports a + subset of CSS, so keep this simple. */ + +body { + font-family: sans-serif; + margin: 8px; +} + +h1 { + color: #1f4e79; + font-size: x-large; +} + +h2 { + color: #1f4e79; + font-size: large; + margin-top: 20px; +} + +h3 { + color: #2e75b6; + font-size: medium; + margin-top: 14px; +} + +pre { + background-color: #f3f3f3; + font-family: monospace; + margin-left: 16px; +} + +code { + font-family: monospace; +} + +table.options { + border-collapse: collapse; + border-color: #c8c8c8; + border-style: solid; +} + +table.options th { + background-color: #e4ecf5; + padding: 4px; + text-align: left; +} + +table.options td { + padding: 4px; + vertical-align: top; +} + +p.note { + background-color: #fff8dc; +} + +p.tip { + background-color: #eaf5ea; +} + +p.nav { + color: #707070; + font-size: small; +} + +p.figure { + margin-left: 16px; +} diff --git a/gui/help/suppressions.html b/gui/help/suppressions.html new file mode 100644 index 00000000000..2baf18c318b --- /dev/null +++ b/gui/help/suppressions.html @@ -0,0 +1,158 @@ + + +Hiding and suppressing warnings + + + + +

Hiding and suppressing warnings

+ +

There are several ways to get rid of warnings you do not want to see. They +differ in how long they last and where they are stored:

+ + + + + + + + + + + + + + + + + + +
MethodLastsStored inBest for
HideUntil the next analysisNowhereGetting warnings out of the way while you work
Severity buttons and filterUntil you change themGUI settingsConcentrating on some kinds of warnings
Suppress from the context menuPermanentProject fileTurning off a kind of warning for the whole project
Suppressions in the project dialogPermanentProject fileSuppressions for some files, lines or symbols
Inline suppressionsPermanentSource codeA single false warning
Excluding filesPermanentProject fileCode you do not want to analyze at all
+ +

The difference between hiding and suppressing: a hidden warning +comes back the next time you analyze the code. A suppressed warning is not +reported again until you remove the suppression.

+ + +

Hiding warnings

+ +

Select one or more warnings, right-click and choose Hide N +result(s). To hide all warnings with the same id as the selected warning, +choose Hide all with id.

+ +

+ +

Hidden warnings are not deleted. Use View > Show hidden to show +them again. They are also shown again after the next analysis.

+ +

By default, hidden warnings are not saved when you save the results to a +file. Enable Save all errors when creating report in the +preferences to save them too.

+ + +

Severity buttons and the quick filter

+ +

The buttons in the severity toolbar show or hide all warnings of a +severity, and the quick filter shows only warnings that contain some text. See +The main window. These do not change the results; +they only change what you see.

+ + +

Suppressing from the context menu

+ +

Select one or more warnings, right-click and choose Suppress selected +id(s). All warnings with the ids of the selected warnings are removed from +the list, and a suppression for each id is added to the project file. The +warnings are not reported in future analyses.

+ +

Note: this suppresses the id in all files of the +project, not only the selected warning. If you only want to suppress one +warning, use an inline suppression, or add a suppression +with a file name or line number in the project dialog.

+ +

This only works when a project is open. Without a project the warnings are +removed from the list, but nothing is saved. Critical errors, such as syntax +errors, can not be suppressed this way.

+ + +

Suppressions in the project dialog

+ +

Open File > Edit Project File... and go to the Warning +options tab. The Suppressions list shows all suppressions of the +project, including the ones made with the context menu.

+ +

+ +

Click Add to add a suppression. You must give the Error ID; +the other fields make the suppression more specific:

+
    +
  • File name: only in files that match. Wildcards * and + ? can be used, for example src/legacy/*.
  • +
  • Line number: only on this line of the file.
  • +
  • Symbol name: only for warnings about this variable or + function.
  • +
+ +

Some examples:

+ + + + + + + + +
Error IDFile nameLineEffect
unusedFunction  No unused function warnings at all, for example for a library whose + functions are called by other programs.
*src/generated/* No warnings in generated code (but the code is still analyzed).
nullPointersrc/io.c120No null pointer warning on line 120 of + src/io.c.
+ +

Double-click a suppression to edit it, or select it and click +Remove to remove it. After you click OK, the project is analyzed +again.

+ + +

Inline suppressions

+ +

An inline suppression is a comment in the source code, just before the line +with the warning, or at the end of that line:

+ +
void f()
+{
+    char *p = get_buffer();
+    // cppcheck-suppress nullPointer
+    *p = 0;
+
+    *p = 1; // cppcheck-suppress nullPointer
+}
+ +

You can suppress several ids at once, and add a comment that explains +why:

+ +
// cppcheck-suppress[nullPointer,uninitvar] get_buffer() never returns NULL
+ +

Inline suppressions are the best way to suppress a single false warning: +they stay with the code when it is moved, and the next person who reads the +code sees that the warning was looked at. See the Cppcheck manual for more +forms, for example suppressing a whole block or file.

+ +

Inline suppressions must be enabled:

+
    +
  • for a project, with Enable inline suppressions on the Warning + options tab of the project dialog (enabled by default for new + projects),
  • +
  • without a project, with Enable inline suppressions in the + preferences.
  • +
+ + +

Excluding files

+ +

To not analyze some files or folders at all, add them to Exclude source +files on the Warning options tab of the project dialog. See +Exclude source files.

+ + + + + diff --git a/gui/help/tagging.html b/gui/help/tagging.html index 7ac4e7ee8d9..4f0a86452ea 100644 --- a/gui/help/tagging.html +++ b/gui/help/tagging.html @@ -1,22 +1,68 @@ Tagging warnings +

Tagging warnings

-

You can manually categorize warnings.

+

Tags let you categorize warnings by hand. You choose the names of the tags +yourself. Some ideas:

+
    +
  • a review status: todo, checked, + fixed later,
  • +
  • your opinion of the warning: bug, false + positive, not important,
  • +
  • who should look at it: frontend, network, + team b.
  • +
-

You choose the names of the categories yourself in the project file -dialog.

+

Unlike suppressions, tags do not remove warnings. They are a way to keep +track of what you have looked at and what you have decided about each +warning.

-

If tag names are configured, then you can tag the warnings by -right-clicking on them and selecting the proper tag in the -context menu.

+

Defining tags

-

Tags are saved in the project file and will be permanent.

+

Open File > Edit Project File..., go to the Warning options +tab and enter the tag names in Warning tags, separated by semicolons:

+ +
todo;false positive;fixed later
+ +

+ +

Tag names can contain letters, digits and spaces. Tags need a project; there +are no tags when you analyze without a project.

+ +

Tagging warnings

+ +

Select one or more warnings, right-click, open the Tag submenu and +choose a tag. Choose No tag to remove the tag. The Tag submenu is +only shown if the project has tags.

+ +

+ +

The tag is shown in the Tags column. Click the column header to sort +the warnings by tag, so that warnings with the same tag are listed +together.

+ +

Where tags are stored

+ +

The tags you give to warnings are saved in the project file at once. Each +tagged warning is identified by a hash of the warning and the code of the +function it is in, so the tag stays with the warning when code elsewhere in +the file changes or lines are added above the function. If the function itself +is changed, the warning gets a new hash and the tag is lost. That is +intended: when the code has changed, the warning should be looked at +again.

+ +

Because the tags are in the project file, everyone who uses the project file +sees the same tags. Tags are also included when you save the results as +XML.

+ + - diff --git a/gui/help/tools.html b/gui/help/tools.html new file mode 100644 index 00000000000..6301283bbd0 --- /dev/null +++ b/gui/help/tools.html @@ -0,0 +1,146 @@ + + +Scratchpad, library editor and other tools + + + + +

Scratchpad, library editor and other tools

+ + +

Scratchpad

+ +

The scratchpad lets you analyze a piece of code without saving it in a file. +Use it to try out how Cppcheck handles some code, to reduce a false warning to +a small example before you report it, or to check a code snippet from a +review.

+ +

Open it with View > Show Scratchpad....

+ +

+ +
    +
  1. Type or paste C or C++ code in the editor.
  2. +
  3. Optionally enter a file name. It is mainly used to decide the language: + test.c is analyzed as C and test.cpp as C++. If + you leave it empty, the code is analyzed as C++.
  4. +
  5. Click Check.
  6. +
+ +

The results are shown in the results list of the main window, and they +replace the results that were shown before. The code is analyzed with the +settings of the open project, or with the settings of the Analyze menu +if no project is open. The code can not include your own headers, since it is +not stored in a file.

+ +

The scratchpad keeps its text while the GUI is running, so you can change +the code and click Check again.

+ + +

Library editor

+ +

A library configuration file (.cfg) tells Cppcheck how the +functions of a library behave. Cppcheck comes with configurations for many +libraries (see Libraries). For +your own libraries, or libraries that have no configuration, you can write one +yourself. The library editor helps you with the function part of the +configuration.

+ +

Open it with View > Library Editor....

+ +

+ +

Working with files

+ +

Click Open to load an existing .cfg file, Save +to save your changes and Save as to save to a new file. To start a new +configuration, add functions and click Save as.

+ +

Save your configuration in the folder of your project file. It then +appears in the Libraries list on the Types and Functions tab of +the project dialog, where you can select it.

+ +

The editor only shows the functions of a configuration. Other parts of the +file, such as memory and resource allocation functions, defines and types, are +kept when you save. If a file contains elements that the editor does not know, +it can not be opened in the editor; use a text editor for such files.

+ +

Functions

+ +

The list on the left shows the functions of the configuration. Type in +Filter to show only functions whose names contain the text. Click +Sort to sort the list by name.

+ +

Click Add to add a function. Enter the function name and the number +of arguments. If several functions have the same properties, you can enter +their names separated by commas; they then share one entry.

+ +

Select a function to see and change its properties:

+ + + + + + + + +
PropertyMeaning
CommentsYour notes about the function. They are saved as + an XML comment before the function in the file.
noreturnTrue if the function never returns, like + exit() or a fatal error handler. Then Cppcheck knows that the + code after a call is not reached. False if it always returns. + Unknown if it depends.
return value must be usedWarn if the return value is ignored, + for example for functions that return an error code or a new object.
ignore function in leaks checkingThe function does not take + ownership of a pointer that is passed to it. Without this, Cppcheck may + assume that the function frees or stores the memory, and stop tracking a + possible leak.
ArgumentsThe properties of each argument. Select an argument + and click Edit to change them.
+ +

Argument properties

+ + + + + + + + + + +
PropertyMeaning
Not boolA boolean value (for example the result of a + comparison) is wrong for this argument. Typical for pointers and + sizes.
Not nullA null pointer must not be passed.
Not uninitThe value must be initialized. For pointers this + means the data it points at is read by the function.
StringThe argument must be a zero terminated string.
Format stringThe argument is a printf style format string; + the following arguments are checked against it.
Min size of bufferThe minimum size of the buffer that is + passed. argvalue: the value of another argument (for example the + size argument of memset); mul: the product of two + arguments; strlen: the length of a string argument.
Valid valuesThe values that are allowed, for example + 0: (zero or more), 1:255 or + 0,2:5. Cppcheck warns if another value can be passed.
+ +

For all features of the configuration format, see the Cppcheck manual and +the files in the cfg folder of the Cppcheck installation. You can +edit .cfg files in a text editor too.

+ +

To find which functions in your code are not configured yet, use +Analyze > Reanalyze and check library; see +Checking the library +configuration.

+ + +

Thread details

+ +

View > Thread Details shows what each analysis thread is doing: +the file it analyzes, when it started on the file and how far it has come. +Use it to find files that take a long time to analyze. If one file takes very +long, you can for example exclude it, reduce the number of configurations with +undefines, or use a lower check +level.

+ +

The number of threads is set in the +preferences.

+ + + + + diff --git a/gui/help/troubleshooting.html b/gui/help/troubleshooting.html new file mode 100644 index 00000000000..b9b4cd99ef9 --- /dev/null +++ b/gui/help/troubleshooting.html @@ -0,0 +1,190 @@ + + +Troubleshooting + + + + +

Troubleshooting

+ +

Answers to common questions and problems.

+ +

I get many "Include file not found" messages

+ +

There are two kinds:

+
    +
  • missingIncludeSystem: a standard or system header, such as + <stdio.h> or <vector>, was not found. + This is normal. Cppcheck does not need these headers, because it knows the + standard library and the libraries you select in the project. Hide the + information severity, or suppress the id + missingIncludeSystem in the project.
  • +
  • missingInclude: one of your own headers was not found. Fix this: + add the folder of the header to the + include paths of the project, or import the project from your build + system so that Cppcheck gets the same include paths as the compiler.
  • +
+ +

Use Analyze > Check configuration (defines, includes) to get a +list of the configuration problems of the project.

+ +

Cppcheck reports a syntax error or an unknown macro

+ +

Cppcheck does not analyze a file it can not parse. A message like There +is an unknown macro here somewhere. Configuration is required. means that +the code uses a macro that Cppcheck does not know, in a place where the code +can not be parsed without knowing what the macro means. For example:

+ +
DECLARE_HANDLER(foo)    // what is this?
+{
+    ...
+}
+ +

To fix it, do one of these:

+
    +
  • add the include path of the header that defines the macro,
  • +
  • select the library that the macro belongs to (for example qt for + Q_OBJECT and signals, or windows for the + Windows API macros),
  • +
  • give the macro a value in + Defines, for example DECLARE_HANDLER(x)=void x(), or in a + library configuration file.
  • +
+ +

If the code is correct and compiles, but Cppcheck still reports a syntax +error, please report it as a Cppcheck bug.

+ +

The analysis is slow

+ +
    +
  • Use a build dir. Then + unchanged files are not analyzed again.
  • +
  • Increase the Number of threads in the + preferences.
  • +
  • Use the Reduced or Normal check level instead of + Exhaustive.
  • +
  • Make sure that Force checking all #ifdef configurations is off in + the preferences.
  • +
  • Use undefines to skip + configurations you do not need, or import a compile database: then each + file is analyzed with one configuration only.
  • +
  • Do not add system include folders (such as /usr/include) to + the include paths.
  • +
  • Exclude generated code and + 3rd party code.
  • +
  • Use View > Thread Details to find files that take long; see + Thread details.
  • +
+ +

A warning is wrong (false positive)

+ +

First check the configuration: missing include paths and missing library +configurations are common causes. For example, if your code calls a function +that never returns and Cppcheck does not know that, it can report problems in +code that is never reached. Configure the function as noreturn in a +library configuration (see Library +editor).

+ +

If the configuration is right, suppress the warning (see +Hiding and suppressing warnings) and please +report the false positive to the Cppcheck project with a small code example. +Use the scratchpad to make the example as +small as possible.

+ +

A bug that I know of is not found

+ +
    +
  • Check that the severity of the warning is shown in the severity toolbar, + that the quick filter is empty, that no warnings are hidden (View > + Show hidden) and that View > Report is Normal.
  • +
  • Check that the file was analyzed: look in the Analysis Log.
  • +
  • Check that the code was analyzed with the right configuration. If the + code is in an #ifdef block, it may only be analyzed when a + macro is defined.
  • +
  • Select the libraries that the code uses, so that Cppcheck knows how their + functions behave.
  • +
  • Try the Exhaustive check level and enable inconclusive warnings in + the preferences.
  • +
  • Bugs that span several files need a build dir (whole program + analysis).
  • +
+ +

Cppcheck can not find all bugs. If you think the bug should be found, +create a small example in the scratchpad and report it to the Cppcheck +project.

+ + +

Checking the library configuration

+ +

Select Analyze > Reanalyze and check library. The project is +analyzed again, and Cppcheck reports information messages for functions +it has no configuration for, for example:

+
    +
  • checkLibraryNoReturn: Cppcheck does not know if the function + can return. Configure noreturn for it.
  • +
  • checkLibraryFunction: the function is not configured at all. + If it is a library function, configure it so that Cppcheck can check how it + is used.
  • +
+ +

Write the missing configuration in a .cfg file with the +library editor or a text editor, put it +in the folder of the project file and select it on the Types and +Functions tab of the project.

+ +

Addons do not work

+ +
    +
  • Addons are Python scripts. Install Python, and if it is not in the PATH, + set the Python binary in the + preferences.
  • +
  • The project needs a build + dir. Without it, the analysis is stopped with the message To check + the project using addons, you need a build directory.
  • +
  • If an addon is shown as (Not found) in the project dialog, the + Cppcheck installation is incomplete.
  • +
+ +

Clang-Tidy is "not found"

+ +

Install Clang-Tidy (it is part of LLVM/Clang). If it is not in the PATH, set +the Clang path in the preferences to the +folder where clang-tidy is.

+ +

Double-clicking a warning does nothing

+ +

No editor is configured, or no default editor is selected. Add your editor +on the Applications tab of the +preferences and click Set as default. If the editor does not start, +check the executable path and the parameters.

+ +

The results are old

+ +

When you open a project with a build dir, the results of the last analysis +are shown, not a new analysis. Click Reanalyze all files to analyze the +current code.

+ +

"Failed to load std.cfg"

+ +

The GUI can not find its data files. The Cppcheck installation is broken; +reinstall Cppcheck. If you built Cppcheck yourself, make sure the +cfg folder is installed next to the program, or configure the data +folder with the --data-dir command line +option.

+ +

Where can I get more help?

+ + + + + + + diff --git a/gui/help/walkthrough.html b/gui/help/walkthrough.html index 9f27ce05f6c..dbaff99a073 100644 --- a/gui/help/walkthrough.html +++ b/gui/help/walkthrough.html @@ -1,69 +1,156 @@ -Walk through +Getting started + -

Quick walk through

+

Getting started

-This is a quick and short walk through to get you started. +

This page walks you through a first analysis: you create a project file, +run the analysis and look at the results. It takes a few minutes. The other +pages in this help explain each step in more detail.

-

Step 1: Create a project.

+

Step 1: Create a project file

-

Create a new project:

+

Select File > New Project File... (Ctrl+Shift+N). A file dialog +asks where to save the project file. Save it in the root folder of your code, +for example next to your CMakeLists.txt or Visual Studio +solution. Paths in the project file are stored relative to the project file, +so the project keeps working if you move the whole folder or check it into +version control.

-
+

When you have chosen a file name, the Project file dialog opens. A +new project automatically gets a build dir called +<name>-cppcheck-build-dir. Cppcheck stores its work files +there; it makes repeated analysis much faster and is required for some +features. See Cppcheck build dir.

-

In the Paths and Defines tab, it is recommended that you import your -project file at the top.

+

Step 2: Tell Cppcheck where the code is

-
+

Open the Paths and Defines tab. You have two choices.

-

In the Types and Functions tab, try to activate all 3rd party -libraries you use (windows, posix, ...).

+

Choice A: Import a project (recommended)

-
+

If you build your code with Visual Studio, CMake, Meson, Bear or any other +tool that can produce a compile database, import it. Click Browse... +next to Import Project and select one of:

+
    +
  • a Visual Studio solution (*.sln, *.slnx) or + project (*.vcxproj),
  • +
  • a compile database (compile_commands.json). CMake creates it + if you configure with -DCMAKE_EXPORT_COMPILE_COMMANDS=ON,
  • +
  • a Borland C++ Builder 6 project (*.bpr).
  • +
-

In the Analysis tab, leave the default settings to start with.

+

Cppcheck then reads the list of source files, the include paths, the +preprocessor defines and the language standard from the imported file. The +Paths, Include Paths and Undefines fields are disabled +because the values come from the imported project.

-

In the Warnings options tab, leave the default settings to start -with.

+

-

In the Addons tab, leave the default settings to start with.

+

Choice B: Enter the paths yourself

+

If you can not import a project, enter the information manually:

+
    +
  • Paths: click Add... and select the folders (or files) to + analyze. Cppcheck analyzes all C/C++ source files in these folders and + their subfolders.
  • +
  • Include Paths: add the folders where your own header files are. + Cppcheck needs your headers to understand types, macros and functions. + You do not need to add the standard library or system headers; Cppcheck + has built-in knowledge about them.
  • +
  • Defines: optionally enter macros, for example + DEBUG;VERSION=3.
  • +
-

Step 2: Analyze code.

+

-

When the project file has been created, the analysis will start -automatically.

+

Step 3: Select libraries

-

While analysis is performed in the background, you can investigate the -results.

+

Open the Types and Functions tab. In the Libraries list, +check the libraries your code uses, for example posix, windows, +qt, boost, gtk or sdl. A library configuration tells +Cppcheck how the functions and types in that library behave: which functions +allocate memory, which arguments must not be null, which functions never +return, and so on. This gives you more and better warnings.

-
+

Set the Platform to the target of your code if it differs from the +computer you run Cppcheck on. This matters for portability and overflow +checks, since the sizes of int, long and pointers +differ between platforms.

+

-

Step 3: Investigate warnings.

+

Step 4: Leave the rest as it is

-

In the toolbar you choose what types of warnings you want to see -(error/warning/style/performance/portability/information).

+

The Analysis, Warning options and Addons tabs have good +default values. You can come back later and change them; see +Project files for a description of every +option.

-
+

Click OK. The project file is saved. If the build dir does not exist +yet, the GUI asks if it should create it: answer Yes.

+

Step 5: Watch the analysis

-

All warnings are shown in a list. If you select a warning in the list, then -details about that warning is shown.

+

The analysis starts immediately. A progress bar above the results shows +how many files have been analyzed. You do not have to wait: warnings appear +in the list as soon as they are found, and you can start looking at them. +To stop the analysis, click the Stop button in the toolbar or press +Esc.

-

If you right click on warning(s) then you get a context menu.

+

Step 6: Look at the results

-
+

The results list groups the warnings by file. Click the arrow next to a +file name, or use View > Expand all, to see the warnings. Click a +warning to show its details and the source code in the lower part of the +window. The line with the problem is highlighted.

-

The difference of "Hide" and "Suppress" is that -suppressions are saved in the project file. The suppressed warnings will not be -shown again unless you remove the suppression. When you hide a warning then -they will be temporarily hidden; the next time you analyze your code these -warnings will be shown again.

+

+ +

Some warnings have an arrow in front of them. Expand them to see +notes: these show the path through the code that leads to the +problem, for example where a variable got the value that later causes the +bug. Click a note to jump to that line.

+ +

Use the colored buttons in the toolbar to show or hide warnings by +severity. Start with errors and warnings; they are the most likely to be +real bugs. See Severities.

+ +

+ +

Right-click a warning to get more options: open the file in your editor, +copy the warning, hide it, suppress it or tag it.

+ +

+ +

Read Investigating warnings to +learn how to work efficiently with the results.

+ +

Step 7: Fix the code and analyze again

+ +

Fix the bugs in your editor. Then click Reanalyze all files in the +toolbar. Because the project has a build dir, Cppcheck only does the full +analysis again for files that changed (or that include a changed header). For +the other files the results are taken from the build dir, so this is +fast.

+ +

If you do not agree with a warning, you can suppress it so that it is not +shown again. See Hiding and suppressing +warnings.

+ +

Next time

+ +

The project files you used recently are listed in the File menu. +When you open a project that has a build dir, the GUI first shows the results +from the last analysis. Click Reanalyze all files in the toolbar to +analyze the code again. Thanks to the build dir, files that did not change +are not analyzed again; their old results are reused.

+ + - diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 3ed37eb7b25..5ddb790b77b 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -59,6 +59,7 @@ #include #include +#include #include #include #include @@ -96,6 +97,7 @@ #include #include #include +#include #include #include #include @@ -118,6 +120,18 @@ static QString fromNativePath(const QString& p) { #endif } +// The files selected in the results view are not necessarily spelled the same way as the +// project or files.txt spells them, compare them as absolute paths +static QString comparablePath(const QString& path) { + return QDir::cleanPath(QFileInfo(path).absoluteFilePath()); +} + +static QSet comparablePaths(const QStringList& paths) { + QSet ret; + std::transform(paths.cbegin(), paths.cend(), std::inserter(ret, ret.end()), comparablePath); + return ret; +} + template> static T toStdStringList(const QStringList& stringList) { T ret; @@ -568,21 +582,31 @@ void MainWindow::saveSettings() const mUI->mResults->saveSettings(mSettings); } -void MainWindow::doAnalyzeProject(ImportProject p, const bool checkLib, const bool checkConfig, const QStringList& recheckFiles) +void MainWindow::doAnalyzeProject(ImportProject p, const bool checkLib, const bool checkConfig, const QStringList& selectedFiles, const Recheck recheck) { Settings checkSettings; auto supprs = std::make_shared(); if (!getCppcheckSettings(checkSettings, *supprs)) return; - // filter requested files - if (!recheckFiles.isEmpty()) { + // Filter the selected files + if (recheck == Recheck::Selected) { + const QSet selected = comparablePaths(selectedFiles); p.fileSettings.remove_if([&](const FileSettings& fs) { - return !recheckFiles.contains(QString::fromStdString(fs.filename())); + return !selected.contains(comparablePath(QString::fromStdString(fs.filename()))); }); + if (p.fileSettings.empty()) { + QMessageBox msg(QMessageBox::Information, + "Cppcheck", + tr("None of the selected files is part of the project, nothing to analyze."), + QMessageBox::Ok, + this); + msg.exec(); + return; + } } - clearResults(); + clearResultsForAnalysis(checkSettings.buildDir, selectedFiles, recheck); mIsLogfileLoaded = false; if (mProjectFile) { @@ -647,7 +671,7 @@ void MainWindow::doAnalyzeProject(ImportProject p, const bool checkLib, const bo mUI->mResults->setCheckSettings(checkSettings); } -void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLib, const bool checkConfig) +void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLib, const bool checkConfig, const QStringList& selectedFiles, const Recheck recheck) { if (files.isEmpty()) return; @@ -657,7 +681,7 @@ void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLib, c if (!getCppcheckSettings(checkSettings, *supprs)) return; - clearResults(); + clearResultsForAnalysis(checkSettings.buildDir, selectedFiles, recheck); mIsLogfileLoaded = false; FileList pathList; @@ -669,7 +693,6 @@ void MainWindow::doAnalyzeFiles(const QStringList &files, const bool checkLib, c } QStringList fileNames = pathList.getFileList(); - mUI->mResults->clear(true); mUI->mResults->setResultsSource(ResultsTree::ResultsSource::Analysis); mThread->clearFiles(); @@ -1379,11 +1402,6 @@ void MainWindow::reAnalyzeSelected(const QStringList& files) return; if (mProjectFile) { - // Clear details, statistics and progress - mUI->mResults->clear(false); - for (int i = 0; i < files.size(); ++i) - mUI->mResults->clearRecheckFile(files[i]); - analyzeProject(mProjectFile, files); return; } @@ -1393,10 +1411,7 @@ void MainWindow::reAnalyzeSelected(const QStringList& files) if (!getCppcheckSettings(checkSettings, *supprs)) return; - // Clear details, statistics and progress - mUI->mResults->clear(false); - for (int i = 0; i < files.size(); ++i) - mUI->mResults->clearRecheckFile(files[i]); + clearResultsForAnalysis(checkSettings.buildDir, files, Recheck::Selected); mCurrentDirectory = mUI->mResults->getCheckDirectory(); FileList pathList; @@ -1451,7 +1466,7 @@ void MainWindow::reAnalyze(bool all) void MainWindow::clearResults() { if (mProjectFile && !mProjectFile->getBuildDir().isEmpty()) { - QDir dir(QFileInfo(mProjectFile->getFilename()).absolutePath() + '/' + mProjectFile->getBuildDir()); + QDir dir(QDir(QFileInfo(mProjectFile->getFilename()).absolutePath()).filePath(mProjectFile->getBuildDir())); for (const QString& f: dir.entryList(QDir::Files)) { if (!f.endsWith("files.txt")) { static const QRegularExpression rx("^.*.s[0-9]+$"); @@ -1465,6 +1480,42 @@ void MainWindow::clearResults() enableResultsButtons(); } +void MainWindow::clearResultsForAnalysis(const std::string& buildDir, const QStringList& selectedFiles, const Recheck recheck) +{ + switch (recheck) { + case Recheck::None: + clearResults(); + break; + case Recheck::Selected: + // Only the selected files are analyzed, the results of the other files are kept + mUI->mResults->clear(false); + for (const QString& f : selectedFiles) + mUI->mResults->clearRecheckFile(f); + enableResultsButtons(); + break; + case Recheck::Cached: { + // Every file reports its results again, either analyzed or replayed from the analyzer + // information. Remove the analyzer information of the selected files so that they really + // are analyzed again, also by the clang tools that keep their results next to it. + const QSet selected = comparablePaths(selectedFiles); + QDir dir(QString::fromStdString(buildDir)); + std::ifstream filesTxt(buildDir + "/files.txt"); + std::string line; + while (std::getline(filesTxt, line)) { + AnalyzerInformation::Info info; + if (!info.parse(line) || !selected.contains(comparablePath(QString::fromStdString(info.sourceFile)))) + continue; + const QString afile = QString::fromStdString(info.afile); + for (const QString& f : dir.entryList({afile, afile + ".*"}, QDir::Files)) + dir.remove(f); + } + mUI->mResults->clear(true); + enableResultsButtons(); + break; + } + } +} + void MainWindow::openResults() { if (mUI->mResults->hasResults()) { @@ -1863,10 +1914,17 @@ bool MainWindow::loadLastResults() return true; } -void MainWindow::analyzeProject(const ProjectFile *projectFile, const QStringList& recheckFiles, const bool checkLib, const bool checkConfig) +void MainWindow::analyzeProject(const ProjectFile *projectFile, const QStringList& selectedFiles, const bool checkLib, const bool checkConfig) { Settings::terminate(false); + // With a build directory the whole project is analyzed: the analyzer information cache skips + // the unchanged files, and files.txt stays complete so whole program analysis sees every file. + // Without a build directory there is no cache, so only the selected files are analyzed. + Recheck recheck = Recheck::None; + if (!selectedFiles.isEmpty()) + recheck = projectFile->getBuildDir().isEmpty() ? Recheck::Selected : Recheck::Cached; + QFileInfo inf(projectFile->getFilename()); const QString& rootpath = projectFile->getRootPath(); @@ -1968,11 +2026,11 @@ void MainWindow::analyzeProject(const ProjectFile *projectFile, const QStringLis msg.exec(); return; } - doAnalyzeProject(p, checkLib, checkConfig, recheckFiles); // TODO: avoid copy + doAnalyzeProject(p, checkLib, checkConfig, selectedFiles, recheck); // TODO: avoid copy return; } - QStringList paths = recheckFiles.isEmpty() ? projectFile->getCheckPaths() : recheckFiles; + QStringList paths = recheck == Recheck::Selected ? selectedFiles : projectFile->getCheckPaths(); // If paths not given then check the root path (which may be the project // file's location, see above). This is to keep the compatibility with @@ -1981,7 +2039,7 @@ void MainWindow::analyzeProject(const ProjectFile *projectFile, const QStringLis if (paths.isEmpty()) { paths << mCurrentDirectory; } - doAnalyzeFiles(paths, checkLib, checkConfig); + doAnalyzeFiles(paths, checkLib, checkConfig, selectedFiles, recheck); } void MainWindow::newProjectFile() diff --git a/gui/mainwindow.h b/gui/mainwindow.h index c654a2c94f0..a92476a8c20 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -249,6 +250,19 @@ private slots: void changeReportType(); private: + /** @brief How an analysis treats the files selected for a recheck */ + enum class Recheck : std::uint8_t { + /** Not a recheck, everything is analyzed from scratch */ + None, + /** Only the selected files are analyzed, the results of the other files are kept */ + Selected, + /** + * Everything is analyzed. The analyzer information in the build directory is kept, + * except for the selected files, so the unchanged files are not analyzed again. + */ + Cached + }; + bool isCppcheckPremium() const; /** Get filename for last results */ @@ -266,11 +280,11 @@ private slots: /** * @brief Analyze the project. * @param projectFile Pointer to the project to analyze. - * @param recheckFiles files to recheck, empty => check all files + * @param selectedFiles files to recheck, empty => check all files * @param checkLib Flag to indicate if the library should be checked. * @param checkConfig Flag to indicate if the configuration should be checked. */ - void analyzeProject(const ProjectFile *projectFile, const QStringList& recheckFiles, bool checkLib = false, bool checkConfig = false); + void analyzeProject(const ProjectFile *projectFile, const QStringList& selectedFiles, bool checkLib = false, bool checkConfig = false); /** * @brief Set current language @@ -308,8 +322,10 @@ private slots: * @param p imported project * @param checkLib Flag to indicate if library should be checked * @param checkConfig Flag to indicate if the configuration should be checked. + * @param selectedFiles Files selected for a recheck + * @param recheck How the selected files are rechecked */ - void doAnalyzeProject(ImportProject p, bool checkLib = false, bool checkConfig = false, const QStringList& recheckFiles = QStringList()); + void doAnalyzeProject(ImportProject p, bool checkLib = false, bool checkConfig = false, const QStringList& selectedFiles = QStringList(), Recheck recheck = Recheck::None); /** * @brief Analyze all files specified in parameter files @@ -317,8 +333,18 @@ private slots: * @param files List of files and/or directories to analyze * @param checkLib Flag to indicate if library should be checked * @param checkConfig Flag to indicate if the configuration should be checked. + * @param selectedFiles Files selected for a recheck + * @param recheck How the selected files are rechecked + */ + void doAnalyzeFiles(const QStringList &files, bool checkLib = false, bool checkConfig = false, const QStringList& selectedFiles = QStringList(), Recheck recheck = Recheck::None); + + /** + * @brief Clear the results that a new analysis replaces + * @param buildDir Build directory of the analysis + * @param selectedFiles Files selected for a recheck + * @param recheck How the selected files are rechecked */ - void doAnalyzeFiles(const QStringList &files, bool checkLib = false, bool checkConfig = false); + void clearResultsForAnalysis(const std::string& buildDir, const QStringList& selectedFiles, Recheck recheck); /** * @brief Get our default cppcheck settings and read project file. diff --git a/gui/manualtest/docs/handbook.html b/gui/manualtest/docs/handbook.html new file mode 100644 index 00000000000..1da9f571224 --- /dev/null +++ b/gui/manualtest/docs/handbook.html @@ -0,0 +1,453 @@ + + + + + +gui-test Handbook + + + +
+ +
+
gui-test
+

gui-test Handbook

+

The manual tests for cppcheck-gui are written in Gherkin, the plain-language Given/When/Then format. gui-test turns them into automated tests: Claude explores the GUI once and writes a script, and from then on the script is replayed without any AI.

+

Updated 2026-10-24

+ +

Overview

+

Working with gui-test has three steps:

+
    +
  1. Write the test in plain words: what the starting point is, what you do and what you expect to see.
  2. +
  3. Generate the script, once. Claude does the test in the application and writes down what it did as a script.
  4. +
  5. Run the tests as often as you like. The scripts are replayed without AI, and you get a report with the results and screenshots.
  6. +
+

All of this is done in the web interface. The application runs on its own virtual screen, so your desktop is not touched while tests run.

+ +
+ + + Claude writes the script once, every run replays it without AI + + + + + + + + + + A test in words + Gherkin scenarios + + gen.py + Claude does it once + + Replay passes? + + Script saved + in FILE.scripts.json + + run.py + replays it, no AI + + report.html + and results.json + yes + no: Claude gets the reason, up to 3 tries + every run + +
From a test in words to a report: gen.py once, run.py every run.
+
+ +

The tests are kept in tests/, and every run puts its report, logs and screenshots in a new directory under results/.

+ +

Getting started

+

Start web.py with the cppcheck-gui binaries you want to test, then open http://127.0.0.1:8080/ in a browser.

+
./web.py --opensource ~/cppcheck/build/bin/cppcheck-gui \
+         --premium ~/premium/build/bin/cppcheck-gui --src ~/cppcheck
+
    +
  • --opensource and --premium each take the binary of that edition. Give one, both or none; without a binary you can edit tests but not generate or run them.
  • +
  • --src is the git checkout the binaries are built from. It is only used for the git SHA, branch and commit in the report; the default is the directory of the binary.
  • +
  • --dir (default tests), --out (default results) and --port (default 8080) change where test files and results live and which port is used. The server only listens on 127.0.0.1.
  • +
+

Some packages must be installed first. On Ubuntu (checked on 26.04):

+
sudo apt install xvfb xdotool dbus at-spi2-core python3-gi gir1.2-atspi-2.0 python3-pil tesseract-ocr tesseract-ocr-eng
+

The tesseract packages are only needed for ocr checks. To generate scripts the claude command line tool must be installed too.

+ +

The web interface

+
    +
  • Header: Save, Run all (every test in every file), the Edition picker, a status message and a link to this handbook. The Edition picker only shows the editions that web.py got a binary for, and "both" when it got two. Without a binary there is no picker, and tests can be edited but not generated or run.
  • +
  • Left column: three boxes. +
      +
    • Test files, with New file. A file is flagged invalid when a test in it has errors, and regenerate N when N tests have an outdated script.
    • +
    • Test projects, with New test project.
    • +
    • Results: Reports lists the earlier runs with their date, edition, version, test files and result. Click a date to open the report.
    • +
  • +
  • Main area: the open test file with its tests, the open test, or the open test project. Each has an ✕ in the top right corner to close it.
  • +
  • Job box: while a script is generated or tests run, it shows the progress, the results as they come in and a link to the report. Stop ends the job. Its ✕ hides the box until the next job.
  • +
+ +

Gherkin

+

The manual tests are written in Gherkin, the language that Cucumber, behave and other behaviour-driven development tools use. Gherkin describes behaviour in plain words with a small set of keywords, so a test reads the same for a developer, a tester and Claude. Each test file in tests/ is a .feature file with one feature, and every scenario in it is one test.

+
Feature: Preferences
+
+  Background:
+    Given the application is started with no project loaded
+
+  @id:t28ce8afe @project:embedded @edition:opensource
+  Scenario Outline: Misra rule text file
+    Given Edit > Preferences is open on the Addons tab
+    When I select the rule text file {project:embedded}/<rulefile>
+    And I close the dialog with OK
+    And I open the project file {project:embedded}/embedded.cppcheck
+    And I wait until the analysis is done
+    Then the Misra error for the unused parameter has the rule text from the file
+    And there are no internalError results
+
+    Examples:
+      | rulefile              |
+      | rules.txt             |
+      | rules with spaces.txt |
+ +

Keywords

+
+ + + + + + + + + + + + + + + + +
KeywordMeaning here
Feature:The first line of the file. Its text is the title of the test file, shown in the editor and the report. Lines below it, before the first scenario, are a free description
Background:Steps that come before every scenario of the file, typically Given the application is started with no project loaded. At most one, before the scenarios
Scenario:One test. The text after the colon is the name of the test, unique within the file. Example: means the same
Scenario Outline:A test that is run once for every row of its Examples table. Scenario Template: means the same
Examples:The table of a scenario outline. The first row is the header with the column names; <column> in a step is replaced by the value of the row. See Examples (test matrix)
GivenThe starting point: the state that the application is in before the test does anything
WhenAn action of the user: a click, a menu entry, typing, opening a file
ThenThe expected result: something that can be seen in the GUI or in a file. Every scenario needs at least one Then
And, But, *Continue the step above with the same meaning, e.g. a second Then. A scenario can not start with And or But
"""A doc string: lines of text that belong to the step above, e.g. code to type into the scratch pad. It ends with another """
| a | b |A data table that belongs to the step above
@tagTags on the line above a scenario, see below
# textA comment. Comments are lost when the web interface saves the file
TODO:Not standard Gherkin: a description line under the scenario name that says why the test can't be automated yet
+

A scenario can switch between When and Then more than once, when a result has to be checked in the middle of the test:

+
  Scenario: Filter the results
+    Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu
+    And the analysis is done
+    When I type "arrayIndex" in the Filter field
+    Then only the arrayIndexOutOfBounds error in b.c is shown
+    When I clear the Filter field
+    Then all errors are shown again
+ +

Tags

+

Everything about a test that is not a step is a tag on the line above the scenario. Tags can't contain spaces.

+
+ + + + + + + +
TagMeaning
@id:t1a2b3c4dIdentifies the test, also when it is renamed. The script is stored by this id. Added automatically when it is missing; don't change it
@ticket:14893The ticket of the test, shown as #14893
@project:NAMEA test project that the test uses, one tag per project
@edition:opensourceAn edition that the test is for, one tag per edition. Without the tag the test is for all editions
@disabledThe test is not run
+

Other tags are kept but have no meaning for gui-test.

+ +

Writing good steps

+

Claude reads the steps as they are when it makes the script, and the Then steps become the checks. A good scenario is one that a new tester could follow without asking:

+
    +
  • Use the words of the GUI: the menu entries, button texts and dialog titles as they are shown, e.g. When I open File > Edit Project File.
  • +
  • Write Given steps as a state (Given the analysis is done), When steps as an action (When I click Recheck) and Then steps as something that can be seen (Then the nullPointer error in a.c is gone).
  • +
  • One thing per Then step. Then there are no results for a.c and And there are no results for b.c become two checks, and a failure points at the right one.
  • +
  • Be concrete about results: name the file, the error id and the line instead of "the results are correct".
  • +
  • Say how to wait: And I wait until the analysis is done.
  • +
  • Refer to files with {project:NAME}/path, and to the scratch directory with {work}.
  • +
  • Keep the steps that all tests of a file share in the Background.
  • +
+

Changing the steps, the Background or the Examples makes the script of the test outdated, because the script was made for the old words.

+ +

Differences from Cucumber

+
    +
  • There are no step definitions. In Cucumber every step is matched by a pattern to code that someone writes. Here Claude reads the scenario once and writes a script for it, and the script is replayed. Steps can therefore be free text; they don't have to repeat fixed phrases.
  • +
  • The script of a scenario is stored next to the feature file in FILE.scripts.json, by test id.
  • +
  • Rule:, tags on Examples, and more than one Feature per file are not supported.
  • +
  • Placeholders in braces are gui-test variables, not Gherkin: {project:NAME}, {work} and {edition}.
  • +
  • TODO: description lines are a gui-test convention.
  • +
+ +

Writing tests

+

A test is a Gherkin scenario, written as if for a person: Given steps say where the test starts, When steps what is done and Then steps the result to expect. Claude reads exactly these words when it makes the script, so be concrete.

+
Feature: Results list
+
+  Background:
+    Given the application is started with no project loaded
+
+  @id:t389a5f3a @project:basic-project
+  Scenario: Clear results
+    Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu
+    And the analysis is done
+    When I click Clear results
+    Then the results are cleared: the result tree is empty
+

The files can be edited in the web interface or in a text editor. The Gherkin chapter describes the format; the web interface shows the tags of a scenario (ticket, editions, test projects, enabled) as separate fields.

+

Tests live in test files (tests/*.feature), one file per area of the GUI. Click a file in the left column to open it, or New file to create one. An open file shows:

+
    +
  • Title: the Feature: line, shown in the report.
  • +
  • Background: the steps that are done before every test of the file, e.g. Given the application is started with no project loaded.
  • +
  • Tests: the list of tests. Click one to edit it, + New test to add one. A test is flagged invalid when it has errors and regenerate when its script is outdated.
  • +
  • Run tests: runs all tests in the file.
  • +
+

Nothing is written to disk until you press Save; a dot after the file name means there are unsaved changes. Errors, such as a test without a Then step, are shown under the field and must be fixed before you can save.

+

The test editor has these fields. The ↑ and ↓ buttons move the test in the list, and Delete removes it.

+
+ + + + + + + + + + + +
FieldWhat to write
NameUnique within the file. Shown in reports and the history, so a rename starts a new history line
TicketOptional, e.g. a Trac ticket number
enabledUntick to leave the test out of every run without deleting it
EditionsTick the editions the test runs in; by default all. The script is the same for all editions, {edition} is replaced by the edition's name
Scenario stepsOne Gherkin step per line, e.g. "When I open File > New Project File". Every Then step becomes at least one check in the script. Use <column> for the values of the Examples
TODOWhy a test can't be automated yet, e.g. "cannot be automated". Leave empty otherwise. In the file it is a line TODO: ... below the scenario name
Test projectsTick the projects whose files the test uses, see below
ScriptThe script of the test, with the buttons Generate script, Run test and, when it is outdated, Approve the script. See Scripts
ExamplesA Gherkin table; every row is a separate run and the test becomes a Scenario Outline
+ +

Examples (test matrix)

+

A Scenario Outline is run once for every row of its Examples table:

+
    When I select the platform <platform>
+    ...
+    Examples:
+      | platform | lang |
+      | native   | C    |
+      | unix32   | C++  |
+

That is 2 runs. A step like "When I select the platform <platform>" gets the value of each run, in the script it is {platform}. The runs are named after the test plus the values, e.g. Relative paths [platform=unix32, lang=C++], and each one gets its own line in the report. The editor shows how many runs the Examples give.

+ +

Test projects

+

A test project is a directory of files that tests use: source files, a .cppcheck project file, a .cfg file. They live in tests/projects/NAME and are edited under Test projects in the left column. Before every run the project is copied to a new empty directory, so a test always starts with the same files, even if an earlier test changed them. In a script the copy is {project:NAME}, or {project} when the test has only one project.

+

Changing a file in a project makes the scripts of the tests that use it outdated, because the script was made for the old files.

+ +

Scripts

+

A test runs only when it has an up-to-date script. Generate it with Claude once, check it, and from then on it is replayed without AI.

+ +

Generating a script

+

Open the test and press Generate script. gen.py starts the application with the test projects in place, and Claude does the test by hand: it looks at the accessibility tree, clicks and types, and checks the expected result (the Then steps). It then answers with a script. The script is replayed from scratch and saved in FILE.scripts.json only if that replay passes. When the replay fails, Claude is told why and tries again, 3 attempts in all. While a script is generated the editor is locked.

+
    +
  • A Scenario Outline is explored with the first row of its Examples. The script uses {column} where the values belong.
  • +
  • When the application does not do what the expected result says, Claude still writes the script that checks it and marks that one check "observed_fail": true. The script is saved, and the test fails until the bug is fixed. That is a finding, not a broken script.
  • +
  • When the test can't be done through the GUI, Claude answers CANNOT: <reason> and no script is saved.
  • +
+

Read the generated script before you trust it, especially its expect steps: they decide what the test proves.

+ +

The script format

+

A script is a JSON list of steps. Each step has do (an action) or expect (a check), and a label in the words of the test that is shown when it fails. Elements are found by name (part of the accessible name, case-insensitive) and role, and if needed path, nth and exact.

+
[
+  {"do": "click", "name": "Help", "role": "menu item", "label": "Open the Help menu"},
+  {"do": "click", "name": "Contents", "role": "menu item", "label": "Choose Help > Contents"},
+  {"expect": "visible", "name": "Cppcheck GUI help", "role": "dialog", "label": "A help window opens"}
+]
+
+ + + + + + + + + + + + + + + +
StepWhat it does
do: click, rightclick, doubleclick, focus, hoverAct on an element; "mouse": true clicks with the mouse
do: settextReplace the text of an edit field with value
do: type, keyKeyboard input to the focused element; keys uses xdotool names like ctrl+o, Return
do: waitWait for an element to appear, or with "gone": true to disappear
do: restartQuit and start the application again; settings are kept
do: sleep, write, copyPause, write a file in {work}, or copy a file in a test project
expect: visible, goneAn element is shown, or is not
expect: stateAn element is or is not checked, enabled, focused, selected, expanded...
expect: valueThe value or text of a field equals something
expect: text, ocrText is (not) on the screen; ocr reads pixels with tesseract, for context menus AT-SPI can't see
expect: fileA file contains, does not contain or matches a regex
expect: alive, exitedThe application is still running, or has quit by itself with status 0
expect: captureSearch regex in an element and save group 1 as a name; {name} in the later steps is replaced by it, for text that changes such as the version
+

Checks and actions wait for their element up to timeout seconds, 5 by default. The placeholders {work}, {home}, {project:NAME}, {column} (of the Examples) and {edition} are replaced before the run, captured values when the capture step has passed. The full description is under How to write a script below the script in the editor.

+ +

Outdated scripts

+

A script is made for the test's steps, the Background of the file, TODO, Examples and the files of its test projects. When any of those change, the script is OUTDATED: it is kept but skipped by every run, and the editor says so in red. You then have three choices:

+
    +
  1. Generate script again.
  2. +
  3. Approve the script when the change does not affect it, e.g. a typo fix in a step.
  4. +
  5. Edit the script by hand in the editor; it has to be valid JSON before you can save.
  6. +
+ +

Running tests

+

Every test starts a fresh application with an empty HOME and fresh copies of its test projects, so tests never depend on each other.

+ +

From the web interface

+

Pick the edition in the header first: opensource, premium or both. Then:

+
    +
  • Run test in an open test runs that test, all the rows of its Examples.
  • +
  • Run tests in an open test file runs every test in that file.
  • +
  • Run all runs every test in every file.
  • +
+

With "both", the run is done for one edition and then the other, and each edition gets its own report. The job box shows the test and step that is running and the results as they come. Stop ends the run at once: the test that was running is SKIP "aborted by user", and the report is written with the tests that are done. Only one job runs at a time.

+ +

From the command line

+
./run.py ~/cppcheck/build/bin/cppcheck-gui tests/application.feature tests/projects.feature --edition opensource
+
+ + + + + + + + + +
OptionMeaning
APPThe binary to test
FILE ...One or more test files
--edition opensource|premiumAPP is this edition; only the tests for it run. Without it all tests run and there is no history per edition
--test TEXTOnly tests whose name contains TEXT (case-insensitive)
--id IDOnly the test with this id, all the rows of its Examples
--src DIRGit checkout for the SHA in the report; default the directory of APP
--out DIRWhere the run directories go; default results
+

run.py prints one line per test and the path of the report, and exits with 1 when a test failed, so it can be used in a script or CI job. Scripts are generated the same way with ./gen.py APP FILE.feature; it takes --edition, --test, --id, --force (also tests that have a script), --model and --attempts.

+ +

What happens in a run

+
    +
  1. The tests to run are selected: enabled, for this edition, not filtered out. Tests without a script, or with an outdated one, are SKIP.
  2. +
  3. For each test, the test projects are copied and the application is started on a new virtual screen with an empty HOME.
  4. +
  5. The script is replayed step by step. After every step that acts on the GUI (click, type, key, settext, restart...) a screenshot is saved.
  6. +
  7. At the end, or at the first failing step, the step log, a final screenshot and the application log are saved, and the log is searched for a crash.
  8. +
  9. After the last test, results.json and report.html are written in the run directory.
  10. +
+ +

Reading the report

+

Each run writes one self-contained report.html; read it top-down: the verdict first, then what changed, then the details of each failure.

+
+ The top of a report: verdict, run details, number boxes, results per test file, the last runs and the status history +
The top of a report from three runs of two test files.
+
+
+ + + + + + + + + + +
PartWhat it tells you
HeaderFAILED or PASSED with the count, and the run details: date, edition, duration, git SHA ("+ uncommitted changes" when the checkout was dirty), branch, commit, application, host, test files
Number boxesPassed, failed (how many crashed the app), skipped, duration, and with history the change against the previous run
Results per test fileA bar per file, green/red/amber. Shows whether failures are in one part of the GUI. Only when the run has more than one file
The last runsPass, fail and skip counts for up to 15 runs of the same edition; the number on a column is its failures
Changed since the previous runNEW failures, tests that are fixed, and tests that are STILL FAILING
Status historyA row per test that did not pass in every run: "new failure", "failing since 10/22 12:00 (b8b27a)", "fixed since", "flaky: 4 changes", "never ran"
Failed and skipped testsA card per test: the reason, the step strip, the screenshots after the last 3 steps and the final screen with a red frame
All testsEvery test grouped by file, with its time, links to its files and its step screenshots
+ +

The step strip

+

Every test has a strip with a cell per script step: green passed, red failed, grey not run. A failure at step 2 of 14 usually means the test or the application broke early. A failure at the last step usually means one check is wrong, or the bug the check describes. Under the strip it says e.g. "failed at step 9 of 14", "not run" or "did not start".

+ +

Files in a run directory

+

A run directory is results/<date>-<time>-<edition>-<sha>/, e.g. 20261022-120317-opensource-b8b27a95/. The files of a test are named after the test (NAME below), with spaces and other special characters replaced by _. They are also linked from the report.

+
+ + + + + + + + +
FileContent
report.htmlThe report
results.jsonThe run details and every result. The history is read from these files
NAME.txtThe step log: each step, ok or FAIL, its time and its screenshot
NAME.pngThe screen at the end of the test, or when it failed
NAME.stepNN.pngThe screen after step NN, for steps that act on the GUI
NAME.app.logWhat the application printed
+

The history compares runs of the same edition in the same results directory. Tests are matched by name.

+ +

Troubleshooting

+

Start with the reason in the report and the final screenshot: together they usually say whether the application, the script or the test is wrong.

+
+ + + + + + + + + + + + +
What you seeWhat it means and what to do
SKIP "no script"The test has no script yet. Generate one, or write it by hand
SKIP "OUTDATED SCRIPT"The test or one of its test projects changed after the script was made. Generate again, or approve the script if the change doesn't matter to it
FAIL "timeout waiting for element to appear"An element with that name and role wasn't found within the timeout. The reason lists the most similar visible elements and the open windows: a renamed button shows up there. Fix the name in the script, or regenerate
FAIL with observed_fail=True in the reasonClaude saw the application not do what the expected result says when it made the script. It is a known bug, and the test fails until the bug is fixed
FAIL with CRASHThe application was not running at the end of the test, or its log has a fatal message (SIGSEGV, SIGABRT, an assertion, AddressSanitizer, QFATAL...). A crash fails the test even if every step passed. Read NAME.app.log. A test that quits the application with status 0 is not a crash
FAIL "could not start"The session or the application did not start. Check that the packages under Getting started are installed, and that the binary runs
"flaky" in the status historyThe test changes between PASS and FAIL. Usually timing: give the slow step a longer timeout, or add a wait step before it
A context menu can't be foundSome menus are not in the accessibility tree. Check them with an ocr step and choose with key Down and Return
"path ... is outside the test directories"write, copy and file steps may only use {work}, {home} and the test project copies
Generate script or Run test is greyed outweb.py has no binary for the edition picked in the header, or the test is not for that edition. Run test also needs an up-to-date script
+ +

Reference

+

The commands, with all their options. web.py, run.py, gen.py and guitest.py also print their help with --help.

+
web.py [--opensource APP] [--premium APP] [--src DIR] [--dir tests] [--out results] [--port 8080]
+run.py APP FILE.feature... [--edition opensource|premium] [--test TEXT] [--id ID] [--src DIR] [--out results]
+gen.py APP FILE.feature [--edition opensource|premium] [--test TEXT] [--id ID] [--force] [--model M] [--attempts 3]
+testfile.py convert IN.md|IN.json OUT.feature
+ +

guitest.py

+

guitest.py is what Claude uses to drive the GUI, and you can use it by hand to look at the GUI the way a script sees it. The session lives in $GUITEST_STATE (default /tmp/guitest-<uid>/state.json).

+
guitest.py start ~/cppcheck/build/bin/cppcheck-gui
+guitest.py tree --showing --depth 3
+guitest.py click --name Help --role "menu item"
+guitest.py screenshot /tmp/screen.png
+guitest.py stop
+
+ + + + + + + + + + + + +
CommandWhat it does
start APP [ARGS]Start Xvfb, D-Bus, AT-SPI and the application. --home DIR (default an empty directory), --size 1280x900
stop, restartStop everything; quit and start the application again with its settings kept
alive, logExit 0 if the application runs; print what it wrote to stdout and stderr
windows, textsThe top level windows and dialogs; every visible text
treeThe accessibility tree. --showing only visible elements, --depth N, --path P one subtree
click, rightclick, doubleclick, focus, hoverAct on an element found with --name, --role, --path, --nth, --exact. --mouse for a real mouse click
settext VALUE, type VALUE, key KEYSSet a field's text; type into the focused element; press keys (xdotool names)
waitWait for an element, --timeout 10, --gone to wait until it disappears
info, suggestRole, name, text, value and states of one element; the visible elements most like --name/--role
ocr, screenshot FILEText on the screen read by tesseract; a PNG of the screen
+
+
+ + diff --git a/gui/manualtest/docs/report.png b/gui/manualtest/docs/report.png new file mode 100644 index 00000000000..2a24756da06 Binary files /dev/null and b/gui/manualtest/docs/report.png differ diff --git a/gui/manualtest/gen.py b/gui/manualtest/gen.py new file mode 100755 index 00000000000..0a3360065dd --- /dev/null +++ b/gui/manualtest/gen.py @@ -0,0 +1,234 @@ +#!/usr/bin/env python3 +"""Let Claude write the scripts of the tests. The scripts are replayed by run.py without AI. + + gen.py APP FILE.feature [--edition opensource|premium] [--test SUBSTRING] [--force] [--model M] + +For every test without a script (or every test with --force) Claude gets the scenario, drives the +GUI once with the guitest.py commands and answers with a script, see testfile.SCRIPT_DOC. +The script is run again from scratch and is saved in FILE.scripts.json only if that replay passes. +A Scenario Outline is explored with the first row of its Examples, the script uses {column} where +the values of the row belong. With --edition APP is that edition, tests that are not for it are +left out; the script is used for all the editions of the test. +""" + +import argparse +import json +import os +import re +import signal +import subprocess +import sys +import tempfile + +import runner +import testfile + +HERE = os.path.dirname(os.path.abspath(__file__)) +GUITEST = os.path.join(HERE, 'guitest.py') + +PROMPT = """You are writing an automated GUI test script for a Qt application that has been started for you. +First do the test by hand, driving the application only with this command line tool (each call is separate, +the session is already running): + + python3 {guitest} + +{help} + +Tips: +- Start with `tree --showing --depth 3`, `windows` and `texts` to see what is on screen. +- Use `info --name X` to see the roles and states of an element, e.g. the [checked] state. +- Menu items: click the menu (e.g. --name File --role "menu item"), then click the entry. +- Keyboard input goes to the focused element: `focus` first, then `type` / `key`. +- The files of the test are in the test projects, they are already in place, use them as they are:{projects} + Do not make copies of them. In the script write {{project:NAME}} instead of the directory, it is another + directory every run. Anything else that you need can be created in {work} (use Write), do not touch other places. +- A menu that is on screen but not in `tree`/`texts` (e.g. a context menu) can be read with `ocr`; check it in the + script with {{"expect": "ocr", "contains": "..."}} and use the keyboard (`key Down`, `key Return`) to choose in it. +- Never read or modify the application source code. + +Test name: {name} + +The test is written in Gherkin: the Background and the Given steps are the starting point, the When steps are +what you do and the Then steps are the EXPECTED result. + +{body} + +When you have done the test and checked the EXPECTED result (the Then steps), answer with a script that does the +same without you. The script is replayed by a program, so: +- use the exact roles and names that you saw. Give a name and a role. Use "path" only when nothing else tells + the element apart, paths change when the dialogs change (a file dialog's name field is found by its label) +- a name matches any element that contains it, so always give the role too: a toolbar button + "Preferences" and the dialog "Preferences" have the same name, the dialog is role "dialog" +- give every step a "label" that says what it is for, in the words of the test +- end with "expect" steps that check the EXPECTED result, at least one for each Then step +- the files of the test are the test projects, refer to them with {{project:NAME}} paths; files that + you made yourself are created by "write" steps (in {{work}}), not by you +- the application is started fresh before the script, with an empty HOME +- {matrixnote} +- {editionnote} + +{scriptdoc} + +{previous}Check the EXPECTED result honestly. If the application does not do what EXPECTED says that is a finding, not +a mistake in the script: still write the script that checks EXPECTED (it will fail, that is the point) and put +the line `OBSERVED: FAIL - ` before the JSON block and add "observed_fail": true to +the one check that fails. Otherwise put `OBSERVED: PASS`. + +Finish with the script as one JSON list in a ```json code block and nothing after it. +If the test cannot be done through the GUI answer with the single line CANNOT: . +""" + + +PREVIOUS = """An earlier attempt gave this script: +{script} + +When it was replayed from scratch by the program it failed: +{error} + +Find out what is wrong (look at the GUI again if needed) and answer with a corrected script. + +""" + + +def start_session(app, root, projects): + work = tempfile.mkdtemp(prefix='guitest-work-') + state = os.path.join(work, 'state.json') + env = dict(os.environ, GUITEST_STATE=state) + sub = lambda *a, **kw: subprocess.run([sys.executable, GUITEST, *a], env=env, text=True, **kw) + variables = testfile.materialize(root, projects, work) + r = sub('start', app, capture_output=True) + if r.returncode: + sys.exit('error: could not start: ' + (r.stdout + r.stderr).strip()) + with open(state) as f: + home = json.load(f)['env']['HOME'] + return work, home, env, sub, variables + + +def explore(app, root, test, combo, edition, model, background, previous=''): + """Claude does the test by hand and returns (script, error); with a script the error is (OBSERVED, reason).""" + work, home, env, sub, variables = start_session(app, root, test.get('projects', [])) + try: + note = ('this is a Scenario Outline, you explore it with the Examples row %s. Write {%s} in the script wherever ' + 'that value is used, the script is run once for every row of the Examples' % ( + ', '.join('%s=%s' % kv for kv in combo.items()), '}, {'.join(combo)) + ) if combo else 'there are no Examples, write the values in the script as they are' + others = [e for e in testfile.editions(test) if e != edition] + if not edition: + editionnote = 'there is one edition of the application' + elif others: + editionnote = ('the application is the %s edition. The same script is also run with the %s edition, ' + 'write {edition} where the name of the edition is shown' % (edition, ' and '.join(others))) + else: + editionnote = 'the script is only run with the %s edition' % edition + projects = ''.join('\n {project:%s} = %s, files: %s' % (n, variables['project:' + n], + ', '.join(sorted(testfile.project_files(root, n)))) + for n in test.get('projects', [])) or ' none' + prompt = PROMPT.format(guitest=GUITEST, help=sub('--help', capture_output=True).stdout, work=work, + name=test['name'], body=testfile.body(test, combo, edition, background), matrixnote=note, + editionnote=editionnote, + scriptdoc=testfile.SCRIPT_DOC, previous=previous, projects=projects) + cmd = ['claude', '-p', '--allowedTools', 'Bash(python3 %s:*)' % GUITEST, 'Read', 'Write', '--add-dir', work] + if model: + cmd += ['--model', model] + p = subprocess.run(cmd, input=prompt, env=env, text=True, capture_output=True, cwd=work) + finally: + sub('stop', capture_output=True) + m = re.findall(r'^CANNOT:\s*(.*)$', p.stdout, re.M) + if m: + return None, 'Claude: cannot be tested through the GUI: ' + m[-1] + m = re.findall(r'```json\s*(.*?)```', p.stdout, re.S) + if not m: + return None, 'no script in the answer of Claude: ' + (p.stdout.strip() or p.stderr.strip())[:300] + try: + script = json.loads(m[-1]) + except ValueError as e: + return None, 'the script is not valid JSON: %s' % e + errors = testfile.validate_script(script) + observed = re.findall(r'^OBSERVED:\s*(PASS|FAIL)\s*-?\s*(.*)$', p.stdout, re.M) + return (None, '; '.join(errors)) if errors else (script, observed[-1] if observed else ('PASS', '')) + + +def replay(app, root, test, script): + work, home, env, sub, variables = start_session(app, root, test.get('projects', [])) + try: + ok, msg, log = runner.run_script(sub, script, work, home, variables) + finally: + sub('stop', capture_output=True) + return ok, msg + + +def store(path, test_id, script, made_for): + """Put the script in the file as it is now, the file may have been saved by the web interface meanwhile.""" + doc = testfile.ensure_ids(testfile.load(path)) + for t in doc['tests']: + if t['id'] == test_id: + t['script'], t['script_for'] = script, made_for + testfile.save(path, doc) + + +def main(): + ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + ap.add_argument('app') + ap.add_argument('file') + ap.add_argument('--edition', choices=testfile.EDITIONS, help='the edition that APP is, only the tests for it') + ap.add_argument('--test', help='only tests whose name contains this') + ap.add_argument('--id', help='only the test with this id') + ap.add_argument('--force', action='store_true', help='also tests that have a script') + ap.add_argument('--model') + ap.add_argument('--attempts', type=int, default=3, help='tries per test, a failed replay is told to Claude') + args = ap.parse_args() + signal.signal(signal.SIGINT, signal.default_int_handler) # also when started in the background + if not args.file.endswith(testfile.EXT): + sys.exit('error: FILE must be a %s test file, convert markdown or JSON with testfile.py convert' % testfile.EXT) + app = os.path.abspath(args.app) + doc = testfile.ensure_ids(testfile.load(args.file)) + root = os.path.dirname(os.path.abspath(args.file)) + errors = testfile.validate(doc, root) + if errors: + sys.exit('error: ' + '; '.join(errors)) + + failed = 0 + for t in doc['tests']: + if args.test and args.test.lower() not in t['name'].lower() or args.id and t['id'] != args.id: + continue + if (t.get('script') and not args.force) or not t.get('enabled', True): + continue + if args.edition and args.edition not in testfile.editions(t): + print('%s: not a test for the %s edition' % (t['name'], args.edition), flush=True) + continue + combo = testfile.combinations(t)[0] + values = dict(combo, edition=args.edition) if args.edition else combo + made_for = testfile.definition_hash(t, root, doc.get('background')) # the test may be edited while Claude works + print('%s: exploring...' % t['name'], flush=True) + previous, saved = '', False + for attempt in range(1, args.attempts + 1): + script, err = explore(app, root, t, combo, args.edition, args.model, doc.get('background'), previous) + if script is not None: + # the replay uses the first combination, as the exploration did + observed, why = err + ok, err = replay(app, root, t, testfile.subst_deep(script, values)) + # a test that fails on the check that Claude saw fail by hand is a finding: the script is right + m = re.match(r'step (\d+)/', err) + finding = (not ok and observed == 'FAIL' and m and script[int(m.group(1)) - 1].get('observed_fail')) + if ok or finding: + store(args.file, t['id'], script, made_for) + print('%s: saved a script with %d steps (attempt %d)%s' % ( + t['name'], len(script), attempt, + '. It FAILS on a check, as Claude saw: ' + why if finding else ''), flush=True) + saved = True + break + err = 'the replay of the script failed:\n' + err + previous = PREVIOUS.format(script=json.dumps(script, indent=1), error=err) + print('%s: attempt %d failed. %s' % (t['name'], attempt, err), flush=True) + if re.search(r'usage limit|rate limit|limit reached|out of credits', str(err), re.I): + sys.exit('error: Claude refuses to answer (limit), stopping. Run gen.py again later.') + if err.startswith('Claude: cannot'): + break + if not saved: + failed += 1 + print('%s: no script saved' % t['name'], flush=True) + sys.exit(1 if failed else 0) + + +if __name__ == '__main__': + main() diff --git a/gui/manualtest/guitest.py b/gui/manualtest/guitest.py new file mode 100755 index 00000000000..0b28cd7031d --- /dev/null +++ b/gui/manualtest/guitest.py @@ -0,0 +1,715 @@ +#!/usr/bin/env python3 +"""GUI test helper for Qt applications, driven through AT-SPI. + +The application runs in its own Xvfb display with its own D-Bus and +accessibility bus, so the real desktop is never touched. Each subcommand is a +separate process; the session state (environment, pids) lives in a JSON file. + + guitest.py start APP [ARGS...] start the session and the application + guitest.py tree show the accessibility tree + guitest.py click --name Recheck click an element + guitest.py stop kill everything + +State file: $GUITEST_STATE, default /tmp/guitest-/state.json +""" + +import argparse +import contextlib +import io +import glob +import json +import os +import re +import shutil +import signal +import subprocess +import struct +import sys +import tempfile +import threading +import time +import warnings + +warnings.filterwarnings("ignore") + +STATE = os.environ.get('GUITEST_STATE', '/tmp/guitest-%d/state.json' % os.getuid()) + + +# ---------------------------------------------------------------- session + +def load_state(): + try: + with open(STATE) as f: + return json.load(f) + except FileNotFoundError: + sys.exit('error: no session, run "guitest.py start APP" first') + + +# the shell tells how the application ended in app.log: 139 is SIGSEGV, 134 SIGABRT, 143 killed by us +WRAPPER = '"$@" & echo $! > "$0"; wait $!; echo "application exited with status $?" >&2' + + +def launch(cmd, env, tmp, log): + """Start the application. Returns the shell that waits for it and the pid of the application.""" + pidfile = os.path.join(tmp, 'app.pid') + if os.path.exists(pidfile): + os.remove(pidfile) + p = subprocess.Popen(['sh', '-c', WRAPPER, pidfile] + cmd, env=env, start_new_session=True, + stdin=subprocess.DEVNULL, stdout=log, stderr=subprocess.STDOUT) + for _ in range(100): + try: + with open(pidfile) as f: + return p, int(f.read()) + except (OSError, ValueError): + time.sleep(0.05) + sys.exit('error: the application did not start') + + +def exit_info(state): + """' (exited with status 139, SIGSEGV)' when the log says how the application ended, else ''.""" + try: + with open(os.path.join(state['tmp'], 'app.log'), errors='replace') as f: + m = re.findall(r'application exited with status (\d+)', f.read()) + except OSError: + return '' + if not m: + return '' + code = int(m[-1]) + sig = ', ' + signal.Signals(code - 128).name if 128 < code < 160 else '' + return ' (exited with status %d%s)' % (code, sig) + + +def start(args): + if os.path.exists(STATE): + sys.exit('error: session already running (%s), run stop first' % STATE) + app = os.path.abspath(args.app) + if not os.access(app, os.X_OK): + sys.exit('error: not executable: ' + app) + for tool in ('Xvfb', 'xdotool', 'dbus-daemon', '/usr/libexec/at-spi-bus-launcher'): + if not shutil.which(tool) and not os.path.exists(tool): + sys.exit('error: missing ' + tool) + + tmp = tempfile.mkdtemp(prefix='guitest-') + runtime = os.path.join(tmp, 'run') + home = args.home or os.path.join(tmp, 'home') + os.makedirs(runtime, mode=0o700) + os.makedirs(home, exist_ok=True) + # Cppcheck Premium needs its license file in HOME + lic = os.path.join('.cppcheckpremium', 'cppcheck-premium.lic') + src_lic = os.path.join(os.path.expanduser('~'), lic) + dst_lic = os.path.join(home, lic) + if os.path.isfile(src_lic) and os.path.realpath(src_lic) != os.path.realpath(dst_lic): + os.makedirs(os.path.dirname(dst_lic), exist_ok=True) + shutil.copy2(src_lic, dst_lic) + pids = [] + + def spawn(cmd, env, **kw): + kw.setdefault('stdout', subprocess.DEVNULL) + kw.setdefault('stderr', subprocess.DEVNULL) + p = subprocess.Popen(cmd, env=env, start_new_session=True, stdin=subprocess.DEVNULL, **kw) + pids.append(p.pid) + return p + + env = dict(os.environ) + env.update(XDG_RUNTIME_DIR=runtime, HOME=home) + for k in ('XDG_CONFIG_HOME', 'XDG_DATA_HOME', 'XDG_CACHE_HOME', 'XDG_CONFIG_DIRS'): + env.pop(k, None) # QSettings must not find the real preferences + env.pop('WAYLAND_DISPLAY', None) + env.pop('DBUS_SESSION_BUS_ADDRESS', None) + + # session bus + out = subprocess.run(['dbus-daemon', '--session', '--fork', '--print-address', '--print-pid'], + env=env, capture_output=True, text=True, check=True).stdout.split() + env['DBUS_SESSION_BUS_ADDRESS'] = out[0] + pids.append(int(out[1])) + + # X server + r, w = os.pipe() + spawn(['Xvfb', '-displayfd', str(w), '-screen', '0', args.size + 'x24', '-fbdir', tmp], + env, pass_fds=(w,)) + os.close(w) + env['DISPLAY'] = ':' + os.read(r, 16).decode().strip() + os.close(r) + + # accessibility bus + spawn(['/usr/libexec/at-spi-bus-launcher', '--launch-immediately'], env) + for _ in range(100): + if glob.glob(os.path.join(runtime, 'at-spi', 'bus_*')): + break + time.sleep(0.1) + else: + kill(pids, tmp) + sys.exit('error: accessibility bus did not start') + + env.update(QT_QPA_PLATFORM='xcb', QT_ACCESSIBILITY='1', + QT_LINUX_ACCESSIBILITY_ALWAYS_ON='1', QT_NO_XDG_DESKTOP_PORTAL='1', + QT_QPA_PLATFORMTHEME='generic', # not the KDE file dialog, its KIO jobs crash in this session + LANG='C', LC_ALL='C') + log = open(os.path.join(tmp, 'app.log'), 'w') + appproc, app_pid = launch([app] + args.args, env, tmp, log) + pids.append(appproc.pid) + + state = dict(env={k: env[k] for k in ('XDG_RUNTIME_DIR', 'HOME', 'DBUS_SESSION_BUS_ADDRESS', 'DISPLAY', + 'QT_QPA_PLATFORM', 'QT_ACCESSIBILITY', + 'QT_LINUX_ACCESSIBILITY_ALWAYS_ON', 'QT_NO_XDG_DESKTOP_PORTAL', 'QT_QPA_PLATFORMTHEME', + 'LANG', 'LC_ALL')}, + pids=pids, app_pid=app_pid, app_pgid=appproc.pid, app_cmd=[app] + args.args, tmp=tmp) + os.makedirs(os.path.dirname(STATE), exist_ok=True) + with open(STATE, 'w') as f: + json.dump(state, f) + + # wait for the application to show up on the accessibility bus + os.environ.update(state['env']) + for _ in range(100): + if appproc.poll() is not None: + print(open(os.path.join(tmp, 'app.log')).read()) + kill(pids, tmp) + os.remove(STATE) + sys.exit('error: application exited with code %s' % appproc.returncode) + if find_app(state) is not None: + print('started, display %s, app log %s/app.log' % (env['DISPLAY'], tmp)) + return + time.sleep(0.2) + sys.exit('error: application did not appear on the accessibility bus (see %s/app.log)' % tmp) + + +def restart(args): + """Quit the application and start it again, same HOME so settings are kept.""" + state = load_state() + try: + os.killpg(state['app_pgid'], signal.SIGTERM) + except ProcessLookupError: + pass + time.sleep(1) + env = dict(os.environ) + env.update(state['env']) + log = open(os.path.join(state['tmp'], 'app.log'), 'a') + p, state['app_pid'] = launch(state['app_cmd'], env, state['tmp'], log) + state['app_pgid'] = p.pid + state['pids'].append(p.pid) + with open(STATE, 'w') as f: + json.dump(state, f) + for _ in range(100): + if find_app(state) is not None: + print('restarted') + return + time.sleep(0.2) + sys.exit('error: application did not come back') + + +def kill(pids, tmp): + for pid in reversed(pids): + try: + os.killpg(pid, signal.SIGTERM) + except (ProcessLookupError, PermissionError): + try: + os.kill(pid, signal.SIGTERM) + except (ProcessLookupError, PermissionError): + pass + time.sleep(0.3) + shutil.rmtree(tmp, ignore_errors=True) + + +def stop(args): + try: + state = load_state() + except SystemExit: + return + kill(state['pids'], state['tmp']) + os.remove(STATE) + print('stopped') + + +# ---------------------------------------------------------------- AT-SPI + +_atspi = None + + +def atspi(): + global _atspi + if _atspi is None: + os.environ.update(load_state()['env']) + import gi + gi.require_version('Atspi', '2.0') + from gi.repository import Atspi + _atspi = Atspi + return _atspi + + +def find_app(state): + A = atspi() + desktop = A.get_desktop(0) + for i in range(desktop.get_child_count()): + try: + app = desktop.get_child_at_index(i) + if app is not None and app.get_process_id() == state['app_pid']: + return app + except Exception: + pass + return None + + +def app_running(state): + """The process is there (a zombie is a crashed application nobody has collected).""" + try: + with open('/proc/%d/stat' % state['app_pid']) as f: + return f.read().rsplit(')', 1)[1].split()[0] != 'Z' + except OSError: + return False + + +def get_app(): + state = load_state() + for _ in range(25): # the application does not answer on the accessibility bus while a modal dialog opens + app = find_app(state) + if app is not None: + return app + if not app_running(state): + break + time.sleep(0.2) + if app_running(state): + sys.exit('error: the application is running but does not answer on the accessibility bus (busy or hung?)') + sys.exit('error: the application is not running%s. log: %s/app.log' % (exit_info(state) or ' (crashed?)', state['tmp'])) + + +def children(node): + try: + for i in range(node.get_child_count()): + c = node.get_child_at_index(i) + if c is not None: + yield i, c + except Exception: + return + + +def states(node): + A = atspi() + st = node.get_state_set() + names = [] + for label, s in (('showing', A.StateType.SHOWING), ('enabled', A.StateType.ENABLED), + ('focused', A.StateType.FOCUSED), ('checked', A.StateType.CHECKED), + ('selected', A.StateType.SELECTED), ('expanded', A.StateType.EXPANDED), + ('editable', A.StateType.EDITABLE), ('modal', A.StateType.MODAL)): + if st.contains(s): + names.append(label) + return names + + +def walk(node, path=(), depth=0): + yield path, node, depth + for i, c in children(node): + yield from walk(c, path + (i,), depth + 1) + + +def node_text(node): + # the interface functions take the accessible as first argument, node.get_text_iface() does not work here + A = atspi() + try: + if 'Text' in A.Accessible.get_interfaces(node): + return A.Text.get_text(node, 0, min(A.Text.get_character_count(node), 2000)) + except Exception: + pass + return None + + +def node_value(node): + A = atspi() + try: + if 'Value' in A.Accessible.get_interfaces(node): + return A.Value.get_current_value(node) + except Exception: + pass + return None + + +def extents(node): + A = atspi() + try: + e = node.get_component_iface().get_extents(A.CoordType.SCREEN) + return e.x, e.y, e.width, e.height + except Exception: + return None + + +def describe(path, node, with_geom=True): + name = node.get_name() or '' + s = '%s %s %r' % ('.'.join(map(str, path)) or '-', node.get_role_name(), name) + text = node_text(node) + if text and text != name: + s += ' text=%r' % (text if len(text) < 200 else text[:200] + '...') + val = node_value(node) + if val is not None: + s += ' value=%s' % val + st = states(node) + if st: + s += ' [%s]' % ','.join(st) + g = extents(node) + if with_geom and g and g[2] > 0: + s += ' @%d,%d %dx%d' % g + return s + + +def cmd_tree(args): + app = get_app() + root, rootpath = app, () + if args.path: + rootpath = tuple(int(x) for x in args.path.split('.')) + for i in rootpath: + root = root.get_child_at_index(i) + for path, node, depth in walk(root, rootpath): + d = len(path) - len(rootpath) + if d > args.depth: + continue + if args.showing and 'showing' not in states(node) and d > 0: + continue + print(' ' * d + describe(path, node)) + + +def cmd_windows(args): + app = get_app() + for i, c in children(app): + print(describe((i,), c)) + + +def cmd_texts(args): + """All visible text on screen, one line per element, for checking EXPECTED.""" + app = get_app() + for path, node, depth in walk(app): + if 'showing' not in states(node): + continue + role = node.get_role_name() + name = node.get_name() or '' + text = node_text(node) + if role in ('label', 'push button', 'check box', 'radio button', 'menu item', 'text', 'entry', + 'page tab', 'combo box', 'table cell', 'tree item', 'list item', 'status bar', + 'title bar', 'spin button', 'frame', 'dialog', 'alert') or text: + line = '%s %s %r' % ('.'.join(map(str, path)), role, name) + if text and text != name: + line += ' text=%r' % text + if 'checked' in states(node): + line += ' [checked]' + print(line) + + +# ---------------------------------------------------------------- finding + +def select(args, need_showing=True): + app = get_app() + if args.path: + node = app + for i in (int(x) for x in args.path.split('.')): + node = node.get_child_at_index(i) + if node is None: + sys.exit('error: no such path') + return node + matches = [] + for path, node, depth in walk(app): + role = node.get_role_name() + if args.role and args.role.lower() != role.lower(): + continue + name = node.get_name() or '' + text = '' # found by name only: the text of a panel would match the message of an error + if args.name is not None: + want = args.name.lower() + if args.exact: + if name.lower() != want and text.lower() != want: + continue + elif want not in name.lower() and want not in text.lower(): + continue + elif not args.role: + sys.exit('error: give --name, --role or --path') + if need_showing and 'showing' not in states(node): + continue + matches.append((path, node)) + if not matches: + sys.exit('error: no matching visible element (name=%r role=%r); try "tree --showing"' % (args.name, args.role)) + if args.nth is None and len(matches) > 1: + lines = '\n'.join(' ' + describe(p, n) for p, n in matches[:15]) + sys.exit('error: %d matches, narrow with --role/--exact or pick with --nth N (0-based):\n%s' % (len(matches), lines)) + nth = args.nth or 0 + if nth >= len(matches): + sys.exit('error: no matching visible element: only %d match(es) for name=%r role=%r, nth=%d is too high' + % (len(matches), args.name, args.role, nth)) + return matches[nth][1] + + +def xdo(*a): + env = dict(os.environ) + env.update(load_state()['env']) + subprocess.run(['xdotool'] + [str(x) for x in a], env=env, check=True) + + +def center(node): + g = extents(node) + if not g or g[2] <= 0: + sys.exit('error: element has no geometry') + return g[0] + g[2] // 2, g[1] + g[3] // 2 + + +def mouse(node, button=1, count=1): + x, y = center(node) + xdo('mousemove', x, y) + time.sleep(0.05) + xdo('click', '--repeat', count, '--delay', 80, button) + + +def do_action(node): + A = atspi() + try: + act = node.get_action_iface() + if act is None: + return False + for i in range(act.get_n_actions()): + if act.get_action_name(i).lower() in ('click', 'press', 'toggle', 'activate', 'check', 'uncheck'): + return act.do_action(i) + except Exception: + pass + return False + + +def cmd_click(args): + node = select(args) + desc = describe((), node, False) + if args.mouse: + mouse(node) + else: + # the action of a button that opens a modal dialog does not return until the dialog is closed + done = [] + t = threading.Thread(target=lambda: done.append(do_action(node)), daemon=True) + t.start() + t.join(args.settle + 1) + if done == [False]: + mouse(node) + elif not done: + time.sleep(args.settle) + print('clicked ' + desc, flush=True) + os._exit(0) + time.sleep(args.settle) + print('clicked ' + desc) + + +def cmd_rightclick(args): + node = select(args) + mouse(node, 3) + time.sleep(args.settle) + print('right-clicked ' + describe((), node, False)) + + +def cmd_doubleclick(args): + node = select(args) + mouse(node, 1, 2) + time.sleep(args.settle) + print('double-clicked ' + describe((), node, False)) + + +def cmd_focus(args): + node = select(args) + ok = node.get_component_iface().grab_focus() + if not ok: + mouse(node) + print('focused ' + describe((), node, False)) + + +def cmd_settext(args): + node = select(args) + et = node.get_editable_text_iface() + if et is None: + sys.exit('error: element is not editable text') + et.set_text_contents(args.value) + time.sleep(args.settle) + print('set text of ' + describe((), node, False)) + + +def cmd_type(args): + xdo('type', '--delay', 20, '--', args.value) + time.sleep(args.settle) + + +def cmd_key(args): + xdo('key', *args.keys) + time.sleep(args.settle) + + +def cmd_hover(args): + x, y = center(select(args)) + xdo('mousemove', x, y) + + +def cmd_wait(args): + deadline = time.time() + args.timeout + while True: + try: + node = select(args) + found = describe((), node, False) + except SystemExit as e: + if 'matches' in str(e): # ambiguous means it exists + found = str(e).split('\n')[0] + else: + found = None + if args.gone != (found is not None): + print('gone' if args.gone else 'found ' + found) + return + if time.time() > deadline: + sys.exit('error: timeout waiting for element %s' % ('to disappear' if args.gone else 'to appear')) + time.sleep(0.3) + + +def cmd_info(args): + """One line about the element: role, name, text, value and [states].""" + print(describe((), select(args), False)) + + +def cmd_suggest(args): + """Visible named elements, the ones most like --name first (for error messages).""" + import difflib + want = (args.name or '').lower() + items = [] + for path, node, depth in walk(get_app()): + name = (node.get_name() or '').strip() + if name and 'showing' in states(node): + items.append((node.get_role_name(), name)) + items.sort(key=lambda it: ((it[0].lower() != (args.role or '').lower()) if args.role else 0, + -difflib.SequenceMatcher(None, want, it[1].lower()).ratio())) + seen = [] + for it in items: + if it not in seen: + seen.append(it) + print('%s %r' % it) + if len(seen) >= args.limit: + break + + +def cmd_screenshot(args): + from PIL import Image + state = load_state() + src = os.path.join(state['tmp'], 'Xvfb_screen0') + data = open(src, 'rb').read() + (hdr, _ver, _fmt, _depth, w, h, _xoff, _bo, _bu, _bbo, _bp, bpp, bpl, _vc, + rm, gm, bm, _bpr, _ncm, ncolors) = struct.unpack('>20I', data[:80]) + off = hdr + ncolors * 12 + img = Image.frombuffer('RGB', (w, h), data[off:off + bpl * h], 'raw', 'BGRX', bpl, 1) + img.save(args.file) + print('saved %s (%dx%d)' % (args.file, w, h)) + + +def cmd_ocr(args): + """Text on the screen read by tesseract, also what AT-SPI does not show (some context menus).""" + import tempfile + png = os.path.join(tempfile.mkdtemp(prefix='guitest-ocr-'), 'screen.png') + args.file = png + with contextlib.redirect_stdout(io.StringIO()): + cmd_screenshot(args) + from PIL import Image + img = Image.open(png) + img = img.resize((img.width * 2, img.height * 2), Image.LANCZOS) + img.save(png) + p = subprocess.run(['tesseract', png, '-', '--psm', '11'], capture_output=True, text=True) + if p.returncode: + sys.exit('error: tesseract failed: ' + p.stderr.strip()) + shutil.rmtree(os.path.dirname(png), ignore_errors=True) + print(p.stdout) + + +def cmd_log(args): + print(open(os.path.join(load_state()['tmp'], 'app.log')).read()) + + +def cmd_alive(args): + sys.exit(0 if app_running(load_state()) else 'application is not running') + + +# ---------------------------------------------------------------- cli + +def selector(p): + p.add_argument('--name', help='substring of accessible name or text (case-insensitive)') + p.add_argument('--role', help='role, e.g. "push button", "menu item", "tree item", "check box"') + p.add_argument('--path', help='path from "tree", e.g. 0.1.2') + p.add_argument('--nth', type=int, help='pick the Nth match (0-based)') + p.add_argument('--exact', action='store_true', help='--name must match exactly') + + +def main(): + ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + sub = ap.add_subparsers(dest='cmd', required=True) + + p = sub.add_parser('start', help='start session and application') + p.add_argument('app') + p.add_argument('args', nargs='*') + p.add_argument('--home', help='HOME for the application (default: empty temporary dir)') + p.add_argument('--size', default='1280x900') + p.set_defaults(f=start) + + sub.add_parser('stop', help='stop session').set_defaults(f=stop) + sub.add_parser('restart', help='quit and start the application again (settings are kept)').set_defaults(f=restart) + sub.add_parser('alive', help='exit 0 if the application is running').set_defaults(f=cmd_alive) + sub.add_parser('log', help='application stdout/stderr').set_defaults(f=cmd_log) + sub.add_parser('windows', help='top level windows and dialogs').set_defaults(f=cmd_windows) + sub.add_parser('texts', help='all visible texts').set_defaults(f=cmd_texts) + + p = sub.add_parser('tree', help='accessibility tree') + p.add_argument('--depth', type=int, default=99) + p.add_argument('--path', help='only this subtree') + p.add_argument('--showing', action='store_true', help='only visible elements') + p.set_defaults(f=cmd_tree) + + for name, f, h in (('click', cmd_click, 'click (uses the accessibility action when there is one)'), + ('rightclick', cmd_rightclick, 'right click (opens context menu)'), + ('doubleclick', cmd_doubleclick, 'double click'), + ('focus', cmd_focus, 'give keyboard focus'), + ('hover', cmd_hover, 'move the mouse over the element')): + p = sub.add_parser(name, help=h) + selector(p) + p.add_argument('--settle', type=float, default=0.5, help='seconds to wait afterwards') + if name == 'click': + p.add_argument('--mouse', action='store_true', help='use a real mouse click') + p.set_defaults(f=f) + + p = sub.add_parser('settext', help='replace the text of an edit field') + selector(p) + p.add_argument('value') + p.add_argument('--settle', type=float, default=0.3) + p.set_defaults(f=cmd_settext) + + p = sub.add_parser('type', help='type text with the keyboard into the focused element') + p.add_argument('value') + p.add_argument('--settle', type=float, default=0.3) + p.set_defaults(f=cmd_type) + + p = sub.add_parser('key', help='press keys, xdotool syntax, e.g. Return ctrl+o Escape') + p.add_argument('keys', nargs='+') + p.add_argument('--settle', type=float, default=0.3) + p.set_defaults(f=cmd_key) + + p = sub.add_parser('wait', help='wait until a (visible) element exists') + selector(p) + p.add_argument('--timeout', type=float, default=10) + p.add_argument('--gone', action='store_true', help='wait until it disappears') + p.set_defaults(f=cmd_wait) + + p = sub.add_parser('info', help='role, name, text, value and states of one element') + selector(p) + p.set_defaults(f=cmd_info) + + p = sub.add_parser('suggest', help='visible elements most similar to --name/--role') + p.add_argument('--name') + p.add_argument('--role') + p.add_argument('--limit', type=int, default=8) + p.set_defaults(f=cmd_suggest) + + p = sub.add_parser('ocr', help='print the text on the screen as read by tesseract (for what "texts" does not show)') + p.set_defaults(f=cmd_ocr) + p = sub.add_parser('screenshot', help='save a PNG of the screen') + p.add_argument('file') + p.set_defaults(f=cmd_screenshot) + + args = ap.parse_args() + try: # command history next to the state file, so a watcher can see what a test is doing + with open(os.path.join(os.path.dirname(STATE), 'commands.log'), 'a') as f: + f.write(time.strftime('%H:%M:%S ') + ' '.join(sys.argv[1:]) + '\n') + except OSError: + pass + args.f(args) + + +if __name__ == '__main__': + main() diff --git a/gui/manualtest/mainwindow.md b/gui/manualtest/mainwindow.md deleted file mode 100644 index 563a538530f..00000000000 --- a/gui/manualtest/mainwindow.md +++ /dev/null @@ -1,21 +0,0 @@ - -# Main window - -Some manual testing in the main window interface - - -## Test: Recheck file - -1. Load a project with results. -1. Restart the GUI. -1. Right click on a file and click on "Recheck". - -EXPECTED: Results for that file should be refreshed. - - -## Test: Switch project - -1. Open project #1 -1. Open project #2 that has different results - -EXPECTED: Results for project #1 should go away, results for project #2 should be shown diff --git a/gui/manualtest/projectfiledialog.md b/gui/manualtest/projectfiledialog.md deleted file mode 100644 index ce7d39b1df0..00000000000 --- a/gui/manualtest/projectfiledialog.md +++ /dev/null @@ -1,52 +0,0 @@ - -# Project file dialog - -Some manual testing in the project file dialog interface - - -## Test: Relative paths - -Ticket: #14983 - -1. Configure files/paths in project folder: - * import a projectfile - * add include paths in project folder - * exclude file/folder - -2. Save project - -EXPECTED: Relative paths should be used in the XML - - -## Test: Platform file pic8.xml - -Ticket: #14489 - -EXPECTED: In the project file dialog it should be possible to select xml files i.e. pic8.xml - -TODO: can this test be automated - - -## Test: Custom cfg file - -Ticket: #14672 - -1. Copy addons/avr.cfg to a file "aa.cfg" in same folder as a cppcheck GUI project file - -EXPECTED: It should not be possible to activate "aa.cfg" in the project file dialog, it should appear in alphabetical order. - - -## Test: Misra C checkbox - -Ticket: #14488 - -Matrix: Use both open source and premium - -1. Load project file in trac ticket 14488 -1. Goto "Edit project" -1. Goto "Addons" tab - -EXPECTED: The misra c checkbox should be checked - -TODO: can this test be automated - diff --git a/gui/manualtest/report.py b/gui/manualtest/report.py new file mode 100644 index 00000000000..e84df758eb9 --- /dev/null +++ b/gui/manualtest/report.py @@ -0,0 +1,408 @@ +"""The HTML report of a run.py run: summary, results per test file, history over the earlier runs, +the failed tests with their screenshots and all tests. One file, no external resources. + +write(path, run, history) where run is what run.py saves as results.json and history is the +results.json of earlier runs of the same edition, oldest first. +""" + +import html +import os + +STATUSES = ('PASS', 'FAIL', 'SKIP') +ICON = {'PASS': '✓', 'FAIL': '✗', 'SKIP': '–', None: ''} +COLOR = {'PASS': 'var(--pass)', 'FAIL': 'var(--fail)', 'SKIP': 'var(--skip)'} +HISTORY_RUNS = 15 # columns in the history, including this run + +CSS = """ +:root { + --ink: #1b2330; --ink-2: #4a5568; --muted: #6b7686; --line: #e2e6ec; --line-2: #cfd6df; --paper: #fff; --band: #f7f8fa; + --accent: #2456c8; --accent-soft: #e8eefb; + --pass: #0ca30c; --pass-bg: #e4f5e4; --pass-ink: #0b5a0b; + --fail: #d03b3b; --fail-bg: #fbe6e6; --fail-ink: #9a1d1d; + --skip: #fab219; --skip-bg: #fdf2d6; --skip-ink: #6e4b00; + --none: #dfe3e9; + --sans: system-ui, -apple-system, "Segoe UI", Ubuntu, Cantarell, Roboto, sans-serif; + --mono: ui-monospace, "DejaVu Sans Mono", Menlo, Consolas, monospace; + color-scheme: light; +} +* { box-sizing: border-box; } +body { margin: 0; background: var(--paper); color: var(--ink); font: 14px/1.5 var(--sans); } +main { max-width: 72rem; margin: 0 auto; padding: 1.6rem max(16px, 2.2rem) 3rem; } +h1, h2, h3 { margin: 0; text-wrap: balance; } +a { color: var(--accent); } +section { margin-top: 2rem; } +h2 { font-size: 1.02rem; font-weight: 650; margin-bottom: .2rem; } +.sub { color: var(--muted); font-size: .85rem; margin: 0 0 .8rem; } +.rhead { display: flex; gap: 1rem 2rem; align-items: flex-start; justify-content: space-between; flex-wrap: wrap; } +.rhead h1 { font-size: 1.35rem; font-weight: 650; } +.eyebrow { text-transform: uppercase; letter-spacing: .08em; font-size: .72rem; color: var(--muted); font-weight: 600; } +.verdict { border-radius: 8px; padding: .45rem .85rem; font-weight: 650; } +.verdict.FAIL { background: var(--fail-bg); color: var(--fail-ink); } +.verdict.PASS { background: var(--pass-bg); color: var(--pass-ink); } +.meta { display: grid; grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr)); gap: .55rem 1.5rem; margin: 1.1rem 0 0; + padding-top: 1rem; border-top: 1px solid var(--line); } +.meta div { min-width: 0; } +.meta dt { font-size: .75rem; color: var(--muted); } +.meta dd { margin: 0; overflow-wrap: anywhere; } +.meta dd.mono { font-family: var(--mono); font-size: .85rem; } +.dirty, .aborted { color: var(--fail-ink); } +.dirty { font-size: .75rem; margin-left: .3rem; } +.tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr)); gap: .8rem; margin-top: 1.4rem; } +.tile { border: 1px solid var(--line); border-radius: 8px; padding: .75rem .9rem; } +.tile .lbl { font-size: .8rem; color: var(--muted); display: flex; align-items: center; gap: .4rem; } +.tile .val { font-size: 1.7rem; font-weight: 650; line-height: 1.2; font-variant-numeric: tabular-nums; } +.tile .note { font-size: .78rem; color: var(--muted); } +.dot { width: .6rem; height: .6rem; border-radius: 50%; display: inline-block; flex: none; } +.d-PASS { background: var(--pass); } .d-FAIL { background: var(--fail); } .d-SKIP { background: var(--skip); } +.chip { display: inline-block; border-radius: 5px; padding: 0 .45rem; font-size: .75rem; font-weight: 650; line-height: 1.6; white-space: nowrap; } +.c-PASS { background: var(--pass-bg); color: var(--pass-ink); } +.c-FAIL { background: var(--fail-bg); color: var(--fail-ink); } +.c-SKIP { background: var(--skip-bg); color: var(--skip-ink); } +.c-CRASH { background: var(--fail-ink); color: #fff; } +.c-NEW { background: var(--accent-soft); color: var(--accent); } +.legend { display: flex; gap: 1rem; flex-wrap: wrap; font-size: .8rem; color: var(--ink-2); margin: .2rem 0 .5rem; } +.legend span { display: inline-flex; align-items: center; gap: .35rem; } +.chart { overflow-x: auto; } +.chart svg { display: block; width: 100%; height: auto; min-width: 34rem; } +.chart text { font-family: var(--sans); fill: var(--ink-2); font-size: 12px; } +.chart text.m { fill: var(--muted); font-size: 11px; } +.chart text.b { fill: var(--ink); font-weight: 600; } +.chart text.sha { font-family: var(--mono); font-size: 9.5px; fill: var(--muted); } +.chart .grid { stroke: var(--line); stroke-width: 1; } +.cols { display: grid; grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr)); gap: 1.5rem 2.5rem; } +.cols > * { min-width: 0; } +.changes { display: grid; gap: .45rem; } +.changes div { display: flex; gap: .5rem; align-items: baseline; flex-wrap: wrap; } +.file { color: var(--muted); font-size: .8rem; } +.tbl { overflow-x: auto; } +table.tests { border-collapse: collapse; width: 100%; min-width: 40rem; } +.tests th { text-align: left; font-size: .75rem; color: var(--muted); font-weight: 600; padding: .35rem .6rem; border-bottom: 1px solid var(--line-2); } +.tests td { padding: .45rem .6rem; border-bottom: 1px solid var(--line); vertical-align: top; } +.tests tr.grp td { background: var(--band); font-weight: 600; font-size: .82rem; color: var(--ink-2); padding-top: .55rem; } +.tests tr.grp span { font-weight: 400; color: var(--muted); } +.tests td.t { white-space: nowrap; text-align: right; font-variant-numeric: tabular-nums; color: var(--ink-2); } +.tests td.links { white-space: nowrap; font-size: .82rem; } +.tests details { margin-top: .3rem; font-size: .82rem; } +.tests summary { color: var(--muted); cursor: pointer; } +.reason { font-family: var(--mono); font-size: .8rem; color: var(--ink-2); white-space: pre-wrap; overflow-wrap: anywhere; } +.strip { display: flex; gap: 2px; width: 11rem; margin-top: .35rem; } +.strip i { flex: 1; height: .5rem; background: var(--pass); } +.strip i:first-child { border-radius: 3px 0 0 3px; } .strip i:last-child { border-radius: 0 3px 3px 0; } +.strip i.f { background: var(--fail); } .strip i.n { background: var(--none); } +.stripnote { font-size: .75rem; color: var(--muted); } +.card { border: 1px solid var(--line); border-left: 4px solid var(--fail); border-radius: 8px; padding: .9rem 1rem; display: grid; gap: .5rem; } +.card + .card { margin-top: .8rem; } +.card.SKIP { border-left-color: var(--skip); } +.card-head { display: flex; gap: .5rem; align-items: baseline; flex-wrap: wrap; } +.card-head h3 { font-size: .98rem; } +.card-head .links { margin-left: auto; font-size: .82rem; } +.film { display: flex; gap: .6rem; overflow-x: auto; padding-bottom: .3rem; } +.shot { flex: none; width: 10.5rem; font-size: .75rem; color: var(--ink-2); text-decoration: none; } +.shot:hover b { text-decoration: underline; } +.shot img { display: block; width: 100%; aspect-ratio: 4/3; object-fit: cover; object-position: left top; + border: 1px solid var(--line-2); border-radius: 5px; background: var(--band); } +.shot.bad img { outline: 3px solid var(--fail); outline-offset: -1px; } +.shot b { color: var(--ink); } +.film.small .shot { width: 7.5rem; } +table.hgrid { border-collapse: separate; border-spacing: 3px; } +.hgrid th.name { text-align: right; padding-right: .6rem; font-size: .82rem; font-weight: 500; white-space: nowrap; } +.hgrid th.run { font-size: .68rem; color: var(--muted); font-weight: 500; text-align: center; } +.hgrid th.run.cur { color: var(--ink); font-weight: 700; } +.hgrid td.cell { width: 1.6rem; height: 1.35rem; border-radius: 3px; text-align: center; font-size: .72rem; font-weight: 700; color: #fff; background: var(--band); } +.hgrid td.PASS { background: var(--pass); } .hgrid td.FAIL { background: var(--fail); } +.hgrid td.SKIP { background: var(--skip); color: var(--skip-ink); } +.hgrid td.cur { box-shadow: 0 0 0 2px var(--paper), 0 0 0 3.5px var(--ink); } +.hgrid td.note { font-size: .78rem; color: var(--muted); padding-left: .7rem; white-space: nowrap; } +@media (max-width: 520px) { .card-head .links { margin-left: 0; width: 100%; } } +""" + +e = html.escape + + +def dur(s): + s = int(round(s)) + return '%d min %d s' % (s // 60, s % 60) if s >= 60 else '%d s' % s + + +def chip(status): + return '%s %s' % (status, ICON[status], status) + + +def crash_chip(r): + return ' CRASH' if r['crash'] else '' + + +def count(results, status): + return sum(1 for r in results if r['status'] == status) + + +def short_date(started): + return '%d/%d' % (int(started[5:7]), int(started[8:10])) + + +def links(r, outdir): + """Links to the files of a test that exist (a skipped test has none).""" + out = [(r['slug'] + ext, text) for ext, text in (('.txt', 'steps'), ('.app.log', 'app log'), ('.png', 'screenshot')) + if os.path.exists(os.path.join(outdir, r['slug'] + ext))] + return ' · '.join('%s' % (e(f), t) for f, t in out) + + +def strip(r): + """One cell per step: green passed, red failed, grey not run.""" + n, at = r.get('steps', 0), r.get('failed_step', 0) + if not n: + return '' + if r['status'] == 'SKIP': + cells, note = ['n'] * n, 'not run' + elif r['status'] == 'FAIL' and not at and not r['crash']: + cells, note = ['n'] * n, 'did not start' + else: + cells = ['' if not at or k < at else 'f' if k == at else 'n' for k in range(1, n + 1)] + note = 'failed at step %d of %d' % (at, n) if at else '%d of %d steps' % (n, n) + return '
%s
%s
' % ( + note, ''.join('' % c for c in cells), note) + + +def hbar(x, y, w, h, r, fill, tip): + """A horizontal bar, rounded at the data end only.""" + r = min(r, w / 2, h / 2) + return ('%s' + % (x, y, w - r, r, r, r, r, h - 2 * r, r, r, r, r, w - r, fill, e(tip))) + + +def vbar(x, base, w, h, r, fill, tip, top): + """A column segment; the top segment is rounded at the data end.""" + if not top: + return '%s' % (x, base - h, w, h, fill, e(tip)) + r = min(r, w / 2, h) + return ('%s' + % (x, base, h - r, r, r, r, r, w - 2 * r, r, r, r, r, h - r, fill, e(tip))) + + +def legend(): + return '
%s
' % ''.join('%s' % (k, k) for k in STATUSES) + + +def per_file_chart(run): + rows = [] + for f in run['files']: + rs = [r for r in run['results'] if r['file'] == f['file']] + if rs: + rows.append(dict({k: count(rs, k) for k in STATUSES}, title=f['title'] or f['file'], n=len(rs))) + big = max(r['n'] for r in rows) + step = 1 if big <= 10 else 5 if big <= 50 else 20 + top = -(-big // step) * step + left, width, rh, h = 210, 900, 30, 18 + bw = width - left - 70 + sx = lambda v: v / top * bw + s = [] + for v in range(0, top + 1, step): + s.append('%d' + % (left + sx(v), left + sx(v), len(rows) * rh + 4, left + sx(v), len(rows) * rh + 20, v)) + for i, r in enumerate(rows): + y = 8 + i * rh + title = r['title'] if len(r['title']) <= 30 else r['title'][:29] + '…' + s.append('%s%s' % (left - 10, y + h / 2 + 4, e(title), e(r['title']))) + x = left + segs = [k for k in STATUSES if r[k]] + for j, k in enumerate(segs): + last = j == len(segs) - 1 + w = sx(r[k]) - (0 if last else 2) # a 2px gap between the segments + tip = '%s\n%d %s of %d tests' % (r['title'], r[k], k, r['n']) + s.append(hbar(x, y, w, h, 4, COLOR[k], tip) if last else + '%s' % (x, y, w, h, COLOR[k], e(tip))) + x += sx(r[k]) + s.append('%d/%d' % (x + 8, y + h / 2 + 4, r['PASS'], r['n'])) + return ('
%s
' + % (width, len(rows) * rh + 28, ''.join(s))) + + +def trend_chart(runs): + width, left, base, top = 900, 34, 190, 14 + n = len(runs) + bw = min(30, (width - left - 30) / n * 0.6) + gap = min((width - left - 20 - n * bw) / max(n - 1, 1), 30) + big = max(len(r['results']) for r in runs) or 1 + step = 5 if big <= 25 else 10 if big <= 60 else 50 + ymax = -(-big // step) * step + sy = lambda v: v / ymax * (base - top) + s = [] + for v in range(0, ymax + 1, step): + s.append('%d' + % (left, width - 10, base - sy(v), base - sy(v), left - 6, base - sy(v) + 4, v)) + for i, run in enumerate(runs): + x, cur = left + 6 + i * (bw + gap), i == n - 1 + c = {k: count(run['results'], k) for k in STATUSES} + tip = 'Run %s · %s%s\n%d pass · %d fail · %d skip' % (run['started'][:16].replace('T', ' '), run['sha'][:8], + ' (aborted)' if run.get('aborted') else '', c['PASS'], c['FAIL'], c['SKIP']) + y0 = base + segs = [k for k in STATUSES if c[k]] + for j, k in enumerate(segs): + last = j == len(segs) - 1 + s.append(vbar(x, y0, bw, sy(c[k]) - (0 if last else 2), 4, COLOR[k], tip, last)) + y0 -= sy(c[k]) + if c['FAIL']: + s.append('%d' % (x + bw / 2, y0 - 6, c['FAIL'])) + s.append('%s' % ('b' if cur else 'm', x + bw / 2, base + 16, short_date(run['started']))) + s.append('%s' % (x + bw / 2, base + 30, e(run['sha'][:6]))) + if cur: + s.append('this run' % (x + bw / 2, base + 46)) + return ('
%s
' + % (width, base + 52, ''.join(s))) + + +def describe_history(h, runs): + """What a row of the status history says: flaky, failing since, fixed since...""" + seen = [x for x in h if x] + last = h[-1] + changes = sum(1 for a, b in zip(seen, seen[1:]) if a != b) + since = len(h) - 1 + while since > 0 and h[since - 1] == last: + since -= 1 + when = '%s %s (%s)' % (short_date(runs[since]['started']), runs[since]['started'][11:16], runs[since]['sha'][:6]) + if all(x == 'SKIP' for x in seen): + return 'never ran' + if changes >= 4: + return 'flaky: %d changes' % changes + if last == 'FAIL': + return 'new failure' if since == len(h) - 1 else 'failing since ' + when + if last == 'SKIP': + return 'skipped since ' + short_date(runs[since]['started']) + return 'fixed since ' + when if last == 'PASS' else '' + + +def history_sections(run, history): + runs = history[-(HISTORY_RUNS - 1):] + [run] + status = [{r['name']: r['status'] for r in x['results']} for x in runs] + prev = status[-2] + cur = run['results'] + new = [r for r in cur if r['status'] == 'FAIL' and prev.get(r['name']) != 'FAIL'] + fixed = [r for r in cur if r['status'] == 'PASS' and prev.get(r['name']) == 'FAIL'] + still = [r for r in cur if r['status'] == 'FAIL' and prev.get(r['name']) == 'FAIL'] + line = lambda r, tag: '
%s%s%s
' % (tag, e(r['name']), e(r['file'])) + changes = ''.join([line(r, 'NEW ' + chip('FAIL')) for r in new] + + [line(r, chip('PASS')) for r in fixed] + + [line(r, '✗ STILL FAILING') for r in still]) or \ + '

No test changed between PASS and FAIL.

' + p = runs[-2] + out = ['

The last %d runs

%s. The number on a column is the failed tests.

%s%s
' + % (len(runs), e(run['edition'] or 'All editions'), legend(), trend_chart(runs)), + '

Changed since the previous run

Run %s · %s

%s
' + % (e(p['started'][:16].replace('T', ' ')), e(p['sha'][:10]), changes)] + rows = [r for r in cur if any(s.get(r['name'], 'PASS') != 'PASS' for s in status)] + if rows: + head = '%s' % ''.join( + '%s' % (' cur' if i == len(runs) - 1 else '', short_date(x['started'])) for i, x in enumerate(runs)) + body = [] + for r in rows: + h = [s.get(r['name']) for s in status] + cells = ''.join('%s' % ( + x or '', ' cur' if i == len(runs) - 1 else '', + e('%s · %s %s: %s' % (r['name'], short_date(runs[i]['started']), runs[i]['sha'][:8], x or 'not in this run')), ICON[x]) + for i, x in enumerate(h)) + body.append('%s%s%s' % (e(r['name']), cells, describe_history(h, runs))) + out.append('

Status history

The tests that did not pass in every run. ' + 'The framed column is this run.

%s%s
' + % (head, ''.join(body))) + return out, len(new) - len(fixed), len(new), len(fixed) + + +def film(r, outdir): + """The screenshots after the last steps before the failure, and the final screenshot.""" + shots = [(s['file'], 'Step %d' % s['step'], s['label'], False) for s in r.get('shots', [])][-3:] + if os.path.exists(os.path.join(outdir, r['slug'] + '.png')): + at = r.get('failed_step', 0) + shots.append((r['slug'] + '.png', 'Step %d · failed here' % at if at else 'At the end', '', True)) + return '
%s
' % ''.join( + '%s%s
%s
' % ( + ' bad' if bad else '', e(f), e(f), e(title), e(title), e(label)) for f, title, label, bad in shots) if shots else '' + + +def problem_cards(run, outdir): + rs = [r for r in run['results'] if r['status'] != 'PASS'] + rs.sort(key=lambda r: r['status'] != 'FAIL') + return ''.join('
%s%s

%s

%s%s
' + '%s
%s
%s
' % ( + r['status'], chip(r['status']), crash_chip(r), e(r['name']), e(r['file']), links(r, outdir), + strip(r) if r['status'] == 'FAIL' else '', e(r['reason']), film(r, outdir) if r['status'] == 'FAIL' else '') + for r in rs) + + +def all_tests(run, outdir): + rows = [] + for f in run['files']: + rs = [r for r in run['results'] if r['file'] == f['file']] + if not rs: + continue + rows.append('%s · %s · %d of %d passed' % ( + e(f['title'] or f['file']), e(f['file']), count(rs, 'PASS'), len(rs))) + for r in rs: + shots = r.get('shots', []) + more = ('
screenshots after the steps (%d)
%s
' % ( + len(shots), ''.join('Step %d
%s
' % ( + e(s['file']), e(s['file']), s['step'], e(s['label'])) for s in shots))) if shots else '' + rows.append('%s%s
%s
%s%s%s%s' % ( + chip(r['status']), crash_chip(r), e(r['name']), strip(r), more, + dur(r['seconds']) if r['status'] != 'SKIP' else '–', links(r, outdir))) + return ('
' + '%s
ResultTestTimeFiles
' % ''.join(rows)) + + +def write(path, run, history): + outdir = os.path.dirname(path) + rs = run['results'] + c = {k: count(rs, k) for k in STATUSES} + ran = c['PASS'] + c['FAIL'] + total = sum(r['seconds'] for r in rs) + crashes = sum(1 for r in rs if r['crash']) + verdict = 'FAIL' if c['FAIL'] else 'PASS' + sha = run['sha'][:8] + text = ('✗ FAILED · %d of %d tests failed' % (c['FAIL'], len(rs)) if c['FAIL'] else + '✓ PASSED · all %d tests passed' % ran if not c['SKIP'] else '✓ PASSED · %d passed, %d skipped' % (ran, c['SKIP'])) + meta = [('Date', e(run['started'][:19].replace('T', ' ')), ''), + ('Edition', e(run['edition'] or 'not given, all tests'), ''), + ('Duration', dur(total), ''), + ('Git SHA', e(run['sha']) + ('+ uncommitted changes' if run['dirty'] else ''), 'mono'), + ('Branch', e(run['branch']), ''), + ('Commit', e(run['subject']), ''), + ('Application', e(run['app']), 'mono'), + ('Host', e(run['host']), ''), + ('Test files', e(', '.join(f['file'] for f in run['files'])), '')] + if run.get('aborted'): + meta.append(('Aborted', 'the run was stopped before all tests were done', '')) + hist, delta, new, fixed = history_sections(run, history) if history else ([], 0, 0, 0) + + def tile(label, value, note, status=''): + return '
%s%s
%s
%s
' % ( + '' % status if status else '', label, value, note) + tiles = [tile('Passed', c['PASS'], '%d %% of the tests' % round(100 * c['PASS'] / len(rs)) if rs else '', 'PASS'), + tile('Failed', c['FAIL'], '%d of them crashed the app' % crashes if crashes else 'no crashes', 'FAIL'), + tile('Skipped', c['SKIP'], 'no script or outdated script' if c['SKIP'] else ' ', 'SKIP'), + tile('Duration', dur(total), 'average %d s per test' % round(total / ran) if ran else ' ')] + if history: + tiles.append(tile('Compared to the previous run', '%+d' % delta if delta else '±0', + '%d new failure%s, %d fixed' % (new, '' if new == 1 else 's', fixed))) + + out = ['', '', + '', + 'GUI test report %s %s' % (e(run['edition'] or ''), e(sha)), '
', + '
GUI test report

%s %s · %s

%s
' % ( + e(os.path.basename(run['app'])), e(run['edition'] or ''), e(sha), verdict, text), + '
%s
' % ''.join('
%s
%s
' % (k, cls, v) for k, v, cls in meta), + '
%s
' % ''.join(tiles)] + if len([f for f in run['files'] if any(r['file'] == f['file'] for r in rs)]) > 1: + out.append('

Results per test file

Which part of the GUI has problems.

%s%s
' + % (legend(), per_file_chart(run))) + out += hist + if c['FAIL'] or c['SKIP']: + out.append('

Failed and skipped tests

The reason, how far the test got, and the screenshots ' + 'after the last steps. The red frame is the screen when the test failed.

%s
' % problem_cards(run, outdir)) + if rs: + out.append('

All tests

Grouped by test file. The strip shows the steps: green passed, ' + 'red failed, grey not run.

%s
' % all_tests(run, outdir)) + if not history: + out.append('

No earlier runs of this edition with results.json were found in %s, ' + 'the history is shown from the next run.

' % e(os.path.dirname(outdir))) + out.append('
') + with open(path, 'w', encoding='utf-8') as f: + f.write('\n'.join(out) + '\n') diff --git a/gui/manualtest/run.py b/gui/manualtest/run.py new file mode 100755 index 00000000000..1d7668cda27 --- /dev/null +++ b/gui/manualtest/run.py @@ -0,0 +1,230 @@ +#!/usr/bin/env python3 +"""Run the manual tests in a test file by letting Claude drive the GUI. + + run.py APP FILE.feature... [--edition opensource|premium] [--test SUBSTRING] [--id ID] [--src DIR] [--out DIR] + +FILE.feature is a Gherkin test file, edited with web.py or by hand, see testfile.py. The scripts +are in FILE.scripts.json. For each scenario (and each row of its Examples) the application is started +fresh (empty HOME) and the script of the test is run with guitest.py commands, see runner.py. +No AI is involved. With --edition APP is that edition and only the tests for it are run. +Tests without a script are SKIP. A step that fails gives PASS -> FAIL with the +step, the reason and the elements that are on the screen. +""" + +import argparse +import os +import re +import datetime +import json +import platform +import signal +import subprocess +import sys +import tempfile +import time + +import report +import runner +import testfile + +HERE = os.path.dirname(os.path.abspath(__file__)) +GUITEST = os.path.join(HERE, 'guitest.py') + +def parse(path, edition=None): + return [dict(t, file=os.path.basename(path)) for t in testfile.expand(path, edition)] + + +CRASH_RE = re.compile(r'exited with status (?!0\b|143\b)\d+|Segmentation fault|SIGSEGV|SIGABRT|Aborted|core dumped|terminate called|' + r'QFATAL|Fatal error|AddressSanitizer|runtime error:|Assertion .* failed', re.I) + + +def screenshot(sub, path): + """Save a screenshot without the empty (black) part of the screen right of and below the windows. + The top left corner stays, so positions in the image are screen positions.""" + if sub('screenshot', path, capture_output=True).returncode: + return False + try: + from PIL import Image + img = Image.open(path) + box = img.convert('RGB').getbbox() + if box and (box[2] < img.width or box[3] < img.height): + img.crop((0, 0, box[2], box[3])).save(path) + except (ImportError, OSError): + pass + return True + + +def detect_crash(sub, outdir, slug): + """Return a description when the application died or logged a fatal error, else ''.""" + log = sub('log', capture_output=True).stdout + with open(os.path.join(outdir, slug + '.app.log'), 'w') as f: + f.write(log) + hits = [l.strip() for l in log.splitlines() if CRASH_RE.search(l)] + dead = sub('alive', capture_output=True).returncode != 0 + if dead and re.search(r'application exited with status 0\b', log): + dead = False # the test closed the application (Quit) + if not dead and not hits: + return '' + why = 'application is not running at the end of the test' if dead else 'fatal message in application log' + return why + (': ' + hits[0] if hits else '') + + +def emit(kind, **data): + """One line of progress for the web interface, with --events.""" + if EVENTS: + print('@' + json.dumps(dict(data, kind=kind)), flush=True) + + +EVENTS = False + + +def run_test(app, test, outdir, on_step=None): + """Returns {status, reason, crash, steps, failed_step, shots}. failed_step is 0 when no step failed, + shots are the screenshots after the steps: [{step, label, file}].""" + slug = re.sub(r'\W+', '_', test['name']) + shots, reached = [], [0] + result = lambda status, reason, crash='', failed=0: {'status': status, 'reason': reason, 'crash': crash, + 'steps': len(test['script']), 'failed_step': failed, 'shots': shots} + if test.get('stale'): + return result('SKIP', 'OUTDATED SCRIPT: the test was changed after the script was made. ' + 'Generate the script again (gen.py or the web interface) or approve it there.') + if not test['script']: + return result('SKIP', 'no script, make one with gen.py or in the web interface') + work = tempfile.mkdtemp(prefix='guitest-work-') + state = os.path.join(work, 'state.json') + env = dict(os.environ, GUITEST_STATE=state) + sub = lambda *a, **kw: subprocess.run([sys.executable, GUITEST, *a], env=env, text=True, **kw) + try: + variables = testfile.materialize(test['root'], test['projects'], work) # same files every run + except FileNotFoundError as e: + return result('FAIL', str(e)) + r = sub('start', app, capture_output=True) + if r.returncode: + return result('FAIL', 'could not start: ' + (r.stdout + r.stderr).strip()) + try: + with open(state) as f: + home = json.load(f)['env']['HOME'] + def shot(i, label): + name = '%s.step%02d.png' % (slug, i) + if not screenshot(sub, os.path.join(outdir, name)): + return None + shots.append({'step': i, 'label': label, 'file': name}) + return name + def step(i, n, label): + reached[0] = i + if on_step: + on_step(i, n, label) + ok, reason, log = runner.run_script(sub, test['script'], work, home, variables, step, shot) + with open(os.path.join(outdir, slug + '.txt'), 'w') as f: + f.write(log) + screenshot(sub, os.path.join(outdir, slug + '.png')) + crash = detect_crash(sub, outdir, slug) + status = 'PASS' if ok else 'FAIL' + if crash: + # a crash is a failure even if all the steps passed + status, reason = 'FAIL', 'APPLICATION CRASHED: %s\n%s' % (crash, reason) + return result(status, reason, crash, 0 if ok else reached[0]) + finally: + sub('stop', capture_output=True) + + +def git(directory, *a): + r = subprocess.run(['git', '-C', directory, *a], text=True, capture_output=True) + return r.stdout.strip() if r.returncode == 0 else '' + + +def app_info(app, src): + """git info for the tested application, taken from SRC (default: the directory of the binary).""" + d = os.path.abspath(src) if src else os.path.dirname(app) + sha = git(d, 'rev-parse', 'HEAD') + return { + 'path': app, + 'sha': sha or 'unknown', + 'branch': git(d, 'rev-parse', '--abbrev-ref', 'HEAD') or 'unknown', + 'subject': git(d, 'log', '-1', '--format=%s') if sha else '', + 'dirty': bool(git(d, 'status', '--porcelain', '--untracked-files=no')) if sha else False, + } + + +def load_history(out, edition, current): + """results.json of the earlier runs of EDITION in OUT, oldest first.""" + runs = [] + for d in sorted(os.listdir(out)): + path = os.path.join(out, d, 'results.json') + if d == current or not os.path.isfile(path): + continue + try: + with open(path, encoding='utf-8') as f: + run = json.load(f) + except (OSError, ValueError): + continue + if run.get('edition') == edition: + runs.append(run) + return runs[-(report.HISTORY_RUNS - 1):] + + +def main(): + ap = argparse.ArgumentParser() + ap.add_argument('app') + ap.add_argument('file', nargs='+', help='one or more .feature test files') + ap.add_argument('--edition', choices=testfile.EDITIONS, help='the edition that APP is, only the tests for it') + ap.add_argument('--test', help='only tests whose name contains this') + ap.add_argument('--id', help='only the test with this id (all the rows of its Examples)') + ap.add_argument('--src', help='git checkout of the application (default: the directory of APP)') + ap.add_argument('--out', default=os.path.join(HERE, 'results')) + ap.add_argument('--events', action='store_true', help='progress lines for the web interface') + args = ap.parse_args() + global EVENTS + EVENTS = args.events + signal.signal(signal.SIGINT, signal.default_int_handler) # also when started in the background + + started = datetime.datetime.now() + info = app_info(os.path.abspath(args.app), args.src) + # each run gets its own directory: results/[-]-/ + parent = args.out + args.out = os.path.join(args.out, '%s%s-%s' % (started.strftime('%Y%m%d-%H%M%S'), + '-' + args.edition if args.edition else '', info['sha'][:8])) + os.makedirs(args.out, exist_ok=True) + failed = 0 + results = [] + aborted = False + try: + selected = [t for f in args.file for t in parse(f, args.edition) + if not (args.test and args.test.lower() not in t['name'].lower() or args.id and t['id'] != args.id)] + emit('start', total=len(selected), out=args.out, edition=args.edition) + for index, test in enumerate(selected, 1): + name = test['name'] + emit('test', index=index, name=name, file=test['file'], steps=len(test['script'])) + t0 = time.time() + try: + res = run_test(os.path.abspath(args.app), test, args.out, + lambda k, n, label: emit('step', step=k, steps=n, label=label)) + except KeyboardInterrupt: + results.append({'name': name, 'file': test['file'], 'status': 'SKIP', 'reason': 'aborted by user', 'crash': '', + 'seconds': time.time() - t0, 'slug': re.sub(r'\W+', '_', name), 'steps': 0, 'failed_step': 0, 'shots': []}) + emit('result', **results[-1]) + raise + results.append(dict(res, name=name, file=test['file'], seconds=time.time() - t0, slug=re.sub(r'\W+', '_', name))) + emit('result', **results[-1]) + print('%-4s %s: %s' % (res['status'], name, res['reason']), flush=True) + failed += res['status'] == 'FAIL' + except KeyboardInterrupt: + # the report is written with what is done, tests not started are left out + aborted = True + print('aborted') + run = {'started': started.isoformat(timespec='seconds'), 'edition': args.edition, 'app': info['path'], + 'sha': info['sha'], 'dirty': info['dirty'], 'branch': info['branch'], 'subject': info['subject'], + 'host': '%s, %s' % (platform.node(), platform.platform()), 'aborted': aborted, + 'files': [{'file': os.path.basename(f), 'title': testfile.load(f).get('title', '')} for f in args.file], + 'results': results} + with open(os.path.join(args.out, 'results.json'), 'w', encoding='utf-8') as f: + json.dump(run, f, indent=1) + path = os.path.join(args.out, 'report.html') + report.write(path, run, load_history(parent, args.edition, os.path.basename(args.out))) + print('report: ' + path) + emit('done', report=path) + sys.exit(1 if failed else 0) + + +if __name__ == '__main__': + main() diff --git a/gui/manualtest/runner.py b/gui/manualtest/runner.py new file mode 100644 index 00000000000..11634cdb1e4 --- /dev/null +++ b/gui/manualtest/runner.py @@ -0,0 +1,232 @@ +"""Executes a test script (see testfile.SCRIPT_DOC) with guitest.py commands, no AI involved. + +run_script() gets `sub`, a function that runs one guitest.py command in the session of the test: +sub(cmd, *args, capture_output=True) -> CompletedProcess with returncode, stdout, stderr. +""" + +import os +import re +import shutil +import time + +import testfile + +# actions that change the GUI, a screenshot is taken after each of them +GUI_ACTIONS = ('click', 'rightclick', 'doubleclick', 'focus', 'hover', 'settext', 'type', 'key', 'restart') +NO_ELEMENT = ('no matching visible element', 'does not answer on the accessibility bus') +DEFAULT_TIMEOUT = 5 + + +def selector_args(step): + a = [] + for k in ('name', 'role', 'path'): + if k in step: + a += ['--' + k, str(step[k])] + if 'nth' in step: + a += ['--nth', str(step['nth'])] + if step.get('exact'): + a.append('--exact') + return a + + +def describe(step): + return ' '.join('%s=%r' % (k, v) for k, v in step.items() if k != 'label') + + +def message(p): + text = (p.stderr.strip() or p.stdout.strip() or 'exit code %d' % p.returncode).removeprefix('error: ') + return text.replace('; try "tree --showing"', '') + + +class StepFailed(Exception): + pass + + +def check_path(path, allowed): + path = os.path.realpath(path) + if not any(path == d or path.startswith(d + os.sep) for d in (os.path.realpath(x) for x in allowed)): + raise StepFailed('path %s is outside the test directories' % path) + return path + + +def gui(sub, cmd, step, extra=()): + """Run a command that needs an element. The element may not have appeared yet, so retry.""" + deadline = time.time() + step.get('timeout', DEFAULT_TIMEOUT) + while True: + p = sub(cmd, *selector_args(step), *extra, capture_output=True) + if p.returncode == 0: + return p + if not any(m in message(p) for m in NO_ELEMENT) or time.time() > deadline: + raise StepFailed(message(p)) + time.sleep(0.4) + + +def run_step(sub, step, dirs, captured): + action = step.get('do') or step['expect'] + if 'do' in step: + if action in ('click', 'rightclick', 'doubleclick', 'focus', 'hover'): + gui(sub, action, step, ['--mouse'] if step.get('mouse') else []) + elif action == 'settext': + gui(sub, 'settext', step, [step['value']]) + elif action == 'type': + ok(sub('type', step['value'], capture_output=True)) + elif action == 'key': + keys = step['keys'].split() if isinstance(step['keys'], str) else step['keys'] + ok(sub('key', *keys, capture_output=True)) + elif action == 'wait': + ok(sub('wait', *selector_args(step), '--timeout', str(step.get('timeout', 10)), + *(['--gone'] if step.get('gone') else []), capture_output=True)) + elif action == 'restart': + ok(sub('restart', capture_output=True)) + elif action == 'sleep': + time.sleep(float(step['seconds'])) + elif action == 'copy': + src, dst = check_path(step['from'], dirs), check_path(step['to'], dirs) + if not os.path.isfile(src): + raise StepFailed('file %s does not exist' % src) + os.makedirs(os.path.dirname(dst), exist_ok=True) + shutil.copyfile(src, dst) + elif action == 'write': + path = check_path(step['path'], dirs) + os.makedirs(os.path.dirname(path), exist_ok=True) + with open(path, 'w', encoding='utf-8') as f: + f.write(step['content']) + return + if action == 'visible': + ok(sub('wait', *selector_args(step), '--timeout', str(step.get('timeout', DEFAULT_TIMEOUT)), + capture_output=True)) + elif action == 'gone': + ok(sub('wait', *selector_args(step), '--gone', '--timeout', str(step.get('timeout', DEFAULT_TIMEOUT)), + capture_output=True)) + elif action == 'state': + info = gui(sub, 'info', step).stdout + have = set((re.search(r'\[([\w,]*)\]\s*$', info.strip()) or [None, ''])[1].split(',')) + if 'state' in step and step['state'] not in have: + raise StepFailed('element is not %s, its states are [%s]: %s' % (step['state'], ','.join(sorted(have)), info.strip())) + if 'not_state' in step and step['not_state'] in have: + raise StepFailed('element is %s but should not be: %s' % (step['not_state'], info.strip())) + elif action == 'value': + info = gui(sub, 'info', step).stdout.strip() + found = re.findall(r" value=(\S+)", info) + re.findall(r" text='(.*?)'(?= value=| \[|$)", info) + if not any(same(v, step['equals']) for v in found): + raise StepFailed('the value is %s, not %r: %s' % (found or 'missing', step['equals'], info)) + elif action == 'exited': + deadline = time.time() + step.get('timeout', DEFAULT_TIMEOUT) + while sub('alive', capture_output=True).returncode == 0: + if time.time() > deadline: + raise StepFailed('the application is still running') + time.sleep(0.3) + status = re.findall(r'application exited with status (\d+)', sub('log', capture_output=True).stdout) + if status and status[-1] != '0': + raise StepFailed('the application ended with status %s, not 0' % status[-1]) + elif action == 'text': + deadline = time.time() + step.get('timeout', DEFAULT_TIMEOUT) # the screen may take a moment to change + while True: + texts = sub('texts', capture_output=True).stdout + problem = None + if 'contains' in step and step['contains'] not in texts: + problem = 'the text %r is not on the screen' % step['contains'] + elif 'not_contains' in step and step['not_contains'] in texts: + problem = 'the text %r is on the screen but should not be' % step['not_contains'] + if not problem: + break + if time.time() > deadline: + raise StepFailed(problem) + time.sleep(0.4) + elif action == 'ocr': + deadline = time.time() + step.get('timeout', DEFAULT_TIMEOUT) + norm = lambda x: re.sub(r'\s+', ' ', x).lower() + while True: + p = sub('ocr', capture_output=True) + if p.returncode: + raise StepFailed(message(p)) + seen = norm(p.stdout) + problem = None + if 'contains' in step and norm(step['contains']) not in seen: + problem = 'the text %r is not on the screen (OCR)' % step['contains'] + elif 'not_contains' in step and norm(step['not_contains']) in seen: + problem = 'the text %r is on the screen (OCR) but should not be' % step['not_contains'] + if not problem: + break + if time.time() > deadline: + raise StepFailed(problem + '. OCR read: ' + seen[:300]) + time.sleep(0.4) + elif action == 'file': + path = check_path(step['path'], dirs) + try: + with open(path, encoding='utf-8', errors='replace') as f: + text = f.read() + except FileNotFoundError: + raise StepFailed('file %s does not exist' % path) + if 'contains' in step and step['contains'] not in text: + raise StepFailed('%s does not contain %r' % (path, step['contains'])) + if 'not_contains' in step and step['not_contains'] in text: + raise StepFailed('%s contains %r but should not' % (path, step['not_contains'])) + if 'regex' in step and not re.search(step['regex'], text, re.M): + raise StepFailed('%s does not match /%s/' % (path, step['regex'])) + elif action == 'alive': + ok(sub('alive', capture_output=True)) + elif action == 'capture': + info = gui(sub, 'info', step).stdout.strip() + m = re.search(step['regex'], info) + if not m: + raise StepFailed('/%s/ does not match: %s' % (step['regex'], info)) + captured[step['as']] = m.group(1) if m.groups() else m.group(0) + + +def same(a, b): + try: + return float(a) == float(b) # a spin box says 1.0 + except ValueError: + return a == b + + +def ok(p): + if p.returncode: + raise StepFailed(message(p)) + + +def context(sub, step): + """What the screen looks like when a step failed, to make a renamed button easy to find.""" + out = [] + if {'name', 'role', 'path'} & set(step): + cmd = ['suggest'] + ['--%s=%s' % (k, step[k]) for k in ('name', 'role') if k in step] + s = sub(*cmd, capture_output=True).stdout.strip() + if s: + out.append('most similar visible elements:\n' + '\n'.join(' ' + l for l in s.splitlines())) + w = sub('windows', capture_output=True).stdout.strip() + if w: + out.append('windows:\n' + '\n'.join(' ' + l.split(' @')[0] for l in w.splitlines()[:6])) + return '\n '.join(out) + + + +def run_script(sub, script, work, home, variables=None, progress=None, shot=None): + """Returns (ok, message, log). On failure the message names the step and what was on screen. + shot(i, label) is called after each step i that is one of GUI_ACTIONS and returns the name of the + screenshot it saved, or None.""" + dirs = [work, home] + variables = dict(variables or {}, work=work, home=home) + captured = {} # {name} values of the capture steps so far + log = [] + for i, step in enumerate(script, 1): + step = testfile.subst_deep(step, dict(variables, **captured)) + t0 = time.time() + label = step.get('label') + if progress: + progress(i, len(script), label or describe(step)) + head = 'step %d/%d%s: %s' % (i, len(script), ' "%s"' % label if label else '', describe(step)) + try: + run_step(sub, step, dirs, captured) + except StepFailed as e: + log.append('FAIL %s (%.1f s)' % (head, time.time() - t0)) + msg = '%s\n %s' % (head, e) + ctx = context(sub, step) + return False, msg + ('\n ' + ctx if ctx else ''), '\n'.join(log) + '\n' + msg + '\n' + log.append('ok %s (%.1f s)' % (head, time.time() - t0)) + if shot and step.get('do') in GUI_ACTIONS: + time.sleep(0.2) # let the application paint + name = shot(i, label or describe(step)) + if name: + log[-1] += ' screenshot ' + name + return True, 'all %d steps passed' % len(script), '\n'.join(log) + '\n' diff --git a/gui/manualtest/testfile.py b/gui/manualtest/testfile.py new file mode 100644 index 00000000000..a915e7960fa --- /dev/null +++ b/gui/manualtest/testfile.py @@ -0,0 +1,743 @@ +#!/usr/bin/env python3 +"""Test files for run.py, written in Gherkin (FILE.feature), with the scripts in FILE.scripts.json. + + Feature: Project file dialog + + Background: + Given the application is started with no project loaded + + @id:t1a2b3c4d @ticket:14983 @project:relative-paths + Scenario: Relative paths + TODO: cannot be automated optional, a description line that starts with TODO: + When I open the project dialog + And I select the platform + Then relative paths are used in the XML + + Examples: + | platform | lang | + | native | C | + | unix32 | C++ | + +Feature: is the title of the file. Background: steps are done before every scenario of the file. +A scenario has steps that start with Given, When, Then, And, But or *, at least one Then (the +expected result). A step can be followed by a doc string (lines between \"\"\") or a table (| a | b |). +Lines that start with # are comments, they are not kept when the file is saved by web.py. + +Tags of a scenario (all optional): + @id:ID identifies a test when it is renamed, added when it is missing + @ticket:NUMBER the ticket of the test (#NUMBER) + @project:NAME a test project, see below; one tag per project + @edition:NAME an edition that the test is for, one of EDITIONS; one tag per edition, none: all + @disabled the test is not run +Other tags are kept but not used. + +A run is for one edition (run.py --edition, with the binary of that edition), the tests that are +not for it are left out. The script is the same for all editions, {edition} in the steps and the +script is the name of the edition of the run. + +Examples (Scenario Outline) are the test matrix: the test is run once for every row of the table. + in the steps and {column} in the script are replaced by the value of the row. + +"script" is what run.py executes, see SCRIPT_DOC below. It is written by gen.py (an AI explores +the GUI once) or by hand, and is then replayed without any AI. The scripts are kept in +FILE.scripts.json, {"ID": {"script": [...], "script_for": "..."}}, next to the feature file. + +@project:NAME are test projects, directories with files and code in DIR/projects/NAME, +shared by all tests next to them. Before every run they are copied to an empty temporary directory, +so a test always starts with the same files: {project:NAME} in steps and scripts is the copy of NAME, +and {project} when the test has exactly one project. + +A script is made for the steps (with the Background), todo, examples and test projects (the files in +them) of a test. "script_for" is a hash of those at the time, when they are changed afterwards the +script is OUTDATED: it is kept but not run until it is generated again, edited or approved. + +In Python a test file is a dict {"title", "background": [lines], "tests": [test]}, a test is +{"id", "name", "steps": [lines], "todo", "ticket", "enabled", "projects", "editions", "examples": +[{column: value}], "script", "script_for"}. The lines of the steps are Gherkin without indentation. + + testfile.py convert IN.md|IN.json OUT.feature import a markdown or an older JSON test file +""" + +import hashlib +import itertools +import json +import os +import re +import shutil +import sys + +AXIS_RE = re.compile(r'^\w+$') +PROJECT_RE = re.compile(r'^[\w-]+$') +PROJECTS = 'projects' # test projects: one directory per project, next to the test files +EDITIONS = ('opensource', 'premium') +EXT = '.feature' +SCRIPTS_EXT = '.scripts.json' + +SCRIPT_DOC = """A script is a list of steps. Every step is an object with "do" (an action) or "expect" (a check), +and an optional "label" that says what the step is for (shown when it fails). Elements are found +with name (substring of the accessible name/text, case-insensitive), role, path, nth, exact, like +the guitest.py commands. {work} is a temporary directory for files, {home} the HOME of the +application, {project:NAME} the copy of the test project NAME ({project} when the test has just one), +use those for the files of a test instead of write steps. {column} values of the Examples row and {edition} +(opensource or premium, the same script is used for both) are replaced before the run. + +actions + {"do": "click|rightclick|doubleclick|focus|hover", "name": "...", "role": "...", "mouse": true} + {"do": "settext", "name": "...", "value": "..."} set the text of an edit field + {"do": "type", "value": "..."} keyboard input to the focused element + {"do": "key", "keys": ["ctrl+o", "Return"]} xdotool key names + {"do": "wait", "name": "...", "gone": true, "timeout": 10} + {"do": "restart"} quit and start the application again + {"do": "sleep", "seconds": 1} + {"do": "write", "path": "{work}/a.c", "content": "..."} + {"do": "copy", "from": "{project:p}/a_v2.c", "to": "{project:p}/a.c"} change a file of the project +checks, the test fails when one is wrong + {"expect": "visible", "name": "...", "role": "...", "timeout": 5} + {"expect": "gone", "name": "..."} + {"expect": "state", "name": "...", "state": "checked"} or "not_state": "checked"; also + showing enabled focused selected expanded + {"expect": "value", "name": "...", "equals": "1"} value or text of a field, a spin box... + {"expect": "exited"} the application has ended by itself, status 0 (Quit) + {"expect": "text", "contains": "..."} or "not_contains": anywhere on screen + {"expect": "ocr", "contains": "Recheck"} text on the screen read by OCR (tesseract), or "not_contains"; + only for what "text" cannot see, e.g. a context menu that + is not in the accessibility tree. Case is ignored. + {"expect": "file", "path": "{home}/x.xml", "contains": "...", "not_contains": "...", "regex": "..."} + {"expect": "alive"} + {"expect": "capture", "name": "...", "role": "frame", "regex": "'Cppcheck (\\d[^']*)'", "as": "version"} + the regex is searched in the element's info line + (role 'name' text='...' value=...), group 1 (or the + whole match) is stored and {version} in the later + steps is replaced by it; use it instead of hard coding + text that changes, e.g. the version +A check can have "observed_fail": true when the application was seen not to do what the check says +(a known failure, only for the check that failed). Text checks wait up to "timeout" seconds (default 5). +Actions that need an element wait up to "timeout" seconds (default 5) for it to appear.""" + +SELECTOR = {'name', 'role', 'path', 'nth', 'exact'} +# step name -> (required keys, allowed optional keys) +STEPS = { + 'do': { + 'click': ((), SELECTOR | {'mouse'}), 'rightclick': ((), SELECTOR), 'doubleclick': ((), SELECTOR), + 'focus': ((), SELECTOR), 'hover': ((), SELECTOR), + 'settext': (('value',), SELECTOR), 'type': (('value',), set()), 'key': (('keys',), set()), + 'wait': ((), SELECTOR | {'gone'}), 'restart': ((), set()), + 'sleep': (('seconds',), set()), 'write': (('path', 'content'), set()), 'copy': (('from', 'to'), set()), + }, + 'expect': { + 'visible': ((), SELECTOR), 'gone': ((), SELECTOR), 'value': (('equals',), SELECTOR), 'exited': ((), set()), + 'state': ((), SELECTOR | {'state', 'not_state'}), + 'text': ((), {'contains', 'not_contains'}), 'file': (('path',), {'contains', 'not_contains', 'regex'}), + 'alive': ((), set()), 'ocr': ((), {'contains', 'not_contains'}), + 'capture': (('regex', 'as'), SELECTOR), + }, +} +NEEDS_SELECTOR = {'click', 'rightclick', 'doubleclick', 'focus', 'hover', 'settext', 'wait', 'visible', 'gone', 'state', 'value', + 'capture'} +STATES = {'showing', 'enabled', 'focused', 'selected', 'expanded', 'checked', 'editable', 'modal'} + + +def validate_script(script, where='script'): + if not isinstance(script, list): + return [where + ': must be a list of steps'] + errors = [] + for i, step in enumerate(script, 1): + w = '%s step %d' % (where, i) + if not isinstance(step, dict): + errors.append(w + ': not an object') + continue + kinds = [k for k in ('do', 'expect') if k in step] + if len(kinds) != 1: + errors.append(w + ': needs exactly one of "do" or "expect"') + continue + kind, action = kinds[0], step[kinds[0]] + if action not in STEPS[kind]: + errors.append('%s: unknown %s "%s", use one of %s' % (w, kind, action, ', '.join(STEPS[kind]))) + continue + required, optional = STEPS[kind][action] + allowed = set(required) | optional | {kind, 'label', 'timeout'} | ({'observed_fail'} if kind == 'expect' else set()) + for k in step: + if k not in allowed: + errors.append('%s: "%s" is not used by %s %s' % (w, k, kind, action)) + for k in required: + if k not in step: + errors.append('%s: %s %s needs "%s"' % (w, kind, action, k)) + if action in NEEDS_SELECTOR and not (SELECTOR - {'nth', 'exact'}) & set(step): + errors.append('%s: %s %s needs name, role or path' % (w, kind, action)) + if action in ('text', 'ocr') and not {'contains', 'not_contains'} & set(step): + errors.append(w + ': expect %s needs contains or not_contains' % action) + if action == 'state' and not {'state', 'not_state'} & set(step): + errors.append(w + ': expect state needs state or not_state') + for k in ('state', 'not_state'): + if k in step and step[k] not in STATES: + errors.append('%s: unknown state "%s", use one of %s' % (w, step[k], ', '.join(sorted(STATES)))) + if action == 'capture': + try: + re.compile(step['regex']) + except (re.error, TypeError) as e: + errors.append('%s: bad regex: %s' % (w, e)) + if not re.fullmatch(r'[\w-]+', str(step['as'])): + errors.append(w + ': "as" must be a name of letters, digits, _ and -') + if script and not any('expect' in s for s in script if isinstance(s, dict)): + errors.append(where + ': needs at least one "expect" step, otherwise nothing is tested') + return errors + + +STEP_RE = re.compile(r'^(Given|When|Then|And|But|\*)\s+\S') +SCENARIO_RE = re.compile(r'^(Scenario Outline|Scenario Template|Scenario|Example):\s*(.*)$') +TAG_RE = re.compile(r'^@[^\s@]+$') +DOCSTRING = ('"""', '```') + + +class ParseError(ValueError): + pass + + +def validate_steps(lines, where, need_then=True): + """Errors in the Gherkin lines of a scenario or background.""" + errors, fence, keyword = [], None, None + for n, line in enumerate(lines, 1): + s = line.strip() + if fence: + if s == fence: + fence = None + continue + if s.startswith(DOCSTRING) or s.startswith('|'): + if keyword is None: + errors.append('%s line %d: a doc string or table must come after a step' % (where, n)) + if s.startswith(DOCSTRING): + fence = s[:3] + continue + m = STEP_RE.match(s) + if not m: + errors.append('%s line %d: a step must start with Given, When, Then, And, But or *: %s' % (where, n, s)) + continue + if keyword is None and m.group(1) in ('And', 'But'): + errors.append('%s line %d: the first step can not start with %s' % (where, n, m.group(1))) + keyword = keyword if m.group(1) in ('And', 'But', '*') else m.group(1) + if fence: + errors.append(where + ': a doc string is not closed with ' + fence) + if need_then and not any(re.match(r'^Then\s', line.strip()) for line in lines): + errors.append(where + ': needs a Then step, the expected result') + return errors + + +def parse(text): + """A .feature file as a test file dict. Raises ParseError.""" + doc = {'title': '', 'tests': []} + tags, section, fence, indent, table = [], None, None, 0, None + lines = text.splitlines() + + def fail(n, msg): + raise ParseError('line %d: %s' % (n, msg)) + + for n, raw in enumerate(lines, 1): + s = raw.strip() + if fence: # inside a doc string, kept as it is + section['steps'].append(raw[indent:] if raw[:indent].strip() == '' else s) + if s == fence: + section['steps'][-1] = s + fence = None + continue + if not s or s.startswith('#'): + continue + if s.startswith('@'): + for tag in s.split('#')[0].split(): + if not TAG_RE.match(tag): + fail(n, 'bad tag ' + tag) + tags.append(tag[1:]) + continue + table = table if s.startswith('|') else None + if s.startswith('Feature:'): + if 'feature' in doc: + fail(n, 'only one Feature per file') + doc['feature'] = True + doc['title'] = s[len('Feature:'):].strip() + if tags: + doc['tags'], tags = tags, [] + section = doc + continue + if 'feature' not in doc: + fail(n, 'the file must start with Feature:') + if s.startswith('Background:'): + if doc['tests'] or 'background' in doc: + fail(n, 'the Background must come before the scenarios, once') + doc['background'] = [] + section = {'steps': doc['background']} + continue + m = SCENARIO_RE.match(s) + if m: + section = scenario(m.group(2).strip(), tags) + doc['tests'].append(section) + tags = [] + continue + if s.startswith(('Rule:', 'Scenarios:')) or (s.startswith('Examples:') and section is doc): + fail(n, s.split(':')[0] + ' is not supported here') + if s.startswith('Examples:'): + if 'name' not in section: + fail(n, 'Examples only belong to a scenario') + section['examples'] = section.get('examples', []) + table = [] + continue + if table is not None: # a row of Examples + cells = [c.strip() for c in s.strip('|').split('|')] + if not s.endswith('|') or len(s) < 2: + fail(n, 'a table row must start and end with |') + if not table: + table.append(cells) + section['_columns'] = cells + elif len(cells) != len(table[0]): + fail(n, 'the row has %d cells, the header has %d' % (len(cells), len(table[0]))) + else: + section['examples'].append(dict(zip(table[0], cells))) + continue + if section is doc: + doc.setdefault('description', []).append(s) + continue + if 'examples' in section: + fail(n, 'steps must come before the Examples') + if not section['steps'] and not STEP_RE.match(s) and 'name' in section: + if s.startswith('TODO:'): # description lines of a scenario + section['todo'] = (section.get('todo', '') + '\n' + s[5:].strip()).strip() + else: + section.setdefault('description', []).append(s) + continue + section['steps'].append(s) + if s.startswith(DOCSTRING): + fence, indent = s[:3], len(raw) - len(raw.lstrip()) + if fence: + fail(len(lines), 'the doc string is not closed') + if 'feature' not in doc: + fail(1, 'no Feature: in the file') + del doc['feature'] + for t in doc['tests']: + if 'examples' in t and not t['examples']: + raise ParseError('%s: Examples without rows' % t['name']) + t.pop('_columns', None) + return doc + + +def scenario(name, tags): + t = {'name': name, 'steps': []} + other = [] + for tag in tags: + key, _, value = tag.partition(':') + if key == 'id' and value: + t['id'] = value + elif key == 'ticket' and value: + t['ticket'] = '#' + value if value.isdigit() else value + elif key == 'project' and value: + t.setdefault('projects', []).append(value) + elif key == 'edition' and value: + t.setdefault('editions', []).append(value) + elif tag == 'disabled': + t['enabled'] = False + else: + other.append(tag) + if other: + t['tags'] = other + return t + + +def write_steps(out, lines, indent): + """Doc strings and tables are indented below their step.""" + fence = None + for line in lines: + s = line.strip() + inner = fence or s.startswith(DOCSTRING) or s.startswith('|') + out.append((indent + ' ' * bool(inner) + line) if line else '') + if fence and s == fence: + fence = None + elif not fence and s.startswith(DOCSTRING): + fence = s[:3] + + +def table(rows): + cols = list(rows[0]) + width = {c: max(len(c), *(len(r.get(c, '')) for r in rows)) for c in cols} + fmt = lambda cells: '| ' + ' | '.join(v.ljust(width[c]) for c, v in zip(cols, cells)) + ' |' + return [fmt(cols)] + [fmt([r.get(c, '') for c in cols]) for r in rows] + + +def to_gherkin(doc): + out = [] + if doc.get('tags'): + out.append(' '.join('@' + t for t in doc['tags'])) + out.append('Feature: ' + doc.get('title', '')) + for line in doc.get('description', []): + out.append(' ' + line) + if doc.get('background'): + out += ['', ' Background:'] + write_steps(out, doc['background'], ' ') + for t in doc['tests']: + tags = ['id:' + t['id']] if t.get('id') else [] + if t.get('ticket'): + tags.append('ticket:' + t['ticket'].lstrip('#')) + tags += ['project:' + p for p in t.get('projects', [])] + if t.get('editions') and len(t['editions']) < len(EDITIONS): + tags += ['edition:' + e for e in t['editions']] + if t.get('enabled') is False: + tags.append('disabled') + tags += t.get('tags', []) + out.append('') + if tags: + out.append(' ' + ' '.join('@' + x for x in tags)) + out.append(' %s: %s' % ('Scenario Outline' if t.get('examples') else 'Scenario', t['name'])) + for line in t.get('description', []): + out.append(' ' + line) + for line in (t.get('todo') or '').splitlines(): + out.append(' TODO: ' + line.strip()) + write_steps(out, t.get('steps', []), ' ') + if t.get('examples'): + out += ['', ' Examples:'] + out += [' ' + row for row in table(t['examples'])] + return '\n'.join(out) + '\n' + + +def legacy_steps(steps, expected): + """Steps and expected result in plain words (markdown and older JSON files) as Gherkin lines.""" + lines = [] + for s in steps: + if s.startswith(('* ', '- ')) and lines: + lines[-1] += ' ' + s[2:] + else: + lines.append(('Given ' if not lines else 'When ' if len(lines) == 1 else 'And ') + s) + if expected: + lines.append('Then ' + ' '.join(expected.split())) + return lines + + +def from_legacy_json(old): + """An older JSON test file: steps, expected and a matrix of axes.""" + doc = {'title': old.get('title', ''), 'tests': []} + for o in old.get('tests', []): + t = {k: o[k] for k in ('id', 'name', 'ticket', 'enabled', 'todo', 'projects', 'editions', 'script', 'script_for') + if k in o} + matrix = o.get('matrix') or {} + steps = legacy_steps(o.get('steps', []), o.get('expected', '')) + t['steps'] = [re.sub(r'\{(%s)\}' % '|'.join(map(re.escape, matrix)), r'<\1>', s) if matrix else s for s in steps] + if matrix: + t['examples'] = [dict(zip(matrix, v)) for v in itertools.product(*matrix.values())] + doc['tests'].append(t) + return doc + + +def from_markdown(text): + m = re.search(r'^#\s+(.+)$', text, re.M) + doc = {'title': m.group(1).strip() if m else '', 'tests': []} + for m in re.finditer(r'^## Test:\s*(.+?)\s*\n(.*?)(?=^## |\Z)', text, re.S | re.M): + test = {'name': m.group(1), 'steps': [], 'expected': '', 'todo': ''} + field = None + for line in m.group(2).splitlines(): + s = line.strip() + if s.startswith('Ticket:'): + test['ticket'] = s[len('Ticket:'):].strip() + field = None + elif s.startswith('EXPECTED:'): + test['expected'] = s[len('EXPECTED:'):].strip() + field = 'expected' + elif s.startswith('TODO:'): + test['todo'] = s[len('TODO:'):].strip() + field = 'todo' + elif not s: + field = None + elif field: + test[field] += '\n' + s + else: + test['steps'].append(re.sub(r'^\d+\.\s+', '', s)) + test['steps'] = legacy_steps(test['steps'], test.pop('expected')) + if not test['todo']: + del test['todo'] + doc['tests'].append(test) + return doc + + +def validate(doc, root=None): + """Return a list of error strings, empty when the document is fine. With ROOT (the directory of + the test file) the test projects must exist.""" + errors = [] + if not isinstance(doc, dict) or not isinstance(doc.get('tests'), list): + return ['the document needs a "tests" list'] + if not isinstance(doc.get('title', ''), str) or '\n' in doc.get('title', ''): + errors.append('the title must be one line') + background = doc.get('background', []) + if not isinstance(background, list) or not all(isinstance(s, str) for s in background): + errors.append('the background must be a list of lines') + else: + errors += validate_steps(background, 'Background', need_then=False) + names = set() + for i, t in enumerate(doc['tests'], 1): + where = 'test %d' % i + if not isinstance(t, dict): + errors.append(where + ': not an object') + continue + name = t.get('name') + if not isinstance(name, str) or not name.strip(): + errors.append(where + ': name is missing') + elif '\n' in name: + errors.append(where + ': the name must be one line') + elif name in names: + errors.append('%s: duplicate name "%s"' % (where, name)) + else: + names.add(name) + steps = t.get('steps', []) + if not isinstance(steps, list) or not all(isinstance(s, str) and '\n' not in s for s in steps): + errors.append(where + ': steps must be a list of lines') + else: + errors += validate_steps(steps, where) + for k in ('todo', 'ticket', 'id'): + if not isinstance(t.get(k, ''), str): + errors.append('%s: %s must be a string' % (where, k)) + if re.search(r'\s', t.get('ticket', '') or '') or re.search(r'\W', t.get('id', '') or ''): + errors.append(where + ': the ticket and the id can not have spaces, they are tags') + projects = t.get('projects', []) + if not isinstance(projects, list) or not all(isinstance(p, str) and PROJECT_RE.match(p) for p in projects): + errors.append(where + ': projects must be a list of project names (letters, digits, _ and -)') + elif root: + errors += ['%s: the test project "%s" does not exist' % (where, p) for p in projects + if not os.path.isdir(os.path.join(root, PROJECTS, p))] + editions = t.get('editions', list(EDITIONS)) + if (not isinstance(editions, list) or not editions or len(set(editions)) != len(editions) + or not all(e in EDITIONS for e in editions)): + errors.append('%s: editions must be a list of one or more of %s' % (where, ', '.join(EDITIONS))) + errors += validate_script(t.get('script', []), where + ' script') + examples = t.get('examples', []) + if not isinstance(examples, list) or not all(isinstance(r, dict) for r in examples): + errors.append(where + ': examples must be a list of rows') + continue + if examples: + cols = list(examples[0]) + for c in cols: + if not AXIS_RE.match(c): + errors.append('%s: Examples column "%s" must be letters, digits and _' % (where, c)) + if any(list(r) != cols for r in examples): + errors.append(where + ': every row of the Examples must have the same columns') + if not all(isinstance(v, str) and v and '|' not in v for r in examples for v in r.values()): + errors.append(where + ': every cell of the Examples needs a value without |') + if len({json.dumps(r, sort_keys=True) for r in examples}) != len(examples): + errors.append(where + ': a row of the Examples is there twice') + return errors + + +def scripts_path(path): + return path[:-len(EXT)] + SCRIPTS_EXT if path.endswith(EXT) else path + SCRIPTS_EXT + + +def load(path): + with open(path, encoding='utf-8') as f: + text = f.read() + if path.endswith('.md'): + return from_markdown(text) + if path.endswith('.json'): + return from_legacy_json(json.loads(text)) + doc = parse(text) + try: + with open(scripts_path(path), encoding='utf-8') as f: + scripts = json.load(f) + except FileNotFoundError: + scripts = {} + for t in doc['tests']: + s = scripts.get(t.get('id')) if t.get('id') else None + if isinstance(s, dict) and s.get('script'): + t['script'] = s['script'] + if s.get('script_for'): + t['script_for'] = s['script_for'] + return doc + + +def combinations(test): + """The rows of the Examples of a test as a list of {column: value}; [{}] when there are none.""" + return [dict(r) for r in test.get('examples') or []] or [{}] + + +def editions(test): + """The editions that a test is for, all of them when it does not say.""" + return test.get('editions') or list(EDITIONS) + + +def substitute(text, combo): + return re.sub(r'\{([\w:-]+)\}', lambda m: combo.get(m.group(1), m.group(0)), text) + + +def substitute_step(text, combo): + """ of the Examples and {edition} in a line of the steps.""" + text = re.sub(r'<(\w+)>', lambda m: combo.get(m.group(1), m.group(0)), text) + return substitute(text, {k: v for k, v in combo.items() if k == 'edition'}) + + +def body(test, combo, edition=None, background=()): + """The test as it is shown to Claude: the scenario in Gherkin, with the values of the run.""" + parts = [] + if test.get('ticket'): + parts.append('Ticket: ' + test['ticket']) + if edition: + parts.append('Edition of the application: ' + edition) + if combo: + parts.append('Examples row for this run: ' + ', '.join('%s=%s' % kv for kv in combo.items())) + combo = dict(combo, edition=edition) if edition else combo + lines = [] + if background: + lines += ['Background:'] + [' ' + substitute_step(s, combo) for s in background] + [''] + lines += ['Scenario: ' + test['name']] + [' ' + substitute_step(s, combo) for s in test.get('steps', [])] + parts.append('\n'.join(lines)) + if test.get('todo'): + parts.append('TODO: ' + substitute_step(test['todo'], combo)) + return '\n\n'.join(parts) + + +def project_files(root, name): + """{relative path: bytes} of a test project.""" + base = os.path.join(root, PROJECTS, name) + out = {} + for dirpath, _, files in os.walk(base): + for f in files: + p = os.path.join(dirpath, f) + with open(p, 'rb') as fh: + out[os.path.relpath(p, base)] = fh.read() + return out + + +def project_hash(root, name): + h = hashlib.sha1() + for path, data in sorted(project_files(root, name).items()): + h.update(path.encode() + b'\0' + data + b'\0') + return h.hexdigest()[:12] + + +def materialize(root, names, work): + """Copy the test projects to WORK/projects/NAME. Returns the variables for the script.""" + variables = {} + for name in names: + src = os.path.join(root, PROJECTS, name) + if not os.path.isdir(src): + raise FileNotFoundError('the test project "%s" does not exist' % name) + dst = os.path.join(work, PROJECTS, name) + shutil.copytree(src, dst) + variables['project:' + name] = dst + if len(names) == 1: + variables['project'] = variables['project:' + names[0]] + return variables + + +def definition_hash(test, root=None, background=()): + """What a script depends on: changing any of these, the Background of the file or a file of a + test project makes the script outdated.""" + d = {'steps': list(background or []) + list(test.get('steps') or []), 'todo': test.get('todo') or '', + 'examples': test.get('examples') or []} + if test.get('projects'): + d['projects'] = {p: project_hash(root, p) if root and os.path.isdir(os.path.join(root, PROJECTS, p)) else 'missing' + for p in test['projects']} + return hashlib.sha1(json.dumps(d, sort_keys=True, ensure_ascii=False).encode()).hexdigest()[:12] + + +def ensure_ids(doc): + for t in doc.get('tests', []): + if not t.get('id'): + t['id'] = 't' + hashlib.sha1(str(t.get('name', '')).encode()).hexdigest()[:8] + return doc + + +def is_stale(test, root=None, background=()): + """A script that was made for another version of the test. No script_for: old file, trusted.""" + return bool(test.get('script') and test.get('script_for') + and test['script_for'] != definition_hash(test, root, background)) + + +def stamp_scripts(doc, old, root=None): + """Before saving. A new, edited or approved ("_approve") script is current for the test as it is + now. An untouched script keeps what it was made for, so editing the test makes it outdated.""" + ensure_ids(doc) + old = ensure_ids(old or {}) + prev = {t['id']: t for t in old.get('tests', [])} + for t in doc['tests']: + t.pop('_stale', None) + approve = t.pop('_approve', False) + if not t.get('script'): + t.pop('script_for', None) + continue + p = prev.get(t['id']) + if approve or p is None or p.get('script') != t['script']: + t['script_for'] = definition_hash(t, root, doc.get('background')) + else: + t['script_for'] = p.get('script_for') or definition_hash(p, root, old.get('background')) + return doc + + +def subst_deep(obj, combo): + if isinstance(obj, str): + return substitute(obj, combo) + if isinstance(obj, list): + return [subst_deep(x, combo) for x in obj] + if isinstance(obj, dict): + return {k: subst_deep(v, combo) for k, v in obj.items()} + return obj + + +def expand(path, edition=None): + """One dict {name, id, body, script, stale, combo} per Examples row of every enabled test. + With EDITION only the tests for that edition, and {edition} is replaced.""" + doc = ensure_ids(load(path)) + root = os.path.dirname(os.path.abspath(path)) + errors = validate(doc, root) + if errors: + sys.exit('error: %s: %s' % (path, '; '.join(errors))) + background = doc.get('background', []) + out = [] + for t in doc['tests']: + if not t.get('enabled', True) or edition and edition not in editions(t): + continue + for combo in combinations(t): + name = t['name'] + (' [%s]' % ', '.join('%s=%s' % kv for kv in combo.items()) if combo else '') + values = dict(combo, edition=edition) if edition else combo + out.append({'name': name, 'id': t['id'], 'body': body(t, combo, edition, background), 'combo': combo, + 'root': root, 'projects': t.get('projects', []), 'stale': is_stale(t, root, background), + 'script': subst_deep(t.get('script', []), values)}) + return out + + +def write_atomic(path, text): + tmp = path + '.tmp' + with open(tmp, 'w', encoding='utf-8') as f: + f.write(text) + os.replace(tmp, path) + + +def save(path, doc): + """Write FILE.feature and the scripts in FILE.scripts.json.""" + if not path.endswith(EXT): + raise ValueError('a test file is saved as ' + EXT) + ensure_ids(doc) + scripts = {t['id']: {k: t[k] for k in ('script', 'script_for') if t.get(k)} for t in doc['tests'] if t.get('script')} + write_atomic(path, to_gherkin(doc)) + if scripts: + write_atomic(scripts_path(path), json.dumps(scripts, indent=2, ensure_ascii=False) + '\n') + elif os.path.exists(scripts_path(path)): + os.remove(scripts_path(path)) + + +def convert(src, dst): + """Import a markdown or an older JSON test file. Scripts that were up to date stay up to date.""" + root = os.path.dirname(os.path.abspath(src)) + current = set() + if src.endswith('.json'): + with open(src, encoding='utf-8') as f: + old = json.load(f) + for o in old.get('tests', []): + d = {k: o.get(k) or ([] if k == 'steps' else {} if k == 'matrix' else '') for k in ('steps', 'expected', 'todo', 'matrix')} + if o.get('projects'): + d['projects'] = {p: project_hash(root, p) if os.path.isdir(os.path.join(root, PROJECTS, p)) else 'missing' + for p in o['projects']} + h = hashlib.sha1(json.dumps(d, sort_keys=True, ensure_ascii=False).encode()).hexdigest()[:12] + if o.get('script') and o.get('script_for') in (None, h): + current.add(o.get('id')) + doc = ensure_ids(load(src)) + for t in doc['tests']: + if t['id'] in current: + t['script_for'] = definition_hash(t, os.path.dirname(os.path.abspath(dst)), doc.get('background')) + save(dst, doc) + + +if __name__ == '__main__': + if len(sys.argv) != 4 or sys.argv[1] != 'convert' or not sys.argv[3].endswith(EXT): + sys.exit(__doc__) + convert(sys.argv[2], sys.argv[3]) diff --git a/gui/manualtest/tests/analysis.feature b/gui/manualtest/tests/analysis.feature new file mode 100644 index 00000000000..fc43506dd98 --- /dev/null +++ b/gui/manualtest/tests/analysis.feature @@ -0,0 +1,55 @@ +Feature: Analysis and recheck + + Background: + Given the application is started with no project loaded + + @id:te65b1fa8 @project:basic-project + Scenario: Reanalyze all files + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I change {project:basic-project}/src/a.c and {project:basic-project}/src/b.c so that they only contain ";" + And I click Reanalyze all files + And I wait until the analysis is done + Then there are no results for a.c + And there are no results for b.c + + @id:tc707b85b @ticket:14893 @project:recheck + Scenario: Recheck a changed file + Given the project file {project:recheck}/p.cppcheck is opened + And the analysis is done + And the results show a nullPointer error in a.c and an arrayIndexOutOfBounds error in b.c + When I copy {project:recheck}/a_v2.c over {project:recheck}/a.c (a_v2.c has an uninitvar error instead) + And I right click on the file a.c in the results and click Recheck + Then the results for a.c are refreshed + And the nullPointer error in a.c is gone + And the uninitvar error from the changed a.c is shown + And the arrayIndexOutOfBounds error in b.c is still shown, unchanged + + @id:tc550387d @project:basic-project + Scenario: Recheck a header file + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I right click on the file util.h in the results + Then the context menu of util.h has a Recheck entry + When I click Recheck + And I wait until the analysis is done + Then the analysis is run again for the files that include util.h + And the nullPointer error in util.h is shown again + + @id:ta6f3b40b @project:syntax-error + Scenario Outline: Analyze a broken source file + Given the project file {project:syntax-error}/.cppcheck checks .c, a broken or unusual source file, and ok.c, which has a nullPointer error + When I open the project file {project:syntax-error}/.cppcheck + And I wait until the analysis is done + Then the analysis finishes + And the application does not crash + And the nullPointer error in ok.c is shown + + Examples: + | case | + | braces | + | empty | + | binary | + | latin1 | + | long_line | + | unclosed_nesting | diff --git a/gui/manualtest/tests/analysis.scripts.json b/gui/manualtest/tests/analysis.scripts.json new file mode 100644 index 00000000000..54d89a4c39d --- /dev/null +++ b/gui/manualtest/tests/analysis.scripts.json @@ -0,0 +1,399 @@ +{ + "te65b1fa8": { + "script": [ + { + "label": "Open the File menu", + "do": "click", + "name": "File", + "role": "menu item" + }, + { + "label": "Choose Open Project File", + "do": "click", + "name": "Open Project File", + "role": "menu item" + }, + { + "label": "Enter the project file path", + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck" + }, + { + "label": "Confirm the file dialog", + "do": "key", + "keys": [ + "Return" + ] + }, + { + "label": "Wait until the first analysis shows results for a.c", + "expect": "visible", + "name": "src/a.c", + "role": "table cell", + "timeout": 30 + }, + { + "label": "Results for b.c are shown too", + "expect": "visible", + "name": "src/b.c", + "role": "table cell" + }, + { + "label": "Edit a.c so it only contains ;", + "do": "write", + "path": "{project:basic-project}/src/a.c", + "content": ";" + }, + { + "label": "Edit b.c so it only contains ;", + "do": "write", + "path": "{project:basic-project}/src/b.c", + "content": ";" + }, + { + "label": "Click Reanalyze all files", + "do": "click", + "name": "Reanalyze all files", + "role": "button" + }, + { + "label": "Wait until the analysis is done (No errors found dialog)", + "expect": "visible", + "name": "No errors found", + "role": "label", + "timeout": 30 + }, + { + "label": "Close the dialog", + "do": "click", + "name": "OK", + "role": "button" + }, + { + "label": "No results for a.c", + "expect": "gone", + "name": "src/a.c", + "role": "table cell" + }, + { + "label": "No results for b.c", + "expect": "gone", + "name": "src/b.c", + "role": "table cell" + } + ], + "script_for": "c692e526a6cd" + }, + "tc707b85b": { + "script": [ + { + "do": "wait", + "name": "Cppcheck", + "role": "frame", + "timeout": 20, + "label": "Application started with no project" + }, + { + "do": "click", + "name": "Open Project File", + "role": "button", + "label": "Open the project file dialog" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:recheck}/p.cppcheck", + "label": "Enter the path of p.cppcheck" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Open the project" + }, + { + "expect": "visible", + "name": "b.c", + "role": "table cell", + "timeout": 30, + "label": "Analysis done, b.c in the results" + }, + { + "expect": "visible", + "name": "a.c", + "role": "table cell", + "timeout": 30, + "label": "a.c in the results" + }, + { + "do": "sleep", + "seconds": 3, + "label": "Let the analysis finish" + }, + { + "do": "copy", + "from": "{project:recheck}/a_v2.c", + "to": "{project:recheck}/a.c", + "label": "Change a.c by copying a_v2.c over it" + }, + { + "do": "rightclick", + "name": "a.c", + "role": "table cell", + "nth": 0, + "label": "Right click on a.c in the results" + }, + { + "expect": "ocr", + "contains": "Recheck", + "label": "Context menu shows Recheck" + }, + { + "do": "key", + "keys": [ + "Down", + "Return" + ], + "label": "Click Recheck" + }, + { + "do": "sleep", + "seconds": 4, + "label": "Wait for the recheck" + }, + { + "do": "click", + "name": "b.c", + "role": "table cell", + "nth": 0, + "label": "Select the b.c row" + }, + { + "do": "key", + "keys": [ + "Right", + "Down", + "Down", + "Down", + "Right" + ], + "label": "Expand b.c and a.c to show their results" + }, + { + "expect": "text", + "contains": "uninitvar", + "label": "The uninitvar error of the changed a.c is shown" + }, + { + "expect": "text", + "not_contains": "nullPointer", + "label": "The nullPointer error is gone" + }, + { + "expect": "text", + "contains": "arrayIndexOutOfBounds", + "label": "The arrayIndexOutOfBounds error in b.c is still shown" + } + ], + "script_for": "0c160519508a" + }, + "tc550387d": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the project file path" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the file dialog" + }, + { + "expect": "visible", + "name": "include/util.h", + "role": "table cell", + "timeout": 30, + "label": "Analysis is done and util.h is in the results" + }, + { + "expect": "visible", + "name": "src/b.c", + "role": "table cell", + "timeout": 30, + "label": "Analysis finished for all files" + }, + { + "do": "rightclick", + "name": "include/util.h", + "role": "table cell", + "label": "Right click on util.h in the results" + }, + { + "do": "sleep", + "seconds": 1, + "label": "Wait for the context menu" + }, + { + "do": "key", + "keys": [ + "Down", + "Return" + ], + "label": "Click the Recheck entry of the context menu" + }, + { + "expect": "text", + "contains": "Checking /tmp", + "timeout": 30, + "label": "The analysis was run again" + }, + { + "expect": "text", + "contains": "src/a.c ...", + "timeout": 30, + "label": "The file that includes util.h is checked again" + }, + { + "do": "sleep", + "seconds": 3, + "label": "Wait until the analysis is done" + }, + { + "do": "click", + "name": "include/util.h", + "role": "table cell", + "mouse": true, + "label": "Select util.h with the mouse so it has focus" + }, + { + "do": "key", + "keys": [ + "Right" + ], + "label": "Expand util.h" + }, + { + "expect": "visible", + "name": "nullPointer", + "role": "table cell", + "timeout": 10, + "label": "The nullPointer error in util.h is shown again" + }, + { + "expect": "visible", + "name": "Null pointer dereference", + "role": "table cell", + "timeout": 5, + "label": "The nullPointer message is shown" + } + ], + "script_for": "dc8fcd30e236" + }, + "ta6f3b40b": { + "script": [ + { + "label": "Start the application with no project loaded", + "expect": "visible", + "name": "Cppcheck", + "role": "frame" + }, + { + "label": "Open the project file", + "do": "click", + "name": "Open Project File", + "role": "button" + }, + { + "label": "Wait for the Select Project File dialog", + "do": "wait", + "name": "Select Project File", + "timeout": 10 + }, + { + "label": "Enter the project file {case}.cppcheck", + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:syntax-error}/{case}.cppcheck" + }, + { + "label": "Confirm the file dialog", + "do": "key", + "keys": [ + "Return" + ] + }, + { + "label": "The project is loaded", + "expect": "visible", + "name": "Project: {case}.cppcheck", + "role": "frame", + "timeout": 15 + }, + { + "label": "Wait until the analysis is done (ok.c is checked)", + "expect": "text", + "contains": "Checking ok.c", + "timeout": 60 + }, + { + "label": "Give the analysis time to finish", + "do": "sleep", + "seconds": 3 + }, + { + "label": "The analysis finishes: Stop analysis is disabled again", + "expect": "state", + "name": "Stop analysis", + "role": "button", + "not_state": "enabled", + "timeout": 60 + }, + { + "label": "The analysis finishes: Reanalyze all files is enabled again", + "expect": "state", + "name": "Reanalyze all files", + "role": "button", + "state": "enabled", + "timeout": 30 + }, + { + "label": "The broken source file {case}.c was analyzed", + "expect": "text", + "contains": "Checking {case}.c" + }, + { + "label": "The nullPointer error in ok.c is shown (ok.c has a result row)", + "expect": "visible", + "name": "ok.c", + "role": "table cell" + }, + { + "label": "The application does not crash", + "expect": "alive" + } + ], + "script_for": "3090dfe1cf47" + } +} diff --git a/gui/manualtest/tests/application.feature b/gui/manualtest/tests/application.feature new file mode 100644 index 00000000000..378e1a636cc --- /dev/null +++ b/gui/manualtest/tests/application.feature @@ -0,0 +1,59 @@ +Feature: Application, menus and help + + Background: + Given the application is started with no project loaded + + @id:t41f9102b + Scenario: All menus open + When I open each of the menus File, Edit, View, Analyze and Help in turn + And I look at its entries and close it with Escape + Then each of the menus File, Edit, View, Analyze and Help opens + And each menu shows at least one entry + + @id:t1cc2be0f + Scenario: Show and hide toolbars + Given all entries of View > Toolbar are checked + When I uncheck the entries of View > Toolbar one at a time + Then a toolbar that is unchecked is no longer shown in the main window + And the toolbars that are still checked are shown + + @id:t5fdeee58 @edition:opensource + Scenario: Same version in the title and in About + Given the title of the main window is "Cppcheck " + When I note the version in the title + And I open Help > About + Then the About dialog shows the same version as the title of the main window + + @id:t90321d9c + Scenario: Help contents + When I open Help > Contents + Then a help window opens + And the help window has contents, it is not empty + + @id:tc059b730 + Scenario: Other Help menu entries + When I open each of the other entries of the Help menu in turn (About and the rest) + And I close each window with Escape or its Close button + Then every entry opens a dialog or window with text in it + And none of them is empty + + @id:t5bf8f6ae @ticket:13982 + Scenario: Scratch pad + When I open View > Scratch Pad + And I enter this code, one line each: + """ + int main(void) + { + int *p = 0; + return *p; + } + """ + And I click Check + Then the code is analysed + And a nullPointer error is shown + And the application does not crash + + @id:t1a2285d8 + Scenario: Quit from the File menu + When I open File > Quit + Then the application closes diff --git a/gui/manualtest/tests/application.scripts.json b/gui/manualtest/tests/application.scripts.json new file mode 100644 index 00000000000..98f5b20a42d --- /dev/null +++ b/gui/manualtest/tests/application.scripts.json @@ -0,0 +1,548 @@ +{ + "t41f9102b": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "expect": "visible", + "name": "Open XML...", + "role": "menu item", + "label": "File menu shows entries" + }, + { + "do": "key", + "keys": [ + "Escape" + ], + "label": "Close the File menu" + }, + { + "do": "click", + "name": "Edit", + "role": "menu item", + "label": "Open the Edit menu" + }, + { + "expect": "visible", + "name": "Clear results", + "role": "menu item", + "label": "Edit menu shows entries" + }, + { + "do": "key", + "keys": [ + "Escape" + ], + "label": "Close the Edit menu" + }, + { + "do": "click", + "name": "View", + "role": "menu item", + "label": "Open the View menu" + }, + { + "expect": "visible", + "name": "Toolbars", + "role": "menu item", + "label": "View menu shows entries" + }, + { + "do": "key", + "keys": [ + "Escape" + ], + "label": "Close the View menu" + }, + { + "do": "click", + "name": "Analyze", + "role": "menu item", + "label": "Open the Analyze menu" + }, + { + "expect": "visible", + "name": "Files...", + "role": "menu item", + "label": "Analyze menu shows entries" + }, + { + "do": "key", + "keys": [ + "Escape" + ], + "label": "Close the Analyze menu" + }, + { + "do": "click", + "name": "Help", + "role": "menu item", + "label": "Open the Help menu" + }, + { + "expect": "visible", + "name": "Contents", + "role": "menu item", + "label": "Help menu shows entries" + }, + { + "do": "key", + "keys": [ + "Escape" + ], + "label": "Close the Help menu" + } + ], + "script_for": "06424398d415" + }, + "t1cc2be0f": { + "script": [ + { + "do": "click", + "name": "View", + "role": "menu item", + "label": "Open View menu" + }, + { + "do": "click", + "name": "Toolbars", + "role": "menu item", + "label": "Open Toolbars submenu" + }, + { + "expect": "state", + "name": "Standard", + "role": "menu item", + "state": "checked", + "label": "Standard toolbar entry is checked" + }, + { + "expect": "state", + "name": "Categories", + "role": "menu item", + "state": "checked", + "label": "Categories toolbar entry is checked" + }, + { + "expect": "state", + "name": "Filter", + "role": "menu item", + "state": "checked", + "label": "Filter toolbar entry is checked" + }, + { + "do": "click", + "name": "Standard", + "role": "menu item", + "label": "Uncheck Standard toolbar" + }, + { + "expect": "gone", + "name": "Standard", + "role": "tool bar", + "label": "Standard toolbar is no longer shown" + }, + { + "expect": "visible", + "name": "Categories", + "role": "tool bar", + "label": "Categories toolbar still shown" + }, + { + "expect": "visible", + "name": "Filter", + "role": "tool bar", + "label": "Filter toolbar still shown" + }, + { + "do": "click", + "name": "Categories", + "role": "menu item", + "label": "Uncheck Categories toolbar" + }, + { + "expect": "gone", + "name": "Categories", + "role": "tool bar", + "label": "Categories toolbar is no longer shown" + }, + { + "expect": "visible", + "name": "Filter", + "role": "tool bar", + "label": "Filter toolbar still shown" + }, + { + "do": "click", + "name": "Filter", + "role": "menu item", + "label": "Uncheck Filter toolbar" + }, + { + "expect": "gone", + "name": "Filter", + "role": "tool bar", + "label": "Filter toolbar is no longer shown" + } + ], + "script_for": "6a99d7841493" + }, + "t5fdeee58": { + "script": [ + { + "expect": "capture", + "name": "Cppcheck", + "role": "frame", + "regex": "'Cppcheck (?:Premium )?(\\d[^']*)'", + "as": "version", + "label": "Note the version in the title of the main window" + }, + { + "do": "click", + "name": "Help", + "role": "menu item", + "label": "Open the Help menu" + }, + { + "do": "click", + "name": "About...", + "role": "menu item", + "label": "Open Help > About" + }, + { + "expect": "visible", + "name": "About Cppcheck", + "role": "dialog", + "label": "About dialog is shown" + }, + { + "expect": "visible", + "name": "Version {version}", + "role": "label", + "label": "About dialog shows the same version as the main window title ({version})" + } + ], + "script_for": "5dadee22b5ec" + }, + "t90321d9c": { + "script": [ + { + "do": "click", + "name": "Help", + "role": "menu item", + "label": "Open the Help menu" + }, + { + "do": "click", + "name": "Contents", + "role": "menu item", + "label": "Choose Help > Contents" + }, + { + "expect": "visible", + "name": "Cppcheck GUI help", + "role": "dialog", + "label": "A help window opens", + "observed_fail": true + }, + { + "expect": "text", + "contains": "Contents", + "label": "The help window has contents (it is not empty)" + }, + { + "expect": "text", + "not_contains": "was not found", + "label": "No error that the help file was not found" + } + ], + "script_for": "7c97b218aa0f" + }, + "tc059b730": { + "script": [ + { + "do": "click", + "name": "Help", + "role": "menu item", + "label": "Open the Help menu" + }, + { + "do": "click", + "name": "License...", + "role": "menu item", + "label": "Open License" + }, + { + "expect": "visible", + "name": "License", + "role": "dialog", + "label": "License dialog opens" + }, + { + "expect": "text", + "contains": "GNU GENERAL PUBLIC LICENSE", + "label": "License dialog has text" + }, + { + "do": "key", + "keys": [ + "Escape" + ], + "label": "Close License with Escape" + }, + { + "expect": "gone", + "name": "License", + "label": "License dialog is closed" + }, + { + "do": "click", + "name": "Help", + "role": "menu item", + "label": "Open the Help menu" + }, + { + "do": "click", + "name": "Authors...", + "role": "menu item", + "label": "Open Authors" + }, + { + "expect": "visible", + "name": "Authors", + "role": "dialog", + "label": "Authors dialog opens" + }, + { + "expect": "text", + "contains": "The cppcheck team", + "label": "Authors dialog has text" + }, + { + "do": "click", + "name": "Close", + "role": "button", + "label": "Close Authors with its Close button" + }, + { + "expect": "gone", + "name": "Authors", + "role": "dialog", + "label": "Authors dialog is closed" + }, + { + "do": "click", + "name": "Help", + "role": "menu item", + "label": "Open the Help menu" + }, + { + "do": "click", + "name": "About...", + "role": "menu item", + "label": "Open About" + }, + { + "expect": "visible", + "name": "About Cppcheck", + "role": "dialog", + "label": "About dialog opens" + }, + { + "expect": "text", + "contains": "Cppcheck - A tool for static C/C++ code analysis.", + "label": "About dialog has text" + }, + { + "do": "key", + "keys": [ + "Escape" + ], + "label": "Close About with Escape" + }, + { + "expect": "gone", + "name": "About Cppcheck", + "role": "dialog", + "label": "About dialog is closed" + }, + { + "do": "click", + "name": "Help", + "role": "menu item", + "label": "Open the Help menu" + }, + { + "do": "click", + "name": "Contents", + "role": "menu item", + "label": "Open Contents" + }, + { + "expect": "visible", + "name": "Cppcheck", + "role": "alert", + "label": "Contents shows a message" + }, + { + "expect": "text", + "contains": "Helpfile", + "label": "Message has text" + }, + { + "do": "key", + "keys": [ + "Escape" + ], + "label": "Close the message with Escape" + }, + { + "expect": "visible", + "name": "Cppcheck GUI help", + "role": "dialog", + "label": "Help window opens" + }, + { + "expect": "text", + "contains": "Introduction", + "observed_fail": true, + "label": "Help window has text in it, not empty" + }, + { + "do": "key", + "keys": [ + "Escape" + ], + "label": "Close the help window with Escape" + } + ], + "script_for": "97511d2313db" + }, + "t5bf8f6ae": { + "script": [ + { + "do": "click", + "name": "View", + "role": "menu item", + "label": "Open the View menu" + }, + { + "do": "click", + "name": "Show Scratchpad", + "role": "menu item", + "label": "Open View > Scratch Pad" + }, + { + "expect": "visible", + "name": "Scratchpad", + "role": "dialog", + "label": "Scratchpad dialog is shown" + }, + { + "do": "focus", + "path": "1.1", + "label": "Focus the code editor of the scratchpad" + }, + { + "do": "type", + "value": "int main(void)", + "label": "Type line 1" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "New line" + }, + { + "do": "type", + "value": "{", + "label": "Type line 2" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "New line" + }, + { + "do": "type", + "value": " int *p = 0;", + "label": "Type line 3" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "New line" + }, + { + "do": "type", + "value": " return *p;", + "label": "Type line 4" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "New line" + }, + { + "do": "type", + "value": "}", + "label": "Type line 5" + }, + { + "do": "click", + "name": "Check", + "role": "button", + "label": "Click Check" + }, + { + "expect": "text", + "contains": "nullPointer", + "timeout": 15, + "label": "A nullPointer error is shown" + }, + { + "expect": "text", + "contains": "Null pointer dereference: p", + "label": "The null pointer message is shown" + }, + { + "expect": "alive", + "label": "The application did not crash" + } + ], + "script_for": "30d9d26803fd" + }, + "t1a2285d8": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Quit", + "role": "menu item", + "label": "Choose File > Quit" + }, + { + "expect": "exited", + "label": "The application closes" + } + ], + "script_for": "bc31dd4069bf" + } +} diff --git a/gui/manualtest/tests/preferences.feature b/gui/manualtest/tests/preferences.feature new file mode 100644 index 00000000000..70d0a82fa47 --- /dev/null +++ b/gui/manualtest/tests/preferences.feature @@ -0,0 +1,42 @@ +Feature: Preferences + + Background: + Given the application is started with no project loaded + + @id:t232a9783 + Scenario: Default number of threads + When I open Edit > Preferences + And I look at the General tab + Then the number of threads is 1 + + @id:tf5b5a7e1 + Scenario: Number of threads cannot be 0 + Given Edit > Preferences is open on the General tab + When I type 0 in the number of threads field + And I close the dialog with OK + And I open Edit > Preferences again + Then the field has not accepted 0 + And the number of threads is at least 1, it is never 0 + + @id:t841cca6c @project:basic-project + Scenario: Analysis with 100 threads + Given the number of threads is set to 100 in Edit > Preferences and the dialog is closed with OK + When I open the project file {project:basic-project}/basic.cppcheck from the File menu + And I wait until the analysis is done + Then the application does not crash + And the analysis is done and the results are shown + + @id:t28ce8afe @project:embedded @edition:opensource @disabled + Scenario Outline: Misra rule text file + Given Edit > Preferences is open on the Addons tab + When I select the rule text file {project:embedded}/ + And I close the dialog with OK + And I open the project file {project:embedded}/embedded.cppcheck + And I wait until the analysis is done + Then the Misra error for the unused parameter has the rule text from the file (TEST RULE TEXT: unused parameters are not allowed) + And there are no internalError results + + Examples: + | rulefile | + | rules.txt | + | rules with spaces.txt | diff --git a/gui/manualtest/tests/preferences.scripts.json b/gui/manualtest/tests/preferences.scripts.json new file mode 100644 index 00000000000..2da801e7e71 --- /dev/null +++ b/gui/manualtest/tests/preferences.scripts.json @@ -0,0 +1,306 @@ +{ + "t232a9783": { + "script": [ + { + "do": "click", + "name": "Edit", + "role": "menu item", + "label": "Open the Edit menu" + }, + { + "do": "click", + "name": "Preferences", + "role": "menu item", + "label": "Open Edit > Preferences" + }, + { + "expect": "visible", + "name": "Preferences", + "role": "dialog", + "label": "Preferences dialog is shown" + }, + { + "expect": "state", + "name": "General", + "role": "page tab", + "state": "selected", + "label": "General tab is shown" + }, + { + "expect": "value", + "name": "Number of threads", + "role": "text", + "equals": "1", + "label": "The number of threads is 1" + } + ], + "script_for": "3c6d225d76b6" + }, + "tf5b5a7e1": { + "script": [ + { + "do": "click", + "name": "Edit", + "role": "menu item", + "label": "Open the Edit menu" + }, + { + "do": "click", + "name": "Preferences", + "role": "menu item", + "label": "Open Edit > Preferences" + }, + { + "expect": "visible", + "name": "Preferences", + "role": "dialog", + "label": "Preferences dialog is shown" + }, + { + "do": "click", + "name": "General", + "role": "page tab", + "label": "Go to the General tab" + }, + { + "do": "settext", + "name": "Number of threads", + "role": "text", + "value": "0", + "label": "Type 0 in the number of threads field" + }, + { + "do": "click", + "name": "OK", + "role": "button", + "label": "Close the dialog with OK" + }, + { + "do": "click", + "name": "Edit", + "role": "menu item", + "label": "Open the Edit menu again" + }, + { + "do": "click", + "name": "Preferences", + "role": "menu item", + "label": "Open Edit > Preferences again" + }, + { + "expect": "visible", + "name": "Preferences", + "role": "dialog", + "label": "Preferences dialog is shown again" + }, + { + "do": "click", + "name": "General", + "role": "page tab", + "label": "Go to the General tab again" + }, + { + "expect": "value", + "name": "Number of threads", + "role": "text", + "equals": "1", + "label": "The number of threads is at least 1, never 0" + } + ], + "script_for": "6a7660844e11" + }, + "t841cca6c": { + "script": [ + { + "do": "click", + "name": "Edit", + "role": "menu item", + "label": "Open the Edit menu" + }, + { + "do": "click", + "name": "Preferences", + "role": "menu item", + "label": "Open Preferences from the Edit menu" + }, + { + "expect": "visible", + "name": "Preferences", + "role": "dialog", + "label": "Preferences dialog is shown" + }, + { + "do": "settext", + "name": "Number of threads", + "role": "text", + "value": "100", + "label": "Set the number of threads to 100" + }, + { + "expect": "value", + "name": "Number of threads", + "role": "text", + "equals": "100", + "label": "Thread count field holds 100" + }, + { + "do": "click", + "name": "OK", + "role": "button", + "label": "Close the Preferences dialog with OK" + }, + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "expect": "visible", + "name": "Select Project File", + "role": "dialog", + "label": "File dialog is shown" + }, + { + "do": "settext", + "name": "File name", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the path of basic.cppcheck" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Open the project file" + }, + { + "expect": "visible", + "name": "src/b.c", + "role": "table cell", + "timeout": 60, + "label": "Analysis is done and results for src/b.c are shown" + }, + { + "expect": "visible", + "name": "src/a.c", + "role": "table cell", + "label": "Results for src/a.c are shown" + }, + { + "expect": "text", + "contains": "Project: basic.cppcheck", + "label": "The project is loaded" + }, + { + "expect": "alive", + "label": "The application did not crash" + } + ], + "script_for": "3f99ba3a159c" + }, + "t28ce8afe": { + "script": [ + { + "do": "click", + "name": "Preferences", + "role": "button", + "label": "Open Preferences" + }, + { + "do": "click", + "name": "Addons", + "role": "page tab", + "label": "Go to the Addons tab" + }, + { + "do": "settext", + "name": "MISRA addon", + "role": "text", + "value": "{project:embedded}/{rulefile}", + "label": "Select the rule text file" + }, + { + "do": "click", + "name": "OK", + "role": "button", + "label": "Close the dialog with OK" + }, + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "do": "settext", + "name": "File name", + "role": "text", + "value": "{project:embedded}/embedded.cppcheck", + "label": "Enter the project file name" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Open the project file" + }, + { + "do": "sleep", + "seconds": 8, + "label": "Wait until the analysis is done" + }, + { + "expect": "visible", + "name": "gpio.c", + "role": "table cell", + "timeout": 20, + "label": "Results for gpio.c are shown" + }, + { + "do": "doubleclick", + "name": "gpio.c", + "role": "table cell", + "label": "Select the gpio.c result row" + }, + { + "do": "key", + "keys": [ + "Right" + ], + "label": "Expand the result row" + }, + { + "expect": "text", + "contains": "TEST RULE TEXT: unused parameters are not allowed", + "timeout": 10, + "label": "Misra error has the rule text from the file" + }, + { + "expect": "text", + "contains": "misra-c2012-2.7", + "label": "The unused parameter Misra rule id is shown" + }, + { + "expect": "text", + "not_contains": "internalError", + "label": "There are no internalError results" + } + ], + "script_for": "755194f793e0" + } +} diff --git a/gui/manualtest/tests/project_dialog.feature b/gui/manualtest/tests/project_dialog.feature new file mode 100644 index 00000000000..2d28b7dbc0e --- /dev/null +++ b/gui/manualtest/tests/project_dialog.feature @@ -0,0 +1,40 @@ +Feature: Project file dialog + + Background: + Given the application is started with no project loaded + + @id:tcf7ddb76 @ticket:14983 @project:relative-paths + Scenario: Relative paths in the saved project + Given a new project file is created and the project file dialog is open + When I import the project {project:relative-paths}/compile_commands.json (Paths and defines, Import project) + And I add the include directory {project:relative-paths}/inc + And I exclude the file {project:relative-paths}/skip/b.c + And I save the project file as {project:relative-paths}/rel.cppcheck + Then in the saved rel.cppcheck the import project is written relative to the project file: compile_commands.json + And the include directory is written relative to the project file: inc + And the excluded file is written relative to the project file: skip/b.c + And the XML contains no absolute path to the project folder + + @id:t5afff002 @ticket:14489 + Scenario: Select the platform pic8.xml + Given a new project file is created and the project file dialog is open + When I open the Platform drop-down list + And I select pic8.xml in the list + Then pic8.xml is in the Platform list + And pic8.xml is the platform that the dialog shows + + @id:t91490557 @ticket:14672 @project:custom-cfg + Scenario: Custom cfg file in the library list + Given the folder of {project:custom-cfg}/p.cppcheck also holds aa.cfg, a copy of cfg/avr.cfg + When I open the project file {project:custom-cfg}/p.cppcheck + And I open the project file dialog (edit the project file) + And I look at the library list (Libraries) + Then aa is in the library list + And aa comes before avr, the list is in alphabetical order + + @id:t0ec0680b @ticket:14488 @project:embedded @edition:opensource + Scenario: Misra checkbox of a loaded project + When I open the project file {project:embedded}/embedded.cppcheck + And I open the project file dialog (edit the project file) + And I go to the Addons tab + Then the Misra C 2012 checkbox is checked diff --git a/gui/manualtest/tests/project_dialog.scripts.json b/gui/manualtest/tests/project_dialog.scripts.json new file mode 100644 index 00000000000..08dfc5965ce --- /dev/null +++ b/gui/manualtest/tests/project_dialog.scripts.json @@ -0,0 +1,371 @@ +{ + "tcf7ddb76": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "New Project File", + "role": "menu item", + "label": "Create a new project file" + }, + { + "do": "settext", + "name": "File name", + "role": "text", + "value": "{project:relative-paths}/rel.cppcheck", + "label": "Enter the project file name" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the project file name" + }, + { + "expect": "visible", + "name": "Project file: rel.cppcheck", + "role": "dialog", + "label": "Project file dialog is open" + }, + { + "do": "click", + "name": "Add...", + "role": "button", + "nth": 1, + "label": "Add an include directory" + }, + { + "do": "settext", + "name": "Directory:", + "role": "text", + "value": "{project:relative-paths}/inc", + "label": "Enter the include directory {project:relative-paths}/inc" + }, + { + "do": "click", + "name": "Choose", + "role": "button", + "label": "Choose the include directory" + }, + { + "do": "click", + "name": "Warning options", + "role": "page tab", + "label": "Open the tab with the excluded files" + }, + { + "do": "click", + "name": "Exclude file", + "role": "button", + "label": "Exclude a file" + }, + { + "do": "settext", + "name": "File name", + "role": "text", + "value": "{project:relative-paths}/skip/b.c", + "label": "Enter the excluded file {project:relative-paths}/skip/b.c" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the excluded file" + }, + { + "expect": "visible", + "name": "skip/b.c", + "role": "list item", + "label": "skip/b.c is in the exclude list" + }, + { + "do": "click", + "name": "Paths and Defines", + "role": "page tab", + "label": "Back to Paths and Defines" + }, + { + "do": "click", + "name": "Browse...", + "role": "button", + "nth": 0, + "label": "Browse for the import project" + }, + { + "do": "settext", + "name": "File name", + "role": "text", + "value": "{project:relative-paths}/compile_commands.json", + "label": "Enter the import project {project:relative-paths}/compile_commands.json" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the import project" + }, + { + "do": "click", + "name": "OK", + "role": "button", + "label": "Save the project file as rel.cppcheck" + }, + { + "do": "sleep", + "seconds": 1 + }, + { + "do": "key", + "keys": [ + "Escape" + ], + "label": "Dismiss the build dir question" + }, + { + "expect": "file", + "path": "{project:relative-paths}/rel.cppcheck", + "contains": "compile_commands.json", + "label": "Import project is relative" + }, + { + "expect": "file", + "path": "{project:relative-paths}/rel.cppcheck", + "contains": "", + "label": "Excluded file is relative (skip/b.c)" + }, + { + "expect": "file", + "path": "{project:relative-paths}/rel.cppcheck", + "not_contains": "{project:relative-paths}", + "label": "No absolute path to the project folder in the XML" + } + ], + "script_for": "edfc96b05beb" + }, + "t5afff002": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "New Project File", + "role": "menu item", + "label": "Create a new project file" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{work}/t.cppcheck", + "label": "Enter the project file name" + }, + { + "do": "click", + "name": "Save", + "role": "button", + "exact": true, + "label": "Save the new project file; the project file dialog opens" + }, + { + "expect": "visible", + "name": "Project file", + "role": "dialog", + "label": "Project file dialog is open" + }, + { + "do": "click", + "name": "Types and Functions", + "role": "page tab", + "label": "Go to the tab with the Platform setting" + }, + { + "do": "click", + "name": "Platform", + "role": "combo box", + "label": "Open the Platform drop-down list" + }, + { + "expect": "visible", + "name": "pic8.xml", + "role": "list item", + "label": "pic8.xml is in the Platform list" + }, + { + "do": "click", + "name": "pic8.xml", + "role": "list item", + "exact": true, + "mouse": true, + "label": "Select pic8.xml in the list" + }, + { + "expect": "visible", + "name": "pic8.xml", + "role": "combo box", + "label": "The dialog shows pic8.xml as the platform" + } + ], + "script_for": "619f376b22e1" + }, + "t91490557": { + "script": [ + { + "do": "click", + "name": "Open Project File", + "role": "button", + "label": "Open the project file dialog from the toolbar" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:custom-cfg}/p.cppcheck", + "label": "Enter the path of p.cppcheck" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Open the project file" + }, + { + "expect": "visible", + "name": "Cppcheck", + "role": "alert", + "label": "Analysis finishes and an alert appears" + }, + { + "do": "click", + "name": "OK", + "role": "button", + "label": "Dismiss the alert" + }, + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Edit Project File", + "role": "menu item", + "label": "Open the project file dialog (edit the project file)" + }, + { + "expect": "visible", + "name": "Project file: p.cppcheck", + "role": "dialog", + "label": "The project file dialog is open" + }, + { + "expect": "visible", + "name": "aa", + "role": "list item", + "exact": true, + "label": "aa is in the Libraries list" + }, + { + "expect": "visible", + "name": "avr", + "role": "list item", + "exact": true, + "label": "avr is in the Libraries list" + } + ], + "script_for": "b0bf245f7042" + }, + "t0ec0680b": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "do": "wait", + "name": "Select Project File", + "role": "dialog", + "label": "File dialog is shown" + }, + { + "do": "settext", + "name": "File name", + "role": "text", + "value": "{project:embedded}/embedded.cppcheck", + "label": "Enter the project file path" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Open the project file" + }, + { + "do": "wait", + "name": "Project: embedded.cppcheck", + "role": "frame", + "label": "Project is loaded" + }, + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu again" + }, + { + "do": "click", + "name": "Edit Project File...", + "role": "menu item", + "label": "Open the project file dialog" + }, + { + "do": "wait", + "name": "Project file: embedded.cppcheck", + "role": "dialog", + "label": "Project file dialog is shown" + }, + { + "do": "click", + "name": "Addons", + "role": "page tab", + "label": "Go to the Addons tab" + }, + { + "expect": "state", + "name": "Misra C 2012", + "role": "check box", + "state": "checked", + "label": "The Misra C 2012 checkbox is checked" + } + ], + "script_for": "187bd0d82a72" + } +} diff --git a/gui/manualtest/tests/projects.feature b/gui/manualtest/tests/projects.feature new file mode 100644 index 00000000000..a4c2324551e --- /dev/null +++ b/gui/manualtest/tests/projects.feature @@ -0,0 +1,72 @@ +Feature: Open and create projects + + Background: + Given the application is started with no project loaded + + @id:tf9fc8bf6 @project:basic-project + Scenario: Open a project file + When I open the project file {project:basic-project}/basic.cppcheck with the open project file entry in the File menu + Then the project opens + And the title of the main window names basic.cppcheck + And the analysis results are shown: nullPointer errors in a.c and util.h, arrayIndexOutOfBounds in b.c + + @id:t6bb11424 @project:switch-project + Scenario: Open a second project + TODO: with and without build dir + Given the project file {project:switch-project}/one/p1.cppcheck is opened + And the analysis is done + And the results show a nullPointer error in a.c + When I open the project file {project:switch-project}/two/p2.cppcheck + And I wait until the analysis is done + Then the results of the first project (nullPointer in a.c) are gone + And the results of the second project (arrayIndexOutOfBounds in b.c) are shown + + @id:t176fd17f @project:switch-project + Scenario: Open a recent project + Given the project file {project:switch-project}/one/p1.cppcheck is opened and analysed + And the project file {project:switch-project}/two/p2.cppcheck is opened and analysed + When I open the File menu + And I click p1.cppcheck in the list of recent projects + Then the project p1.cppcheck is opened + And the title of the main window names p1.cppcheck, not p2.cppcheck or another file + + @id:t1e899c1c @project:basic-project + Scenario: New project file + When I open File > New Project File + And I enter the file name {project:basic-project}/OSgui.cppcheck + And I add the folder {project:basic-project}/src as a path to check in the project file dialog + And I save the project file without selecting an addon + And I wait until the analysis is done + Then the project file OSgui.cppcheck is saved without any addon in it + And the analysis is run + And the results are shown: nullPointer errors in a.c, arrayIndexOutOfBounds in b.c + And util.h is not checked, the new project has no include path to it + + @id:t202b9515 @project:basic-project + Scenario Outline: New project file with an addon + When I open File > New Project File + And I enter the file name {project:basic-project}/OSgui.cppcheck + And I add the folder {project:basic-project}/src as a path to check in the project file dialog + And I tick the checkbox of the addon whose name contains "" on the Addons tab (Misra C, Y2038 or Thread safety) + And I save the project file + And I wait until the analysis is done + Then the project file OSgui.cppcheck is saved with an addon entry that contains "" (misra, y2038 or threadsafety) + And the analysis is run and results are shown + And none of the results is an internalError about the addon + + Examples: + | addon | + | misra | + | y2038 | + | thread | + + @id:tf6da2cfd @project:basic-project @edition:opensource + Scenario: Add the Misra addon to a project + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I open File > Edit Project File + And I select MISRA C 2012 on the Addons tab + And I save the project file + And I wait until the analysis is done + Then basic.cppcheck has the addon misra in it + And the analysis is run again diff --git a/gui/manualtest/tests/projects.scripts.json b/gui/manualtest/tests/projects.scripts.json new file mode 100644 index 00000000000..a78d2f6b793 --- /dev/null +++ b/gui/manualtest/tests/projects.scripts.json @@ -0,0 +1,771 @@ +{ + "tf9fc8bf6": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Choose Open Project File in the File menu" + }, + { + "expect": "visible", + "name": "Select Project File", + "role": "dialog", + "label": "The project file dialog is shown" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the path of basic.cppcheck" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the dialog to open the project" + }, + { + "expect": "visible", + "name": "Project: basic.cppcheck", + "role": "frame", + "timeout": 15, + "label": "The title of the main window names basic.cppcheck" + }, + { + "do": "wait", + "name": "Select Project File", + "gone": true, + "label": "The dialog is closed" + }, + { + "do": "sleep", + "seconds": 4, + "label": "Wait for the analysis to finish" + }, + { + "do": "focus", + "role": "tree", + "label": "Focus the results tree" + }, + { + "do": "key", + "keys": [ + "Home", + "Down", + "Down", + "Right", + "Up", + "Right", + "Up", + "Right", + "Home" + ], + "label": "Expand the results of all three files and go to the top" + }, + { + "expect": "visible", + "name": "nullPointer", + "role": "table cell", + "timeout": 10, + "label": "nullPointer errors are shown for util.h and a.c" + }, + { + "expect": "text", + "contains": "src/a.c", + "label": "Results for a.c are shown" + }, + { + "expect": "text", + "contains": "include/util.h", + "label": "Results for util.h are shown" + }, + { + "do": "key", + "keys": [ + "End" + ], + "label": "Scroll to the results of b.c" + }, + { + "expect": "visible", + "name": "arrayIndexOutOfBounds", + "role": "table cell", + "timeout": 10, + "label": "arrayIndexOutOfBounds error is shown for b.c" + } + ], + "script_for": "7128457516b3" + }, + "t6bb11424": { + "script": [ + { + "do": "click", + "name": "Open Project File", + "role": "button", + "label": "Open the first project" + }, + { + "do": "type", + "value": "{project:switch-project}/one/p1.cppcheck", + "label": "Enter path of p1.cppcheck" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the file dialog" + }, + { + "expect": "visible", + "name": "Project: p1.cppcheck", + "role": "frame", + "timeout": 10, + "label": "First project is loaded" + }, + { + "expect": "visible", + "name": "a.c", + "role": "table cell", + "timeout": 20, + "label": "Results of the first project show a.c" + }, + { + "do": "click", + "name": "Open Project File", + "role": "button", + "label": "Open the second project" + }, + { + "do": "type", + "value": "{project:switch-project}/two/p2.cppcheck", + "label": "Enter path of p2.cppcheck" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the file dialog" + }, + { + "expect": "visible", + "name": "Project: p2.cppcheck", + "role": "frame", + "timeout": 10, + "label": "Second project is loaded" + }, + { + "expect": "visible", + "name": "b.c", + "role": "table cell", + "timeout": 20, + "label": "Results of the second project show b.c" + }, + { + "expect": "gone", + "name": "a.c", + "role": "table cell", + "label": "Results of the first project are gone" + } + ], + "script_for": "70097c80a6ed" + }, + "t176fd17f": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:switch-project}/one/p1.cppcheck", + "label": "Enter the path of p1.cppcheck" + }, + { + "do": "click", + "name": "Open", + "role": "button", + "exact": true, + "label": "Open p1.cppcheck" + }, + { + "expect": "text", + "contains": "Project: p1.cppcheck", + "timeout": 10, + "label": "Project p1 is open" + }, + { + "expect": "visible", + "name": "Checking a.c", + "timeout": 15, + "label": "Analysis of p1 is done" + }, + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:switch-project}/two/p2.cppcheck", + "label": "Enter the path of p2.cppcheck" + }, + { + "do": "click", + "name": "Open", + "role": "button", + "exact": true, + "label": "Open p2.cppcheck" + }, + { + "expect": "text", + "contains": "Project: p2.cppcheck", + "timeout": 10, + "label": "Project p2 is open" + }, + { + "do": "sleep", + "seconds": 3, + "label": "Wait until the analysis of p2 is done" + }, + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "p1.cppcheck", + "role": "menu item", + "label": "Click p1.cppcheck in the recent projects list" + }, + { + "expect": "text", + "contains": "Project: p1.cppcheck", + "timeout": 10, + "label": "Main window title names p1.cppcheck" + }, + { + "expect": "text", + "not_contains": "Project: p2.cppcheck", + "label": "Title does not name p2.cppcheck" + } + ], + "script_for": "2ea42621479d" + }, + "t1e899c1c": { + "script": [ + { + "label": "Open File menu", + "do": "click", + "name": "File", + "role": "menu item" + }, + { + "label": "Open File > New Project File", + "do": "click", + "name": "New Project File", + "role": "menu item" + }, + { + "label": "Wait for the file name dialog", + "do": "wait", + "name": "Select Project Filename", + "role": "dialog" + }, + { + "label": "Enter the file name OSgui.cppcheck", + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/OSgui.cppcheck" + }, + { + "label": "Confirm the file name", + "do": "key", + "keys": [ + "Return" + ] + }, + { + "label": "Project file dialog is shown", + "expect": "visible", + "name": "Project file: OSgui.cppcheck", + "role": "dialog" + }, + { + "label": "Add a path to check", + "do": "click", + "name": "Add...", + "role": "button", + "nth": 0 + }, + { + "label": "Wait for the directory dialog", + "do": "wait", + "name": "Select a directory to check", + "role": "dialog" + }, + { + "label": "Enter the src folder", + "do": "settext", + "name": "Directory:", + "role": "text", + "value": "{project:basic-project}/src" + }, + { + "label": "Choose the src folder", + "do": "click", + "name": "Choose", + "role": "button" + }, + { + "label": "src is in the paths list", + "expect": "visible", + "name": "src", + "role": "list item" + }, + { + "label": "Save the project file without selecting an addon", + "do": "click", + "name": "OK", + "role": "button" + }, + { + "label": "Create the build dir when asked", + "do": "click", + "name": "Yes", + "role": "button" + }, + { + "label": "Wait until the analysis has checked b.c", + "expect": "text", + "contains": "Checking src/b.c", + "timeout": 30 + }, + { + "label": "Wait for the results of a.c", + "expect": "visible", + "name": "src/a.c", + "role": "table cell", + "timeout": 30 + }, + { + "label": "Select a.c results", + "do": "click", + "name": "src/a.c", + "role": "table cell", + "nth": 0, + "mouse": true + }, + { + "label": "Collapse a.c results to get a known state", + "do": "key", + "keys": [ + "Left" + ] + }, + { + "label": "Expand a.c results", + "do": "key", + "keys": [ + "Right" + ] + }, + { + "label": "nullPointer is reported in a.c", + "expect": "visible", + "name": "nullPointer", + "role": "table cell", + "timeout": 10 + }, + { + "label": "Select b.c results", + "do": "click", + "name": "src/b.c", + "role": "table cell", + "nth": 0, + "mouse": true + }, + { + "label": "Collapse b.c results to get a known state", + "do": "key", + "keys": [ + "Left" + ] + }, + { + "label": "Expand b.c results", + "do": "key", + "keys": [ + "Right" + ] + }, + { + "label": "arrayIndexOutOfBounds is reported in b.c", + "expect": "visible", + "name": "arrayIndexOutOfBounds", + "role": "table cell", + "timeout": 10 + }, + { + "label": "util.h is not checked", + "expect": "text", + "not_contains": "Checking include/util.h" + }, + { + "label": "Project file contains the src path", + "expect": "file", + "path": "{project:basic-project}/OSgui.cppcheck", + "contains": "" + }, + { + "label": "Project file has no addon", + "expect": "file", + "path": "{project:basic-project}/OSgui.cppcheck", + "not_contains": "addon" + }, + { + "label": "Project file has no include path", + "expect": "file", + "path": "{project:basic-project}/OSgui.cppcheck", + "not_contains": "include" + } + ], + "script_for": "b3616d866fea" + }, + "t202b9515": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "New Project File...", + "role": "menu item", + "label": "Open File > New Project File" + }, + { + "do": "wait", + "name": "Select Project Filename", + "role": "dialog", + "label": "Wait for the file name dialog" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/OSgui.cppcheck", + "label": "Enter the file name OSgui.cppcheck" + }, + { + "do": "focus", + "name": "File name:", + "role": "text", + "label": "Focus the file name field" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the file name" + }, + { + "do": "wait", + "name": "Project file: OSgui.cppcheck", + "role": "dialog", + "timeout": 10, + "label": "Wait for the project file dialog" + }, + { + "do": "click", + "name": "Paths and Defines", + "role": "page tab", + "label": "Go to the Paths and Defines tab" + }, + { + "do": "click", + "name": "Add...", + "role": "button", + "nth": 0, + "label": "Add a path to check" + }, + { + "do": "wait", + "name": "Select a directory to check", + "role": "dialog", + "label": "Wait for the directory dialog" + }, + { + "do": "settext", + "name": "Directory:", + "role": "text", + "value": "{project:basic-project}/src", + "label": "Enter the folder src" + }, + { + "do": "click", + "name": "Choose", + "role": "button", + "label": "Choose the folder src" + }, + { + "do": "wait", + "name": "Select a directory to check", + "role": "dialog", + "gone": true, + "label": "Directory dialog closes" + }, + { + "expect": "visible", + "name": "src", + "role": "list item", + "exact": true, + "label": "src is in the paths to check" + }, + { + "do": "click", + "name": "Addons", + "role": "page tab", + "label": "Go to the Addons tab" + }, + { + "do": "click", + "name": "{addon}", + "role": "check box", + "nth": 0, + "label": "Tick the addon checkbox" + }, + { + "expect": "state", + "name": "{addon}", + "role": "check box", + "nth": 0, + "state": "checked", + "label": "The addon checkbox is ticked" + }, + { + "do": "click", + "name": "OK", + "role": "button", + "label": "Save the project file" + }, + { + "do": "wait", + "name": "Yes", + "role": "button", + "timeout": 10, + "label": "Question to create the build dir" + }, + { + "do": "click", + "name": "Yes", + "role": "button", + "label": "Create the build dir" + }, + { + "do": "wait", + "name": "src/b.c", + "role": "table cell", + "timeout": 120, + "label": "Wait for the analysis results" + }, + { + "do": "sleep", + "seconds": 3 + }, + { + "expect": "state", + "name": "Stop analysis", + "role": "button", + "not_state": "enabled", + "timeout": 120, + "label": "The analysis is done" + }, + { + "do": "focus", + "name": "src/a.c", + "role": "table cell", + "label": "Select the results of a.c" + }, + { + "do": "key", + "keys": [ + "asterisk", + "End", + "asterisk" + ], + "label": "Expand the results of all files" + }, + { + "do": "sleep", + "seconds": 1 + }, + { + "expect": "file", + "path": "{project:basic-project}/OSgui.cppcheck", + "contains": "{addon}", + "label": "Project file has the addon entry" + }, + { + "expect": "file", + "path": "{project:basic-project}/OSgui.cppcheck", + "contains": "", + "label": "Project file has the path src" + }, + { + "expect": "visible", + "name": "src/a.c", + "role": "table cell", + "label": "Analysis results are shown" + }, + { + "expect": "text", + "not_contains": "internalError", + "label": "No internalError about the addon in the results" + } + ], + "script_for": "60cd34c48191" + }, + "tf6da2cfd": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the project file path" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the file dialog" + }, + { + "do": "wait", + "name": "Checking src/b.c", + "timeout": 20, + "label": "Wait for the first analysis to run" + }, + { + "do": "sleep", + "seconds": 3, + "label": "Let the first analysis finish" + }, + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Edit Project File", + "role": "menu item", + "label": "Choose Edit Project File" + }, + { + "expect": "visible", + "name": "Project file: basic.cppcheck", + "role": "dialog", + "label": "Project file dialog is open" + }, + { + "do": "click", + "name": "Addons", + "role": "page tab", + "label": "Go to the Addons tab" + }, + { + "do": "click", + "name": "Misra C 2012", + "role": "check box", + "label": "Select MISRA C 2012" + }, + { + "expect": "state", + "name": "Misra C 2012", + "state": "checked", + "label": "MISRA C 2012 is checked" + }, + { + "do": "click", + "name": "OK", + "role": "button", + "label": "Save the project file" + }, + { + "expect": "gone", + "name": "Project file: basic.cppcheck", + "label": "Project file dialog is closed" + }, + { + "do": "sleep", + "seconds": 4, + "label": "Wait for the second analysis to finish" + }, + { + "expect": "file", + "path": "{project:basic-project}/basic.cppcheck", + "contains": "misra", + "label": "Project file has the misra addon" + }, + { + "expect": "visible", + "name": "Checking src/b.c", + "role": "list item", + "nth": 1, + "label": "The analysis was run again" + } + ], + "script_for": "452f351f0fb2" + } +} diff --git a/gui/manualtest/tests/projects/basic-project/basic.cppcheck b/gui/manualtest/tests/projects/basic-project/basic.cppcheck new file mode 100644 index 00000000000..c8805a32587 --- /dev/null +++ b/gui/manualtest/tests/projects/basic-project/basic.cppcheck @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/gui/manualtest/tests/projects/basic-project/include/util.h b/gui/manualtest/tests/projects/basic-project/include/util.h new file mode 100644 index 00000000000..48ae2d54a95 --- /dev/null +++ b/gui/manualtest/tests/projects/basic-project/include/util.h @@ -0,0 +1,5 @@ +static inline int helper(void) +{ + int *r = 0; + return *r; +} diff --git a/gui/manualtest/tests/projects/basic-project/src/a.c b/gui/manualtest/tests/projects/basic-project/src/a.c new file mode 100644 index 00000000000..3a84d86a5ff --- /dev/null +++ b/gui/manualtest/tests/projects/basic-project/src/a.c @@ -0,0 +1,18 @@ +#include "util.h" + +int first(void) +{ + int *p = 0; + return *p; +} + +int second(void) +{ + int *q = 0; + return *q; +} + +int main(void) +{ + return first() + second() + helper(); +} diff --git a/gui/manualtest/tests/projects/basic-project/src/b.c b/gui/manualtest/tests/projects/basic-project/src/b.c new file mode 100644 index 00000000000..20be2edc145 --- /dev/null +++ b/gui/manualtest/tests/projects/basic-project/src/b.c @@ -0,0 +1,5 @@ +void f(void) +{ + char a[4]; + a[10] = 0; +} diff --git a/gui/manualtest/tests/projects/custom-cfg/a.c b/gui/manualtest/tests/projects/custom-cfg/a.c new file mode 100644 index 00000000000..58fe69254d0 --- /dev/null +++ b/gui/manualtest/tests/projects/custom-cfg/a.c @@ -0,0 +1,4 @@ +int main(void) +{ + return 0; +} diff --git a/gui/manualtest/tests/projects/custom-cfg/aa.cfg b/gui/manualtest/tests/projects/custom-cfg/aa.cfg new file mode 100644 index 00000000000..bb21afac352 --- /dev/null +++ b/gui/manualtest/tests/projects/custom-cfg/aa.cfg @@ -0,0 +1,402 @@ + + + + + + + + + + + + + + + + + + + + + + + false + + + 0:255 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + false + + + + + + + + + + + + + + + false + + + + + + + + + + + + false + + + + + + 0: + + + + false + + + + + + + + + + + + + + false + + + + + + + + + + + + + + false + + + + + + + + false + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + false + + + + + + + + + + + + + + + false + + + + false + + + + + + + false + + + + + + + false + + + + + + + + + + false + + + + + + + + + + + + + + + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + false + + + + + + + + + + + + + + + diff --git a/gui/manualtest/tests/projects/custom-cfg/p.cppcheck b/gui/manualtest/tests/projects/custom-cfg/p.cppcheck new file mode 100644 index 00000000000..e8db10582ad --- /dev/null +++ b/gui/manualtest/tests/projects/custom-cfg/p.cppcheck @@ -0,0 +1,6 @@ + + + + + + diff --git a/gui/manualtest/tests/projects/embedded/board.h b/gui/manualtest/tests/projects/embedded/board.h new file mode 100644 index 00000000000..8a5bddc04a0 --- /dev/null +++ b/gui/manualtest/tests/projects/embedded/board.h @@ -0,0 +1,10 @@ +#ifndef BOARD_H +#define BOARD_H + +#define GPIOA_ODR (*(volatile unsigned int *)0x40020014U) +#define UART_DR (*(volatile unsigned int *)0x40011004U) + +void gpio_set(unsigned int pin, unsigned int mask); +void uart_putc(char c); + +#endif diff --git a/gui/manualtest/tests/projects/embedded/embedded.cppcheck b/gui/manualtest/tests/projects/embedded/embedded.cppcheck new file mode 100644 index 00000000000..679b87f6d90 --- /dev/null +++ b/gui/manualtest/tests/projects/embedded/embedded.cppcheck @@ -0,0 +1,9 @@ + + + + + + + misra + + diff --git a/gui/manualtest/tests/projects/embedded/gpio.c b/gui/manualtest/tests/projects/embedded/gpio.c new file mode 100644 index 00000000000..73968d86135 --- /dev/null +++ b/gui/manualtest/tests/projects/embedded/gpio.c @@ -0,0 +1,6 @@ +#include "board.h" + +void gpio_set(unsigned int pin, unsigned int mask) +{ + GPIOA_ODR |= mask; +} diff --git a/gui/manualtest/tests/projects/embedded/main.c b/gui/manualtest/tests/projects/embedded/main.c new file mode 100644 index 00000000000..6daafe949b4 --- /dev/null +++ b/gui/manualtest/tests/projects/embedded/main.c @@ -0,0 +1,10 @@ +#include "board.h" + +int main(void) +{ + gpio_set(5U, 0x20U); + uart_putc('A'); + for (;;) + { + } +} diff --git a/gui/manualtest/tests/projects/embedded/rules with spaces.txt b/gui/manualtest/tests/projects/embedded/rules with spaces.txt new file mode 100644 index 00000000000..a707cb8673d --- /dev/null +++ b/gui/manualtest/tests/projects/embedded/rules with spaces.txt @@ -0,0 +1,7 @@ +Appendix A Summary of guidelines + +Rule 2.7 +TEST RULE TEXT: unused parameters are not allowed +Category Advisory +Analysis Decidable, Single Translation Unit +Applies to C90, C99 diff --git a/gui/manualtest/tests/projects/embedded/rules.txt b/gui/manualtest/tests/projects/embedded/rules.txt new file mode 100644 index 00000000000..a707cb8673d --- /dev/null +++ b/gui/manualtest/tests/projects/embedded/rules.txt @@ -0,0 +1,7 @@ +Appendix A Summary of guidelines + +Rule 2.7 +TEST RULE TEXT: unused parameters are not allowed +Category Advisory +Analysis Decidable, Single Translation Unit +Applies to C90, C99 diff --git a/gui/manualtest/tests/projects/embedded/uart.c b/gui/manualtest/tests/projects/embedded/uart.c new file mode 100644 index 00000000000..3720b2fde22 --- /dev/null +++ b/gui/manualtest/tests/projects/embedded/uart.c @@ -0,0 +1,6 @@ +#include "board.h" + +void uart_putc(char c) +{ + UART_DR = (unsigned int)c; +} diff --git a/gui/manualtest/tests/projects/recheck/a.c b/gui/manualtest/tests/projects/recheck/a.c new file mode 100644 index 00000000000..a4f00f729cb --- /dev/null +++ b/gui/manualtest/tests/projects/recheck/a.c @@ -0,0 +1,5 @@ +int main(void) +{ + int *p = 0; + return *p; +} diff --git a/gui/manualtest/tests/projects/recheck/a_v2.c b/gui/manualtest/tests/projects/recheck/a_v2.c new file mode 100644 index 00000000000..229abfebb92 --- /dev/null +++ b/gui/manualtest/tests/projects/recheck/a_v2.c @@ -0,0 +1,5 @@ +int main(void) +{ + int x; + return x; +} diff --git a/gui/manualtest/tests/projects/recheck/b.c b/gui/manualtest/tests/projects/recheck/b.c new file mode 100644 index 00000000000..20be2edc145 --- /dev/null +++ b/gui/manualtest/tests/projects/recheck/b.c @@ -0,0 +1,5 @@ +void f(void) +{ + char a[4]; + a[10] = 0; +} diff --git a/gui/manualtest/tests/projects/recheck/p.cppcheck b/gui/manualtest/tests/projects/recheck/p.cppcheck new file mode 100644 index 00000000000..760eb8837f8 --- /dev/null +++ b/gui/manualtest/tests/projects/recheck/p.cppcheck @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gui/manualtest/tests/projects/relative-paths/compile_commands.json b/gui/manualtest/tests/projects/relative-paths/compile_commands.json new file mode 100644 index 00000000000..130de6bca98 --- /dev/null +++ b/gui/manualtest/tests/projects/relative-paths/compile_commands.json @@ -0,0 +1,4 @@ +[ + {"directory": ".", "command": "gcc -c src/a.c", "file": "src/a.c"}, + {"directory": ".", "command": "gcc -c skip/b.c", "file": "skip/b.c"} +] diff --git a/gui/manualtest/tests/projects/relative-paths/inc/util.h b/gui/manualtest/tests/projects/relative-paths/inc/util.h new file mode 100644 index 00000000000..874a45c458c --- /dev/null +++ b/gui/manualtest/tests/projects/relative-paths/inc/util.h @@ -0,0 +1 @@ +int helper(int x); diff --git a/gui/manualtest/tests/projects/relative-paths/skip/b.c b/gui/manualtest/tests/projects/relative-paths/skip/b.c new file mode 100644 index 00000000000..5bb061143c0 --- /dev/null +++ b/gui/manualtest/tests/projects/relative-paths/skip/b.c @@ -0,0 +1,4 @@ +int unused(void) +{ + return 0; +} diff --git a/gui/manualtest/tests/projects/relative-paths/src/a.c b/gui/manualtest/tests/projects/relative-paths/src/a.c new file mode 100644 index 00000000000..db8654dea9f --- /dev/null +++ b/gui/manualtest/tests/projects/relative-paths/src/a.c @@ -0,0 +1,6 @@ +#include "util.h" + +int main(void) +{ + return helper(1); +} diff --git a/gui/manualtest/tests/projects/switch-project/one/a.c b/gui/manualtest/tests/projects/switch-project/one/a.c new file mode 100644 index 00000000000..a4f00f729cb --- /dev/null +++ b/gui/manualtest/tests/projects/switch-project/one/a.c @@ -0,0 +1,5 @@ +int main(void) +{ + int *p = 0; + return *p; +} diff --git a/gui/manualtest/tests/projects/switch-project/one/p1.cppcheck b/gui/manualtest/tests/projects/switch-project/one/p1.cppcheck new file mode 100644 index 00000000000..5eb66587401 --- /dev/null +++ b/gui/manualtest/tests/projects/switch-project/one/p1.cppcheck @@ -0,0 +1,6 @@ + + + + + + diff --git a/gui/manualtest/tests/projects/switch-project/two/b.c b/gui/manualtest/tests/projects/switch-project/two/b.c new file mode 100644 index 00000000000..20be2edc145 --- /dev/null +++ b/gui/manualtest/tests/projects/switch-project/two/b.c @@ -0,0 +1,5 @@ +void f(void) +{ + char a[4]; + a[10] = 0; +} diff --git a/gui/manualtest/tests/projects/switch-project/two/p2.cppcheck b/gui/manualtest/tests/projects/switch-project/two/p2.cppcheck new file mode 100644 index 00000000000..a79d287d385 --- /dev/null +++ b/gui/manualtest/tests/projects/switch-project/two/p2.cppcheck @@ -0,0 +1,6 @@ + + + + + + diff --git a/gui/manualtest/tests/projects/syntax-error/binary.c b/gui/manualtest/tests/projects/syntax-error/binary.c new file mode 100644 index 00000000000..c91312c3af0 Binary files /dev/null and b/gui/manualtest/tests/projects/syntax-error/binary.c differ diff --git a/gui/manualtest/tests/projects/syntax-error/binary.cppcheck b/gui/manualtest/tests/projects/syntax-error/binary.cppcheck new file mode 100644 index 00000000000..7804897af2d --- /dev/null +++ b/gui/manualtest/tests/projects/syntax-error/binary.cppcheck @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gui/manualtest/tests/projects/syntax-error/braces.c b/gui/manualtest/tests/projects/syntax-error/braces.c new file mode 100644 index 00000000000..66d81f572c3 --- /dev/null +++ b/gui/manualtest/tests/projects/syntax-error/braces.c @@ -0,0 +1,3 @@ +int main( { + return 0 +} diff --git a/gui/manualtest/tests/projects/syntax-error/braces.cppcheck b/gui/manualtest/tests/projects/syntax-error/braces.cppcheck new file mode 100644 index 00000000000..94d206fd67c --- /dev/null +++ b/gui/manualtest/tests/projects/syntax-error/braces.cppcheck @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gui/manualtest/tests/projects/syntax-error/empty.c b/gui/manualtest/tests/projects/syntax-error/empty.c new file mode 100644 index 00000000000..e69de29bb2d diff --git a/gui/manualtest/tests/projects/syntax-error/empty.cppcheck b/gui/manualtest/tests/projects/syntax-error/empty.cppcheck new file mode 100644 index 00000000000..eb36efbe086 --- /dev/null +++ b/gui/manualtest/tests/projects/syntax-error/empty.cppcheck @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gui/manualtest/tests/projects/syntax-error/latin1.c b/gui/manualtest/tests/projects/syntax-error/latin1.c new file mode 100644 index 00000000000..7e730fd3a83 --- /dev/null +++ b/gui/manualtest/tests/projects/syntax-error/latin1.c @@ -0,0 +1,6 @@ +/* färg och smör */ +int färg(void) +{ + const char *s = "grön"; + return s[0]; +} diff --git a/gui/manualtest/tests/projects/syntax-error/latin1.cppcheck b/gui/manualtest/tests/projects/syntax-error/latin1.cppcheck new file mode 100644 index 00000000000..06ccf58dfd5 --- /dev/null +++ b/gui/manualtest/tests/projects/syntax-error/latin1.cppcheck @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gui/manualtest/tests/projects/syntax-error/long_line.c b/gui/manualtest/tests/projects/syntax-error/long_line.c new file mode 100644 index 00000000000..14807c9e52b --- /dev/null +++ b/gui/manualtest/tests/projects/syntax-error/long_line.c @@ -0,0 +1 @@ +int x = a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + a + diff --git a/gui/manualtest/tests/projects/syntax-error/long_line.cppcheck b/gui/manualtest/tests/projects/syntax-error/long_line.cppcheck new file mode 100644 index 00000000000..f13ad9aa112 --- /dev/null +++ b/gui/manualtest/tests/projects/syntax-error/long_line.cppcheck @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gui/manualtest/tests/projects/syntax-error/ok.c b/gui/manualtest/tests/projects/syntax-error/ok.c new file mode 100644 index 00000000000..8e1e58ce827 --- /dev/null +++ b/gui/manualtest/tests/projects/syntax-error/ok.c @@ -0,0 +1,5 @@ +int ok(void) +{ + int *p = 0; + return *p; +} diff --git a/gui/manualtest/tests/projects/syntax-error/unclosed_nesting.c b/gui/manualtest/tests/projects/syntax-error/unclosed_nesting.c new file mode 100644 index 00000000000..7d6ac74625a --- /dev/null +++ b/gui/manualtest/tests/projects/syntax-error/unclosed_nesting.c @@ -0,0 +1,4 @@ +int f(int a) +{ + return ((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((a; +} diff --git a/gui/manualtest/tests/projects/syntax-error/unclosed_nesting.cppcheck b/gui/manualtest/tests/projects/syntax-error/unclosed_nesting.cppcheck new file mode 100644 index 00000000000..baeddf3ef2f --- /dev/null +++ b/gui/manualtest/tests/projects/syntax-error/unclosed_nesting.cppcheck @@ -0,0 +1,7 @@ + + + + + + + diff --git a/gui/manualtest/tests/projects/xml-results/a.c b/gui/manualtest/tests/projects/xml-results/a.c new file mode 100644 index 00000000000..38775adee5f --- /dev/null +++ b/gui/manualtest/tests/projects/xml-results/a.c @@ -0,0 +1,5 @@ +int first(void) +{ + int *p = 0; + return *p; +} diff --git a/gui/manualtest/tests/projects/xml-results/results.xml b/gui/manualtest/tests/projects/xml-results/results.xml new file mode 100644 index 00000000000..c6f4b14c0c1 --- /dev/null +++ b/gui/manualtest/tests/projects/xml-results/results.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/gui/manualtest/tests/result_list.feature b/gui/manualtest/tests/result_list.feature new file mode 100644 index 00000000000..f370d296fb0 --- /dev/null +++ b/gui/manualtest/tests/result_list.feature @@ -0,0 +1,91 @@ +Feature: Results list + + Background: + Given the application is started with no project loaded + + @id:t852206f1 + Scenario: Severity buttons toggle + When I click each of the toolbar buttons Error, Warning, Style, Portability, Performance, Information, Cppcheck and Clang once + Then every button can be clicked and changes between checked and unchecked + When I click each of them once more + Then all buttons are in the state they had at the start + + @id:td7decf1a @project:basic-project + Scenario: Filter the results + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I type "arrayIndex" in the Filter field + Then only the arrayIndexOutOfBounds error in b.c is shown + When I clear the Filter field + Then all errors are shown again + + @id:t2af9d498 @project:basic-project + Scenario: Expand all + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I open View > Collapse All + And I open View > Expand All + Then all files are expanded and show their errors + And the errors in a.c, util.h and b.c are visible + + @id:tec898362 @project:basic-project + Scenario: Collapse all + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I open View > Expand All + And I open View > Collapse All + Then all files are collapsed + And the file entries are shown and their errors are not + + @id:t4c027507 @project:basic-project + Scenario: Context menu of a file entry + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I right click on the file a.c in the results (not on one of its errors) + Then the context menu of the file entry has the entries Recheck and Open containing folder + But it has none of the entries Hide, Hide all with ID or Suppress selected id, they only apply to a single error + + @id:taacc3841 @project:basic-project + Scenario: Hide one error + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I expand a.c in the results + And I right click on the first nullPointer error (line 6) and click Hide + Then that error is gone + And the other errors are still shown, including the second nullPointer error in a.c (line 12) + + @id:t2937b690 @project:basic-project + Scenario: Hide all errors with the same ID + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I expand a.c in the results + And I right click on a nullPointer error and click Hide all with ID + Then all nullPointer errors are gone, in a.c and in util.h + And the arrayIndexOutOfBounds error in b.c is still shown + + @id:t313463d3 @project:basic-project + Scenario: Show hidden errors again + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I expand a.c in the results + And I right click on the first nullPointer error and click Hide all with id + Then the a.c results are hidden + When I open View > Show Hidden + Then the error that was hidden is shown again + + @id:t90bf32e9 @project:basic-project + Scenario: Suppress selected ID + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I expand a.c in the results + And I right click on a nullPointer error and click Suppress selected id + And I open File > Edit Project File and go to Warning options + Then no nullPointer error is shown in the results + And the id nullPointer is listed under Suppressions in the project file dialog + + @id:t389a5f3a @project:basic-project + Scenario: Clear results + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I click Clear results + Then the results are cleared: the result tree is empty diff --git a/gui/manualtest/tests/result_list.scripts.json b/gui/manualtest/tests/result_list.scripts.json new file mode 100644 index 00000000000..739dd0bd32e --- /dev/null +++ b/gui/manualtest/tests/result_list.scripts.json @@ -0,0 +1,1127 @@ +{ + "t852206f1": { + "script": [ + { + "do": "click", + "name": "Show errors", + "role": "check box", + "label": "Click Error once" + }, + { + "do": "click", + "name": "Show warnings", + "role": "check box", + "label": "Click Warning once" + }, + { + "do": "click", + "name": "Show style warnings", + "role": "check box", + "label": "Click Style once" + }, + { + "do": "click", + "name": "Show portability", + "role": "check box", + "label": "Click Portability once" + }, + { + "do": "click", + "name": "Show performance warnings", + "role": "check box", + "label": "Click Performance once" + }, + { + "do": "click", + "name": "Show information", + "role": "check box", + "label": "Click Information once" + }, + { + "do": "click", + "name": "Cppcheck", + "role": "check box", + "label": "Click Cppcheck once" + }, + { + "do": "click", + "name": "Clang", + "role": "check box", + "label": "Click Clang once" + }, + { + "expect": "state", + "name": "Show errors", + "role": "check box", + "not_state": "checked", + "label": "Error changed to unchecked after first click" + }, + { + "expect": "state", + "name": "Show warnings", + "role": "check box", + "not_state": "checked", + "label": "Warning changed to unchecked after first click" + }, + { + "expect": "state", + "name": "Show style warnings", + "role": "check box", + "not_state": "checked", + "label": "Style changed to unchecked after first click" + }, + { + "expect": "state", + "name": "Show portability", + "role": "check box", + "not_state": "checked", + "label": "Portability changed to unchecked after first click" + }, + { + "expect": "state", + "name": "Show performance warnings", + "role": "check box", + "not_state": "checked", + "label": "Performance changed to unchecked after first click" + }, + { + "expect": "state", + "name": "Show information", + "role": "check box", + "not_state": "checked", + "label": "Information changed to unchecked after first click" + }, + { + "expect": "state", + "name": "Cppcheck", + "role": "check box", + "not_state": "checked", + "label": "Cppcheck changed to unchecked after first click" + }, + { + "expect": "state", + "name": "Clang", + "role": "check box", + "not_state": "checked", + "label": "Clang changed to unchecked after first click" + }, + { + "do": "click", + "name": "Show errors", + "role": "check box", + "label": "Click Error a second time" + }, + { + "do": "click", + "name": "Show warnings", + "role": "check box", + "label": "Click Warning a second time" + }, + { + "do": "click", + "name": "Show style warnings", + "role": "check box", + "label": "Click Style a second time" + }, + { + "do": "click", + "name": "Show portability", + "role": "check box", + "label": "Click Portability a second time" + }, + { + "do": "click", + "name": "Show performance warnings", + "role": "check box", + "label": "Click Performance a second time" + }, + { + "do": "click", + "name": "Show information", + "role": "check box", + "label": "Click Information a second time" + }, + { + "do": "click", + "name": "Cppcheck", + "role": "check box", + "label": "Click Cppcheck a second time" + }, + { + "do": "click", + "name": "Clang", + "role": "check box", + "label": "Click Clang a second time" + }, + { + "expect": "state", + "name": "Show errors", + "role": "check box", + "state": "checked", + "label": "Error is back to its start state (checked)" + }, + { + "expect": "state", + "name": "Show warnings", + "role": "check box", + "state": "checked", + "label": "Warning is back to its start state (checked)" + }, + { + "expect": "state", + "name": "Show style warnings", + "role": "check box", + "state": "checked", + "label": "Style is back to its start state (checked)" + }, + { + "expect": "state", + "name": "Show portability", + "role": "check box", + "state": "checked", + "label": "Portability is back to its start state (checked)" + }, + { + "expect": "state", + "name": "Show performance warnings", + "role": "check box", + "state": "checked", + "label": "Performance is back to its start state (checked)" + }, + { + "expect": "state", + "name": "Show information", + "role": "check box", + "state": "checked", + "label": "Information is back to its start state (checked)" + }, + { + "expect": "state", + "name": "Cppcheck", + "role": "check box", + "state": "checked", + "label": "Cppcheck is back to its start state (checked)" + }, + { + "expect": "state", + "name": "Clang", + "role": "check box", + "state": "checked", + "label": "Clang is back to its start state (checked)" + } + ], + "script_for": "e5baac140df9" + }, + "td7decf1a": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the project file path" + }, + { + "do": "click", + "name": "Open", + "role": "button", + "exact": true, + "label": "Confirm the file dialog" + }, + { + "expect": "visible", + "name": "src/b.c", + "role": "table cell", + "timeout": 30, + "label": "Analysis is done and results are shown" + }, + { + "expect": "visible", + "name": "src/a.c", + "role": "table cell", + "label": "All files are listed before filtering" + }, + { + "expect": "visible", + "name": "include/util.h", + "role": "table cell", + "label": "util.h is listed before filtering" + }, + { + "do": "focus", + "path": "0.4.1", + "role": "text", + "label": "Focus the Filter field" + }, + { + "do": "type", + "value": "arrayIndex", + "label": "Type arrayIndex in the Filter field" + }, + { + "expect": "visible", + "name": "src/b.c", + "role": "table cell", + "label": "Only the b.c error remains shown" + }, + { + "expect": "gone", + "name": "src/a.c", + "role": "table cell", + "label": "a.c error is filtered out" + }, + { + "expect": "gone", + "name": "include/util.h", + "role": "table cell", + "label": "util.h error is filtered out" + }, + { + "do": "settext", + "path": "0.4.1", + "role": "text", + "value": "", + "label": "Clear the Filter field" + }, + { + "expect": "visible", + "name": "src/a.c", + "role": "table cell", + "label": "a.c error is shown again" + }, + { + "expect": "visible", + "name": "src/b.c", + "role": "table cell", + "label": "b.c error is shown again" + }, + { + "expect": "visible", + "name": "include/util.h", + "role": "table cell", + "label": "util.h error is shown again" + } + ], + "script_for": "f86b9b8205a7" + }, + "t2af9d498": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the project file path" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the file dialog" + }, + { + "do": "wait", + "name": "Checking src/b.c", + "role": "list item", + "timeout": 30, + "label": "Wait until the analysis has run" + }, + { + "expect": "visible", + "name": "src/a.c", + "role": "table cell", + "timeout": 30, + "label": "Results are shown" + }, + { + "do": "click", + "name": "View", + "role": "menu item", + "label": "Open the View menu" + }, + { + "do": "click", + "name": "Collapse all", + "role": "menu item", + "label": "View > Collapse All" + }, + { + "do": "click", + "name": "Expand all", + "role": "menu item", + "label": "View > Expand All (menu is still open)" + }, + { + "expect": "visible", + "name": "Null pointer dereference: r", + "role": "table cell", + "label": "The error in util.h is visible" + }, + { + "expect": "visible", + "name": "Null pointer dereference: p", + "role": "table cell", + "label": "The error in a.c is visible" + }, + { + "expect": "state", + "name": "include/util.h", + "role": "table cell", + "state": "expanded", + "nth": 0, + "label": "util.h is expanded" + }, + { + "expect": "state", + "name": "src/a.c", + "role": "table cell", + "state": "expanded", + "nth": 0, + "label": "a.c is expanded" + } + ], + "script_for": "3d1da0542440" + }, + "tec898362": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "do": "wait", + "name": "Select Project File", + "role": "dialog", + "label": "File dialog appears" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the project file path" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the file dialog" + }, + { + "expect": "visible", + "name": "src/b.c", + "role": "table cell", + "timeout": 60, + "label": "Analysis is done and the file entries are shown" + }, + { + "do": "click", + "name": "View", + "role": "menu item", + "label": "Open the View menu" + }, + { + "do": "click", + "name": "Expand all", + "role": "menu item", + "label": "View > Expand All" + }, + { + "expect": "visible", + "name": "nullPointer", + "role": "table cell", + "label": "Errors are visible after expanding" + }, + { + "do": "hover", + "name": "View", + "role": "menu item", + "label": "Open the View menu again" + }, + { + "do": "click", + "name": "Collapse all", + "role": "menu item", + "label": "View > Collapse All" + }, + { + "expect": "visible", + "name": "include/util.h", + "role": "table cell", + "label": "File entry util.h is shown" + }, + { + "expect": "visible", + "name": "src/a.c", + "role": "table cell", + "label": "File entry a.c is shown" + }, + { + "expect": "visible", + "name": "src/b.c", + "role": "table cell", + "label": "File entry b.c is shown" + }, + { + "expect": "gone", + "name": "nullPointer", + "label": "Errors are not shown" + }, + { + "expect": "gone", + "name": "constVariablePointer", + "label": "Style errors are not shown" + } + ], + "script_for": "405a34af72d2" + }, + "t4c027507": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Choose Open Project File from the File menu" + }, + { + "do": "wait", + "name": "Select Project File", + "role": "dialog", + "label": "Wait for the file dialog" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the path of basic.cppcheck" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the file dialog" + }, + { + "do": "wait", + "name": "src/b.c", + "role": "table cell", + "timeout": 60, + "label": "Wait until the analysis is done and results are shown" + }, + { + "do": "wait", + "name": "Select Project File", + "gone": true, + "label": "File dialog is closed" + }, + { + "do": "rightclick", + "name": "src/a.c", + "role": "table cell", + "label": "Right click on the file a.c in the results" + }, + { + "expect": "ocr", + "contains": "Recheck", + "label": "Context menu has Recheck" + }, + { + "expect": "ocr", + "contains": "Open containing folder", + "label": "Context menu has Open containing folder" + }, + { + "expect": "ocr", + "not_contains": "Hide", + "label": "Context menu has no Hide entries" + }, + { + "expect": "ocr", + "not_contains": "Suppress selected id", + "label": "Context menu has no Suppress selected id" + } + ], + "script_for": "237d77caee36" + }, + "taacc3841": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the project file path" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Open the project file" + }, + { + "expect": "visible", + "name": "src/a.c", + "role": "table cell", + "timeout": 30, + "label": "Analysis is done and results show a.c" + }, + { + "do": "focus", + "name": "src/a.c", + "role": "table cell", + "label": "Focus the a.c row" + }, + { + "do": "key", + "keys": [ + "Right" + ], + "label": "Expand a.c in the results" + }, + { + "expect": "visible", + "name": "Null pointer dereference: p", + "role": "table cell", + "label": "First nullPointer error (line 6) is shown" + }, + { + "do": "rightclick", + "name": "Null pointer dereference: p", + "role": "table cell", + "label": "Right click on the first nullPointer error" + }, + { + "do": "key", + "keys": [ + "Down", + "Down", + "Down", + "Return" + ], + "label": "Click Hide (Hide 1 result(s)) in the context menu" + }, + { + "expect": "gone", + "name": "Null pointer dereference: p", + "label": "The hidden error is gone" + }, + { + "expect": "visible", + "name": "Null pointer dereference: q", + "role": "table cell", + "label": "Second nullPointer error (line 12) is still shown" + }, + { + "expect": "visible", + "name": "Variable 'p' can be declared as pointer to const", + "role": "table cell", + "label": "Other errors are still shown (line 5)" + }, + { + "expect": "visible", + "name": "Variable 'q' can be declared as pointer to const", + "role": "table cell", + "label": "Other errors are still shown (line 11)" + } + ], + "script_for": "13f9f46bd6a3" + }, + "t2937b690": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the project file path" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Open the project file" + }, + { + "expect": "visible", + "name": "src/a.c", + "role": "table cell", + "timeout": 30, + "label": "Wait until the analysis is done and results are shown" + }, + { + "do": "doubleclick", + "name": "src/a.c", + "role": "table cell", + "label": "Select a.c in the results" + }, + { + "do": "key", + "keys": [ + "Right" + ], + "label": "Expand a.c in the results" + }, + { + "expect": "visible", + "name": "nullPointer", + "role": "table cell", + "label": "nullPointer errors are listed before hiding" + }, + { + "do": "rightclick", + "name": "nullPointer", + "role": "table cell", + "nth": 0, + "label": "Right click on a nullPointer error" + }, + { + "do": "key", + "keys": [ + "Down", + "Down", + "Down", + "Down" + ], + "label": "Move to Hide all with id in the context menu" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Click Hide all with ID" + }, + { + "expect": "gone", + "name": "nullPointer", + "role": "table cell", + "label": "All nullPointer errors are gone from a.c and util.h" + }, + { + "expect": "visible", + "name": "constVariablePointer", + "role": "table cell", + "label": "Other errors in a.c are still shown" + }, + { + "do": "key", + "keys": [ + "End", + "Right" + ], + "label": "Expand b.c in the results" + }, + { + "expect": "visible", + "name": "arrayIndexOutOfBounds", + "role": "table cell", + "label": "The arrayIndexOutOfBounds error in b.c is still shown" + } + ], + "script_for": "0c3a81139be4" + }, + "t313463d3": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Given the project file is opened from the File menu: open File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Given the project file is opened from the File menu: Open Project File" + }, + { + "do": "wait", + "name": "Select Project File", + "role": "dialog", + "label": "Project file dialog is shown" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the project file basic.cppcheck" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Open the project file" + }, + { + "expect": "visible", + "name": "Project: basic.cppcheck", + "role": "frame", + "timeout": 10, + "label": "The project is loaded" + }, + { + "expect": "visible", + "name": "src/a.c", + "role": "table cell", + "timeout": 30, + "label": "And the analysis is done: a.c is in the results" + }, + { + "expect": "state", + "name": "Stop analysis", + "role": "button", + "not_state": "enabled", + "timeout": 30, + "label": "And the analysis is done" + }, + { + "do": "focus", + "name": "src/a.c", + "role": "table cell", + "label": "When I expand a.c in the results: select a.c" + }, + { + "do": "key", + "keys": [ + "Right" + ], + "label": "When I expand a.c in the results" + }, + { + "expect": "visible", + "name": "Null pointer dereference: p", + "role": "table cell", + "label": "The first nullPointer error of a.c is shown" + }, + { + "expect": "visible", + "name": "Null pointer dereference: q", + "role": "table cell", + "label": "The second nullPointer error of a.c is shown" + }, + { + "do": "rightclick", + "name": "Null pointer dereference: p", + "role": "table cell", + "label": "And I right click on the first nullPointer error" + }, + { + "expect": "ocr", + "contains": "Hide all with id", + "label": "The context menu has Hide all with id" + }, + { + "do": "key", + "keys": [ + "Up", + "Up", + "Up" + ], + "label": "Move to Hide all with id in the context menu" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "And click Hide all with id" + }, + { + "expect": "gone", + "name": "Null pointer dereference: p", + "label": "Then the a.c results are hidden: first nullPointer error" + }, + { + "expect": "gone", + "name": "Null pointer dereference: q", + "label": "Then the a.c results are hidden: second nullPointer error" + }, + { + "expect": "visible", + "name": "Variable 'p' can be declared as pointer to const", + "role": "table cell", + "label": "Other a.c results are still shown" + }, + { + "do": "click", + "name": "View", + "role": "menu item", + "label": "When I open View menu" + }, + { + "do": "click", + "name": "Show hidden", + "role": "menu item", + "label": "When I open View > Show Hidden" + }, + { + "expect": "visible", + "name": "Null pointer dereference: p", + "role": "table cell", + "label": "Then the error that was hidden is shown again" + }, + { + "expect": "visible", + "name": "Null pointer dereference: q", + "role": "table cell", + "label": "Then the other hidden nullPointer error is shown again" + } + ], + "script_for": "0b1c29212e8d" + }, + "t90bf32e9": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open File menu" + }, + { + "do": "click", + "name": "Open Project File", + "role": "menu item", + "label": "Click Open Project File" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter project file path" + }, + { + "do": "click", + "name": "Open", + "role": "button", + "exact": true, + "label": "Confirm the file dialog" + }, + { + "expect": "visible", + "name": "src/a.c", + "role": "table cell", + "timeout": 60, + "label": "Wait until the analysis is done" + }, + { + "do": "sleep", + "seconds": 3, + "label": "Let the analysis finish" + }, + { + "do": "focus", + "name": "src/a.c", + "role": "table cell", + "label": "Select a.c in the results" + }, + { + "do": "key", + "keys": [ + "Right" + ], + "label": "Expand a.c in the results" + }, + { + "expect": "visible", + "name": "nullPointer", + "role": "table cell", + "label": "nullPointer error is shown under a.c" + }, + { + "do": "rightclick", + "name": "nullPointer", + "role": "table cell", + "nth": 0, + "label": "Right click on a nullPointer error" + }, + { + "do": "key", + "keys": [ + "Down", + "Down", + "Down", + "Down", + "Down", + "Return" + ], + "label": "Click Suppress selected id" + }, + { + "expect": "gone", + "name": "nullPointer", + "role": "table cell", + "label": "No nullPointer error is shown in the results" + }, + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open File menu" + }, + { + "do": "click", + "name": "Edit Project File", + "role": "menu item", + "label": "Click Edit Project File" + }, + { + "do": "click", + "name": "Warning options", + "role": "page tab", + "label": "Go to Warning options" + }, + { + "expect": "visible", + "name": "nullPointer", + "role": "list item", + "label": "The id nullPointer is listed under Suppressions" + } + ], + "script_for": "fb50a62ef505" + }, + "t389a5f3a": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "Choose Open Project File" + }, + { + "do": "settext", + "name": "File name", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the project file path" + }, + { + "do": "click", + "name": "Open", + "role": "button", + "exact": true, + "label": "Confirm the file dialog" + }, + { + "expect": "visible", + "name": "src/b.c", + "role": "table cell", + "timeout": 30, + "label": "Analysis results are shown" + }, + { + "do": "sleep", + "seconds": 3, + "label": "Wait until the analysis is done" + }, + { + "expect": "state", + "name": "Clear results", + "role": "button", + "state": "enabled", + "label": "Analysis finished, Clear results is available" + }, + { + "do": "click", + "name": "Clear results", + "role": "button", + "label": "Click Clear results" + }, + { + "expect": "gone", + "name": "src/a.c", + "role": "table cell", + "label": "Result tree has no src/a.c entry" + }, + { + "expect": "gone", + "name": "src/b.c", + "role": "table cell", + "label": "Result tree has no src/b.c entry" + }, + { + "expect": "gone", + "name": "include/util.h", + "role": "table cell", + "label": "Result tree has no include/util.h entry" + } + ], + "script_for": "96a64734a43b" + } +} diff --git a/gui/manualtest/tests/xml_results.feature b/gui/manualtest/tests/xml_results.feature new file mode 100644 index 00000000000..2a7b48c5285 --- /dev/null +++ b/gui/manualtest/tests/xml_results.feature @@ -0,0 +1,45 @@ +Feature: XML results + + Background: + Given the application is started with no project loaded + + @id:tc1fc409e @project:basic-project + Scenario Outline: Save results to a file + Given the project file {project:basic-project}/basic.cppcheck is opened from the File menu + And the analysis is done + When I open File > Save results to file + And I choose the file type for files + And I save the results as results. in the work directory {work} + Then the file results. is saved in the format + And it has the nullPointer error in a.c ("Null pointer dereference") + And it has the arrayIndexOutOfBounds error in b.c ("out of bounds") + + Examples: + | format | + | xml | + | txt | + | csv | + + @id:tcdb051d4 @project:xml-results + Scenario: Open XML results + When I open File > Open XML + And I select {project:xml-results}/results.xml + Then the XML results are opened + And the nullPointer error in a.c is shown + + @id:t8d9a2076 @ticket:13984 @project:xml-results + Scenario: No Recheck in XML results + Given the XML results {project:xml-results}/results.xml are opened with File > Open XML + When I right click on the file a.c in the results + Then the context menu of the file has no Recheck entry and no Open containing folder entry, XML results can not be analysed again + And the application does not crash + + @id:t053b7c9c @project:xml-results @project:basic-project + Scenario: Reanalyze enabled after XML results + Given the XML results {project:xml-results}/results.xml are opened with File > Open XML + Then the button Reanalyze all files is disabled + And if I rightclick on a.c in the results I get a popup + And there is a option "Recheck 1 file(s)" in the popup that is disabled + When I open the project file {project:basic-project}/basic.cppcheck + And I wait until the analysis is done + Then the button Reanalyze all files is enabled and can be clicked diff --git a/gui/manualtest/tests/xml_results.scripts.json b/gui/manualtest/tests/xml_results.scripts.json new file mode 100644 index 00000000000..95fa6cebb97 --- /dev/null +++ b/gui/manualtest/tests/xml_results.scripts.json @@ -0,0 +1,466 @@ +{ + "tc1fc409e": { + "script": [ + { + "label": "Start the application with no project loaded", + "expect": "visible", + "name": "Cppcheck", + "role": "frame" + }, + { + "label": "Open the File menu", + "do": "click", + "name": "File", + "role": "menu item" + }, + { + "label": "Choose File > Open Project File", + "do": "click", + "name": "Open Project File...", + "role": "menu item" + }, + { + "label": "Wait for the project file dialog", + "do": "wait", + "name": "Select Project File", + "role": "dialog" + }, + { + "label": "Enter the project file basic.cppcheck", + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck" + }, + { + "label": "Open the project file", + "do": "key", + "keys": [ + "Return" + ] + }, + { + "label": "The project is loaded", + "expect": "visible", + "name": "Project: basic.cppcheck", + "role": "frame", + "timeout": 10 + }, + { + "label": "Analysis has produced results for b.c", + "expect": "visible", + "name": "src/b.c", + "role": "table cell", + "timeout": 30 + }, + { + "label": "Wait until the analysis is done", + "expect": "state", + "name": "Stop analysis", + "role": "button", + "not_state": "enabled", + "timeout": 30 + }, + { + "label": "Open the File menu", + "do": "click", + "name": "File", + "role": "menu item" + }, + { + "label": "Open File > Save results to file", + "do": "click", + "name": "Save results to file...", + "role": "menu item" + }, + { + "label": "Wait for the save dialog", + "do": "wait", + "name": "Save the report file", + "role": "dialog" + }, + { + "label": "Open the Files of type list", + "do": "click", + "name": "XML files", + "role": "combo box", + "mouse": true + }, + { + "label": "Choose the file type for {format} files", + "do": "click", + "name": "(*.{format})", + "role": "list item", + "mouse": true + }, + { + "label": "Enter results.{format} in the work directory as file name", + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{work}/results.{format}" + }, + { + "label": "Save the results", + "do": "click", + "name": "Save", + "role": "button", + "exact": true + }, + { + "label": "The save dialog is closed", + "expect": "gone", + "name": "Save the report file", + "role": "dialog" + }, + { + "label": "results.{format} is saved and names a.c", + "expect": "file", + "path": "{work}/results.{format}", + "contains": "src/a.c" + }, + { + "label": "results.{format} has the nullPointer error in a.c (Null pointer dereference)", + "expect": "file", + "path": "{work}/results.{format}", + "contains": "Null pointer dereference" + }, + { + "label": "results.{format} has the arrayIndexOutOfBounds error in b.c (out of bounds)", + "expect": "file", + "path": "{work}/results.{format}", + "regex": "src/b.c[\\s\\S]*out of bounds|out of bounds[\\s\\S]*src/b.c" + } + ], + "script_for": "dad1485bb95a" + }, + "tcdb051d4": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open XML", + "role": "menu item", + "label": "Choose File > Open XML" + }, + { + "expect": "visible", + "name": "Open the report file", + "role": "dialog", + "label": "The file dialog is shown" + }, + { + "do": "settext", + "name": "File name", + "role": "text", + "value": "{project:xml-results}/results.xml", + "label": "Select results.xml of the xml-results project" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Confirm the file dialog" + }, + { + "do": "wait", + "name": "Open the report file", + "gone": true, + "label": "The file dialog closes" + }, + { + "expect": "visible", + "name": "a.c", + "role": "table cell", + "label": "The file a.c is listed in the results" + }, + { + "do": "focus", + "name": "a.c", + "role": "table cell", + "label": "Give keyboard focus to the a.c entry" + }, + { + "do": "key", + "keys": [ + "Right" + ], + "label": "Expand the a.c entry to see its error" + }, + { + "expect": "visible", + "name": "nullPointer", + "role": "table cell", + "label": "The nullPointer error is shown" + }, + { + "expect": "visible", + "name": "Null pointer dereference: p", + "role": "table cell", + "label": "The nullPointer summary is shown" + }, + { + "expect": "visible", + "name": "error", + "role": "table cell", + "label": "The severity of the error is shown" + } + ], + "script_for": "35589d1420ec" + }, + "t8d9a2076": { + "script": [ + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Open the File menu" + }, + { + "do": "click", + "name": "Open XML", + "role": "menu item", + "label": "Choose File > Open XML" + }, + { + "do": "wait", + "name": "Open the report file", + "timeout": 10, + "label": "Wait for the open dialog" + }, + { + "do": "settext", + "name": "File name", + "role": "text", + "value": "{project:xml-results}/results.xml", + "label": "Enter the path of results.xml" + }, + { + "do": "click", + "name": "Open", + "role": "button", + "nth": 1, + "label": "Confirm the file dialog" + }, + { + "expect": "visible", + "name": "a.c", + "role": "table cell", + "timeout": 10, + "label": "The results show the file a.c" + }, + { + "do": "rightclick", + "name": "a.c", + "role": "table cell", + "label": "Right click on the file a.c in the results" + }, + { + "do": "key", + "keys": [ + "Menu" + ], + "label": "Make sure the context menu is open" + }, + { + "expect": "gone", + "name": "Recheck", + "label": "The context menu has no Recheck entry" + }, + { + "expect": "gone", + "name": "Open containing folder", + "label": "The context menu has no Open containing folder entry" + }, + { + "expect": "alive", + "label": "The application does not crash" + } + ], + "script_for": "a23ab5dd15e4" + }, + "t053b7c9c": { + "script": [ + { + "expect": "visible", + "name": "Cppcheck", + "role": "frame", + "label": "Given the application is started with no project loaded" + }, + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "Given the XML results are opened with File > Open XML: open the File menu" + }, + { + "do": "click", + "name": "Open XML...", + "role": "menu item", + "label": "Given the XML results are opened with File > Open XML: choose Open XML" + }, + { + "expect": "visible", + "name": "Open the report file", + "role": "dialog", + "label": "The Open XML file dialog is shown" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:xml-results}/results.xml", + "label": "Enter the XML results file name" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Open the XML results" + }, + { + "do": "wait", + "name": "Open the report file", + "gone": true, + "timeout": 10, + "label": "Wait until the file dialog is closed" + }, + { + "expect": "visible", + "name": "results.xml", + "role": "frame", + "timeout": 10, + "label": "The XML results are loaded" + }, + { + "expect": "visible", + "name": "a.c", + "role": "table cell", + "timeout": 10, + "label": "a.c is shown in the results" + }, + { + "expect": "state", + "name": "Reanalyze all files", + "role": "button", + "not_state": "enabled", + "label": "Then the button Reanalyze all files is disabled" + }, + { + "do": "rightclick", + "name": "a.c", + "role": "table cell", + "label": "And if I rightclick on a.c in the results" + }, + { + "do": "sleep", + "seconds": 1 + }, + { + "expect": "ocr", + "contains": "Copy", + "label": "I get a popup" + }, + { + "expect": "ocr", + "not_contains": "Recheck", + "label": "There is an option Recheck 1 file(s) in the popup that is disabled (greyed out, not read by OCR)" + }, + { + "do": "key", + "keys": [ + "Escape" + ], + "label": "Close the popup" + }, + { + "do": "click", + "name": "File", + "role": "menu item", + "label": "When I open the project file: open the File menu" + }, + { + "do": "click", + "name": "Open Project File...", + "role": "menu item", + "label": "When I open the project file: choose Open Project File" + }, + { + "expect": "visible", + "name": "Select Project File", + "role": "dialog", + "label": "The project file dialog is shown" + }, + { + "do": "settext", + "name": "File name:", + "role": "text", + "value": "{project:basic-project}/basic.cppcheck", + "label": "Enter the project file name" + }, + { + "do": "key", + "keys": [ + "Return" + ], + "label": "Open the project file" + }, + { + "do": "wait", + "name": "Select Project File", + "gone": true, + "timeout": 10, + "label": "Wait until the file dialog is closed" + }, + { + "expect": "visible", + "name": "Project: basic.cppcheck", + "role": "frame", + "timeout": 10, + "label": "The project is loaded" + }, + { + "expect": "state", + "name": "Stop analysis", + "role": "button", + "not_state": "enabled", + "timeout": 30, + "label": "And I wait until the analysis is done" + }, + { + "expect": "state", + "name": "Reanalyze all files", + "role": "button", + "state": "enabled", + "timeout": 30, + "label": "Then the button Reanalyze all files is enabled" + }, + { + "do": "click", + "name": "Reanalyze all files", + "role": "button", + "label": "And can be clicked" + }, + { + "expect": "alive", + "label": "The application still runs after clicking Reanalyze all files" + }, + { + "expect": "state", + "name": "Reanalyze all files", + "role": "button", + "state": "enabled", + "timeout": 30, + "label": "Reanalyze all files is enabled again after the reanalysis" + } + ], + "script_for": "299ae476b3db" + } +} diff --git a/gui/manualtest/web.py b/gui/manualtest/web.py new file mode 100644 index 00000000000..e538b00bdb8 --- /dev/null +++ b/gui/manualtest/web.py @@ -0,0 +1,464 @@ +#!/usr/bin/env python3 +"""Web interface for editing, generating and running the Gherkin tests. + + web.py [--opensource APP] [--premium APP] [--src DIR] [--dir tests] [--out results] [--port 8080] + +Serves on 127.0.0.1 only. Reads and writes DIR/*.feature, with the scripts in DIR/*.scripts.json, +and starts gen.py and run.py with the application that is tested, one binary per edition. SRC is the git checkout that both are built +from, for the git sha in the reports. --app is the same as --opensource. Without any APP the +tests can be edited but not generated or run. +""" + +import argparse +import json +import mimetypes +import os +import re +import signal +import subprocess +import sys +import shutil +import threading +import time +from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer +from urllib.parse import parse_qs, quote, unquote, urlparse + +import testfile + +HERE = os.path.dirname(os.path.abspath(__file__)) +NAME_RE = re.compile(r'^[\w.-]+\.feature$') +ID_RE = re.compile(r'^\w+$') + + +class Job: + """gen.py or run.py in the background, one at a time. The output is shown in the web page. + A run of several editions is one run.py after the other, each with its own report.""" + + def __init__(self, kind, file, test_id, cmds, out_dir): + self.kind, self.file, self.test_id, self.out_dir = kind, file, test_id, out_dir + self.editions = [e for e, _ in cmds] + self.lines, self.reports, self.rc = [], [], None + self.started = time.time() + self.progress = {'total': 0, 'index': 0, 'test': '', 'testfile': '', 'step': 0, 'steps': 0, 'label': '', 'base': None, + 'edition': None, 'results': []} + self.proc, self.stopped, self.lock = None, False, threading.Lock() + threading.Thread(target=self.work, args=(cmds,), daemon=True).start() + + def work(self, cmds): + rc = 0 + for edition, cmd in cmds: + with self.lock: + if self.stopped: + break + self.edition = edition + self.proc = subprocess.Popen(cmd, cwd=HERE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, + env=dict(os.environ, PYTHONUNBUFFERED='1'), start_new_session=True) + if len(cmds) > 1: + self.lines.append('=== %s ===' % edition) + self.read() + rc = max(rc, self.proc.wait()) + self.rc = rc + + def stop(self): + with self.lock: + self.stopped = True + if self.proc and self.proc.poll() is None: + self.proc.send_signal(signal.SIGINT) # run.py writes its report, gen.py cleans up + + def read(self): + for line in self.proc.stdout: + line = line.rstrip('\n') + if line.startswith('@{') and self.event(line[1:]): + continue + self.lines.append(line) + m = re.match(r'report: (.+)$', line) + if m: + self.reports.append({'edition': self.edition, + 'url': '/results/' + os.path.relpath(m.group(1), self.out_dir)}) + + def event(self, text): + """A progress line from run.py --events. False when it is not one.""" + try: + e = json.loads(text) + kind, p = e['kind'], self.progress + except (ValueError, KeyError, TypeError): + return False + if kind == 'start': + p.update(total=e['total'], index=0, test='', testfile='', step=0, steps=0, label='', edition=e.get('edition'), + base='/results/' + os.path.relpath(e['out'], self.out_dir)) + elif kind == 'test': + p.update(index=e['index'], test=e['name'], testfile=e.get('file', ''), step=0, steps=e['steps'], label='') + elif kind == 'step': + p.update(step=e['step'], steps=e['steps'], label=e['label']) + elif kind == 'result': + p['results'].append(dict({k: e[k] for k in ('name', 'status', 'reason', 'seconds', 'crash', 'slug')}, + file=e.get('file', ''), + shots=e.get('shots', []), edition=p['edition'], base=p['base'])) + return True + + def info(self): + return {'kind': self.kind, 'file': self.file, 'id': self.test_id, 'running': self.rc is None, + 'rc': self.rc, 'output': '\n'.join(self.lines), 'reports': self.reports, 'editions': self.editions, + 'progress': self.progress, 'started': self.started, 'now': time.time()} + + +class Handler(BaseHTTPRequestHandler): + directory = None + out_dir = None + apps = {} # edition -> path of the binary + src = None + job = None + lock = threading.Lock() + + def log_message(self, fmt, *args): + pass + + def reply(self, code, data, ctype='application/json'): + if ctype == 'application/json': + data = json.dumps(data, ensure_ascii=False) + if isinstance(data, str): + data = data.encode() + self.send_response(code) + self.send_header('Content-Type', ctype + ('; charset=utf-8' if ctype.startswith(('text/', 'application/json')) else '')) + self.send_header('Content-Length', str(len(data))) + self.send_header('Cache-Control', 'no-store') + self.end_headers() + self.wfile.write(data) + + def allowed(self): + # only localhost names as Host (DNS rebinding) and JSON for writes (cross-site forms) + host = self.headers.get('Host', '').rsplit(':', 1)[0] + if host not in ('127.0.0.1', 'localhost'): + self.reply(403, {'error': 'bad host'}) + return False + if self.command in ('PUT', 'POST') and self.headers.get('Content-Type', '').split(';')[0] != 'application/json': + self.reply(415, {'error': 'application/json required'}) + return False + return True + + def path_of(self, query): + name = parse_qs(query).get('name', [''])[0] + if not NAME_RE.match(name): + self.reply(400, {'error': 'bad file name (letters, digits, _ - . and .feature)'}) + return None + return os.path.join(self.directory, name) + + def project_path(self, query): + name = parse_qs(query).get('name', [''])[0] + if not testfile.PROJECT_RE.match(name): + self.reply(400, {'error': 'bad project name (letters, digits, _ and -)'}) + return None + return os.path.join(self.directory, testfile.PROJECTS, name) + + def used_by(self, project): + used = [] + for f in sorted(os.listdir(self.directory)): + if NAME_RE.match(f): + try: + tests = testfile.load(os.path.join(self.directory, f)).get('tests', []) + except (ValueError, OSError): + continue + used += ['%s: %s' % (f, t.get('name')) for t in tests if project in t.get('projects', [])] + return used + + def reports(self): + """The earlier runs in the out directory, newest first.""" + found = [] + for d in os.listdir(self.out_dir) if os.path.isdir(self.out_dir) else []: + if not os.path.isfile(os.path.join(self.out_dir, d, 'report.html')): + continue + try: + with open(os.path.join(self.out_dir, d, 'results.json'), encoding='utf-8') as f: + run = json.load(f) + counts = {} + for r in run.get('results', []): + counts[r['status']] = counts.get(r['status'], 0) + 1 + except (ValueError, OSError, KeyError, TypeError): + run, counts = {}, {} + found.append({'id': d, 'url': '/results/%s/report.html' % quote(d), 'started': run.get('started', ''), + 'edition': run.get('edition'), 'branch': run.get('branch'), 'sha': (run.get('sha') or '')[:8], + 'dirty': run.get('dirty'), 'aborted': run.get('aborted'), 'counts': counts, + 'files': [f.get('title') or f.get('file') for f in run.get('files', [])]}) + return sorted(found, key=lambda r: r['id'], reverse=True) + + def annotate(self, doc): + """Add _stale (the script is outdated) and _errors (what is wrong with the test or its script) + to every test, for the web page. Not saved, see stamp_scripts.""" + tests = doc.get('tests') if isinstance(doc, dict) else None + background = doc.get('background') if isinstance(doc, dict) and isinstance(doc.get('background'), list) else [] + for t in tests if isinstance(tests, list) else []: + if not isinstance(t, dict): + continue + t['_stale'] = testfile.is_stale(t, self.directory, background) + t['_errors'] = testfile.validate({'tests': [t]}, self.directory) + + def file_status(self): + """{file: {invalid: n, stale: n}}: tests with errors and tests whose script must be generated again. + invalid is 1 for a file that is not valid Gherkin.""" + out = {} + for name in os.listdir(self.directory): + if not NAME_RE.match(name): + continue + try: + doc = testfile.ensure_ids(testfile.load(os.path.join(self.directory, name))) + self.annotate(doc) + tests = [t for t in doc['tests'] if isinstance(t, dict)] + bad = sum(1 for t in tests if t['_errors']) + (len(tests) != len(doc['tests'])) + bool( + testfile.validate(dict(doc, tests=[]), self.directory)) + out[name] = {'invalid': bad, 'stale': sum(1 for t in tests if t['_stale'])} + except (ValueError, OSError, KeyError, TypeError, AttributeError): + out[name] = {'invalid': 1, 'stale': 0} + return out + + def body(self): + return json.loads(self.rfile.read(int(self.headers.get('Content-Length', 0))) or b'null') + + def do_GET(self): + if not self.allowed(): + return + u = urlparse(self.path) + if u.path == '/': + with open(os.path.join(HERE, 'web', 'index.html'), 'rb') as f: + self.reply(200, f.read(), 'text/html') + elif u.path == '/api/files': + self.reply(200, sorted(f for f in os.listdir(self.directory) if NAME_RE.match(f))) + elif u.path == '/api/file-status': + self.reply(200, self.file_status()) + elif u.path == '/api/script-doc': + self.reply(200, testfile.SCRIPT_DOC, 'text/plain') + elif u.path == '/api/config': + self.reply(200, {'apps': self.apps, 'editions': list(testfile.EDITIONS), 'can_run': bool(self.apps)}) + elif u.path == '/api/job': + self.reply(200, self.job.info() if self.job else None) + elif u.path == '/api/projects': + base = os.path.join(self.directory, testfile.PROJECTS) + names = sorted(n for n in os.listdir(base) if os.path.isdir(os.path.join(base, n))) if os.path.isdir(base) else [] + self.reply(200, [{'name': n, 'used_by': self.used_by(n)} for n in names]) + elif u.path == '/api/project': + path = self.project_path(u.query) + if path: + if not os.path.isdir(path): + return self.reply(404, {'error': 'no such project'}) + files, binary = {}, [] + for rel, data in sorted(testfile.project_files(self.directory, os.path.basename(path)).items()): + try: + files[rel] = data.decode('utf-8') + except UnicodeDecodeError: + binary.append(rel) + self.reply(200, {'files': files, 'binary': binary, 'used_by': self.used_by(os.path.basename(path))}) + elif u.path == '/api/reports': + self.reply(200, self.reports()) + elif u.path.startswith('/results/'): + self.static_file(self.out_dir, unquote(u.path[len('/results/'):])) + elif u.path.startswith('/docs/'): + self.static_file(os.path.join(HERE, 'docs'), unquote(u.path[len('/docs/'):])) + elif u.path == '/api/file': + path = self.path_of(u.query) + if path: + try: + doc = testfile.ensure_ids(testfile.load(path)) + except FileNotFoundError: + return self.reply(404, {'error': 'no such file'}) + except ValueError as e: + return self.reply(400, {'error': '%s is not valid Gherkin (fix it in a text editor): %s' % ( + os.path.basename(path), e)}) + self.annotate(doc) + self.reply(200, doc) + else: + self.reply(404, {'error': 'not found'}) + + def static_file(self, base, rel): + """A file below BASE: the results of the runs or the handbook.""" + base = os.path.realpath(base) + path = os.path.realpath(os.path.join(base, rel)) + if not path.startswith(base + os.sep) or not os.path.isfile(path): + return self.reply(404, {'error': 'not found'}) + ctype = 'text/plain' if path.endswith('.log') else mimetypes.guess_type(path)[0] or 'text/plain' + with open(path, 'rb') as f: + self.reply(200, f.read(), ctype) + + def do_PUT(self): + if not self.allowed(): + return + u = urlparse(self.path) + if u.path == '/api/project': + return self.put_project(u.query) + path = self.path_of(u.query) if u.path == '/api/file' else None + if not path: + return + try: + doc = self.body() + except ValueError: + return self.reply(400, {'errors': ['not valid JSON']}) + errors = testfile.validate(doc, self.directory) + if errors: + return self.reply(400, {'errors': errors}) + try: + old = testfile.load(path) + except (FileNotFoundError, ValueError): + old = None + testfile.save(path, testfile.stamp_scripts(doc, old, self.directory)) + self.reply(200, {'saved': os.path.basename(path)}) + + def put_project(self, query): + path = self.project_path(query) + if not path: + return + try: + files = self.body()['files'] + assert isinstance(files, dict) and all(isinstance(v, str) for v in files.values()) + except (ValueError, KeyError, TypeError, AssertionError): + return self.reply(400, {'errors': ['expected {"files": {"path": "content"}}']}) + clean = {} + for rel, content in files.items(): + norm = os.path.normpath(rel) + if (not rel or os.path.isabs(norm) or norm.startswith('..') or '\0' in rel or norm == '.' + or norm.split(os.sep)[0] == '..'): + return self.reply(400, {'errors': ['bad file path: %r (relative, inside the project)' % rel]}) + clean[norm] = content + if sum(len(c) for c in clean.values()) > 4_000_000: + return self.reply(400, {'errors': ['the project is too big for this editor']}) + os.makedirs(path, exist_ok=True) + # text files that are not in the request were removed in the editor, binary files stay + for rel, data in testfile.project_files(self.directory, os.path.basename(path)).items(): + if rel not in clean: + try: + data.decode('utf-8') + except UnicodeDecodeError: + continue + os.remove(os.path.join(path, rel)) + for rel, content in clean.items(): + target = os.path.join(path, rel) + os.makedirs(os.path.dirname(target), exist_ok=True) + with open(target + '.tmp', 'w', encoding='utf-8', newline='') as f: + f.write(content) + os.replace(target + '.tmp', target) + for dirpath, dirs, fs in os.walk(path, topdown=False): # directories that became empty + if dirpath != path and not os.listdir(dirpath): + os.rmdir(dirpath) + self.reply(200, {'saved': os.path.basename(path), 'files': len(clean)}) + + def do_POST(self): + if not self.allowed(): + return + route = urlparse(self.path).path + try: + data = self.body() + if route == '/api/job': + self.start_job(data) + elif route == '/api/job/stop': + if self.job and self.job.rc is None: + self.job.stop() + self.reply(200, {'stopping': True}) + else: + self.reply(404, {'error': 'not found'}) + except (ValueError, KeyError, TypeError): + self.reply(400, {'errors': ['bad request']}) + + def start_job(self, data): + action, name, test_id, edition = data['action'], data['file'], data.get('id'), data.get('edition') + if not self.apps: + return self.reply(400, {'errors': ['web.py was started without --opensource or --premium']}) + everything = action == 'run' and name == '*' # every test file in the directory + if action not in ('generate', 'run') or not (everything or NAME_RE.match(name)) or ( + test_id and not ID_RE.match(test_id)): + return self.reply(400, {'errors': ['bad request']}) + if action == 'generate' and not test_id: + return self.reply(400, {'errors': ['generate needs a test id']}) + if everything: + paths = sorted(os.path.join(self.directory, n) for n in os.listdir(self.directory) if NAME_RE.match(n)) + if not paths or test_id: + return self.reply(404, {'errors': ['no test files']}) + else: + paths = [os.path.join(self.directory, name)] + if not os.path.isfile(paths[0]): + return self.reply(404, {'errors': ['no such file']}) + path = paths[0] + # the editions of the job: the chosen ones that web.py has a binary for and, for one test, that it is for + editions = [e for e in testfile.EDITIONS if e in self.apps and edition in (e, 'both')] + if test_id: + test = next((t for t in testfile.ensure_ids(testfile.load(path)).get('tests', []) if t['id'] == test_id), None) + if not test: + return self.reply(404, {'errors': ['no such test']}) + allowed = [e for e in testfile.editions(test) if e in self.apps] + if action == 'generate' and not set(editions) & set(allowed): + editions = allowed # the script is the same for all editions, make it with one that we have + editions = [e for e in editions if e in allowed] + if not editions: + return self.reply(400, {'errors': ['the test is not for the edition %s, or web.py has no application for it' % (edition or '')]}) + if action == 'generate': + editions = editions[:1] + cmds = [] + for e in editions: + app = self.apps[e] + if action == 'generate': + cmd = [sys.executable, 'gen.py', app, path, '--force', '--id', test_id, '--edition', e] + else: + cmd = [sys.executable, 'run.py', app, *paths, '--out', self.out_dir, '--events', '--edition', e] + cmd += ['--src', self.src] if self.src else [] + cmd += ['--id', test_id] if test_id else [] + cmds.append((e, cmd)) + with self.lock: + if self.job and self.job.rc is None: + return self.reply(409, {'errors': ['a job is already running']}) + Handler.job = Job(action, name, test_id, cmds, self.out_dir) + self.reply(200, self.job.info()) + + def do_DELETE(self): + if not self.allowed(): + return + u = urlparse(self.path) + if u.path == '/api/project': + path = self.project_path(u.query) + if path: + used = self.used_by(os.path.basename(path)) + if used: + return self.reply(409, {'errors': ['the project is used by: ' + '; '.join(used)]}) + if not os.path.isdir(path): + return self.reply(404, {'error': 'no such project'}) + shutil.rmtree(path) + self.reply(200, {'deleted': os.path.basename(path)}) + return + path = self.path_of(u.query) if u.path == '/api/file' else None + if path: + try: + os.remove(path) + if os.path.exists(testfile.scripts_path(path)): + os.remove(testfile.scripts_path(path)) + self.reply(200, {'deleted': os.path.basename(path)}) + except FileNotFoundError: + self.reply(404, {'error': 'no such file'}) + + +def main(): + ap = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) + for e in testfile.EDITIONS: + ap.add_argument('--' + e, *(['--app'] if e == 'opensource' else []), metavar='APP', + help='the %s edition of the application to test' % e) + ap.add_argument('--src', help='git checkout of the application, the same for all editions (default: the directory of APP)') + ap.add_argument('--dir', default=os.path.join(HERE, 'tests')) + ap.add_argument('--out', default=os.path.join(HERE, 'results')) + ap.add_argument('--port', type=int, default=8080) + args = ap.parse_args() + for e in testfile.EDITIONS: + app = getattr(args, e) + if app: + if not os.access(app, os.X_OK): + sys.exit('error: not executable: ' + app) + Handler.apps[e] = os.path.abspath(app) + Handler.src = os.path.abspath(args.src) if args.src else None + Handler.directory = os.path.abspath(args.dir) + Handler.out_dir = os.path.realpath(args.out) + os.makedirs(Handler.directory, exist_ok=True) + os.makedirs(Handler.out_dir, exist_ok=True) + Handler.out_dir = os.path.realpath(Handler.out_dir) + server = ThreadingHTTPServer(('127.0.0.1', args.port), Handler) + print('http://127.0.0.1:%d/ (%s)' % (args.port, Handler.directory), flush=True) + try: + server.serve_forever() + except KeyboardInterrupt: + pass + + +if __name__ == '__main__': + main() diff --git a/gui/manualtest/web/index.html b/gui/manualtest/web/index.html new file mode 100644 index 00000000000..7cccc8e9b23 --- /dev/null +++ b/gui/manualtest/web/index.html @@ -0,0 +1,677 @@ + + + + + +GUI tester + + + +
+

GUI tester

+ no file selected + + + + + + Handbook +
+
+ +

Select a file on the left or create a new one.

+
+
+ + + diff --git a/gui/resultitem.h b/gui/resultitem.h index e0c212b2138..9c9b0b82af3 100644 --- a/gui/resultitem.h +++ b/gui/resultitem.h @@ -53,8 +53,8 @@ class ResultItem : public QStandardItem return mIconFileName; } private: - const Type mType; - const int mErrorPathIndex; + Type mType; + int mErrorPathIndex; QString mIconFileName; }; diff --git a/gui/resultstree.cpp b/gui/resultstree.cpp index ed8b3c7412e..2c99ecf3ed1 100644 --- a/gui/resultstree.cpp +++ b/gui/resultstree.cpp @@ -246,7 +246,7 @@ bool ResultsTree::addErrorItem(const ErrorItem& errorItem) const QString s = errorItem.toString(); if (mErrorList.contains(s)) return false; - mErrorList.append(s); + mErrorList.insert(s); QSharedPointer errorItemPtr{new ErrorItem(errorItem)}; @@ -427,7 +427,7 @@ void ResultsTree::clear(const QString &filename) if (stripped == fileItem->text() || filename == fileItem->errorItem->file0) { - mErrorList.removeAll(fileItem->errorItem->toString()); + removeFileErrorsFromErrorList(fileItem); mModel->removeRow(i); break; } @@ -445,7 +445,7 @@ void ResultsTree::clearRecheckFile(const QString &filename) QString storedfile = fileItem->getErrorPathItem().file; storedfile = ((!mCheckPath.isEmpty() && storedfile.startsWith(mCheckPath)) ? storedfile.mid(mCheckPath.length() + 1) : storedfile); if (actualfile == storedfile) { - mErrorList.removeAll(fileItem->errorItem->toString()); + removeFileErrorsFromErrorList(fileItem); mModel->removeRow(i); break; } @@ -1132,6 +1132,15 @@ void ResultsTree::saveErrors(Report *report, const ResultItem *fileItem) const } } +void ResultsTree::removeFileErrorsFromErrorList(const ResultItem *fileItem) +{ + for (int i{0}; i < fileItem->rowCount(); ++i) { + const auto *errorItem = dynamic_cast(fileItem->child(i, COLUMN_FILE)); + if (errorItem && errorItem->errorItem) + mErrorList.remove(errorItem->errorItem->toString()); + } +} + void ResultsTree::updateFromOldReport(const QString &filename) { showColumn(COLUMN_SINCE_DATE); @@ -1194,7 +1203,15 @@ void ResultsTree::updateSettings(bool showFullPath, void ResultsTree::setCheckDirectory(const QString &dir) { + if (mCheckPath == dir) + return; + mCheckPath = dir; + + // A partial recheck keeps results whose displayed paths are relative to the check path, so + // they are recalculated. Not without a check path, QDir("") would turn absolute paths into "../..". + if (!mCheckPath.isEmpty()) + refreshFilePaths(); } const QString& ResultsTree::getCheckDirectory() const diff --git a/gui/resultstree.h b/gui/resultstree.h index 23fe5567ed9..c829c21fc6a 100644 --- a/gui/resultstree.h +++ b/gui/resultstree.h @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -356,6 +357,12 @@ protected slots: */ void saveErrors(Report *report, const ResultItem *fileItem) const; + /** + * @brief Remove all errors of a file item from the duplicate-check list + * @param fileItem Item whose errors to remove + */ + void removeFileErrorsFromErrorList(const ResultItem *fileItem); + /** * @brief Convert a severity string to a icon filename * @@ -566,8 +573,8 @@ protected slots: QStringList mHiddenMessageId; - // List of existing errors so we can avoid duplicates - QStringList mErrorList; + // Set of existing errors so we can avoid duplicates + QSet mErrorList; QItemSelectionModel* mSelectionModel{}; ThreadHandler *mThread{}; diff --git a/gui/test/data/xmlfiles/xmlreport_v2.xml b/gui/test/data/xmlfiles/xmlreport_v2.xml index 31af1a92cff..e8e03c3adbb 100644 --- a/gui/test/data/xmlfiles/xmlreport_v2.xml +++ b/gui/test/data/xmlfiles/xmlreport_v2.xml @@ -2,10 +2,10 @@ - + - + @@ -15,7 +15,7 @@ - + diff --git a/gui/test/resultstree/testresultstree.cpp b/gui/test/resultstree/testresultstree.cpp index 31520f3e6d9..c4a7d3080c0 100644 --- a/gui/test/resultstree/testresultstree.cpp +++ b/gui/test/resultstree/testresultstree.cpp @@ -106,12 +106,6 @@ Application& ApplicationList::getApplication(const int /*unused*/) { const Application& ApplicationList::getApplication(const int index) const { return mApplications.at(index); } -QString XmlReport::quoteMessage(const QString &message) { - return message; -} -QString XmlReport::unquoteMessage(const QString &message) { - return message; -} XmlReport::XmlReport(const QString& filename) : Report(filename) {} // NOLINTNEXTLINE(performance-unnecessary-value-param) void ThreadResult::finishCheck(CheckThread::Details /*unused*/) { @@ -265,6 +259,31 @@ void TestResultsTree::resultsInSameFile() const } } +void TestResultsTree::clearRecheckFile() const +{ + // #14893 - rechecking a file removes its results, the results of the other files are kept + ResultsTree tree(nullptr); + QVERIFY(tree.addErrorItem(createErrorItem("file1.c", 10, Severity::style, "test", "bugId"))); + QVERIFY(tree.addErrorItem(createErrorItem("file1.c", 20, Severity::style, "test", "bugId"))); + QVERIFY(tree.addErrorItem(createErrorItem("file2.c", 10, Severity::style, "test", "bugId"))); + + const auto* model = dynamic_cast(tree.model()); + QVERIFY(model != nullptr); + QCOMPARE(model->rowCount(), 2); + + tree.clearRecheckFile("file1.c"); + QCOMPARE(model->rowCount(), 1); + QCOMPARE(model->item(0,0)->text(), "file2.c"); + + // the recheck reports the results of the rechecked file again, they must not be treated as duplicates + QVERIFY(tree.addErrorItem(createErrorItem("file1.c", 10, Severity::style, "test", "bugId"))); + QVERIFY(tree.addErrorItem(createErrorItem("file1.c", 20, Severity::style, "test", "bugId"))); + QCOMPARE(model->rowCount(), 2); + + // the results of the other files are still known + QVERIFY(!tree.addErrorItem(createErrorItem("file2.c", 10, Severity::style, "test", "bugId"))); +} + void TestResultsTree::testReportType() const { TestReport report("{id},{classification},{guideline}"); diff --git a/gui/test/resultstree/testresultstree.h b/gui/test/resultstree/testresultstree.h index add0390c456..dcce568b4ba 100644 --- a/gui/test/resultstree/testresultstree.h +++ b/gui/test/resultstree/testresultstree.h @@ -26,6 +26,7 @@ private slots: void duplicateResults() const; void multiLineResult() const; void resultsInSameFile() const; + void clearRecheckFile() const; void testReportType() const; void testReportTypeIcon() const; void testGetGuidelineError() const; diff --git a/gui/test/xmlreportv2/testxmlreportv2.cpp b/gui/test/xmlreportv2/testxmlreportv2.cpp index 2dc0927b870..d157a4bef6d 100644 --- a/gui/test/xmlreportv2/testxmlreportv2.cpp +++ b/gui/test/xmlreportv2/testxmlreportv2.cpp @@ -21,7 +21,9 @@ #include "erroritem.h" #include "xmlreportv2.h" +#include #include +#include #include void TestXmlReportV2::readXml() const @@ -53,4 +55,39 @@ void TestXmlReportV2::readXml() const QCOMPARE(item2.message, QString("Mismatching allocation and deallocation: k")); } +void TestXmlReportV2::writeXmlEscaping() const +{ + QTemporaryDir dir; + const QString path = dir.path() + "/results.xml"; + + ErrorItem item; + item.errorId = "id"; + item.severity = Severity::style; + item.summary = "\"x\" & ""; + item.message = item.summary; + QErrorPathItem loc; + loc.file = "a&b.cpp"; + loc.line = 1; + item.errorPath << loc; + { + XmlReportV2 report(path, QString()); + QVERIFY(report.create()); + report.writeHeader(); + report.writeError(item); + report.writeFooter(); + } + + QFile file(path); + QVERIFY(file.open(QIODevice::ReadOnly)); + QVERIFY(file.readAll().contains("msg=\""x" & <y> &quot;\"")); + + XmlReportV2 report(path, QString()); + QVERIFY(report.open()); + const QList errors = report.read(); + QCOMPARE(errors.size(), 1); + QCOMPARE(errors[0].summary, item.summary); + QCOMPARE(errors[0].message, item.message); + QCOMPARE(errors[0].errorPath[0].file, loc.file); +} + QTEST_MAIN(TestXmlReportV2) diff --git a/gui/test/xmlreportv2/testxmlreportv2.h b/gui/test/xmlreportv2/testxmlreportv2.h index 9b864239414..9662bd00b27 100644 --- a/gui/test/xmlreportv2/testxmlreportv2.h +++ b/gui/test/xmlreportv2/testxmlreportv2.h @@ -23,4 +23,5 @@ class TestXmlReportV2 : public QObject { private slots: void readXml() const; + void writeXmlEscaping() const; }; diff --git a/gui/threadhandler.cpp b/gui/threadhandler.cpp index 3f89d58b558..577dcdc3375 100644 --- a/gui/threadhandler.cpp +++ b/gui/threadhandler.cpp @@ -21,6 +21,7 @@ #include "checkthread.h" #include "common.h" #include "filesettings.h" +#include "importproject.h" #include "resultsview.h" #include "settings.h" #include "utils.h" @@ -53,6 +54,7 @@ ThreadHandler::~ThreadHandler() void ThreadHandler::clearFiles() { mLastFiles.clear(); + mLastFileSettings.clear(); mResults.clearFiles(); mAnalyseWholeProgram = false; mCtuInfo.clear(); @@ -63,6 +65,7 @@ void ThreadHandler::clearFiles() void ThreadHandler::setFiles(std::list files) { mLastFiles = files; + mLastFileSettings.clear(); mResults.setFiles(std::move(files)); } @@ -70,6 +73,7 @@ void ThreadHandler::setProject(const ImportProject &prj) { mResults.setProject(prj); mLastFiles.clear(); + mLastFileSettings = prj.fileSettings; } void ThreadHandler::setCheckFiles(bool all) @@ -190,7 +194,7 @@ void ThreadHandler::threadDone() createThreads(1); mRunningThreadCount = 1; setupCheckThread(*mThreads[0]); - mThreads[0]->analyseWholeProgram(mLastFiles, mCtuInfo); + mThreads[0]->analyseWholeProgram(mLastFiles, mLastFileSettings, mCtuInfo); mAnalyseWholeProgram = false; mCtuInfo.clear(); return; diff --git a/gui/threadhandler.h b/gui/threadhandler.h index 17f011c32ac..879da0db8da 100644 --- a/gui/threadhandler.h +++ b/gui/threadhandler.h @@ -20,6 +20,7 @@ #ifndef THREADHANDLER_H #define THREADHANDLER_H +#include "filesettings.h" #include "settings.h" #include "suppressions.h" #include "threadresult.h" @@ -238,6 +239,12 @@ protected slots: */ std::list mLastFiles; + /** + * @brief Files of the project checked last time (used by the whole program analysis) + * + */ + std::list mLastFileSettings; + /** @brief date and time when current checking started */ QDateTime mCheckStartTime; diff --git a/gui/xmlreport.cpp b/gui/xmlreport.cpp index c5f00fc5bb7..8d184ca6658 100644 --- a/gui/xmlreport.cpp +++ b/gui/xmlreport.cpp @@ -32,28 +32,6 @@ XmlReport::XmlReport(const QString &filename) : Report(filename) {} -QString XmlReport::quoteMessage(const QString &message) -{ - QString quotedMessage(message); - quotedMessage.replace("&", "&"); - quotedMessage.replace("\"", """); - quotedMessage.replace("'", "'"); - quotedMessage.replace("<", "<"); - quotedMessage.replace(">", ">"); - return quotedMessage; -} - -QString XmlReport::unquoteMessage(const QString &message) -{ - QString quotedMessage(message); - quotedMessage.replace("&", "&"); - quotedMessage.replace(""", "\""); - quotedMessage.replace("'", "'"); - quotedMessage.replace("<", "<"); - quotedMessage.replace(">", ">"); - return quotedMessage; -} - int XmlReport::determineVersion(const QString &filename) { QFile file; diff --git a/gui/xmlreport.h b/gui/xmlreport.h index 2483b1b7471..83c222291ab 100644 --- a/gui/xmlreport.h +++ b/gui/xmlreport.h @@ -42,20 +42,6 @@ class XmlReport : public Report { */ virtual QList read() = 0; - /** - * @brief Quote the message. - * @param message Message to quote. - * @return quoted message. - */ - static QString quoteMessage(const QString &message); - - /** - * @brief Unquote the message. - * @param message Message to quote. - * @return quoted message. - */ - static QString unquoteMessage(const QString &message); - /** * @brief Get the XML report format version from the file. * @param filename Filename of the report file. diff --git a/gui/xmlreportv2.cpp b/gui/xmlreportv2.cpp index abf6aa361ba..b707b6d44dd 100644 --- a/gui/xmlreportv2.cpp +++ b/gui/xmlreportv2.cpp @@ -132,10 +132,8 @@ void XmlReportV2::writeError(const ErrorItem &error) // Don't localize severity so we can read these files mXmlWriter->writeAttribute(SeverityAttribute, GuiSeverity::toString(error.severity)); - const QString summary = XmlReport::quoteMessage(error.summary); - mXmlWriter->writeAttribute(MsgAttribute, summary); - const QString message = XmlReport::quoteMessage(error.message); - mXmlWriter->writeAttribute(VerboseAttribute, message); + mXmlWriter->writeAttribute(MsgAttribute, error.summary); + mXmlWriter->writeAttribute(VerboseAttribute, error.message); if (error.inconclusive) mXmlWriter->writeAttribute(InconclusiveAttribute, "true"); if (!error.remark.isEmpty()) @@ -145,7 +143,7 @@ void XmlReportV2::writeError(const ErrorItem &error) if (error.hash > 0) mXmlWriter->writeAttribute(HashAttribute, QString::number(error.hash)); if (!error.file0.isEmpty()) - mXmlWriter->writeAttribute(IncludedFromFilenameAttribute, quoteMessage(error.file0)); + mXmlWriter->writeAttribute(IncludedFromFilenameAttribute, error.file0); if (!error.sinceDate.isEmpty()) mXmlWriter->writeAttribute(SinceDateAttribute, error.sinceDate); if (!error.tags.isEmpty()) @@ -155,12 +153,12 @@ void XmlReportV2::writeError(const ErrorItem &error) mXmlWriter->writeStartElement(LocationElementName); QString file = QDir::toNativeSeparators(error.errorPath[i].file); - mXmlWriter->writeAttribute(FilenameAttribute, XmlReport::quoteMessage(file)); + mXmlWriter->writeAttribute(FilenameAttribute, file); mXmlWriter->writeAttribute(LineAttribute, QString::number(error.errorPath[i].line)); if (error.errorPath[i].column > 0) mXmlWriter->writeAttribute(ColumnAttribute, QString::number(error.errorPath[i].column)); if (error.errorPath.count() > 1) - mXmlWriter->writeAttribute(InfoAttribute, XmlReport::quoteMessage(error.errorPath[i].info)); + mXmlWriter->writeAttribute(InfoAttribute, error.errorPath[i].info); mXmlWriter->writeEndElement(); } @@ -228,10 +226,8 @@ ErrorItem XmlReportV2::readError(const QXmlStreamReader *reader) QXmlStreamAttributes attribs = reader->attributes(); item.errorId = attribs.value(QString(), IdAttribute).toString(); item.severity = GuiSeverity::fromString(attribs.value(QString(), SeverityAttribute).toString()); - const QString summary = attribs.value(QString(), MsgAttribute).toString(); - item.summary = XmlReport::unquoteMessage(summary); - const QString message = attribs.value(QString(), VerboseAttribute).toString(); - item.message = XmlReport::unquoteMessage(message); + item.summary = attribs.value(QString(), MsgAttribute).toString(); + item.message = attribs.value(QString(), VerboseAttribute).toString(); if (attribs.hasAttribute(QString(), InconclusiveAttribute)) item.inconclusive = true; if (attribs.hasAttribute(QString(), RemarkAttribute)) @@ -258,14 +254,14 @@ ErrorItem XmlReportV2::readError(const QXmlStreamReader *reader) QXmlStreamAttributes attribs = mXmlReader->attributes(); QString file0 = attribs.value(QString(), IncludedFromFilenameAttribute).toString(); if (!file0.isEmpty()) - item.file0 = XmlReport::unquoteMessage(file0); + item.file0 = file0; QErrorPathItem loc; - loc.file = XmlReport::unquoteMessage(attribs.value(QString(), FilenameAttribute).toString()); + loc.file = attribs.value(QString(), FilenameAttribute).toString(); loc.line = attribs.value(QString(), LineAttribute).toString().toUInt(); if (attribs.hasAttribute(QString(), ColumnAttribute)) loc.column = attribs.value(QString(), ColumnAttribute).toString().toInt(); if (attribs.hasAttribute(QString(), InfoAttribute)) - loc.info = XmlReport::unquoteMessage(attribs.value(QString(), InfoAttribute).toString()); + loc.info = attribs.value(QString(), InfoAttribute).toString(); item.errorPath.push_front(loc); } break; diff --git a/htmlreport/cppcheck-htmlreport b/htmlreport/cppcheck-htmlreport index fb263c73d12..3f8d2399da1 100755 --- a/htmlreport/cppcheck-htmlreport +++ b/htmlreport/cppcheck-htmlreport @@ -620,15 +620,15 @@ class AnnotateCodeFormatter(HtmlFormatter): # from actual message if error.get('verbose') and (error['verbose'] != error['msg']): index = t.rfind('\n') - t = t[:index] + HTML_EXPANDABLE_INCONCLUSIVE % (error['msg'], html_escape(error['verbose'].replace("\\012", '\n'))) + t[index + 1:] + t = t[:index] + HTML_EXPANDABLE_INCONCLUSIVE % (html_escape(error['msg']), html_escape(error['verbose'].replace("\\012", '\n'))) + t[index + 1:] else: - t = t.replace('\n', HTML_INCONCLUSIVE % error['msg']) + t = t.replace('\n', HTML_INCONCLUSIVE % html_escape(error['msg'])) except KeyError: if error.get('verbose') and (error['verbose'] != error['msg']): index = t.rfind('\n') - t = t[:index] + HTML_EXPANDABLE_ERROR % (error['msg'], html_escape(error['verbose'].replace("\\012", '\n'))) + t[index + 1:] + t = t[:index] + HTML_EXPANDABLE_ERROR % (html_escape(error['msg']), html_escape(error['verbose'].replace("\\012", '\n'))) + t[index + 1:] else: - t = t.replace('\n', HTML_ERROR % error['msg']) + t = t.replace('\n', HTML_ERROR % html_escape(error['msg'])) line_no = line_no + 1 yield i, t @@ -824,7 +824,7 @@ def main() -> None: if is_remote: # Construct remote URL for GitHub/GitLab # tr_str() will use the actual line number, so we can just start with line 1 - remote_url = source_dir.rstrip('/') + '/' + filename + '#L1' + remote_url = source_dir.rstrip('/') + '/' + html_escape(filename) + '#L1' files[filename] = {'errors': [], 'htmlfile': remote_url} else: files[filename] = {'errors': [], 'htmlfile': str(file_no) + '.html'} @@ -900,10 +900,10 @@ def main() -> None: (options.title, htmlFormatter.get_style_defs('.highlight'), options.title, - ': ' + filename)) + ': ' + html_escape(filename))) output_file.write(HTML_HEAD_END) - output_file.write(HTML_MENU % (filename.split('/')[-1])) + output_file.write(HTML_MENU % (html_escape(filename.split('/')[-1]))) for error in sorted(errors, key=lambda k: k['line']): output_file.write(" %s %s" % (data['htmlfile'], error['line'], error['id'], error['line'])) output_file.write(HTML_MENU_END) @@ -1006,7 +1006,7 @@ def main() -> None: for filename, data in sorted(files.items()): file_error = filename in decode_errors or filename.endswith('*') is_file = filename != '' and not file_error - row_content = filename if file_error else "%s" % (data['htmlfile'], filename) + row_content = html_escape(filename) if file_error else "%s" % (data['htmlfile'], html_escape(filename)) htmlfile = data.get('htmlfile') if is_file else None output_file.write("\n ") @@ -1122,7 +1122,7 @@ def main() -> None: if it == 0: LENGTH = len(str(i[1])) # <- length of longest number, now get the difference and try to make other numbers align to it - stats_file.write(" " * 3 + str(i[1]) + " " * (1 + LENGTH - len(str(i[1]))) + " " + i[0] + "
\n") + stats_file.write(" " * 3 + str(i[1]) + " " * (1 + LENGTH - len(str(i[1]))) + " " + html_escape(i[0]) + "
\n") it += 1 if it == 10: # print only the top 10 break diff --git a/lib/analyzerinfo.cpp b/lib/analyzerinfo.cpp index aa8d82c27fa..3bdc6875e63 100644 --- a/lib/analyzerinfo.cpp +++ b/lib/analyzerinfo.cpp @@ -21,7 +21,6 @@ #include "errorlogger.h" #include "filesettings.h" #include "path.h" -#include "utils.h" #include #include @@ -197,12 +196,13 @@ std::string AnalyzerInformation::skipAnalysis(const tinyxml2::XMLDocument &analy std::string AnalyzerInformation::getAnalyzerInfoFileFromFilesTxt(std::istream& filesTxt, const std::string &sourcefile, const std::string &cfg, size_t fsFileId) { + const std::string simplifiedSourcefile = Path::simplifyPath(sourcefile); std::string line; while (std::getline(filesTxt,line)) { AnalyzerInformation::Info filesTxtInfo; if (!filesTxtInfo.parse(line)) continue; // TODO: report error? - if (endsWith(sourcefile, filesTxtInfo.sourceFile) && filesTxtInfo.cfg == cfg && filesTxtInfo.fsFileId == fsFileId) + if (filesTxtInfo.sourceFile == simplifiedSourcefile && filesTxtInfo.cfg == cfg && filesTxtInfo.fsFileId == fsFileId) return filesTxtInfo.afile; } return ""; diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 31c8d2e0e2d..e2e19b6bd91 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -26,6 +26,7 @@ #include "infer.h" #include "library.h" #include "mathlib.h" +#include "refthunk.h" #include "settings.h" #include "symboldatabase.h" #include "token.h" @@ -3141,7 +3142,7 @@ namespace { }; struct ExpressionChangedSkipDeadCode { - const Library& library; + RefThunk library; const std::function(const Token* tok)>* evaluate; ExpressionChangedSkipDeadCode(const Library& library, const std::function(const Token* tok)>& evaluate) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 0f02016bd01..223bde3b452 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -195,6 +195,65 @@ void CheckClassImpl::handleUnionMembers(std::vector& usageList) } } +static std::vector getInheritedConstructors(const Scope *scope) +{ + std::vector result; + + if (!scope || !scope->bodyStart || !scope->definedType) + return result; + + const auto isInherited = [](const Function &baseCtor, const Scope *scope) { + if (baseCtor.type != FunctionType::eConstructor || baseCtor.argCount() == 0) + return false; + if (baseCtor.isDelete() || baseCtor.access == AccessControl::Private) + return false; + return std::none_of(scope->functionList.cbegin(), scope->functionList.cend(), [&](const Function &func) { + return func.isConstructor() && func.argCount() == baseCtor.argCount() && + func.argsMatch(baseCtor.nestedIn, baseCtor.argDef, func.argDef, "", 0); + }); + }; + + const std::vector &bases = scope->definedType->derivedFrom; + const Token *baseName = nullptr; + const std::list *baseFuncs = nullptr; + for (const Token *tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) { + if (Token::Match(tok, "using %name%")) { + const auto base = std::find_if( + bases.cbegin(), + bases.cend(), + [&tok](const Type::BaseInfo &info) { + return info.name == tok->strAt(1); + } + ); + if (base != bases.cend() && base->type && base->type->classScope) { + baseName = tok->next(); + baseFuncs = &base->type->classScope->functionList; + } + continue; + } + + if (tok->str() == ";") { + baseName = nullptr; + continue; + } + + if (tok->str() == "{") { + baseName = nullptr; + tok = tok->link(); + continue; + } + + if (baseName && Token::Match(tok, "%name% :: %name% ;") && + tok->str() == baseName->str() && tok->strAt(2) == baseName->str() && + std::any_of(baseFuncs->cbegin(), baseFuncs->cend(), [&](const Function &func) { + return isInherited(func, scope); + })) + result.push_back(tok->tokAt(2)); + } + + return result; +} + //--------------------------------------------------------------------------- // ClassCheck: Check that all class constructors are ok. //--------------------------------------------------------------------------- @@ -223,9 +282,11 @@ void CheckClassImpl::constructors() }); }); + const std::vector inheritedCtors = getInheritedConstructors(scope); + // There are no constructors. std::set diagVars; - if (scope->numConstructors == 0 && printStyle && !usedInUnion) { + if (scope->numConstructors == 0 && inheritedCtors.empty() && printStyle && !usedInUnion) { // If there is a private variable, there should be a constructor.. int needInit = 0, haveInit = 0; std::vector uninitVars; @@ -339,6 +400,30 @@ void CheckClassImpl::constructors() } } + if (!inheritedCtors.empty()) { + clearAllVar(usageList); + + for (Usage &usage : usageList) { + if (usage.var->hasDefault()) + usage.init = true; + } + + handleUnionMembers(usageList); + + // Inherited constructors don't initialize members of the derived class + for (const Token *baseCtorTok : inheritedCtors) { + for (const Usage &usage : usageList) { + if (isInitialized(usage, FunctionType::eConstructor)) + continue; + const Variable& var = *usage.var; + if (var.typeScope() && var.typeScope()->numConstructors > 0) + continue; + uninitVarError(baseCtorTok, false, FunctionType::eConstructor, var.scope()->className, var.name(), scope != var.scope(), false, false, true); + diagVars.emplace(&var); + } + } + } + if (scope->numConstructors == 0) { // Mark all variables not used @@ -347,19 +432,25 @@ void CheckClassImpl::constructors() // Variables with default initializers bool hasAnyDefaultInit = false; bool hasAnySelfInit = false; + bool isDefaultConstructible = true; const bool cpp14OrLater = mSettings.standards.cpp >= Standards::CPP14; for (Usage& usage : usageList) { const Variable& var = *usage.var; + // isReference() is also true for a function pointer that returns a reference + const bool isReferenceMember = var.isReference() && var.nameToken() && Token::Match(var.nameToken()->previous(), "&|&&"); // check for C++11 initializer if (var.hasDefault()) { usage.init = true; hasAnyDefaultInit = true; + } else if (!var.isStatic() && (isReferenceMember || (var.isConst() && !var.isClass()))) { + // the default constructor is deleted, so all members are initialized by every instance + isDefaultConstructible = false; } else if (cpp14OrLater && !hasAnySelfInit && isInitialized(usage, FunctionType::eConstructor)) { hasAnySelfInit = true; } } - if (!hasAnyDefaultInit && !hasAnySelfInit) + if (!isDefaultConstructible || (!hasAnyDefaultInit && !hasAnySelfInit)) continue; handleUnionMembers(usageList); @@ -373,6 +464,10 @@ void CheckClassImpl::constructors() if (var.typeScope() && var.typeScope()->numConstructors > 0) continue; + // a const member of class type is default constructed or makes the class not default constructible + if (var.isConst()) + continue; + if (diagVars.count(&var) == 0) uninitVarError(var.nameToken(), false, FunctionType::eConstructor, var.scope()->className, var.name(), false, false, true); } @@ -1172,12 +1267,15 @@ void CheckClassImpl::noExplicitConstructorError(const Token *tok, const std::str reportError(tok, Severity::style, "noExplicitConstructor", "$symbol:" + classname + '\n' + message + '\n' + verbose, CWE398, Certainty::normal); } -void CheckClassImpl::uninitVarError(const Token *tok, bool isprivate, FunctionType functionType, const std::string &classname, const std::string &varname, bool derived, bool inconclusive, bool noCtor) +void CheckClassImpl::uninitVarError(const Token *tok, bool isprivate, FunctionType functionType, const std::string &classname, const std::string &varname, bool derived, bool inconclusive, bool noCtor, bool inheritedCtor) { std::string message("Member variable '$symbol' "); if (noCtor) message += "has no initializer."; - else { + else if (inheritedCtor) { + message += tok ? "is not initialized in the constructor inherited from '" + tok->str() + "'." : + "is not initialized in the inherited constructor."; + } else { message += "is not initialized in the "; if (functionType == FunctionType::eCopyConstructor) message += "copy "; diff --git a/lib/checkclass.h b/lib/checkclass.h index 0aa8fc29da3..74f61ee4705 100644 --- a/lib/checkclass.h +++ b/lib/checkclass.h @@ -182,7 +182,7 @@ class CPPCHECKLIB CheckClassImpl : public CheckImpl { void noCopyConstructorError(const Scope *scope, bool isdefault, const Token *alloc, bool inconclusive); void noOperatorEqError(const Scope *scope, bool isdefault, const Token *alloc, bool inconclusive); void noDestructorError(const Scope *scope, bool isdefault, const Token *alloc); - void uninitVarError(const Token *tok, bool isprivate, FunctionType functionType, const std::string &classname, const std::string &varname, bool derived, bool inconclusive, bool noCtor = false); + void uninitVarError(const Token *tok, bool isprivate, FunctionType functionType, const std::string &classname, const std::string &varname, bool derived, bool inconclusive, bool noCtor = false, bool inheritedCtor = false); void uninitVarError(const Token *tok, const std::string &classname, const std::string &varname); void missingMemberCopyError(const Token *tok, FunctionType functionType, const std::string& classname, const std::string& varname); void operatorEqVarError(const Token *tok, const std::string &classname, const std::string &varname, bool inconclusive); diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index 57c8412cdd9..ad547cf543e 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -1301,6 +1301,10 @@ void CheckConditionImpl::checkIncorrectLogicOperator() if (isfloat && (op1 == "==" || op1 == "!=" || op2 == "==" || op2 == "!=")) continue; + // no double value to compare (1e400L would become infinity) + if (isfloat && (MathLib::isLongDoubleOutOfDoubleRange(value1) || MathLib::isLongDoubleOutOfDoubleRange(value2))) + continue; + // the expr are not the token of the value but they provide better context const double d1 = isfloat ? MathLib::toDoubleNumber(value1) : 0; const double d2 = isfloat ? MathLib::toDoubleNumber(value2) : 0; diff --git a/lib/checkersreport.cpp b/lib/checkersreport.cpp index f2c4a84653f..9779bdd93c6 100644 --- a/lib/checkersreport.cpp +++ b/lib/checkersreport.cpp @@ -129,19 +129,19 @@ void CheckersReport::countCheckers() mActiveCheckersCount = mAllCheckersCount = 0; for (const auto& checkReq: checkers::allCheckers) { - if (mActiveCheckers.count(checkReq.first) > 0) + if (mActiveCheckers().count(checkReq.first) > 0) ++mActiveCheckersCount; ++mAllCheckersCount; } - for (const auto& addonInfo: mSettings.addonInfos) { + for (const auto& addonInfo: mSettings().addonInfos) { for (const auto& checkReq: addonInfo.checkers) { - if (mActiveCheckers.count(checkReq.first) > 0) + if (mActiveCheckers().count(checkReq.first) > 0) ++mActiveCheckersCount; ++mAllCheckersCount; } } - if (mSettings.addons.count("misra")) { + if (mSettings().addons.count("misra")) { const bool doUnusedFunctionOnly = Settings::unusedFunctionOnly(); for (const checkers::MisraInfo& info: checkers::misraC2012Rules) { const std::string rule = std::to_string(info.a) + "." + std::to_string(info.b); @@ -185,7 +185,7 @@ std::string CheckersReport::getReport(const std::string& criticalErrors) const } for (const auto& checkReq: checkers::allCheckers) { const std::string& checker = checkReq.first; - const bool active = mActiveCheckers.count(checkReq.first) > 0; + const bool active = mActiveCheckers().count(checkReq.first) > 0; const std::string& req = checkReq.second; fout << (active ? "Yes " : "No ") << checker; if (!active && !req.empty()) @@ -193,12 +193,12 @@ std::string CheckersReport::getReport(const std::string& criticalErrors) const fout << std::endl; } - for (const auto& addonInfo: mSettings.addonInfos) { + for (const auto& addonInfo: mSettings().addonInfos) { if (addonInfo.checkers.empty()) continue; fout << std::endl << std::endl; std::string title; - if (mSettings.premium && addonInfo.name == "premiumaddon.json") + if (mSettings().premium && addonInfo.name == "premiumaddon.json") title = "Cppcheck Premium"; else { title = addonInfo.name; @@ -217,7 +217,7 @@ std::string CheckersReport::getReport(const std::string& criticalErrors) const for (const auto& checkReq: addonInfo.checkers) { const std::string& checker = checkReq.first; - const bool active = mActiveCheckers.count(checkReq.first) > 0; + const bool active = mActiveCheckers().count(checkReq.first) > 0; const std::string& req = checkReq.second; fout << (active ? "Yes " : "No ") << checker; if (!active && !req.empty()) @@ -238,7 +238,7 @@ std::string CheckersReport::getXmlReport(const std::string& criticalErrors) cons ret += " \n"; ret += " \n"; const int misraCVersion = getMisraCVersion(mSettings); - for (std::string checker: mActiveCheckers) { + for (std::string checker: mActiveCheckers()) { if (checker.compare(0,8,"Misra C:") == 0) checker = "Misra C " + std::to_string(misraCVersion) + ":" + checker.substr(8); ret += " \n"; diff --git a/lib/checkersreport.h b/lib/checkersreport.h index b189a7f1ebd..179653d3d51 100644 --- a/lib/checkersreport.h +++ b/lib/checkersreport.h @@ -20,6 +20,7 @@ #define checkersReportH #include "config.h" +#include "refthunk.h" #include #include @@ -37,8 +38,8 @@ class CPPCHECKLIB CheckersReport { std::string getXmlReport(const std::string& criticalErrors) const; private: - const Settings& mSettings; - const std::set& mActiveCheckers; + RefThunk mSettings; + RefThunk> mActiveCheckers; void countCheckers(); diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 4476814fcbb..1589b3b7dea 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -24,6 +24,7 @@ #include "fwdanalysis.h" #include "library.h" #include "mathlib.h" +#include "refthunk.h" #include "platform.h" #include "settings.h" #include "standards.h" @@ -1783,6 +1784,8 @@ void CheckOtherImpl::checkConstVariable() continue; if (var->isConst()) continue; + if (Tokenizer::isFunctionPointer(var->nameToken())) // reference to function + continue; const Scope* scope = var->scope(); if (!scope) continue; @@ -3528,9 +3531,11 @@ void CheckOtherImpl::redundantCopyError(const Token *tok,const std::string& varn // Checking for shift by negative values //--------------------------------------------------------------------------- -static bool isNegative(const Token *tok, const Settings &settings) +static const ValueFlow::Value* isNegative(const Token *tok, const Settings &settings) { - return tok->valueType() && tok->valueType()->sign == ValueType::SIGNED && tok->getValueLE(-1LL, settings); + if (!tok->valueType() || tok->valueType()->sign != ValueType::SIGNED) + return nullptr; + return tok->getValueLE(-1LL, settings); } void CheckOtherImpl::checkNegativeBitwiseShift() @@ -3566,24 +3571,28 @@ void CheckOtherImpl::checkNegativeBitwiseShift() if (ternary) continue; - // Get negative rhs value. preferably a value which doesn't have 'condition'. - if (portability && isNegative(tok->astOperand1(), mSettings)) - negativeBitwiseShiftError(tok, 1); - else if (isNegative(tok->astOperand2(), mSettings)) - negativeBitwiseShiftError(tok, 2); + const ValueFlow::Value* value = isNegative(tok->astOperand1(), mSettings); // lhs + if (portability && value) + negativeBitwiseShiftError(tok, true, value); + else { + value = isNegative(tok->astOperand2(), mSettings); // rhs + if (value) + negativeBitwiseShiftError(tok, false, value); + } } } -void CheckOtherImpl::negativeBitwiseShiftError(const Token *tok, int op) +void CheckOtherImpl::negativeBitwiseShiftError(const Token *tok, bool isLHS, const ValueFlow::Value* v) { - if (op == 1) - // LHS - this is used by intention in various software, if it - // is used often in a project and works as expected then this is - // a portability issue - reportError(tok, Severity::portability, "shiftNegativeLHS", "Shifting a negative value is technically undefined behaviour", CWE758, Certainty::normal); - else // RHS - reportError(tok, Severity::error, "shiftNegative", "Shifting by a negative value is undefined behaviour", CWE758, Certainty::normal); + // LHS - this is used by intention in various software, if it + // is used often in a project and works as expected then this is + // a portability issue + const char* id = isLHS ? "shiftNegativeLHS" : "shiftNegative"; + const std::string msg = isLHS ? "Shifting a negative value is technically undefined behaviour" : "Shifting by a negative value is undefined behaviour"; + const Severity severity = isLHS ? Severity::portability : (v && v->errorSeverity() && !v->conditional ? Severity::error : Severity::warning); + const ErrorPath errorPath = getErrorPath(tok, v, msg); + reportError(errorPath, severity, id, msg, CWE758, Certainty::normal); } //--------------------------------------------------------------------------- @@ -4221,12 +4230,12 @@ void CheckOtherImpl::funcArgOrderDifferent(const std::string & functionName, reportError(tokens, Severity::warning, "funcArgOrderDifferent", msg, CWE683, Certainty::normal); } -static const Token *findShadowed(const Scope *scope, const Variable& var, int linenr) +static const Token *findShadowed(const Scope *scope, const Variable& var) { if (!scope) return nullptr; for (const Variable &v : scope->varlist) { - if (scope->isExecutable() && v.nameToken()->linenr() > linenr) + if ((scope->isExecutable() || scope->type == ScopeType::eGlobal) && succeeds(v.nameToken(), var.nameToken())) continue; if (v.name() == var.name()) return v.nameToken(); @@ -4240,9 +4249,9 @@ static const Token *findShadowed(const Scope *scope, const Variable& var, int li if (scope->type == ScopeType::eLambda) return nullptr; - const Token* shadowed = findShadowed(scope->nestedIn, var, linenr); + const Token* shadowed = findShadowed(scope->nestedIn, var); if (!shadowed) - shadowed = findShadowed(scope->functionOf, var, linenr); + shadowed = findShadowed(scope->functionOf, var); return shadowed; } @@ -4276,9 +4285,9 @@ void CheckOtherImpl::checkShadowVariables() } } - const Token *shadowed = findShadowed(scope.nestedIn, var, var.nameToken()->linenr()); + const Token *shadowed = findShadowed(scope.nestedIn, var); if (!shadowed) - shadowed = findShadowed(scope.functionOf, var, var.nameToken()->linenr()); + shadowed = findShadowed(scope.functionOf, var); if (!shadowed) return; if (scope.type == ScopeType::eFunction && scope.className == var.name()) @@ -4312,9 +4321,10 @@ void CheckOtherImpl::checkShadowVariables() void CheckOtherImpl::shadowError(const Token *shadows, const std::string &shadowsType, const Token *shadowed, const std::string &shadowedType) { - ErrorPath errorPath; - errorPath.emplace_back(shadowed, "Shadowed " + shadowedType); - errorPath.emplace_back(shadows, "Shadow " + shadowsType); + ErrorPath errorPath{ + {shadowed, "Shadowed " + shadowedType}, + {shadows, "Shadow " + shadowsType} + }; const std::string &varname = shadows ? shadows->str() : shadowsType; const std::string ShadowsType = char(std::toupper(shadowsType[0])) + shadowsType.substr(1); const std::string ShadowedType = char(std::toupper(shadowedType[0])) + shadowedType.substr(1); @@ -4591,7 +4601,7 @@ struct UnionMember { : name(name) , size(size) {} - const std::string &name; + RefThunk name; size_t size; }; @@ -4601,7 +4611,7 @@ struct Union { , name(scope.className) {} const Scope *scope; - const std::string &name; + RefThunk name; std::vector members; const UnionMember *largestMember() const { @@ -4710,7 +4720,7 @@ void CheckOtherImpl::unionZeroInitError(const Token *tok, "Zero initializing union '$symbol' does not guarantee " + "its complete storage to be zero initialized as its largest member " + "is not declared as the first member. Consider making " + - largestMember.name + " the first member or favor memset()."); + largestMember.name() + " the first member or favor memset()."); } //----------------------------------------------------------------------------- @@ -4943,8 +4953,8 @@ void CheckOther::getErrorMessages(ErrorLogger& errorLogger, const Settings &sett c.zerodivError(nullptr, nullptr); c.misusedScopeObjectError(nullptr, "varname"); c.invalidPointerCastError(nullptr, "float *", "double *", false, false); - c.negativeBitwiseShiftError(nullptr, 1); - c.negativeBitwiseShiftError(nullptr, 2); + c.negativeBitwiseShiftError(nullptr, true); + c.negativeBitwiseShiftError(nullptr, false); c.raceAfterInterlockedDecrementError(nullptr); c.invalidFreeError(nullptr, "malloc", false); c.overlappingWriteUnion(nullptr); diff --git a/lib/checkother.h b/lib/checkother.h index 823a5783fb3..61a865e9ab6 100644 --- a/lib/checkother.h +++ b/lib/checkother.h @@ -310,7 +310,7 @@ class CPPCHECKLIB CheckOtherImpl : public CheckImpl { void unsignedPositiveError(const Token *tok, const ValueFlow::Value *v, const std::string &varname); void pointerPositiveError(const Token *tok, const ValueFlow::Value *v); void suspiciousSemicolonError(const Token *tok); - void negativeBitwiseShiftError(const Token *tok, int op); + void negativeBitwiseShiftError(const Token *tok, bool isLHS, const ValueFlow::Value *v = nullptr); void redundantCopyError(const Token *tok, const std::string &varname); void incompleteArrayFillError(const Token* tok, const std::string& buffer, const std::string& function, bool boolean); void varFuncNullUBError(const Token *tok); diff --git a/lib/checkstl.cpp b/lib/checkstl.cpp index aa08725430a..a4e8a92c188 100644 --- a/lib/checkstl.cpp +++ b/lib/checkstl.cpp @@ -22,6 +22,7 @@ #include "errortypes.h" #include "library.h" #include "mathlib.h" +#include "refthunk.h" #include "pathanalysis.h" #include "settings.h" #include "standards.h" @@ -2884,7 +2885,7 @@ namespace { private: const Token* mBodyTok; const Token* mLoopVar{}; - const Settings& mSettings; + RefThunk mSettings; std::set mVarsChanged; public: @@ -2907,7 +2908,7 @@ namespace { int n = 1 + (astIsPointer(tok) ? 1 : 0); for (int i = 0; i < n; i++) { bool inconclusive = false; - if (isVariableChangedByFunctionCall(tok, i, mSettings.library, &inconclusive)) + if (isVariableChangedByFunctionCall(tok, i, mSettings().library, &inconclusive)) return true; if (inconclusive) return true; diff --git a/lib/checkunusedvar.cpp b/lib/checkunusedvar.cpp index 26368064c63..2add1e6eebc 100644 --- a/lib/checkunusedvar.cpp +++ b/lib/checkunusedvar.cpp @@ -1009,7 +1009,7 @@ void CheckUnusedVarImpl::checkFunctionVariableUsage_iterateScopes(const Scope* c const Token * const equal = skipBracketsAndMembers(tok->next()); // checked for chained assignments - if (tok != start && equal && equal->str() == "=") { + if (tok != start && (Token::simpleMatch(equal, "=") || (start->astParent() && Token::simpleMatch(start->astParent()->astParent(), "=")))) { const nonneg int varId = tok->varId(); const Variables::VariableUsage * const var = variables.find(varId); diff --git a/lib/clangimport.cpp b/lib/clangimport.cpp index 495f01cdff4..0043f5a3cde 100644 --- a/lib/clangimport.cpp +++ b/lib/clangimport.cpp @@ -20,6 +20,7 @@ #include "errortypes.h" #include "mathlib.h" +#include "refthunk.h" #include "standards.h" #include "symboldatabase.h" #include "token.h" @@ -241,8 +242,8 @@ namespace clangimport { , mSymbolDatabase(symbolDatabase) {} - const Settings &mSettings; - SymbolDatabase &mSymbolDatabase; + RefThunk mSettings; + RefThunk mSymbolDatabase; int enumValue = 0; @@ -336,7 +337,10 @@ namespace clangimport { public: AstNode(std::string nodeType, const std::string &ext, Data *data) : nodeType(std::move(nodeType)), mExtTokens(splitString(ext)), mData(data) - {} + { + if (mExtTokens.empty()) + throw InternalError(nullptr, "invalid AST node: " + this->nodeType, InternalError::AST); + } std::string nodeType; std::vector children; @@ -662,7 +666,7 @@ const ::Type * clangimport::AstNode::addTypeTokens(TokenList &tokenList, const s for (const Token *typeToken = tokenList.back(); Token::Match(typeToken, "&|*|%name%"); typeToken = typeToken->previous()) { if (!typeToken->isName()) continue; - const ::Type *recordType = scope->symdb.findVariableType(scope, typeToken); + const ::Type *recordType = scope->symdb().findVariableType(scope, typeToken); if (recordType) { const_cast(typeToken)->type(recordType); return recordType; @@ -691,7 +695,7 @@ void clangimport::AstNode::addFullScopeNameTokens(TokenList &tokenList, const Sc const Scope *clangimport::AstNode::getNestedInScope(TokenList &tokenList) { if (!tokenList.back()) - return &mData->mSymbolDatabase.scopeList.front(); + return &mData->mSymbolDatabase().scopeList.front(); if (tokenList.back()->str() == "}" && mData->mNotScope.find(tokenList.back()) == mData->mNotScope.end()) return tokenList.back()->scope()->nestedIn; return tokenList.back()->scope(); @@ -1052,7 +1056,10 @@ Token *clangimport::AstNode::createTokens(TokenList &tokenList) return nullptr; } if (nodeType == EnumConstantDecl) { - Token *nameToken = addtoken(tokenList, getSpelling()); + const std::string name = getSpelling(); + if (name.empty()) + throw InternalError(nullptr, "invalid AST node: " + nodeType, InternalError::AST); + Token *nameToken = addtoken(tokenList, name); auto *scope = const_cast(nameToken->scope()); scope->enumeratorList.emplace_back(nameToken->scope()); Enumerator *e = &scope->enumeratorList.back(); @@ -1090,8 +1097,8 @@ Token *clangimport::AstNode::createTokens(TokenList &tokenList) const_cast(enumscope->bodyEnd)->deletePrevious(); // Create enum type - mData->mSymbolDatabase.typeList.emplace_back(enumtok, enumscope, enumtok->scope()); - enumscope->definedType = &mData->mSymbolDatabase.typeList.back(); + mData->mSymbolDatabase().typeList.emplace_back(enumtok, enumscope, enumtok->scope()); + enumscope->definedType = &mData->mSymbolDatabase().typeList.back(); if (nametok) const_cast(enumtok->scope())->definedTypesMap[nametok->str()] = enumscope->definedType; @@ -1262,8 +1269,8 @@ Token *clangimport::AstNode::createTokens(TokenList &tokenList) } Scope *recordScope = createScope(tokenList, ScopeType::eStruct, children, classDef); - mData->mSymbolDatabase.typeList.emplace_back(classDef, recordScope, classDef->scope()); - recordScope->definedType = &mData->mSymbolDatabase.typeList.back(); + mData->mSymbolDatabase().typeList.emplace_back(classDef, recordScope, classDef->scope()); + recordScope->definedType = &mData->mSymbolDatabase().typeList.back(); if (!recordName.empty()) { recordScope->className = recordName; const_cast(classDef->scope())->definedTypesMap[recordName] = recordScope->definedType; @@ -1388,6 +1395,10 @@ Token * clangimport::AstNode::createTokensCall(TokenList &tokenList) void clangimport::AstNode::createTokensFunctionDecl(TokenList &tokenList) { + // an address-only node has no name: addtoken("") adds nothing and would return a null back() + const std::string name = getSpelling(); + if (name.empty()) + throw InternalError(nullptr, "invalid AST node: " + nodeType, InternalError::AST); const bool prev = contains(mExtTokens, "prev"); const bool hasBody = !children.empty() && children.back()->nodeType == CompoundStmt; const bool isStatic = contains(mExtTokens, "static"); @@ -1409,11 +1420,14 @@ void clangimport::AstNode::createTokensFunctionDecl(TokenList &tokenList) if (mExtTokens.size() > 4 && mExtTokens[1] == "parent") addFullScopeNameTokens(tokenList, mData->getScope(mExtTokens[2])); - Token *nameToken = addtoken(tokenList, getSpelling() + getTemplateParameters()); + Token *nameToken = addtoken(tokenList, name + getTemplateParameters()); auto *nestedIn = const_cast(nameToken->scope()); if (prev) { - const std::string addr = *(std::find(mExtTokens.cbegin(), mExtTokens.cend(), "prev") + 1); + const auto it = std::find(mExtTokens.cbegin(), mExtTokens.cend(), "prev"); + if (it + 1 == mExtTokens.cend()) + throw InternalError(nullptr, "invalid AST node: " + nodeType, InternalError::AST); + const std::string addr = *(it + 1); mData->ref(addr, nameToken); } if (!nameToken->function()) { @@ -1460,6 +1474,9 @@ void clangimport::AstNode::createTokensFunctionDecl(TokenList &tokenList) AstNodePtr child = children[i]; if (child->nodeType != ParmVarDecl) continue; + // there must be a token between the address and the type + if (child->mExtTokens.size() < 3) + throw InternalError(nullptr, "invalid AST node: " + child->nodeType, InternalError::AST); if (tokenList.back() != par1) addtoken(tokenList, ","); const Type *recordType = addTypeTokens(tokenList, child->mExtTokens.back(), nestedIn); @@ -1546,8 +1563,8 @@ void clangimport::AstNode::createTokensForCXXRecord(TokenList &tokenList) const std::string addr = mExtTokens[0]; mData->scopeDecl(addr, scope); scope->className = className; - mData->mSymbolDatabase.typeList.emplace_back(classToken, scope, classToken->scope()); - scope->definedType = &mData->mSymbolDatabase.typeList.back(); + mData->mSymbolDatabase().typeList.emplace_back(classToken, scope, classToken->scope()); + scope->definedType = &mData->mSymbolDatabase().typeList.back(); const_cast(classToken->scope())->definedTypesMap[className] = scope->definedType; } addtoken(tokenList, ";"); @@ -1562,6 +1579,9 @@ Token * clangimport::AstNode::createTokensVarDecl(TokenList &tokenList) int typeIndex = mExtTokens.size() - 1; while (typeIndex > 1 && std::isalpha(mExtTokens[typeIndex][0])) typeIndex--; + // there must be a name token between the address and the type + if (typeIndex < 2) + throw InternalError(nullptr, "invalid AST node: " + nodeType, InternalError::AST); const std::string type = mExtTokens[typeIndex]; const std::string name = mExtTokens[typeIndex - 1]; const Token *startToken = tokenList.back(); diff --git a/lib/cppcheck.vcxproj b/lib/cppcheck.vcxproj index 553392c53c2..6957309e40f 100644 --- a/lib/cppcheck.vcxproj +++ b/lib/cppcheck.vcxproj @@ -166,6 +166,7 @@ + diff --git a/lib/errorlogger.h b/lib/errorlogger.h index 4b62d1b3218..fa5ad67c7c1 100644 --- a/lib/errorlogger.h +++ b/lib/errorlogger.h @@ -23,6 +23,7 @@ #include "config.h" #include "errortypes.h" +#include "refthunk.h" #include #include @@ -320,7 +321,7 @@ class CPPCHECKLIB ProgressReporter { ~ProgressReporter() { if (mReportProgressInterval < 0) return; - mErrorLogger.reportProgress(mFilename, mStage.c_str(), 100); + mErrorLogger().reportProgress(mFilename, mStage.c_str(), 100); } void report(int value) { @@ -328,17 +329,17 @@ class CPPCHECKLIB ProgressReporter { return; const std::time_t t = std::time(nullptr); if (t >= mLastTime + mReportProgressInterval) { - mErrorLogger.reportProgress(mFilename, mStage.c_str(), value); + mErrorLogger().reportProgress(mFilename, mStage.c_str(), value); mLastTime = t; mLastValue = value; } } private: - ErrorLogger& mErrorLogger; - const int mReportProgressInterval; - const std::string mFilename; - const std::string mStage; + RefThunk mErrorLogger; + int mReportProgressInterval; + std::string mFilename; + std::string mStage; std::time_t mLastTime{0}; int mLastValue{-1}; }; diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index 3398d2fe723..88cee242c8c 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -24,6 +24,7 @@ #include "errorlogger.h" #include "errortypes.h" #include "mathlib.h" +#include "refthunk.h" #include "settings.h" #include "symboldatabase.h" #include "token.h" @@ -50,9 +51,9 @@ namespace { : analyzer(analyzer), tokenList(tokenList), errorLogger(errorLogger), settings(settings) {} ValuePtr analyzer; - const TokenList& tokenList; - ErrorLogger& errorLogger; - const Settings& settings; + RefThunk tokenList; + RefThunk errorLogger; + RefThunk settings; Analyzer::Action actions; bool analyzeOnly{}; bool analyzeTerminate{}; @@ -148,7 +149,7 @@ namespace { traverseRecursive(tok->astOperand2(), f, traverseUnknown); traverseRecursive(tok->astOperand1(), f, traverseUnknown); return Break(Analyzer::Terminate::Escape); - } else if (Token::Match(tok, "%name% (") && isEscapeFunction(tok, settings.library)) { + } else if (Token::Match(tok, "%name% (") && isEscapeFunction(tok, settings().library)) { // Traverse the parameters of the function before escaping traverseRecursive(tok->next()->astOperand2(), f, traverseUnknown); return Break(Analyzer::Terminate::Escape); @@ -356,7 +357,7 @@ namespace { bool isEscapeScope(const Token* endBlock, bool& unknown) const { const Token* ftok = nullptr; - const bool r = isReturnScope(endBlock, settings.library, &ftok); + const bool r = isReturnScope(endBlock, settings().library, &ftok); if (!r && ftok) unknown = true; return r; @@ -721,9 +722,9 @@ namespace { } } else if (tok->isControlFlowKeyword() && Token::Match(tok, "if|while|for (") && Token::simpleMatch(tok->linkAt(1), ") {")) { - if ((settings.vfOptions.maxForwardBranches > 0) && (++branchCount > settings.vfOptions.maxForwardBranches)) { + if ((settings().vfOptions.maxForwardBranches > 0) && (++branchCount > settings().vfOptions.maxForwardBranches)) { // TODO: should be logged on function-level instead of file-level - if (settings.severity.isEnabled(Severity::information)) { + if (settings().severity.isEnabled(Severity::information)) { reportError(Severity::information, "normalCheckLevelMaxBranches", "Limiting analysis of branches. Use --check-level=exhaustive to analyze all branches."); } return Break(Analyzer::Terminate::Bail); @@ -825,8 +826,8 @@ namespace { // Carry the then-fork forward, unless a limit is hit - then only the linear main // path continues (no bail). forkDepth bounds nesting, forkBudget total. <0 = off. assert(forkBudget != nullptr); - const int forkDepthLimit = settings.vfOptions.maxForwardConditionForkDepth; - const int forkBudgetLimit = settings.vfOptions.maxForwardConditionForks; + const int forkDepthLimit = settings().vfOptions.maxForwardConditionForkDepth; + const int forkBudgetLimit = settings().vfOptions.maxForwardConditionForks; const bool depthOk = forkDepthLimit < 0 || forkDepth < forkDepthLimit; const bool budgetOk = forkBudgetLimit < 0 || *forkBudget < forkBudgetLimit; if (pThen != Progress::Break && !thenBranch.isEscape() && depthOk && budgetOk) { @@ -918,10 +919,10 @@ namespace { return Progress::Continue; } - void reportError(Severity severity, const std::string& id, const std::string& msg) { - ErrorMessage::FileLocation loc(tokenList.getSourceFilePath(), 0, 0); - const ErrorMessage errmsg({std::move(loc)}, tokenList.getSourceFilePath(), severity, msg, id, Certainty::normal); - errorLogger.reportErr(errmsg); + void reportError(Severity severity, const std::string& id, const std::string& msg) const { + ErrorMessage::FileLocation loc(tokenList().getSourceFilePath(), 0, 0); + const ErrorMessage errmsg({std::move(loc)}, tokenList().getSourceFilePath(), severity, msg, id, Certainty::normal); + errorLogger().reportErr(errmsg); } static bool isFunctionCall(const Token* tok) diff --git a/lib/fwdanalysis.cpp b/lib/fwdanalysis.cpp index 07ba7cc2e59..7b7987e2e91 100644 --- a/lib/fwdanalysis.cpp +++ b/lib/fwdanalysis.cpp @@ -293,7 +293,7 @@ FwdAnalysis::Result FwdAnalysis::checkRecursive(const Token *expr, const Token * while (argnr < args.size() && args[argnr] != parent) argnr++; if (argnr < args.size()) { - if (mSettings.library.getArgDirection(ftok->astOperand1(), argnr + 1, /*indirect*/ 1) == Library::ArgumentChecks::Direction::DIR_OUT) + if (mSettings().library.getArgDirection(ftok->astOperand1(), argnr + 1, /*indirect*/ 1) == Library::ArgumentChecks::Direction::DIR_OUT) continue; } } diff --git a/lib/fwdanalysis.h b/lib/fwdanalysis.h index e8e27e576b5..b57e36ba34b 100644 --- a/lib/fwdanalysis.h +++ b/lib/fwdanalysis.h @@ -22,6 +22,7 @@ //--------------------------------------------------------------------------- #include "config.h" +#include "refthunk.h" #include #include @@ -77,7 +78,7 @@ class FwdAnalysis { Result check(const Token *expr, const Token *startToken, const Token *endToken) const; Result checkRecursive(const Token *expr, const Token *startToken, const Token *endToken, const std::set &exprVarIds, bool local, bool inInnerClass, int depth=0) const; - const Settings &mSettings; + RefThunk mSettings; enum class What : std::uint8_t { Reassign, UnusedValue } mWhat = What::Reassign; }; diff --git a/lib/importproject.cpp b/lib/importproject.cpp index 24597834694..a53760c1a32 100644 --- a/lib/importproject.cpp +++ b/lib/importproject.cpp @@ -1406,9 +1406,12 @@ std::string ImportProject::applyMSBuildStaticFunction(const std::string &classNa // Format a double as an integer string when the value is whole, // otherwise use std::to_string (which gives 6 decimal places). const auto fmtDouble = [](double d) -> std::string { - const auto i = static_cast(d); - if (!(static_cast(i) < d) && !(static_cast(i) > d)) - return std::to_string(i); + // Converting a double outside the long long range is undefined behaviour + if (d >= static_cast(LLONG_MIN) && d < -static_cast(LLONG_MIN)) { + const auto i = static_cast(d); + if (!(static_cast(i) < d) && !(static_cast(i) > d)) + return std::to_string(i); + } return std::to_string(d); }; if (args.size() == 1) { @@ -1425,16 +1428,14 @@ std::string ImportProject::applyMSBuildStaticFunction(const std::string &classNa // not round-half-away-from-zero. const double fl = std::floor(x); const double frac = x - fl; - long long rounded; + double rounded; if (frac < 0.5) - rounded = static_cast(fl); + rounded = fl; else if (frac > 0.5) - rounded = static_cast(fl) + 1; - else { // exactly 0.5 -- round to nearest even integer - const auto ifl = static_cast(fl); - rounded = ((ifl % 2) == 0) ? ifl : ifl + 1; - } - return std::to_string(rounded); + rounded = fl + 1; + else // exactly 0.5 -- round to nearest even integer + rounded = (std::fabs(std::fmod(fl, 2.0)) < 1) ? fl : fl + 1; + return fmtDouble(rounded); } if (caseInsensitiveStringCompare(member, "Sqrt") == 0 && x >= 0) return fmtDouble(std::sqrt(x)); @@ -1553,6 +1554,8 @@ struct ImportProject::PropertyValueExpander { PropertyValueExpander(ImportProject &project, const PropertiesMap &vars, std::string str, bool unknownAsEmpty = false) : mProject(project), mVars(vars), mStr(std::move(str)), mUnknownAsEmpty(unknownAsEmpty) {} + PropertyValueExpander(const PropertyValueExpander &) = delete; + PropertyValueExpander &operator=(const PropertyValueExpander &) = delete; bool hasValue(const std::string &name) const { if (mVars.count(name)) @@ -2356,6 +2359,8 @@ class ImportProject::ConditionParser { public: ConditionParser(ImportProject &project, const std::string &condition, const PropertiesMap &properties) : mProject(project), mCondition(condition), mVariables(properties) {} + ConditionParser(const ConditionParser &) = delete; + ConditionParser &operator=(const ConditionParser &) = delete; bool parse() { const std::string value = parseOr(); @@ -3141,6 +3146,8 @@ namespace { , thisFileFullPath(properties["MSBuildThisFileFullPath"]) { setMSBuildThis(filename, properties); } + MSBuildThis(const MSBuildThis &) = delete; + MSBuildThis &operator=(const MSBuildThis &) = delete; static void setMSBuildThis(const std::string &filename, PropertiesMap &properties) { // Normalize once so all subsequent path ops can assume '/' separators. @@ -3174,6 +3181,8 @@ namespace { explicit DiscoveringGuard(bool &flag) : mFlag(flag) { mFlag = true; } + DiscoveringGuard(const DiscoveringGuard &) = delete; + DiscoveringGuard &operator=(const DiscoveringGuard &) = delete; ~DiscoveringGuard() { mFlag = false; @@ -3186,6 +3195,8 @@ namespace { ImportStackGuard(std::unordered_set &stack, std::string key) : mStack(stack), mKey(std::move(key)) {} + ImportStackGuard(const ImportStackGuard &) = delete; + ImportStackGuard &operator=(const ImportStackGuard &) = delete; ~ImportStackGuard() { mStack.erase(mKey); @@ -3204,6 +3215,8 @@ namespace { : mCurrent(current), mPrev(current) { mCurrent = std::move(next); } + CurrentFileGuard(const CurrentFileGuard &) = delete; + CurrentFileGuard &operator=(const CurrentFileGuard &) = delete; ~CurrentFileGuard() { mCurrent = std::move(mPrev); diff --git a/lib/mathlib.cpp b/lib/mathlib.cpp index c7c055899fd..9aba7118858 100644 --- a/lib/mathlib.cpp +++ b/lib/mathlib.cpp @@ -532,8 +532,15 @@ double MathLib::toDoubleNumber(const std::string &str, const Token * const tok) std::istringstream istr(str); istr.imbue(std::locale::classic()); double ret; - if (!(istr >> ret)) - throw InternalError(tok, "Internal Error. MathLib::toDoubleNumber: conversion failed: " + str); + if (!(istr >> ret)) { + // Out of the range of double, such as 1e10000 (glibc's HUGE_VAL for + // compilers other than GCC): the stream stores the largest finite + // value and fails, a compiler makes it infinity. + if (!isFloat(str) || std::fabs(ret) < std::numeric_limits::max()) + throw InternalError(tok, "Internal Error. MathLib::toDoubleNumber: conversion failed: " + str); + ret = std::copysign(std::numeric_limits::infinity(), ret); + istr.clear(); + } std::string s; if (istr >> s) { if (isDecimalFloat(str)) @@ -584,6 +591,13 @@ bool MathLib::isFloat(const std::string &str) return isDecimalFloat(str) || isFloatHex(str); } +bool MathLib::isLongDoubleOutOfDoubleRange(const std::string &str) +{ + if (str.empty() || (str.back() != 'l' && str.back() != 'L') || !isFloat(str)) + return false; + return std::isinf(toDoubleNumber(str)); +} + bool MathLib::isDecimalFloat(const std::string &str) { if (str.empty()) diff --git a/lib/mathlib.h b/lib/mathlib.h index 84338b5ce70..bfa1a5b877b 100644 --- a/lib/mathlib.h +++ b/lib/mathlib.h @@ -115,6 +115,8 @@ class CPPCHECKLIB MathLib { static bool isInt(const std::string & str); static bool isFloat(const std::string &str); + /** @brief a long double literal out of the range of double, such as 1e400L, which toDoubleNumber() makes infinity */ + static bool isLongDoubleOutOfDoubleRange(const std::string &str); static bool isDecimalFloat(const std::string &str); static bool isNegative(const std::string &str); static bool isPositive(const std::string &str); diff --git a/lib/preprocessor.cpp b/lib/preprocessor.cpp index 0a0acecab1a..c14eaf813ad 100644 --- a/lib/preprocessor.cpp +++ b/lib/preprocessor.cpp @@ -1114,22 +1114,29 @@ void Preprocessor::dump(std::ostream &out) const std::size_t Preprocessor::calculateHash(const std::string &toolinfo) const { std::string hashData = toolinfo; - for (const simplecpp::Token *tok = mTokens.cfront(); tok; tok = tok->next) { - if (!tok->comment) { - hashData += tok->str(); - hashData += static_cast(tok->location.line); - hashData += static_cast(tok->location.col); - } - } - for (const auto &filedata : mFileCache) { - for (const simplecpp::Token *tok = filedata->tokens.cfront(); tok; tok = tok->next) { + const auto addTokens = [&hashData](const simplecpp::TokenList &tokens) { + for (const simplecpp::Token *tok = tokens.cfront(); tok; tok = tok->next) { if (!tok->comment) { hashData += tok->str(); hashData += static_cast(tok->location.line); hashData += static_cast(tok->location.col); } } - } + }; + addTokens(mTokens); + + // Hash the included files in a fixed order, the order they are loaded in differs between runs + std::vector fileData; + fileData.reserve(mFileCache.size()); + std::transform(mFileCache.cbegin(), mFileCache.cend(), std::back_inserter(fileData), [](const std::unique_ptr &data) { + return data.get(); + }); + std::sort(fileData.begin(), fileData.end(), [](const simplecpp::FileData *a, const simplecpp::FileData *b) { + return a->filename < b->filename; + }); + for (const simplecpp::FileData *data : fileData) + addTokens(data->tokens); + return (std::hash{})(hashData); } diff --git a/lib/preprocessor.h b/lib/preprocessor.h index 91a0b7e7d37..5df52934dfc 100644 --- a/lib/preprocessor.h +++ b/lib/preprocessor.h @@ -105,6 +105,8 @@ class CPPCHECKLIB WARN_UNUSED Preprocessor { static char macroChar; Preprocessor(simplecpp::TokenList& tokens, const Settings& settings, ErrorLogger &errorLogger, Standards::Language lang); + Preprocessor(const Preprocessor &) = delete; + Preprocessor &operator=(const Preprocessor &) = delete; void inlineSuppressions(SuppressionList &suppressions) const; @@ -182,7 +184,7 @@ class CPPCHECKLIB WARN_UNUSED Preprocessor { simplecpp::TokenList& mTokens; const Settings& mSettings; - ErrorLogger &mErrorLogger; + ErrorLogger& mErrorLogger; simplecpp::FileDataCache mFileCache; diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index 142385ac641..0d84dc053a8 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -23,6 +23,7 @@ #include "infer.h" #include "library.h" #include "mathlib.h" +#include "refthunk.h" #include "settings.h" #include "standards.h" #include "symboldatabase.h" @@ -588,7 +589,7 @@ ProgramMemoryState::FindChangedFn ProgramMemoryState::getCachedFindExpressionCha // variable follows the same path) and memoizes those evals in evalCache for the closure's lifetime. using EvalCache = std::map>; const std::shared_ptr cache = changedCache; - const Settings* const sp = &settings; + const Settings* const sp = &settings(); ProgramMemory snapshot = state; const std::shared_ptr evalCache = skipDeadCode ? std::make_shared() : nullptr; return [cache, sp, snapshot, skipDeadCode, evalCache](const Token* expr, @@ -1358,7 +1359,7 @@ static void pruneConditions(std::vector& conds, namespace { struct Executor { ProgramMemory* pm; - const Settings& settings; + RefThunk settings; // Values tracked by the forward/reverse analysis. A tracked value is the authoritative // current value of its expression and takes precedence over the program memory. const ProgramMemory::Map* vars = nullptr; @@ -1762,7 +1763,7 @@ namespace { BuiltinLibraryFunction lf = getBuiltinLibraryFunction(ftok->str()); if (lf) return lf(args); - const std::string& returnValue = settings.library.returnValue(ftok); + const std::string& returnValue = settings().library.returnValue(ftok); if (!returnValue.empty()) { std::unordered_map arg_map; int argn = 0; diff --git a/lib/programmemory.h b/lib/programmemory.h index de81d0bc901..f3133a53c31 100644 --- a/lib/programmemory.h +++ b/lib/programmemory.h @@ -21,6 +21,7 @@ #include "config.h" #include "mathlib.h" +#include "refthunk.h" #include "vfvalue.h" // needed for alias #include @@ -179,7 +180,7 @@ struct ProgramMemoryState { ProgramMemory state; std::map origins; - const Settings& settings; + RefThunk settings; // Memoized findExpressionChanged() pre-filter; structural, so never invalidated. std::shared_ptr changedCache; diff --git a/lib/refthunk.h b/lib/refthunk.h new file mode 100644 index 00000000000..5b2e4d0d5c0 --- /dev/null +++ b/lib/refthunk.h @@ -0,0 +1,61 @@ +/* -*- C++ -*- + * Cppcheck - A tool for static C/C++ code analysis + * Copyright (C) 2007-2026 Cppcheck team. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +//--------------------------------------------------------------------------- +#ifndef refthunkH +#define refthunkH +//--------------------------------------------------------------------------- + +#include + +/** + * Reference wrapper whose operator() returns the referenced object. + * + * It is constructed from a reference and converts implicitly back to one + * (like std::reference_wrapper), so it can replace a reference data member + * without changing the constructor or call sites that pass the member to + * functions taking T&. Unlike a reference member it is copyable and + * assignable; assignment rebinds it. + */ +template +struct RefThunk { + RefThunk() = delete; + + // cppcheck-suppress noExplicitConstructor + // NOLINTNEXTLINE(google-explicit-constructor) + constexpr RefThunk(T& t) noexcept : mPtr(std::addressof(t)) {} + RefThunk(T&& t) = delete; + + constexpr T& operator()() const noexcept { + return *mPtr; + } + + constexpr T& get() const noexcept { + return *mPtr; + } + + // NOLINTNEXTLINE(google-explicit-constructor) + constexpr operator T&() const noexcept { + return *mPtr; + } + +private: + T* mPtr; +}; + +#endif diff --git a/lib/reverseanalyzer.cpp b/lib/reverseanalyzer.cpp index 0c3c966f2b2..d6e9480adb7 100644 --- a/lib/reverseanalyzer.cpp +++ b/lib/reverseanalyzer.cpp @@ -23,6 +23,7 @@ #include "errortypes.h" #include "forwardanalyzer.h" #include "mathlib.h" +#include "refthunk.h" #include "settings.h" #include "symboldatabase.h" #include "token.h" @@ -41,9 +42,9 @@ namespace { : analyzer(analyzer), tokenlist(tokenlist), errorLogger(errorLogger), settings(settings) {} ValuePtr analyzer; - const TokenList& tokenlist; - ErrorLogger& errorLogger; - const Settings& settings; + RefThunk tokenlist; + RefThunk errorLogger; + RefThunk settings; std::pair evalCond(const Token* tok) const { std::vector result = analyzer->evaluate(tok); @@ -265,7 +266,7 @@ namespace { // Assignment to } else if (lhsAction.matches() && !assignTok->astOperand2()->hasKnownIntValue() && assignTok->astOperand2()->exprId() > 0 && - isConstExpression(assignTok->astOperand2(), settings.library)) { + isConstExpression(assignTok->astOperand2(), settings().library)) { const std::string info = "Assignment to '" + assignTok->expressionString() + "'"; ValuePtr a = analyzer->reanalyze(assignTok->astOperand2(), info); if (a) { diff --git a/lib/suppressions.cpp b/lib/suppressions.cpp index c3569e40d85..0089510c86f 100644 --- a/lib/suppressions.cpp +++ b/lib/suppressions.cpp @@ -32,7 +32,6 @@ #include // std::isdigit, std::isalnum, etc #include #include -#include // std::bind, std::placeholders #include #include #include @@ -325,14 +324,27 @@ std::string SuppressionList::addSuppressionLine(const std::string &line) } } +SuppressionList::Suppression *SuppressionList::findSameParameters(const Suppression &suppression) +{ + const std::vector *candidates = &mNonHashSuppressions; + if (suppression.hash > 0) { + const auto it = mHashSuppressions.find(suppression.hash); + if (it == mHashSuppressions.end()) + return nullptr; + candidates = &it->second; + } + const auto found = std::find_if(candidates->cbegin(), candidates->cend(), [&](const Suppression *s) { + return suppression.isSameParameters(*s); + }); + return found != candidates->cend() ? *found : nullptr; +} + std::string SuppressionList::addSuppression(SuppressionList::Suppression suppression) { std::lock_guard lg(mSuppressionsSync); // Check if suppression is already in list - auto foundSuppression = std::find_if(mSuppressions.begin(), mSuppressions.end(), - std::bind(&Suppression::isSameParameters, &suppression, std::placeholders::_1)); - if (foundSuppression != mSuppressions.end()) { + if (findSameParameters(suppression)) { return "suppression '" + suppression.toString() + "' already exists"; } @@ -356,6 +368,12 @@ std::string SuppressionList::addSuppression(SuppressionList::Suppression suppres mSuppressions.push_back(std::move(suppression)); + Suppression *const added = &mSuppressions.back(); + if (added->hash > 0) + mHashSuppressions[added->hash].push_back(added); + else + mNonHashSuppressions.push_back(added); + return ""; } @@ -374,9 +392,8 @@ bool SuppressionList::updateSuppressionState(const SuppressionList::Suppression& std::lock_guard lg(mSuppressionsSync); // Check if suppression is already in list - auto foundSuppression = std::find_if(mSuppressions.begin(), mSuppressions.end(), - std::bind(&Suppression::isSameParameters, &suppression, std::placeholders::_1)); - if (foundSuppression != mSuppressions.end()) { + Suppression *const foundSuppression = findSameParameters(suppression); + if (foundSuppression) { if (suppression.checked) foundSuppression->checked = true; if (suppression.matched) @@ -525,13 +542,21 @@ bool SuppressionList::isSuppressed(const SuppressionList::ErrorMessage &errmsg, // TODO: handle unmatchedPolyspaceSuppression? const bool unmatchedSuppression(errmsg.errorId == "unmatchedSuppression"); bool returnValue = false; - for (Suppression &s : mSuppressions) { - if (!global && !s.isLocal()) - continue; - if (unmatchedSuppression && s.errorId != errmsg.errorId) - continue; - if (s.isMatch(errmsg)) - returnValue = true; + const auto match = [&](const std::vector &suppressions) { + for (Suppression *s : suppressions) { + if (!global && !s->isLocal()) + continue; + if (unmatchedSuppression && s->errorId != errmsg.errorId) + continue; + if (s->isMatch(errmsg)) + returnValue = true; + } + }; + match(mNonHashSuppressions); + if (errmsg.hash != 0) { + const auto it = mHashSuppressions.find(errmsg.hash); + if (it != mHashSuppressions.end()) + match(it->second); } return returnValue; } @@ -540,13 +565,21 @@ bool SuppressionList::isSuppressedExplicitly(const SuppressionList::ErrorMessage { std::lock_guard lg(mSuppressionsSync); - for (Suppression &s : mSuppressions) { - if (!global && !s.isLocal()) - continue; - if (s.errorId != errmsg.errorId) // Error id must match exactly - continue; - if (s.isMatch(errmsg)) - return true; + const auto match = [&](const std::vector &suppressions) { + return std::any_of(suppressions.cbegin(), suppressions.cend(), [&](Suppression *s) { + if (!global && !s->isLocal()) + return false; + if (s->errorId != errmsg.errorId) // Error id must match exactly + return false; + return s->isMatch(errmsg); + }); + }; + if (match(mNonHashSuppressions)) + return true; + if (errmsg.hash != 0) { + const auto it = mHashSuppressions.find(errmsg.hash); + if (it != mHashSuppressions.end()) + return match(it->second); } return false; } @@ -687,7 +720,9 @@ void SuppressionList::markUnmatchedInlineSuppressionsAsChecked(const TokenList & if (currFileIdx != tok->fileIndex() || currLineNr != tok->linenr()) { currLineNr = tok->linenr(); currFileIdx = tok->fileIndex(); - for (auto &suppression : mSuppressions) { + // checked is not used for hash suppressions + for (Suppression *s : mNonHashSuppressions) { + Suppression &suppression = *s; if (suppression.type == SuppressionList::Type::unique) { if (!suppression.checked && (suppression.lineNumber == currLineNr) && (suppression.fileName == tokenlist.file(tok))) { suppression.checked = true; diff --git a/lib/suppressions.h b/lib/suppressions.h index ef5f9c4e405..42955ab7b91 100644 --- a/lib/suppressions.h +++ b/lib/suppressions.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -51,14 +52,14 @@ class CPPCHECKLIB SuppressionList { }; struct CPPCHECKLIB ErrorMessage { - std::size_t hash; + std::size_t hash{}; std::string errorId; void setFileName(std::string s); const std::string &getFileName() const { return mFileName; } - int lineNumber; // TODO: need to be unsigned - Certainty certainty; + int lineNumber{}; // TODO: need to be unsigned + Certainty certainty{}; std::string symbolNames; std::set macroNames; @@ -294,9 +295,20 @@ class CPPCHECKLIB SuppressionList { void markUnmatchedInlineSuppressionsAsChecked(const TokenList &tokenlist); private: + /** + * @brief Find a suppression with the same parameters. mSuppressionsSync must be locked. + * @param suppression the suppression to look for + * @return the found suppression, or nullptr + */ + Suppression *findSameParameters(const Suppression &suppression); + mutable std::mutex mSuppressionsSync; /** @brief List of error which the user doesn't want to see. */ std::list mSuppressions; + /** @brief Suppressions in mSuppressions with hash > 0, indexed by hash */ + std::unordered_map> mHashSuppressions; + /** @brief Suppressions in mSuppressions with hash == 0 */ + std::vector mNonHashSuppressions; }; struct Suppressions diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index c1cd75f2e00..78fd044cc7b 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -917,7 +917,8 @@ void SymbolDatabase::createSymbolDatabaseCopyAndMoveConstructors() continue; const Variable* firstArg = func->getArgumentVar(0); - if (firstArg->type() == scope.definedType) { + // skip references to functions: Foo(Foo& (&f)()) + if (firstArg->type() == scope.definedType && !Token::Match(firstArg->typeEndToken(), "&|&& %name%| ) (")) { if (firstArg->isRValueReference()) func->type = FunctionType::eMoveConstructor; else if (firstArg->isReference() && !firstArg->isPointer()) @@ -2596,6 +2597,10 @@ void Variable::evaluate(const Settings& settings) } else if (tok->str() == "&&") { // Before simplification, && isn't split up setFlag(fIsRValueRef, true); setFlag(fIsReference, true); // Set also fIsReference + } else if (tok->str() == "(" && Token::simpleMatch(tok->link(), ") (")) { + // a reference before the parentheses belongs to the return type of a function pointer: int& (*f)() + setFlag(fIsRValueRef, false); + setFlag(fIsReference, false); } if (tok->str() == "<" && tok->link()) @@ -3031,10 +3036,10 @@ static bool typesMatch( const Token *&new_second) { // get first type - const Type* first_type = first_scope->symdb.findType(first_token, first_scope, /*lookOutside*/ true); + const Type* first_type = first_scope->symdb().findType(first_token, first_scope, /*lookOutside*/ true); if (first_type) { // get second type - const Type* second_type = second_scope->symdb.findType(second_token, second_scope, /*lookOutside*/ true); + const Type* second_type = second_scope->symdb().findType(second_token, second_scope, /*lookOutside*/ true); // check if types match if (first_type == second_type) { const Token* tok1 = first_token; @@ -3830,7 +3835,7 @@ const Token *Type::initBaseInfo(const Token *tok, const Token *tok1) } } - const Type * baseType = classScope->symdb.findType(base.nameTok, enclosingScope); + const Type * baseType = classScope->symdb().findType(base.nameTok, enclosingScope); if (baseType && !baseType->findDependency(this)) base.type = baseType; @@ -4691,7 +4696,7 @@ void SymbolDatabase::printXml(std::ostream &out) const static const Type* findVariableTypeIncludingUsedNamespaces(const Scope* scope, const Token* typeTok) { - const Type* argType = scope->symdb.findVariableType(scope, typeTok); + const Type* argType = scope->symdb().findVariableType(scope, typeTok); if (argType) return argType; @@ -4699,7 +4704,7 @@ static const Type* findVariableTypeIncludingUsedNamespaces(const Scope* scope, c while (scope) { for (const Scope::UsingInfo &ui : scope->usingList) { if (ui.scope) { - argType = scope->symdb.findVariableType(ui.scope, typeTok); + argType = scope->symdb().findVariableType(ui.scope, typeTok); if (argType) return argType; } @@ -4772,7 +4777,7 @@ void Function::addArguments(const Scope *scope) while (Token::Match(typeTok, "const|volatile|enum|struct|::")) typeTok = typeTok->next(); if (Token::Match(typeTok, ",|)")) { // #8333 - scope->symdb.mTokenizer.syntaxError(typeTok); + scope->symdb().mTokenizer.syntaxError(typeTok); } if (Token::Match(typeTok, "%type% <") && Token::Match(typeTok->linkAt(1), "> :: %type%")) typeTok = typeTok->linkAt(1)->tokAt(2); @@ -4791,7 +4796,7 @@ void Function::addArguments(const Scope *scope) endTok = nameTok->previous(); if (hasBody()) - scope->symdb.debugMessage(nameTok, "varid0", "Function::addArguments found argument \'" + nameTok->str() + "\' with varid 0."); + scope->symdb().debugMessage(nameTok, "varid0", "Function::addArguments found argument \'" + nameTok->str() + "\' with varid 0."); } else endTok = typeTok; } else @@ -4822,7 +4827,7 @@ void Function::addArguments(const Scope *scope) if (startTok == nameTok) break; - argumentList.emplace_back(nameTok, startTok, endTok, count++, AccessControl::Argument, argType, functionScope, scope->symdb.mSettings); + argumentList.emplace_back(nameTok, startTok, endTok, count++, AccessControl::Argument, argType, functionScope, scope->symdb().mSettings); if (tok->str() == ")") { // check for a variadic function or a variadic template function @@ -5066,7 +5071,7 @@ void Scope::addVariable(const Token *token_, const Token *start_, const Token *e // keep possible size_t -> int truncation outside emplace_back() to have a single line // C4267 VC++ warning instead of several dozens lines const int varIndex = varlist.size(); - varlist.emplace_back(token_, start_, end_, varIndex, access_, type_, scope_, scope_->symdb.mSettings); + varlist.emplace_back(token_, start_, end_, varIndex, access_, type_, scope_, scope_->symdb().mSettings); } // Get variable list.. @@ -5079,7 +5084,7 @@ void Scope::getVariableList() // global scope else if (type == ScopeType::eGlobal) - getVariableList(symdb.mTokenizer.tokens(), nullptr); + getVariableList(symdb().mTokenizer.tokens(), nullptr); // forward declaration else @@ -5224,7 +5229,7 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess) const Token *typestart = tok; // C++17 structured bindings - if (tok && tok->isCpp() && (symdb.mSettings.standards.cpp >= Standards::CPP17) && Token::Match(tok, "auto &|&&| [")) { + if (tok && tok->isCpp() && (symdb().mSettings.standards.cpp >= Standards::CPP17) && Token::Match(tok, "auto &|&&| [")) { const Token *typeend = Token::findsimplematch(typestart, "[")->previous(); for (tok = typeend->tokAt(2); Token::Match(tok, "%name%|,"); tok = tok->next()) { if (tok->varId()) @@ -5250,7 +5255,7 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess) if (vartok->varId() == 0) { if (!vartok->isBoolean()) - symdb.debugMessage(vartok, "varid0", "Scope::checkVariable found variable \'" + vartok->str() + "\' with varid 0."); + symdb().debugMessage(vartok, "varid0", "Scope::checkVariable found variable \'" + vartok->str() + "\' with varid 0."); return tok; } @@ -5276,7 +5281,7 @@ const Token *Scope::checkVariable(const Token *tok, AccessControl varaccess) } if (Token::Match(tok2, ", %name%")) { if (tok2->next()->varId() == 0) { - symdb.debugMessage(tok2->next(), "varid0", "Scope::checkVariable found variable \'" + tok2->strAt(1) + "\' with varid 0."); + symdb().debugMessage(tok2->next(), "varid0", "Scope::checkVariable found variable \'" + tok2->strAt(1) + "\' with varid 0."); return tok; } addVariable(tok2->next(), typestart, vartok->previous(), varaccess, vType, this); @@ -5366,7 +5371,7 @@ bool Scope::isVariableDeclaration(const Token* const tok, const Token*& vartok, if (isCPP && Token::Match(tok, "throw|new")) return false; - const bool isCPP11 = isCPP && symdb.mSettings.standards.cpp >= Standards::CPP11; + const bool isCPP11 = isCPP && symdb().mSettings.standards.cpp >= Standards::CPP11; if (isCPP11 && tok->str() == "using") return false; @@ -7668,7 +7673,7 @@ static const Token* parsedecl(const Token* type, valuetype->container = container; } else { const Scope *scope = type->scope(); - valuetype->typeScope = scope->symdb.findScope(typeTokens.front(), scope); + valuetype->typeScope = scope->symdb().findScope(typeTokens.front(), scope); if (valuetype->typeScope) valuetype->type = (scope->type == ScopeType::eClass) ? ValueType::Type::RECORD : ValueType::Type::NONSTD; } @@ -9050,5 +9055,5 @@ void SymbolDatabase::getErrorMessages(ErrorLogger& /*errorLogger*/) { // TODO //SymbolDatabase symdb; - //symdb.returnImplicitIntError(nullptr); + //symdb().returnImplicitIntError(nullptr); } diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 08c5382929e..832bcddeab3 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -25,6 +25,7 @@ #include "errortypes.h" #include "library.h" #include "mathlib.h" +#include "refthunk.h" #include "sourcelocation.h" #include "token.h" #include "utils.h" @@ -1045,7 +1046,7 @@ class CPPCHECKLIB Scope { Scope(const SymbolDatabase &symdb_, const Token *classDef_, const Scope *nestedIn_); Scope(const SymbolDatabase &symdb_, const Token *classDef_, const Scope *nestedIn_, ScopeType type_, const Token *start_); - const SymbolDatabase& symdb; + RefThunk symdb; std::string className; const Token* classDef{}; ///< class/struct/union/namespace token const Token* bodyStart{}; ///< '{' token @@ -1349,6 +1350,8 @@ class CPPCHECKLIB SymbolDatabase { public: explicit SymbolDatabase(Tokenizer& tokenizer); ~SymbolDatabase(); + SymbolDatabase(const SymbolDatabase &) = delete; + SymbolDatabase &operator=(const SymbolDatabase &) = delete; /** @brief Information about all namespaces/classes/structures */ std::list scopeList; @@ -1518,8 +1521,8 @@ class CPPCHECKLIB SymbolDatabase { std::list checkedFuncs) const; Tokenizer& mTokenizer; - const Settings &mSettings; - ErrorLogger &mErrorLogger; + const Settings& mSettings; + ErrorLogger& mErrorLogger; /** variable symbol table */ std::vector mVariableList; diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index c636cf72c43..c59fdf288f7 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -71,7 +71,7 @@ namespace { return tokenAndName.token() == mToken; } private: - const Token * const mToken; + const Token * mToken; }; class FindName { @@ -81,7 +81,7 @@ namespace { return tokenAndName.name() == mName; } private: - const std::string mName; + std::string mName; }; class FindFullName { @@ -91,7 +91,7 @@ namespace { return tokenAndName.fullName() == mFullName; } private: - const std::string mFullName; + std::string mFullName; }; } @@ -281,7 +281,7 @@ TemplateSimplifier::TemplateSimplifier(Tokenizer &tokenizer) mErrorLogger(mTokenizer.getErrorLogger()) {} -void TemplateSimplifier::checkComplicatedSyntaxErrorsInTemplates() +void TemplateSimplifier::checkComplicatedSyntaxErrorsInTemplates() const { // check for more complicated syntax errors when using templates.. for (const Token *tok = mTokenList.front(); tok; tok = tok->next()) { @@ -394,13 +394,14 @@ unsigned int TemplateSimplifier::templateParameters(const Token *tok) return 0; if (tok->str() != "<") return 0; - if (Token::Match(tok->previous(), "%var% <")) + if (Token::Match(tok->previous(), "%var%|) <") && !(tok->linkAt(-1) && Token::simpleMatch(tok->linkAt(-1)->tokAt(-1), "operator"))) return 0; tok = tok->next(); if (!tok || tok->str() == ">") return 0; unsigned int level = 0; + unsigned int ternaryLevel = 0; while (tok) { // skip template template @@ -460,8 +461,16 @@ unsigned int TemplateSimplifier::templateParameters(const Token *tok) } // Skip '=', '?', ':' - if (Token::Match(tok, "=|?|:")) + if (Token::Match(tok, "=|?|:")) { + if (tok->str()[0] == '?') + ++ternaryLevel; + else if (tok->str()[0] == ':') { + if (ternaryLevel == 0) + return 0; + --ternaryLevel; + } tok = tok->next(); + } if (!tok) return 0; @@ -2724,7 +2733,7 @@ static bool validTokenEnd(bool bounded, const Token *tok, const Token *backToken // TODO: This is not the correct class for simplifyCalculations(), so it // should be moved away. -bool TemplateSimplifier::simplifyCalculations(Token* frontToken, const Token *backToken, bool isTemplate) +bool TemplateSimplifier::simplifyCalculations(Token* frontToken, const Token *backToken, bool isTemplate) const { bool ret = false; const bool bounded = frontToken || backToken; diff --git a/lib/templatesimplifier.h b/lib/templatesimplifier.h index 3c5fed3ea1c..3dc8b6bf1fd 100644 --- a/lib/templatesimplifier.h +++ b/lib/templatesimplifier.h @@ -47,6 +47,8 @@ struct newInstantiation; class CPPCHECKLIB TemplateSimplifier { public: explicit TemplateSimplifier(Tokenizer &tokenizer); + TemplateSimplifier(const TemplateSimplifier &) = delete; + TemplateSimplifier &operator=(const TemplateSimplifier &) = delete; const std::string& dump() const { return mDump; @@ -58,7 +60,7 @@ class CPPCHECKLIB TemplateSimplifier { /** */ - void checkComplicatedSyntaxErrorsInTemplates(); + void checkComplicatedSyntaxErrorsInTemplates() const; /** * is the token pointing at a template parameters block @@ -333,7 +335,7 @@ class CPPCHECKLIB TemplateSimplifier { * @return true if modifications to token-list are done. * false if no modifications are done. */ - bool simplifyCalculations(Token* frontToken = nullptr, const Token *backToken = nullptr, bool isTemplate = true); + bool simplifyCalculations(Token* frontToken = nullptr, const Token *backToken = nullptr, bool isTemplate = true) const; /** Simplify template instantiation arguments. * @param start first token of arguments @@ -504,10 +506,10 @@ class CPPCHECKLIB TemplateSimplifier { const std::string &indent = " ") const; void printOut(const std::string &text = "") const; - Tokenizer &mTokenizer; - TokenList &mTokenList; - const Settings &mSettings; - ErrorLogger &mErrorLogger; + Tokenizer& mTokenizer; + TokenList& mTokenList; + const Settings& mSettings; + ErrorLogger& mErrorLogger; bool mChanged{}; std::list mTemplateDeclarations; diff --git a/lib/token.h b/lib/token.h index fd4804ec980..3df24a86cb6 100644 --- a/lib/token.h +++ b/lib/token.h @@ -60,7 +60,7 @@ struct ReferenceToken; struct ScopeInfo2 { ScopeInfo2(std::string name_, const Token *bodyEnd_, std::set usingNamespaces_ = std::set()) : name(std::move(name_)), bodyEnd(bodyEnd_), usingNamespaces(std::move(usingNamespaces_)) {} std::string name; - const Token* const bodyEnd{}; + const Token* bodyEnd{}; std::set usingNamespaces; }; diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 1d5b7436405..8dc552c55f8 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -70,10 +70,10 @@ namespace { VarIdScopeInfo(bool isExecutable, bool isStructInit, bool isEnum, nonneg int startVarid) : isExecutable(isExecutable), isStructInit(isStructInit), isEnum(isEnum), startVarid(startVarid) {} - const bool isExecutable{}; - const bool isStructInit{}; - const bool isEnum{}; - const nonneg int startVarid{}; + bool isExecutable{}; + bool isStructInit{}; + bool isEnum{}; + nonneg int startVarid{}; }; } @@ -3632,7 +3632,7 @@ bool Tokenizer::simplifyTokens1(const std::string &configuration, int fileIndex) //--------------------------------------------------------------------------- -void Tokenizer::findComplicatedSyntaxErrorsInTemplates() +void Tokenizer::findComplicatedSyntaxErrorsInTemplates() const { validate(); mTemplateSimplifier->checkComplicatedSyntaxErrorsInTemplates(); @@ -9427,8 +9427,15 @@ void Tokenizer::simplifyFunctionTryCatch() if (!Token::Match(tok, "try {|:")) continue; const Token* par = tok->previous(); - while (par && par->isKeyword()) + while (par && !Token::Match(par, "[);]")) { + if (par->str() == ">") { + if (const Token* ob = par->findOpeningBracket()) { + par = ob; + continue; + } + } par = par->previous(); + } if (!TokenList::isFunctionHead(par, "try")) // TODO: this is supposed to a list of characters and not strings continue; diff --git a/lib/tokenize.h b/lib/tokenize.h index f7f6ddbecae..36f4e48c751 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -327,7 +327,7 @@ class CPPCHECKLIB Tokenizer { void checkForEnumsWithTypedef(); - void findComplicatedSyntaxErrorsInTemplates(); + void findComplicatedSyntaxErrorsInTemplates() const; protected: /** diff --git a/lib/tokenlist.cpp b/lib/tokenlist.cpp index 26b24d649c8..ee10b8b4887 100644 --- a/lib/tokenlist.cpp +++ b/lib/tokenlist.cpp @@ -2379,7 +2379,7 @@ const Token * TokenList::isFunctionHead(const Token *tok, const std::string &suf tok = tok->linkAt(1)->next(); if (Token::Match(tok, "%name% (") && tok->isUpperCaseName()) tok = tok->linkAt(1)->next(); - if (tok && tok->originalName() == "->") { // trailing return type + if (tok && (tok->str() == "->" || tok->originalName() == "->")) { // trailing return type for (tok = tok->next(); tok && !Token::Match(tok, ";|{|override|final|}|)|]"); tok = tok->next()) if (tok->link() && Token::Match(tok, "<|[|(")) tok = tok->link(); diff --git a/lib/tokenlist.h b/lib/tokenlist.h index f5b652f3506..e2cbb1b3cb7 100644 --- a/lib/tokenlist.h +++ b/lib/tokenlist.h @@ -228,6 +228,7 @@ class CPPCHECKLIB TokenList { std::vector mOrigFiles; /** settings */ + // NOLINTNEXTLINE(cppcoreguidelines-avoid-const-or-ref-data-members) - TokenList is move-only const Settings& mSettings; /** File is known to be C/C++ code */ diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 96c2ba24159..4be7a13dbc7 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -89,6 +89,7 @@ #include "infer.h" #include "library.h" #include "mathlib.h" +#include "refthunk.h" #include "path.h" #include "platform.h" #include "programmemory.h" @@ -691,57 +692,6 @@ static void valueFlowArray(TokenList& tokenlist, const Settings& settings) } } -static bool isNonZero(const Token* tok) -{ - return tok && (!tok->hasKnownIntValue() || tok->getKnownIntValue() != 0); -} - -static const Token* getOtherOperand(const Token* tok) -{ - if (!tok) - return nullptr; - if (!tok->astParent()) - return nullptr; - if (tok->astParent()->astOperand1() != tok) - return tok->astParent()->astOperand1(); - if (tok->astParent()->astOperand2() != tok) - return tok->astParent()->astOperand2(); - return nullptr; -} - -static void valueFlowArrayBool(TokenList& tokenlist, const Settings& settings) -{ - for (Token* tok = tokenlist.front(); tok; tok = tok->next()) { - if (tok->hasKnownIntValue()) - continue; - const Variable* var = nullptr; - bool known = false; - const auto val = - std::find_if(tok->values().cbegin(), tok->values().cend(), std::mem_fn(&ValueFlow::Value::isTokValue)); - if (val == tok->values().end()) { - var = tok->variable(); - known = true; - } else { - var = val->tokvalue->variable(); - known = val->isKnown(); - } - if (!var) - continue; - if (!var->isArray() || var->isArgument() || var->getTypeName() == "std::array") - continue; - if (isNonZero(getOtherOperand(tok)) && Token::Match(tok->astParent(), "%comp%")) - continue; - // TODO: Check for function argument - if ((astIsBool(tok->astParent()) && !Token::Match(tok->astParent(), "(|%name%")) || - (tok->astParent() && Token::Match(tok->astParent()->previous(), "if|while|for ("))) { - ValueFlow::Value value{1}; - if (known) - value.setKnown(); - setTokenValue(tok, std::move(value), settings); - } - } -} - static void valueFlowArrayElement(TokenList& tokenlist, const Settings& settings) { for (Token* tok = tokenlist.front(); tok; tok = tok->next()) { @@ -7302,10 +7252,10 @@ struct ValueFlowState { : tokenlist(tokenlist), symboldatabase(symboldatabase), errorLogger(errorLogger), settings(settings) {} - TokenList& tokenlist; - SymbolDatabase& symboldatabase; - ErrorLogger& errorLogger; - const Settings& settings; + RefThunk tokenlist; + RefThunk symboldatabase; + RefThunk errorLogger; + RefThunk settings; std::set skippedFunctions; }; @@ -7341,31 +7291,31 @@ struct ValueFlowPassRunner { bool run(std::initializer_list> passes) const { std::size_t values = 0; - std::size_t n = state.settings.vfOptions.maxIterations; - const bool doProgress = state.settings.reportProgress >= 0; + std::size_t n = state.settings().vfOptions.maxIterations; + const bool doProgress = state.settings().reportProgress >= 0; while (n > 0 && values != getTotalValues()) { values = getTotalValues(); - const std::size_t passnum = state.settings.vfOptions.maxIterations - n + 1; + const std::size_t passnum = state.settings().vfOptions.maxIterations - n + 1; const std::string passnum_s = std::to_string(passnum); if (std::any_of(passes.begin(), passes.end(), [&](const ValuePtr& pass) { // the string concatination is a hot spot in TestIO::testScanfArgument and TestIO::testPrintfArgumentVariables std::string stage = doProgress ? std::string("ValueFlow::") + pass->name() + (' ' + passnum_s) : ""; - ProgressReporter progressReporter(state.errorLogger, state.settings.reportProgress, state.tokenlist.getSourceFilePath(), std::move(stage)); + ProgressReporter progressReporter(state.errorLogger, state.settings().reportProgress, state.tokenlist().getSourceFilePath(), std::move(stage)); return run(pass, passnum); })) return true; --n; } - if (state.settings.debugwarnings) { + if (state.settings().debugwarnings) { if (n == 0 && values != getTotalValues()) { - ErrorMessage::FileLocation loc(state.tokenlist.getFiles()[0], 0, 0); + ErrorMessage::FileLocation loc(state.tokenlist().getFiles()[0], 0, 0); ErrorMessage errmsg({std::move(loc)}, "", Severity::debug, "ValueFlow maximum iterations exceeded", "valueFlowMaxIterations", Certainty::normal); - state.errorLogger.reportErr(errmsg); + state.errorLogger().reportErr(errmsg); } } return false; @@ -7378,7 +7328,7 @@ struct ValueFlowPassRunner { // TODO: add bailout message return true; } - if (!state.tokenlist.isCPP() && pass->cpp()) + if (!state.tokenlist().isCPP() && pass->cpp()) return false; if (timerResults) { std::string name = pass->name(); @@ -7397,15 +7347,15 @@ struct ValueFlowPassRunner { std::size_t getTotalValues() const { std::size_t n = 1; - for (Token* tok = state.tokenlist.front(); tok; tok = tok->next()) + for (Token* tok = state.tokenlist().front(); tok; tok = tok->next()) n += tok->values().size(); return n; } void setSkippedFunctions() { - if (state.settings.vfOptions.maxIfCount > 0) { - for (const Scope* functionScope : state.symboldatabase.functionScopes) { + if (state.settings().vfOptions.maxIfCount > 0) { + for (const Scope* functionScope : state.symboldatabase().functionScopes) { int countIfScopes = 0; std::vector scopes{functionScope}; while (!scopes.empty()) { @@ -7417,22 +7367,22 @@ struct ValueFlowPassRunner { ++countIfScopes; } } - if (countIfScopes > state.settings.vfOptions.maxIfCount) { + if (countIfScopes > state.settings().vfOptions.maxIfCount) { state.skippedFunctions.emplace(functionScope); - if (state.settings.severity.isEnabled(Severity::information)) { + if (state.settings().severity.isEnabled(Severity::information)) { const std::string& functionName = functionScope->className; std::list callstack( 1, - ErrorMessage::FileLocation(functionScope->bodyStart, &state.tokenlist)); + ErrorMessage::FileLocation(functionScope->bodyStart, &state.tokenlist())); const ErrorMessage errmsg(std::move(callstack), - state.tokenlist.getSourceFilePath(), + state.tokenlist().getSourceFilePath(), Severity::information, "Limiting ValueFlow analysis in function '" + functionName + "' since it is too complex. " "Please specify --check-level=exhaustive to perform full analysis.", "checkLevelNormal", // TODO: use more specific ID Certainty::normal); - state.errorLogger.reportErr(errmsg); + state.errorLogger().reportErr(errmsg); } } } @@ -7441,8 +7391,8 @@ struct ValueFlowPassRunner { void setStopTime() { - if (state.settings.vfOptions.maxTime >= 0) - stop = Clock::now() + std::chrono::seconds{state.settings.vfOptions.maxTime}; + if (state.settings().vfOptions.maxTime >= 0) + stop = Clock::now() + std::chrono::seconds{state.settings().vfOptions.maxTime}; } ValueFlowState state; @@ -7540,7 +7490,6 @@ void ValueFlow::setValues(TokenList& tokenlist, VFA(valueFlowSymbolicOperators(symboldatabase, settings)), VFA(valueFlowCondition(SymbolicConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions)), VFA(valueFlowSymbolicInfer(symboldatabase, settings)), - VFA(valueFlowArrayBool(tokenlist, settings)), VFA(valueFlowArrayElement(tokenlist, settings)), VFA(valueFlowRightShift(tokenlist, settings)), VFA_CPP( diff --git a/lib/vf_analyzers.cpp b/lib/vf_analyzers.cpp index b2ef2abe1ea..27c27934f31 100644 --- a/lib/vf_analyzers.cpp +++ b/lib/vf_analyzers.cpp @@ -24,6 +24,7 @@ #include "config.h" #include "library.h" #include "mathlib.h" +#include "refthunk.h" #include "programmemory.h" #include "smallvector.h" #include "settings.h" @@ -59,10 +60,10 @@ static bool isDereferenceOp(const Token* tok) } struct ValueFlowAnalyzer : Analyzer { - const Settings& settings; + RefThunk settings; ProgramMemoryState pms; - explicit ValueFlowAnalyzer(const Settings& s) : settings(s), pms(settings) {} + explicit ValueFlowAnalyzer(const Settings& s) : settings(s), pms(s) {} virtual const ValueFlow::Value* getValue(const Token* tok) const = 0; virtual ValueFlow::Value* getValue(const Token* tok) = 0; @@ -357,7 +358,7 @@ struct ValueFlowAnalyzer : Analyzer { if (dst) { const size_t sz = dst->getSizeOf(settings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointer); if (sz > 0 && sz < sizeof(MathLib::biguint)) { - MathLib::bigint newvalue = ValueFlow::truncateIntValue(value->intvalue, sz, dst, settings.platform); + MathLib::bigint newvalue = ValueFlow::truncateIntValue(value->intvalue, sz, dst, settings().platform); /* Handle overflow/underflow for value bounds */ if (value->bound != ValueFlow::Value::Bound::Point) { @@ -1325,7 +1326,7 @@ struct ExpressionAnalyzer : SingleValueFlowAnalyzer { } void setupExprVarIds(const Token* start, int depth = 0) { - if (depth > settings.vfOptions.maxExprVarIdDepth) { + if (depth > settings().vfOptions.maxExprVarIdDepth) { // TODO: add bailout message return; } @@ -1561,7 +1562,7 @@ struct ContainerExpressionAnalyzer : ExpressionAnalyzer { if (action == Library::Container::Action::PUSH || action == Library::Container::Action::POP || action == Library::Container::Action::APPEND) { // TODO: handle more actions? std::vector args = getArguments(tok->tokAt(3)); bool isVariadic = false; - if (const Library::Function* libFunc = settings.library.getFunction(tok->tokAt(2))) { + if (const Library::Function* libFunc = settings().library.getFunction(tok->tokAt(2))) { const auto& argChecks = libFunc->argumentChecks; isVariadic = argChecks.find(-1) != argChecks.end() && argChecks.at(-1).variadic; } @@ -1609,7 +1610,7 @@ struct ContainerExpressionAnalyzer : ExpressionAnalyzer { case Library::Container::Action::APPEND: { std::vector args = getArguments(tok->astParent()->tokAt(2)); if (args.size() == 1) // TODO: handle overloads - n = ValueFlow::valueFlowGetStrLength(tok->astParent()->tokAt(3), settings.library); + n = ValueFlow::valueFlowGetStrLength(tok->astParent()->tokAt(3), settings().library); if (n == 0) // TODO: handle known empty append val->setPossible(); break; diff --git a/lib/vf_common.cpp b/lib/vf_common.cpp index b1cabcc9201..9b1d0387f38 100644 --- a/lib/vf_common.cpp +++ b/lib/vf_common.cpp @@ -139,12 +139,16 @@ namespace ValueFlow // Bad character literal } } else if (tok->isNumber() && MathLib::isFloat(tok->str())) { - Value value; - value.valueType = Value::ValueType::FLOAT; - value.floatValue = MathLib::toDoubleNumber(tok); - if (!tok->isTemplateArg()) - value.setKnown(); - setTokenValue(tok, std::move(value), settings); + // A long double literal out of the range of double (1e400L) has no + // double value: infinity would make different literals compare equal. + if (!MathLib::isLongDoubleOutOfDoubleRange(tok->str())) { + Value value; + value.valueType = Value::ValueType::FLOAT; + value.floatValue = MathLib::toDoubleNumber(tok); + if (!tok->isTemplateArg()) + value.setKnown(); + setTokenValue(tok, std::move(value), settings); + } } else if (tok->enumerator() && tok->enumerator()->value_known) { Value value(tok->enumerator()->value); if (!tok->isTemplateArg()) diff --git a/lib/vf_settokenvalue.cpp b/lib/vf_settokenvalue.cpp index 21bfbbe2da2..c4d32691422 100644 --- a/lib/vf_settokenvalue.cpp +++ b/lib/vf_settokenvalue.cpp @@ -256,7 +256,7 @@ namespace ValueFlow // Ensure that the comma isn't a function call if (!callParent || (!Token::Match(callParent->previous(), "%name%|> (") && !Token::simpleMatch(callParent, "{") && (!Token::Match(callParent, "( %name%") || settings.library.isNotLibraryFunction(callParent->next())) && - !(callParent->str() == "(" && (Token::simpleMatch(callParent->astOperand1(), "*") || Token::Match(callParent->astOperand1(), "%name%|("))))) { + !(callParent->str() == "(" && Token::Match(callParent->astOperand1(), "%name%|(|[|*|.")))) { setTokenValue(parent, std::move(value), settings); return; } diff --git a/oss-fuzz/Makefile b/oss-fuzz/Makefile index 7413910834f..5b8a1d159d4 100644 --- a/oss-fuzz/Makefile +++ b/oss-fuzz/Makefile @@ -153,43 +153,43 @@ simplecpp.o: ../externals/simplecpp/simplecpp.cpp ../externals/simplecpp/simplec tinyxml2.o: ../externals/tinyxml2/tinyxml2.cpp ../externals/tinyxml2/tinyxml2.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -w -D_LARGEFILE_SOURCE -c -o $@ ../externals/tinyxml2/tinyxml2.cpp -$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkuninitvar.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/programmemory.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyzers.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h +$(libcppdir)/valueflow.o: ../lib/valueflow.cpp ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkuninitvar.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/forwardanalyzer.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/programmemory.h ../lib/refthunk.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyzers.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/valueflow.cpp -$(libcppdir)/tokenize.o: ../lib/tokenize.cpp ../externals/simplecpp/simplecpp.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/tokenize.o: ../lib/tokenize.cpp ../externals/simplecpp/simplecpp.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/tokenize.cpp -$(libcppdir)/symboldatabase.o: ../lib/symboldatabase.cpp ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/keywords.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/symboldatabase.o: ../lib/symboldatabase.cpp ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/keywords.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/symboldatabase.cpp $(libcppdir)/addoninfo.o: ../lib/addoninfo.cpp ../externals/picojson/picojson.h ../lib/addoninfo.h ../lib/config.h ../lib/json.h ../lib/path.h ../lib/standards.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/addoninfo.cpp -$(libcppdir)/analyzerinfo.o: ../lib/analyzerinfo.cpp ../externals/tinyxml2/tinyxml2.h ../lib/analyzerinfo.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/standards.h ../lib/utils.h ../lib/xml.h +$(libcppdir)/analyzerinfo.o: ../lib/analyzerinfo.cpp ../externals/tinyxml2/tinyxml2.h ../lib/analyzerinfo.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/refthunk.h ../lib/standards.h ../lib/utils.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/analyzerinfo.cpp -$(libcppdir)/astutils.o: ../lib/astutils.cpp ../lib/astutils.h ../lib/check.h ../lib/checkclass.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/findtoken.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vfvalue.h +$(libcppdir)/astutils.o: ../lib/astutils.cpp ../lib/astutils.h ../lib/check.h ../lib/checkclass.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/findtoken.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/astutils.cpp -$(libcppdir)/check64bit.o: ../lib/check64bit.cpp ../lib/check.h ../lib/check64bit.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/check64bit.o: ../lib/check64bit.cpp ../lib/check.h ../lib/check64bit.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/check64bit.cpp -$(libcppdir)/checkassert.o: ../lib/checkassert.cpp ../lib/astutils.h ../lib/check.h ../lib/checkassert.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkassert.o: ../lib/checkassert.cpp ../lib/astutils.h ../lib/check.h ../lib/checkassert.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkassert.cpp -$(libcppdir)/checkautovariables.o: ../lib/checkautovariables.cpp ../lib/astutils.h ../lib/check.h ../lib/checkautovariables.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkautovariables.o: ../lib/checkautovariables.cpp ../lib/astutils.h ../lib/check.h ../lib/checkautovariables.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkautovariables.cpp -$(libcppdir)/checkbool.o: ../lib/checkbool.cpp ../lib/astutils.h ../lib/check.h ../lib/checkbool.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkbool.o: ../lib/checkbool.cpp ../lib/astutils.h ../lib/check.h ../lib/checkbool.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbool.cpp -$(libcppdir)/checkbufferoverrun.o: ../lib/checkbufferoverrun.cpp ../externals/tinyxml2/tinyxml2.h ../lib/astutils.h ../lib/check.h ../lib/checkbufferoverrun.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_common.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/checkbufferoverrun.o: ../lib/checkbufferoverrun.cpp ../externals/tinyxml2/tinyxml2.h ../lib/astutils.h ../lib/check.h ../lib/checkbufferoverrun.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_common.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkbufferoverrun.cpp -$(libcppdir)/checkclass.o: ../lib/checkclass.cpp ../externals/tinyxml2/tinyxml2.h ../lib/astutils.h ../lib/check.h ../lib/checkclass.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/checkclass.o: ../lib/checkclass.cpp ../externals/tinyxml2/tinyxml2.h ../lib/astutils.h ../lib/check.h ../lib/checkclass.h ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkclass.cpp -$(libcppdir)/checkcondition.o: ../lib/checkcondition.cpp ../lib/astutils.h ../lib/check.h ../lib/checkcondition.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkother.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkcondition.o: ../lib/checkcondition.cpp ../lib/astutils.h ../lib/check.h ../lib/checkcondition.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkother.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkcondition.cpp $(libcppdir)/checkers.o: ../lib/checkers.cpp ../lib/checkers.h ../lib/config.h @@ -198,79 +198,79 @@ $(libcppdir)/checkers.o: ../lib/checkers.cpp ../lib/checkers.h ../lib/config.h $(libcppdir)/checkersidmapping.o: ../lib/checkersidmapping.cpp ../lib/checkers.h ../lib/config.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkersidmapping.cpp -$(libcppdir)/checkersreport.o: ../lib/checkersreport.cpp ../lib/addoninfo.h ../lib/checkers.h ../lib/checkersreport.h ../lib/config.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/standards.h ../lib/utils.h +$(libcppdir)/checkersreport.o: ../lib/checkersreport.cpp ../lib/addoninfo.h ../lib/checkers.h ../lib/checkersreport.h ../lib/config.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/standards.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkersreport.cpp -$(libcppdir)/checkexceptionsafety.o: ../lib/checkexceptionsafety.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkexceptionsafety.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkexceptionsafety.o: ../lib/checkexceptionsafety.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkexceptionsafety.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkexceptionsafety.cpp -$(libcppdir)/checkfunctions.o: ../lib/checkfunctions.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkfunctions.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkfunctions.o: ../lib/checkfunctions.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkfunctions.h ../lib/checkimpl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkfunctions.cpp -$(libcppdir)/checkimpl.o: ../lib/checkimpl.cpp ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkimpl.o: ../lib/checkimpl.cpp ../lib/checkers.h ../lib/checkimpl.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkimpl.cpp -$(libcppdir)/checkinternal.o: ../lib/checkinternal.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkinternal.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkinternal.o: ../lib/checkinternal.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkinternal.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkinternal.cpp -$(libcppdir)/checkio.o: ../lib/checkio.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkio.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkio.o: ../lib/checkio.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkio.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkio.cpp -$(libcppdir)/checkleakautovar.o: ../lib/checkleakautovar.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkleakautovar.h ../lib/checkmemoryleak.h ../lib/checknullpointer.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkleakautovar.o: ../lib/checkleakautovar.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkleakautovar.h ../lib/checkmemoryleak.h ../lib/checknullpointer.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkleakautovar.cpp -$(libcppdir)/checkmemoryleak.o: ../lib/checkmemoryleak.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkmemoryleak.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkmemoryleak.o: ../lib/checkmemoryleak.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkmemoryleak.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkmemoryleak.cpp -$(libcppdir)/checknullpointer.o: ../lib/checknullpointer.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checknullpointer.o: ../lib/checknullpointer.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/findtoken.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checknullpointer.cpp -$(libcppdir)/checkother.o: ../lib/checkother.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkother.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkother.o: ../lib/checkother.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkother.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkother.cpp -$(libcppdir)/checkpostfixoperator.o: ../lib/checkpostfixoperator.cpp ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkpostfixoperator.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkpostfixoperator.o: ../lib/checkpostfixoperator.cpp ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkpostfixoperator.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkpostfixoperator.cpp -$(libcppdir)/checks.o: ../lib/checks.cpp ../lib/check.h ../lib/check64bit.h ../lib/checkassert.h ../lib/checkautovariables.h ../lib/checkbool.h ../lib/checkbufferoverrun.h ../lib/checkclass.h ../lib/checkcondition.h ../lib/checkexceptionsafety.h ../lib/checkfunctions.h ../lib/checkimpl.h ../lib/checkinternal.h ../lib/checkio.h ../lib/checkleakautovar.h ../lib/checkmemoryleak.h ../lib/checknullpointer.h ../lib/checkother.h ../lib/checkpostfixoperator.h ../lib/checks.h ../lib/checksizeof.h ../lib/checkstl.h ../lib/checkstring.h ../lib/checktype.h ../lib/checkuninitvar.h ../lib/checkunusedvar.h ../lib/checkvaarg.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/standards.h ../lib/vfvalue.h +$(libcppdir)/checks.o: ../lib/checks.cpp ../lib/check.h ../lib/check64bit.h ../lib/checkassert.h ../lib/checkautovariables.h ../lib/checkbool.h ../lib/checkbufferoverrun.h ../lib/checkclass.h ../lib/checkcondition.h ../lib/checkexceptionsafety.h ../lib/checkfunctions.h ../lib/checkimpl.h ../lib/checkinternal.h ../lib/checkio.h ../lib/checkleakautovar.h ../lib/checkmemoryleak.h ../lib/checknullpointer.h ../lib/checkother.h ../lib/checkpostfixoperator.h ../lib/checks.h ../lib/checksizeof.h ../lib/checkstl.h ../lib/checkstring.h ../lib/checktype.h ../lib/checkuninitvar.h ../lib/checkunusedvar.h ../lib/checkvaarg.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/refthunk.h ../lib/standards.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checks.cpp -$(libcppdir)/checksizeof.o: ../lib/checksizeof.cpp ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checksizeof.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checksizeof.o: ../lib/checksizeof.cpp ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checksizeof.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checksizeof.cpp -$(libcppdir)/checkstl.o: ../lib/checkstl.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/checkstl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/pathanalysis.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkstl.o: ../lib/checkstl.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/checkstl.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/pathanalysis.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkstl.cpp -$(libcppdir)/checkstring.o: ../lib/checkstring.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkstring.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkstring.o: ../lib/checkstring.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkstring.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkstring.cpp -$(libcppdir)/checktype.o: ../lib/checktype.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checktype.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checktype.o: ../lib/checktype.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checktype.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checktype.cpp -$(libcppdir)/checkuninitvar.o: ../lib/checkuninitvar.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/checkuninitvar.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkuninitvar.o: ../lib/checkuninitvar.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checknullpointer.h ../lib/checkuninitvar.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkuninitvar.cpp -$(libcppdir)/checkunusedfunctions.o: ../lib/checkunusedfunctions.cpp ../externals/tinyxml2/tinyxml2.h ../lib/analyzerinfo.h ../lib/astutils.h ../lib/checkers.h ../lib/checkunusedfunctions.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/checkunusedfunctions.o: ../lib/checkunusedfunctions.cpp ../externals/tinyxml2/tinyxml2.h ../lib/analyzerinfo.h ../lib/astutils.h ../lib/checkers.h ../lib/checkunusedfunctions.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedfunctions.cpp -$(libcppdir)/checkunusedvar.o: ../lib/checkunusedvar.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkunusedvar.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/checkunusedvar.o: ../lib/checkunusedvar.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkunusedvar.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkunusedvar.cpp -$(libcppdir)/checkvaarg.o: ../lib/checkvaarg.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkvaarg.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/checkvaarg.o: ../lib/checkvaarg.cpp ../lib/astutils.h ../lib/check.h ../lib/checkers.h ../lib/checkimpl.h ../lib/checkvaarg.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/checkvaarg.cpp -$(libcppdir)/clangimport.o: ../lib/clangimport.cpp ../lib/clangimport.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/clangimport.o: ../lib/clangimport.cpp ../lib/clangimport.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/refthunk.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/clangimport.cpp $(libcppdir)/color.o: ../lib/color.cpp ../lib/color.h ../lib/config.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/color.cpp -$(libcppdir)/cppcheck.o: ../lib/cppcheck.cpp ../externals/picojson/picojson.h ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/analyzerinfo.h ../lib/check.h ../lib/checkers.h ../lib/checks.h ../lib/checkunusedfunctions.h ../lib/clangimport.h ../lib/color.h ../lib/config.h ../lib/cppcheck.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/regex.h ../lib/rule.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/version.h ../lib/vfvalue.h +$(libcppdir)/cppcheck.o: ../lib/cppcheck.cpp ../externals/picojson/picojson.h ../externals/simplecpp/simplecpp.h ../lib/addoninfo.h ../lib/analyzerinfo.h ../lib/check.h ../lib/checkers.h ../lib/checks.h ../lib/checkunusedfunctions.h ../lib/clangimport.h ../lib/color.h ../lib/config.h ../lib/cppcheck.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/refthunk.h ../lib/regex.h ../lib/rule.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/timer.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/version.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/cppcheck.cpp -$(libcppdir)/ctu.o: ../lib/ctu.cpp ../externals/tinyxml2/tinyxml2.h ../lib/astutils.h ../lib/check.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/ctu.o: ../lib/ctu.cpp ../externals/tinyxml2/tinyxml2.h ../lib/astutils.h ../lib/check.h ../lib/config.h ../lib/ctu.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/refthunk.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/ctu.cpp -$(libcppdir)/errorlogger.o: ../lib/errorlogger.cpp ../externals/tinyxml2/tinyxml2.h ../lib/check.h ../lib/checkers.h ../lib/color.h ../lib/config.h ../lib/cppcheck.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/errorlogger.o: ../lib/errorlogger.cpp ../externals/tinyxml2/tinyxml2.h ../lib/check.h ../lib/checkers.h ../lib/color.h ../lib/config.h ../lib/cppcheck.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/suppressions.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/errorlogger.cpp $(libcppdir)/errortypes.o: ../lib/errortypes.cpp ../lib/config.h ../lib/errortypes.h ../lib/utils.h @@ -279,10 +279,10 @@ $(libcppdir)/errortypes.o: ../lib/errortypes.cpp ../lib/config.h ../lib/errortyp $(libcppdir)/findtoken.o: ../lib/findtoken.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/findtoken.h ../lib/library.h ../lib/mathlib.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/findtoken.cpp -$(libcppdir)/forwardanalyzer.o: ../lib/forwardanalyzer.cpp ../lib/analyzer.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/forwardanalyzer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueptr.h ../lib/vfvalue.h +$(libcppdir)/forwardanalyzer.o: ../lib/forwardanalyzer.cpp ../lib/analyzer.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/forwardanalyzer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueptr.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/forwardanalyzer.cpp -$(libcppdir)/fwdanalysis.o: ../lib/fwdanalysis.cpp ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/fwdanalysis.o: ../lib/fwdanalysis.cpp ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/fwdanalysis.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/fwdanalysis.cpp $(libcppdir)/importproject.o: ../lib/importproject.cpp ../externals/picojson/picojson.h ../externals/tinyxml2/tinyxml2.h ../lib/checkers.h ../lib/config.h ../lib/filesettings.h ../lib/importproject.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/pathmatch.h ../lib/platform.h ../lib/settings.h ../lib/standards.h ../lib/suppressions.h ../lib/utils.h ../lib/xml.h @@ -294,7 +294,7 @@ $(libcppdir)/infer.o: ../lib/infer.cpp ../lib/calculate.h ../lib/config.h ../lib $(libcppdir)/keywords.o: ../lib/keywords.cpp ../lib/config.h ../lib/keywords.h ../lib/standards.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/keywords.cpp -$(libcppdir)/library.o: ../lib/library.cpp ../externals/tinyxml2/tinyxml2.h ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/library.o: ../lib/library.cpp ../externals/tinyxml2/tinyxml2.h ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/refthunk.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/library.cpp $(libcppdir)/mathlib.o: ../lib/mathlib.cpp ../externals/simplecpp/simplecpp.h ../lib/config.h ../lib/errortypes.h ../lib/mathlib.h ../lib/smallvector.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h @@ -303,7 +303,7 @@ $(libcppdir)/mathlib.o: ../lib/mathlib.cpp ../externals/simplecpp/simplecpp.h .. $(libcppdir)/path.o: ../lib/path.cpp ../externals/simplecpp/simplecpp.h ../lib/config.h ../lib/path.h ../lib/standards.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/path.cpp -$(libcppdir)/pathanalysis.o: ../lib/pathanalysis.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/pathanalysis.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/pathanalysis.o: ../lib/pathanalysis.cpp ../lib/astutils.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/pathanalysis.h ../lib/refthunk.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/pathanalysis.cpp $(libcppdir)/pathmatch.o: ../lib/pathmatch.cpp ../lib/config.h ../lib/path.h ../lib/pathmatch.h ../lib/standards.h @@ -312,19 +312,19 @@ $(libcppdir)/pathmatch.o: ../lib/pathmatch.cpp ../lib/config.h ../lib/path.h ../ $(libcppdir)/platform.o: ../lib/platform.cpp ../externals/tinyxml2/tinyxml2.h ../lib/config.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/standards.h ../lib/utils.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/platform.cpp -$(libcppdir)/preprocessor.o: ../lib/preprocessor.cpp ../externals/simplecpp/simplecpp.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/settings.h ../lib/standards.h ../lib/suppressions.h ../lib/utils.h +$(libcppdir)/preprocessor.o: ../lib/preprocessor.cpp ../externals/simplecpp/simplecpp.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/preprocessor.h ../lib/refthunk.h ../lib/settings.h ../lib/standards.h ../lib/suppressions.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/preprocessor.cpp -$(libcppdir)/programmemory.o: ../lib/programmemory.cpp ../lib/astutils.h ../lib/calculate.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vfvalue.h +$(libcppdir)/programmemory.o: ../lib/programmemory.cpp ../lib/astutils.h ../lib/calculate.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/infer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/programmemory.cpp $(libcppdir)/regex.o: ../lib/regex.cpp ../lib/config.h ../lib/regex.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/regex.cpp -$(libcppdir)/reverseanalyzer.o: ../lib/reverseanalyzer.cpp ../lib/analyzer.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/forwardanalyzer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueptr.h ../lib/vfvalue.h +$(libcppdir)/reverseanalyzer.o: ../lib/reverseanalyzer.cpp ../lib/analyzer.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/forwardanalyzer.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/reverseanalyzer.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueptr.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/reverseanalyzer.cpp -$(libcppdir)/sarifreport.o: ../lib/sarifreport.cpp ../externals/picojson/picojson.h ../lib/check.h ../lib/checkers.h ../lib/config.h ../lib/cppcheck.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/sarifreport.h ../lib/settings.h ../lib/standards.h ../lib/utils.h +$(libcppdir)/sarifreport.o: ../lib/sarifreport.cpp ../externals/picojson/picojson.h ../lib/check.h ../lib/checkers.h ../lib/config.h ../lib/cppcheck.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/sarifreport.h ../lib/settings.h ../lib/standards.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/sarifreport.cpp $(libcppdir)/settings.o: ../lib/settings.cpp ../externals/picojson/picojson.h ../lib/addoninfo.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/json.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/rule.h ../lib/settings.h ../lib/standards.h ../lib/summaries.h ../lib/suppressions.h ../lib/utils.h ../lib/vfvalue.h @@ -333,34 +333,34 @@ $(libcppdir)/settings.o: ../lib/settings.cpp ../externals/picojson/picojson.h .. $(libcppdir)/standards.o: ../lib/standards.cpp ../externals/simplecpp/simplecpp.h ../lib/config.h ../lib/standards.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/standards.cpp -$(libcppdir)/summaries.o: ../lib/summaries.cpp ../lib/analyzerinfo.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/summaries.o: ../lib/summaries.cpp ../lib/analyzerinfo.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/summaries.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/summaries.cpp -$(libcppdir)/suppressions.o: ../lib/suppressions.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/pathmatch.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/suppressions.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h +$(libcppdir)/suppressions.o: ../lib/suppressions.cpp ../externals/tinyxml2/tinyxml2.h ../lib/addoninfo.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/filesettings.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/pathmatch.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/suppressions.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h ../lib/xml.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/suppressions.cpp -$(libcppdir)/templatesimplifier.o: ../lib/templatesimplifier.cpp ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/templatesimplifier.o: ../lib/templatesimplifier.cpp ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenize.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/templatesimplifier.cpp $(libcppdir)/timer.o: ../lib/timer.cpp ../lib/config.h ../lib/timer.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/timer.cpp -$(libcppdir)/token.o: ../lib/token.cpp ../externals/simplecpp/simplecpp.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/tokenrange.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h +$(libcppdir)/token.o: ../lib/token.cpp ../externals/simplecpp/simplecpp.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/tokenrange.h ../lib/utils.h ../lib/valueflow.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/token.cpp -$(libcppdir)/tokenlist.o: ../lib/tokenlist.cpp ../externals/simplecpp/simplecpp.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/keywords.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h +$(libcppdir)/tokenlist.o: ../lib/tokenlist.cpp ../externals/simplecpp/simplecpp.h ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errorlogger.h ../lib/errortypes.h ../lib/keywords.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/standards.h ../lib/templatesimplifier.h ../lib/token.h ../lib/tokenlist.h ../lib/utils.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/tokenlist.cpp $(libcppdir)/utils.o: ../lib/utils.cpp ../lib/config.h ../lib/utils.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/utils.cpp -$(libcppdir)/vf_analyzers.o: ../lib/vf_analyzers.cpp ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyzers.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h +$(libcppdir)/vf_analyzers.o: ../lib/vf_analyzers.cpp ../lib/analyzer.h ../lib/astutils.h ../lib/calculate.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/programmemory.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/valueptr.h ../lib/vf_analyzers.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_analyzers.cpp -$(libcppdir)/vf_common.o: ../lib/vf_common.cpp ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h +$(libcppdir)/vf_common.o: ../lib/vf_common.cpp ../lib/astutils.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/path.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_common.cpp -$(libcppdir)/vf_settokenvalue.o: ../lib/vf_settokenvalue.cpp ../lib/astutils.h ../lib/calculate.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h +$(libcppdir)/vf_settokenvalue.o: ../lib/vf_settokenvalue.cpp ../lib/astutils.h ../lib/calculate.h ../lib/checkers.h ../lib/config.h ../lib/errortypes.h ../lib/library.h ../lib/mathlib.h ../lib/platform.h ../lib/refthunk.h ../lib/settings.h ../lib/smallvector.h ../lib/sourcelocation.h ../lib/standards.h ../lib/symboldatabase.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/valueflow.h ../lib/vf_common.h ../lib/vf_settokenvalue.h ../lib/vfvalue.h $(CXX) ${LIB_FUZZING_ENGINE} $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $(libcppdir)/vf_settokenvalue.cpp $(libcppdir)/vfvalue.o: ../lib/vfvalue.cpp ../lib/config.h ../lib/errortypes.h ../lib/mathlib.h ../lib/smallvector.h ../lib/templatesimplifier.h ../lib/token.h ../lib/utils.h ../lib/vfvalue.h diff --git a/test/cfg/gnu.c b/test/cfg/gnu.c index 42b37036411..830618c241d 100644 --- a/test/cfg/gnu.c +++ b/test/cfg/gnu.c @@ -376,6 +376,13 @@ wchar_t *nullPointer_wmempcpy(wchar_t *dest, const wchar_t *src, size_t n) return wmempcpy(dest,src,n); } +void bufferAccessOutOfBounds_wmempcpy(const wchar_t *src) +{ + wchar_t buf[3]; + // cppcheck-suppress bufferAccessOutOfBounds + wmempcpy(buf, src, 5); +} + int uninitvar_getpw(uid_t uid, char *buf) { uid_t someUid; diff --git a/test/cfg/qt.cpp b/test/cfg/qt.cpp index a850a93f7f2..fe2f48e3175 100644 --- a/test/cfg/qt.cpp +++ b/test/cfg/qt.cpp @@ -83,6 +83,12 @@ void assertWithSideEffect_QDir_exists(const char *path) { // #14720 (void)dir; } +void assertWithSideEffect_QDir_mkdir(const char *path) { // #12468 + QDir dir; + // cppcheck-suppress [assertWithSideEffect, checkLibraryNoReturn] // TODO: #8329 + Q_ASSERT(dir.mkdir(path)); +} + void unusedVariable_QTransform() { // cppcheck-suppress unusedVariable diff --git a/test/cfg/std.c b/test/cfg/std.c index 5d2e6180a4c..a8914d608a9 100644 --- a/test/cfg/std.c +++ b/test/cfg/std.c @@ -619,6 +619,20 @@ void bufferAccessOutOfBounds_wcsncpy() wcsncpy(s, L"abc", 17); } +void bufferAccessOutOfBounds_wmemcpy() +{ + wchar_t a[4]; + // cppcheck-suppress bufferAccessOutOfBounds + wmemcpy(a, L"abcd", 5); +} + +int bufferAccessOutOfBounds_wmemcmp(const wchar_t* b) +{ + const wchar_t a[4] = { L'a', L'b', L'c', L'd' }; + // cppcheck-suppress bufferAccessOutOfBounds + return wmemcmp(a, b, 5); +} + int nullPointer_wcsncmp(const wchar_t* s1, const wchar_t* s2, size_t n) { // cppcheck-suppress nullPointer @@ -2940,6 +2954,27 @@ void *bufferAccessOutOfBounds_memchr(const void *s, int c, size_t n) return memchr(s,c,n); } +bool bufferAccessOutOfBounds_wmemchr(wchar_t c) +{ + const wchar_t buf[] = {'a', 'b', 'c'}; + // cppcheck-suppress bufferAccessOutOfBounds + return wmemchr(buf, c, 5) != NULL; +} + +void bufferAccessOutOfBounds_wmemset(wchar_t c) +{ + wchar_t buf[3]; + // cppcheck-suppress bufferAccessOutOfBounds + wmemset(buf, c, 5); +} + +void bufferAccessOutOfBounds_wmemmove(const wchar_t* s) +{ + wchar_t d[3]; + // cppcheck-suppress bufferAccessOutOfBounds + wmemmove(d, s, 5); +} + void uninitvar_wmemchr(void) { const wchar_t *cs; diff --git a/test/cli/other_test.py b/test/cli/other_test.py index aad4fec264e..0123a97128e 100644 --- a/test/cli/other_test.py +++ b/test/cli/other_test.py @@ -190,8 +190,6 @@ def test_progress(tmpdir): "progress: ValueFlow::valueFlowCondition(SymbolicConditionHandler{}, tokenlist, symboldatabase, errorLogger, settings, skippedFunctions) 1 100%\n" "progress: ValueFlow::valueFlowSymbolicInfer(symboldatabase, settings) 1 0%\n" "progress: ValueFlow::valueFlowSymbolicInfer(symboldatabase, settings) 1 100%\n" - "progress: ValueFlow::valueFlowArrayBool(tokenlist, settings) 1 0%\n" - "progress: ValueFlow::valueFlowArrayBool(tokenlist, settings) 1 100%\n" "progress: ValueFlow::valueFlowArrayElement(tokenlist, settings) 1 0%\n" "progress: ValueFlow::valueFlowArrayElement(tokenlist, settings) 1 100%\n" "progress: ValueFlow::valueFlowRightShift(tokenlist, settings) 1 0%\n" @@ -482,9 +480,9 @@ def test_addon_threadsafety(tmpdir): test_file = os.path.join(tmpdir, 'test.cpp') with open(test_file, 'wt') as f: f.write(""" -extern const char* f() +extern void f() { - return strerror(1); + elf_fill(1); } """) @@ -496,7 +494,7 @@ def test_addon_threadsafety(tmpdir): assert lines == [ 'Checking {} ...'.format(test_file) ] - assert stderr == '{}:4:12: warning: strerror is MT-unsafe [threadsafety-unsafe-call]\n'.format(test_file) + assert stderr == '{}:4:5: warning: elf_fill is MT-unsafe [threadsafety-unsafe-call]\n'.format(test_file) def test_addon_naming(tmpdir): @@ -1069,7 +1067,7 @@ def test_showtime_top5_summary_compdb(tmp_path): def __test_showtime_file(tmp_path, use_compdb=False, use_addons=False, use_clang_tidy=False): - exp_res = 79 + exp_res = 78 # project analysis does not call Preprocessor::getConfig() if use_compdb: exp_res -= 1 @@ -1103,7 +1101,7 @@ def test_showtime_file_clang_tidy_compdb(tmp_path): def __test_showtime_summary(tmp_path, use_compdb=False, use_addons=False, use_clang_tidy=False): - exp_res = 79 + exp_res = 78 # project analysis does not call Preprocessor::getConfig() if use_compdb: exp_res -= 1 @@ -4575,6 +4573,47 @@ def run_and_assert_cppcheck(stdout_exp): # - internalError +def test_analyzerinfo_include_order(tmp_path): # #15132 + with open(tmp_path / 'z.h', 'wt') as f: + f.write('int z;\n') + with open(tmp_path / 'a.h', 'wt') as f: + f.write('int a;\n') + test_file = tmp_path / 'test.c' + with open(test_file, 'wt') as f: + f.write( +"""#include "z.h" +#include "a.h" +int f(void) { return a + z; } +""") + + build_dir = tmp_path / 'b1' + os.makedirs(build_dir) + + args = [ + '-q', + '--debug-analyzerinfo', + '--cppcheck-build-dir={}'.format(build_dir), + str(test_file) + ] + + test_file_s = str(test_file).replace('\\', '/') + test_a1_file_s = str(build_dir / 'test.a1').replace('\\', '/') + + exitcode, stdout, stderr = cppcheck(args) + assert exitcode == 0, stdout + assert stdout.splitlines() == [ + "no cached result '{}' for '{}' found".format(test_a1_file_s, test_file_s) + ] + assert stderr.splitlines() == [] + + exitcode, stdout, stderr = cppcheck(args) + assert exitcode == 0, stdout + assert stdout.splitlines() == [ + "skipping analysis - loaded 0 cached finding(s) from '{}' for '{}'".format(test_a1_file_s, test_file_s) + ] + assert stderr.splitlines() == [] + + def test_ctu_function_call_path_slash(tmp_path): # #14591 test_file = tmp_path / 'test.cpp' with open(test_file, "w") as f: @@ -4886,6 +4925,40 @@ def test_ipc_inline_suppressions(tmp_path): assert stdout_lines == stdout_exp assert stderr.splitlines() == [] + +@pytest.mark.skipif(sys.platform == 'win32', reason="requires ProcessExecutor") +def test_ipc_hash_suppressions(tmp_path): + test_file = tmp_path / 'test.c' + with open(test_file, "w") as f: + f.write('void f() { int x = 1; }') + + _, _, stderr = cppcheck(['--enable=style', '--xml-version=3', str(test_file)]) + error_hash = ElementTree.fromstring(stderr).find('.//error').get('hash') + + suppr_file = tmp_path / 'suppr.xml' + with open(suppr_file, "w") as f: + f.write(f'unreadVariable{test_file}{error_hash}') + + args = [ + '-q', + '--debug-ipc', + '-j2', + '--executor=process', + '--no-cppcheck-build-dir', + '--enable=style', + f'--suppress-xml={suppr_file}', + str(test_file) + ] + + exitcode, stdout, stderr = cppcheck(args) + assert exitcode == 0 + # the hash suppression is not sent to the parent + assert stdout.splitlines() == [ + 'writeToPipe - 5 - 0', + 'handleRead - 5 - 0' + ] + assert stderr.splitlines() == [] + test_redundant_file_reads_params = [ ([], 3), (['--suppress=zerodiv'], 1), diff --git a/test/fixture.cpp b/test/fixture.cpp index de42837a56e..a561b4fc28f 100644 --- a/test/fixture.cpp +++ b/test/fixture.cpp @@ -509,7 +509,7 @@ TestFixture::SettingsBuilder& TestFixture::SettingsBuilder::library(const char l if (REDUNDANT_CHECK && std::find(settings.libraries.cbegin(), settings.libraries.cend(), lib) != settings.libraries.cend()) throw std::runtime_error("redundant setting: libraries (" + std::string(lib) + ")"); // TODO: exename is not yet set - const Library::ErrorCode lib_error = settings.library.load(fixture.exename.c_str(), lib).errorcode; + const Library::ErrorCode lib_error = settings.library.load(fixture().exename.c_str(), lib).errorcode; if (lib_error != Library::ErrorCode::OK) throw std::runtime_error("loading library '" + std::string(lib) + "' failed - " + std::to_string(static_cast(lib_error))); // strip extension @@ -531,7 +531,7 @@ TestFixture::SettingsBuilder& TestFixture::SettingsBuilder::platform(Platform::T std::string errstr; // TODO: exename is not yet set - if (!settings.platform.set(platformStr, errstr, {fixture.exename})) + if (!settings.platform.set(platformStr, errstr, {fixture().exename})) throw std::runtime_error("platform '" + platformStr + "' not found"); return *this; } diff --git a/test/fixture.h b/test/fixture.h index c5828033fd7..3d1e96562ba 100644 --- a/test/fixture.h +++ b/test/fixture.h @@ -25,6 +25,7 @@ #include "config.h" #include "errorlogger.h" #include "errortypes.h" +#include "refthunk.h" #include "platform.h" #include "settings.h" #include "standards.h" @@ -239,7 +240,7 @@ class TestFixture : public ErrorLogger { private: SettingsBuilder& libraryxml(const char xmldata[], std::size_t len); - const TestFixture &fixture; + RefThunk fixture; Settings settings; static constexpr bool REDUNDANT_CHECK = false; diff --git a/test/helpers.h b/test/helpers.h index a08eb3f1572..cd4cde7af1c 100644 --- a/test/helpers.h +++ b/test/helpers.h @@ -136,7 +136,7 @@ class SimpleTokenList } private: - const Settings settings; + Settings settings; TokenList list; }; diff --git a/test/testanalyzerinformation.cpp b/test/testanalyzerinformation.cpp index 2174f7d4676..0356630686c 100644 --- a/test/testanalyzerinformation.cpp +++ b/test/testanalyzerinformation.cpp @@ -53,6 +53,41 @@ class TestAnalyzerInformation : public TestFixture { ASSERT_EQUALS("file1.a4", AnalyzerInformationTest::getAnalyzerInfoFileFromFilesTxt(f, "file1.c", "", 0)); f.str(filesTxt); ASSERT_EQUALS("file1.a4", AnalyzerInformationTest::getAnalyzerInfoFileFromFilesTxt(f, "./file1.c", "", 0)); + + // only an exact match is used - "executor.cpp" is a suffix of "processexecutor.cpp" + // so both used to resolve to the same analyzer info file + { + constexpr char suffixTxt[] = "executor.a1:::executor.cpp\n" + "processexecutor.a2:::processexecutor.cpp\n"; + std::istringstream f1(suffixTxt); + ASSERT_EQUALS("executor.a1", AnalyzerInformationTest::getAnalyzerInfoFileFromFilesTxt(f1, "executor.cpp", "", 0)); + std::istringstream f2(suffixTxt); + ASSERT_EQUALS("processexecutor.a2", AnalyzerInformationTest::getAnalyzerInfoFileFromFilesTxt(f2, "processexecutor.cpp", "", 0)); + } + + // the same, with the exact match on the first line + { + constexpr char suffixTxt[] = "processexecutor.a1:::processexecutor.cpp\n" + "executor.a2:::executor.cpp\n"; + std::istringstream f1(suffixTxt); + ASSERT_EQUALS("processexecutor.a1", AnalyzerInformationTest::getAnalyzerInfoFileFromFilesTxt(f1, "processexecutor.cpp", "", 0)); + std::istringstream f2(suffixTxt); + ASSERT_EQUALS("executor.a2", AnalyzerInformationTest::getAnalyzerInfoFileFromFilesTxt(f2, "executor.cpp", "", 0)); + } + + // a path that only ends with the path in files.txt is not a match + { + constexpr char relTxt[] = "a.a1:::src/a.c\n"; + std::istringstream f1(relTxt); + ASSERT_EQUALS("", AnalyzerInformationTest::getAnalyzerInfoFileFromFilesTxt(f1, "/home/proj/src/a.c", "", 0)); + } + + // no match at all + { + constexpr char noneTxt[] = "a.a1:::a.c\n"; + std::istringstream f1(noneTxt); + ASSERT_EQUALS("", AnalyzerInformationTest::getAnalyzerInfoFileFromFilesTxt(f1, "b.c", "", 0)); + } } void getAnalyzerInfoFile() const { diff --git a/test/testautovariables.cpp b/test/testautovariables.cpp index d1bc3bf830f..a2fa4168ea8 100644 --- a/test/testautovariables.cpp +++ b/test/testautovariables.cpp @@ -133,6 +133,7 @@ class TestAutoVariables : public TestFixture { TEST_CASE(returnReference27); TEST_CASE(returnReference28); TEST_CASE(returnReference29); + TEST_CASE(returnReference30); // #15094 TEST_CASE(returnReferenceFunction); TEST_CASE(returnReferenceContainer); TEST_CASE(returnReferenceLiteral); @@ -1772,6 +1773,23 @@ class TestAutoVariables : public TestFixture { errout_str()); } + void returnReference30() // #15094 + { + check("int& f1(int& (*fp)()) { return fp(); }\n" + "void f2(int& (*fp)()) { int& r = fp(); r = 2; }\n" + "struct D {\n" + " int& call() { return f(); }\n" + " int& (*f)();\n" + "};\n" + "const int& f3(const int& (*fp)(int)) { return fp(1); }\n" + "int& (*g)();\n" + "int& f4() { return g(); }\n" + "typedef int& (*FP)();\n" + "int& f5(FP fp) { return fp(); }\n" + "int* f6(int& (*fp)()) { return &fp(); }\n"); + ASSERT_EQUALS("", errout_str()); + } + void returnReferenceFunction() { check("int& f(int& a) {\n" " return a;\n" diff --git a/test/testclangimport.cpp b/test/testclangimport.cpp index bbbd75822f5..a22f901a261 100644 --- a/test/testclangimport.cpp +++ b/test/testclangimport.cpp @@ -144,6 +144,7 @@ class TestClangImport : public TestFixture { TEST_CASE(crash2); TEST_CASE(crash3); TEST_CASE(nullNodeInvalidLevel); + TEST_CASE(invalidExtTokens); } std::string parse(const char clang[]) { @@ -1421,7 +1422,7 @@ class TestClangImport : public TestFixture { // getSpelling() indexed mExtTokens[typeIndex - 1] without a lower-bound // check, so a node whose line carries no ext tokens (typeIndex <= 0) read // out of bounds. - (void)parse("`-RecordDecl "); // don't crash + ASSERT_THROW_INTERNAL_EQUALS(parse("`-RecordDecl "), AST, "invalid AST node: RecordDecl"); } void nullNodeInvalidLevel() { @@ -1442,6 +1443,29 @@ class TestClangImport : public TestFixture { " `-CXXRecordDecl 0x2\n"); // don't crash (void)parse("`-CXXRecordDecl 0x1"); // don't crash } + + void invalidExtTokens() { + // nodes without the ext tokens the handlers read must not index out of bounds + ASSERT_THROW_INTERNAL_EQUALS(parse("`-FunctionDecl 0x1 col:5 f 'int ()'\n" + " `-CompoundStmt 0x2 \n" + " `-ReturnStmt 0x3 \n" + " `-IntegerLiteral \n"), AST, "invalid AST node: IntegerLiteral"); + ASSERT_THROW_INTERNAL_EQUALS(parse("`-EnumDecl "), AST, "invalid AST node: EnumDecl"); + ASSERT_THROW_INTERNAL_EQUALS(parse("`-VarDecl 0x1"), AST, "invalid AST node: VarDecl"); + ASSERT_THROW_INTERNAL_EQUALS(parse("`-VarDecl 0x1 'int'"), AST, "invalid AST node: VarDecl"); + ASSERT_THROW_INTERNAL_EQUALS(parse("`-VarDecl 0x1 "), AST, "invalid AST node: VarDecl"); + ASSERT_THROW_INTERNAL_EQUALS(parse("`-FieldDecl 0x1 'int'"), AST, "invalid AST node: FieldDecl"); + ASSERT_THROW_INTERNAL_EQUALS(parse("`-FunctionDecl 0x1 col:5 f 'int ()' prev"), AST, "invalid AST node: FunctionDecl"); + // address-only declarations: getSpelling() is empty, addtoken() adds nothing and back() is null + ASSERT_THROW_INTERNAL_EQUALS(parse("`-FunctionDecl 0x1"), AST, "invalid AST node: FunctionDecl"); + ASSERT_THROW_INTERNAL_EQUALS(parse("`-CXXConstructorDecl 0x1"), AST, "invalid AST node: CXXConstructorDecl"); + ASSERT_THROW_INTERNAL_EQUALS(parse("`-CXXMethodDecl 0x1"), AST, "invalid AST node: CXXMethodDecl"); + ASSERT_THROW_INTERNAL_EQUALS(parse("`-EnumConstantDecl 0x1"), AST, "invalid AST node: EnumConstantDecl"); + ASSERT_THROW_INTERNAL_EQUALS(parse("`-FunctionDecl 0x1 col:5 f 'int ()'\n" + " `-ParmVarDecl 0x2 \n"), AST, "invalid AST node: ParmVarDecl"); + ASSERT_THROW_INTERNAL_EQUALS(parse("`-FunctionDecl 0x1 col:5 f 'int ()'\n" + " `-ParmVarDecl 0x2 'int'\n"), AST, "invalid AST node: ParmVarDecl"); + } }; REGISTER_TEST(TestClangImport) diff --git a/test/testcondition.cpp b/test/testcondition.cpp index b23bcc2e20b..abef2d95614 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -69,6 +69,7 @@ class TestCondition : public TestFixture { TEST_CASE(incorrectLogicOperator15); TEST_CASE(incorrectLogicOperator16); // #10070 TEST_CASE(incorrectLogicOperator17); + TEST_CASE(incorrectLogicOperator18); // #12282 TEST_CASE(secondAlwaysTrueFalseWhenFirstTrueError); TEST_CASE(incorrectLogicOp_condSwapping); TEST_CASE(testBug5895); @@ -1758,6 +1759,17 @@ class TestCondition : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void incorrectLogicOperator18() { // #12282 + // long double literals out of the range of double are different values + check("int f(long double x) {\n" + " return x > 1e400L && x < 1e500L;\n" + "}\n" + "int g() {\n" + " return 1e400L < 1e500L;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + } + void incorrectLogicOperator17() { // #12471 check("struct R {\n" " void set() { i = 1; }\n" diff --git a/test/testconstructors.cpp b/test/testconstructors.cpp index 4de49f54311..8668772b199 100644 --- a/test/testconstructors.cpp +++ b/test/testconstructors.cpp @@ -232,6 +232,18 @@ class TestConstructors : public TestFixture { TEST_CASE(uninitTemplate1); // ticket #7372 TEST_CASE(unknownTemplateType); + + TEST_CASE(inheritedCtor1); + TEST_CASE(inheritedCtor2); + TEST_CASE(inheritedCtor3); + TEST_CASE(inheritedCtor4); + TEST_CASE(inheritedCtor5); + TEST_CASE(inheritedCtor6); + TEST_CASE(inheritedCtor7); + TEST_CASE(inheritedCtor8); + TEST_CASE(inheritedCtor9); + TEST_CASE(inheritedCtor10); + TEST_CASE(inheritedCtor11); } @@ -797,6 +809,90 @@ class TestConstructors : public TestFixture { ASSERT_EQUALS("[test.cpp:4:9]: (warning) Member variable 'T::j' has no initializer. [uninitMemberVarNoCtor]\n" "[test.cpp:8:9]: (warning) Member variable 'U::k' has no initializer. [uninitMemberVarNoCtor]\n", errout_str()); + + check("struct S {\n" // #15080 + " int a = 0;\n" + " const int b;\n" + " int k;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + + check("struct S {\n" + " int a = 0;\n" + " int& c;\n" + " int k;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + + check("struct S {\n" + " int a = 0;\n" + " const int* d;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:3:16]: (warning) Member variable 'S::d' has no initializer. [uninitMemberVarNoCtor]\n", errout_str()); + + check("struct S {\n" + " int a = 0;\n" + " int* const p;\n" + " int k;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + + check("struct S {\n" // static members don't affect the default constructor + " int a = 0;\n" + " static const int N;\n" + " static int& r;\n" + " int k;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:5:9]: (warning) Member variable 'S::k' has no initializer. [uninitMemberVarNoCtor]\n", errout_str()); + + check("struct S {\n" // function pointers returning a reference are no references + " int a = 0;\n" + " std::string& (*f)(int, int);\n" + " int& (*g[2])();\n" + " int k;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:3:20]: (warning) Member variable 'S::f' has no initializer. [uninitMemberVarNoCtor]\n" + "[test.cpp:4:12]: (warning) Member variable 'S::g' has no initializer. [uninitMemberVarNoCtor]\n" + "[test.cpp:5:9]: (warning) Member variable 'S::k' has no initializer. [uninitMemberVarNoCtor]\n", + errout_str()); + + check("struct S {\n" + " int a = 0;\n" + " int (*&f)();\n" + " int k;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + + check("struct S {\n" + " int a = 0;\n" + " int (&arr)[2];\n" + " int k;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + + check("typedef const unsigned int Mode;\n" + "struct S {\n" + " std::vector v;\n" + " Mode m;\n" + " int k;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + + check("struct S {\n" + " std::string a;\n" + " const std::string s;\n" + " int k;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:4:9]: (warning) Member variable 'S::k' has no initializer. [uninitMemberVarNoCtor]\n", errout_str()); + + check("struct S {\n" + " const std::array a;\n" + " const std::vector::const_iterator it;\n" + "};\n" + "S f(const std::vector& v) {\n" + " return S{ {}, v.cbegin() };\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } // ticket #4290 "False Positive: style (noConstructor): The class 'foo' does not have a constructor." @@ -4648,6 +4744,144 @@ class TestConstructors : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void inheritedCtor1() { + check("struct Base { Base(int); };\n" + "struct Derived : Base {\n" + " using Base::Base;\n" + " int x;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:3:17]: (warning) Member variable 'Derived::x' is not initialized in the constructor inherited from 'Base'. [uninitMemberVar]\n", errout_str()); + } + + void inheritedCtor2() { + check("struct Base { Base(int); };\n" + "struct Derived : Base {\n" + " using Base::Base;\n" + " int x = 0;\n" + " int y{};\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + } + + void inheritedCtor3() { + check("struct Base { Base(int); };\n" + "struct S { S(); int i; };\n" + "struct Derived : Base {\n" + " using Base::Base;\n" + " S s;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + } + + void inheritedCtor4() { + check("struct Base { Base(int); };\n" + "struct Derived : Base {\n" + " using Base::Base;\n" + " int x = 0;\n" + " int y;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:3:17]: (warning) Member variable 'Derived::y' is not initialized in the constructor inherited from 'Base'. [uninitMemberVar]\n", errout_str()); + } + + void inheritedCtor5() { + check("struct Base { Base(int); };\n" + "struct Derived : Base {\n" + " using Base::Base;\n" + " Derived() : x(0) {}\n" + " int x;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:3:17]: (warning) Member variable 'Derived::x' is not initialized in the constructor inherited from 'Base'. [uninitMemberVar]\n", errout_str()); + } + + void inheritedCtor6() { + check("struct A { A(int); };\n" + "struct B { B(double); };\n" + "struct D : A, B {\n" + " using A::A;\n" + " using B::B;\n" + " int x;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:4:14]: (warning) Member variable 'D::x' is not initialized in the constructor inherited from 'A'. [uninitMemberVar]\n" + "[test.cpp:5:14]: (warning) Member variable 'D::x' is not initialized in the constructor inherited from 'B'. [uninitMemberVar]\n", + errout_str()); + } + + void inheritedCtor7() { + check("struct Base { void f(); };\n" + "struct Derived : Base {\n" + " using Base::f;\n" + " int x = 0;\n" + " int y;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:5:9]: (warning) Member variable 'Derived::y' has no initializer. [uninitMemberVarNoCtor]\n", errout_str()); + } + + void inheritedCtor8() { + check("struct Base { Base(int); };\n" + "struct Derived : Base {\n" + " using Base::Base;\n" + " Derived(int i) : Base(i), x(0) {}\n" + " int x;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + + check("struct Base { Base(int); Base(double); };\n" + "struct Derived : Base {\n" + " using Base::Base;\n" + " Derived(int i) : Base(i), x(0) {}\n" + " int x;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:3:17]: (warning) Member variable 'Derived::x' is not initialized in the constructor inherited from 'Base'. [uninitMemberVar]\n", errout_str()); + } + + void inheritedCtor9() { + check("struct Base { Base(); };\n" + "struct Derived : Base {\n" + " using Base::Base;\n" + " int x;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + + check("struct Base {};\n" + "struct Derived : Base {\n" + " using Base::Base;\n" + " int x;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + + check("struct Base { Base(const Base&); Base(Base&&); };\n" + "struct Derived : Base {\n" + " using Base::Base;\n" + " int x;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + } + + void inheritedCtor10() { + check("struct Base { Base(int) = delete; };\n" + "struct Derived : Base {\n" + " using Base::Base;\n" + " int x;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + + check("class Base { Base(int); };\n" + "struct Derived : Base {\n" + " using Base::Base;\n" + " int x;\n" + "};\n"); + ASSERT_EQUALS("", errout_str()); + } + + void inheritedCtor11() { + check("namespace X { struct Base { Base(int); }; }\n" + "struct Derived : X::Base {\n" + " using X::Base::Base;\n" + " int x;\n" + "};\n"); + ASSERT_EQUALS("[test.cpp:3:20]: (warning) Member variable 'Derived::x' is not initialized in the constructor inherited from 'Base'. [uninitMemberVar]\n", errout_str()); + } + }; REGISTER_TEST(TestConstructors) diff --git a/test/testimportproject.cpp b/test/testimportproject.cpp index 2ecdf677381..47d756db563 100644 --- a/test/testimportproject.cpp +++ b/test/testimportproject.cpp @@ -1327,6 +1327,12 @@ class TestImportProject : public TestFixture { ASSERT_EQUALS("5", cppcheck::testing::expandMSBuildExpression("$([System.Math]::Abs(5))")); ASSERT_EQUALS("2", cppcheck::testing::expandMSBuildExpression("$([System.Math]::Floor(2.9))")); ASSERT_EQUALS("3", cppcheck::testing::expandMSBuildExpression("$([System.Math]::Ceiling(2.1))")); + ASSERT_EQUALS("2", cppcheck::testing::expandMSBuildExpression("$([System.Math]::Round(2.5))")); + ASSERT_EQUALS("4", cppcheck::testing::expandMSBuildExpression("$([System.Math]::Round(3.5))")); + ASSERT_EQUALS("-2", cppcheck::testing::expandMSBuildExpression("$([System.Math]::Round(-2.5))")); + ASSERT_EQUALS("1000000000000000019884624838656.000000", cppcheck::testing::expandMSBuildExpression("$([System.Math]::Pow(10, 30))")); + ASSERT_EQUALS("1000000000000000019884624838656.000000", cppcheck::testing::expandMSBuildExpression("$([System.Math]::Round(1e30))")); + ASSERT_EQUALS("-1000000000000000019884624838656.000000", cppcheck::testing::expandMSBuildExpression("$([System.Math]::Floor(-1e30))")); // --- $([System.IO.Path]::...) --- ASSERT_EQUALS("bar.cpp", cppcheck::testing::expandMSBuildExpression("$([System.IO.Path]::GetFileName('C:/foo/bar.cpp'))")); diff --git a/test/testmathlib.cpp b/test/testmathlib.cpp index 8cbe5b50019..800334926e5 100644 --- a/test/testmathlib.cpp +++ b/test/testmathlib.cpp @@ -22,6 +22,7 @@ #include "token.h" #include "tokenlist.h" +#include #include #include #include @@ -44,6 +45,7 @@ class TestMathLib : public TestFixture { TEST_CASE(isnegative); TEST_CASE(ispositive); TEST_CASE(isFloat); + TEST_CASE(isLongDoubleOutOfDoubleRange); TEST_CASE(isDecimalFloat); TEST_CASE(isGreater); TEST_CASE(isGreaterEqual); @@ -598,6 +600,16 @@ class TestMathLib : public TestFixture { // TODO: test with 128-bit values } + void isLongDoubleOutOfDoubleRange() const { + ASSERT_EQUALS(true, MathLib::isLongDoubleOutOfDoubleRange("1e400L")); + ASSERT_EQUALS(true, MathLib::isLongDoubleOutOfDoubleRange("1.0e4931l")); + ASSERT_EQUALS(false, MathLib::isLongDoubleOutOfDoubleRange("1e300L")); + ASSERT_EQUALS(false, MathLib::isLongDoubleOutOfDoubleRange("1e10000")); + ASSERT_EQUALS(false, MathLib::isLongDoubleOutOfDoubleRange("1e10000f")); + ASSERT_EQUALS(false, MathLib::isLongDoubleOutOfDoubleRange("10L")); + ASSERT_EQUALS(false, MathLib::isLongDoubleOutOfDoubleRange("")); + } + void toDoubleNumber() const { // float values ASSERT_EQUALS_DOUBLE(1.0, MathLib::toDoubleNumber("1."), 0.001); @@ -677,6 +689,13 @@ class TestMathLib : public TestFixture { ASSERT_EQUALS_DOUBLE(static_cast('\200'), MathLib::toDoubleNumber("'\\200'"), 0.000001); ASSERT_EQUALS_DOUBLE(static_cast(L'A'), MathLib::toDoubleNumber("L'A'"), 0.000001); + // out of the range of double, like glibc's HUGE_VAL for compilers other than GCC + ASSERT_EQUALS(true, std::isinf(MathLib::toDoubleNumber("1e10000"))); + ASSERT_EQUALS(true, std::isinf(MathLib::toDoubleNumber("1e10000f"))); + ASSERT_EQUALS(true, std::isinf(MathLib::toDoubleNumber("1e10000L"))); + ASSERT_EQUALS(true, std::isinf(MathLib::toDoubleNumber("1.5E+400"))); + ASSERT_EQUALS(true, std::isinf(MathLib::toDoubleNumber("1.0e4931L"))); // #12282 + ASSERT_THROW_INTERNAL_EQUALS(MathLib::toDoubleNumber("invalid"), INTERNAL, "Internal Error. MathLib::toDoubleNumber: conversion failed: invalid"); // AppleClang before 18 reports a different error diff --git a/test/testother.cpp b/test/testother.cpp index f1d06182184..e285d8d8bd0 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -204,6 +204,7 @@ class TestOther : public TestFixture { TEST_CASE(duplicateExpression20); TEST_CASE(duplicateExpression21); TEST_CASE(duplicateExpression22); + TEST_CASE(duplicateExpression23); // #12282 TEST_CASE(duplicateExpressionLoop); TEST_CASE(duplicateValueTernary); TEST_CASE(duplicateValueTernarySizeof); // #13773 @@ -230,6 +231,7 @@ class TestOther : public TestFixture { TEST_CASE(checkRedundantCopy); TEST_CASE(checkNegativeShift); + TEST_CASE(checkNegativeShiftErrorPath); TEST_CASE(incompleteArrayFill); @@ -4225,6 +4227,17 @@ class TestOther : public TestFixture { " int select(DS &ds) { return select(ds, [](int) {}); }\n" "};\n"); ASSERT_EQUALS("", errout_str()); + + check("int& g();\n" // reference to function + "int k();\n" + "int f1() { int& (&r)() = g; return r(); }\n" + "int f2() { int (&r)() = k; return r(); }\n" + "int& f3(int& (&f)()) { return f(); }\n" + "int f4(int&& (&f)()) { return f(); }\n" + "int f5(int (&f)()) { return f(); }\n" + "using FR = int&(&)();\n" + "void f6(FR f) { f(); }\n"); + ASSERT_EQUALS("", errout_str()); } void constParameterCallback() { @@ -8498,6 +8511,17 @@ class TestOther : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void duplicateExpression23() { // #12282 + // long double literals out of the range of double are different values + check("long double f() {\n" + " return 1e400L / 1e500L;\n" + "}\n" + "int g(long double x) {\n" + " return x == 1e400L || x == 1e500L;\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); + } + void duplicateExpression22() { check("int f() {\n" // #14913 " return 0x1 | (0x2 | 0x4) | 0x1;\n" @@ -10514,6 +10538,24 @@ class TestOther : public TestFixture { ASSERT_EQUALS("", errout_str()); } + void checkNegativeShiftErrorPath() { + setMultiline(); + Settings s = settings1; + s.templateLocation = "{file}:{line}:note:{info}\n"; + + check("int f(int i, bool b) {\n" + " int s = -1;\n" + " if (b)\n" + " return i;\n" + " return i << s;\n" + "}\n", dinit(CheckOptions, $.settings = &s)); + ASSERT_EQUALS("[test.cpp:5:14]: warning: Shifting by a negative value is undefined behaviour [shiftNegative]\n" + "[test.cpp:2:14]: note: Assignment 's=-1', assigned value is -1\n" + "[test.cpp:3:9]: note: Assuming condition is false\n" + "[test.cpp:5:14]: note: Shifting by a negative value is undefined behaviour\n", + errout_str()); + } + void incompleteArrayFill() { check("void f() {\n" " int a[5];\n" @@ -13532,6 +13574,24 @@ class TestOther : public TestFixture { check("struct S { void g(float f) {} void f() {} };\n"); ASSERT_EQUALS("[test.cpp:1:36] -> [test.cpp:1:25]: (style) Argument 'f' shadows outer function [shadowFunction]\n", errout_str()); + + check("int f() {\n" // #15114 + " int i = 0;\n" + " return i;\n" + "}\n" + "int i = 1;\n"); + ASSERT_EQUALS("", errout_str()); + + { + ScopedFile inc("test.h", "int pad1;\nint pad2;\nint pad3;\nint pad4;\nfloat f;\n"); + checkP("void g() {\n" + " #include \"test.h\"\n" + " {\n" + " float f;\n" + " }\n" + "}\n"); + ASSERT_EQUALS("[test.h:5:7] -> [test.cpp:4:15]: (style) Local variable 'f' shadows outer variable [shadowVariable]\n", errout_str()); + } } void knownArgument() { @@ -13734,6 +13794,18 @@ class TestOther : public TestFixture { " return MACRO(true);\n" "}\n"); ASSERT_EQUALS("", errout_str()); + + check("struct S {\n" // #15063 + " int (*f)(int, int);\n" + " int (*a[2])(int, int);\n" + "};\n" + "int g1(struct S* p, int x) {\n" + " return (p->f)(x, 10);\n" + "}\n" + "int g2(struct S s, int x) {\n" + " return s.a[0](x, 10);\n" + "}\n"); + ASSERT_EQUALS("", errout_str()); } void knownArgumentHiddenVariableExpression() { diff --git a/test/testpreprocessor.cpp b/test/testpreprocessor.cpp index 9aad97b2c99..faa1d9ce01b 100644 --- a/test/testpreprocessor.cpp +++ b/test/testpreprocessor.cpp @@ -382,6 +382,7 @@ class TestPreprocessor : public TestFixture { TEST_CASE(limitsDefines); TEST_CASE(hashCalculation); + TEST_CASE(hashCalculationIncludeOrder); TEST_CASE(standard); @@ -3182,6 +3183,25 @@ class TestPreprocessor : public TestFixture { ASSERT(getHash(code2) != getHash(code3)); } + void hashCalculationIncludeOrder() { + // #15132 - the load order of the includes must not change the hash + const ScopedFile headerA("hash_a.h", "int a;\n"); + const ScopedFile headerZ("hash_z.h", "int z;\n"); + const char code[] = "#include \"hash_z.h\"\n" + "#include \"hash_a.h\"\n"; + + const auto getHashLoadOrder = [&](const std::vector &loadOrder) { + std::vector files; + simplecpp::TokenList tokens(code, files, "test.c"); + Preprocessor preprocessor(tokens, settingsDefault, *this, Standards::Language::C); + for (const std::string &header : loadOrder) + ASSERT(preprocessor.loadFile(files, header)); + return preprocessor.calculateHash(""); + }; + + ASSERT_EQUALS(getHashLoadOrder({"hash_z.h", "hash_a.h"}), getHashLoadOrder({"hash_a.h", "hash_z.h"})); + } + void standard() { const char code[] = "int a;\n"; diff --git a/test/testrefthunk.cpp b/test/testrefthunk.cpp new file mode 100644 index 00000000000..f9ae525295a --- /dev/null +++ b/test/testrefthunk.cpp @@ -0,0 +1,134 @@ +/* + * Cppcheck - A tool for static C/C++ code analysis + * Copyright (C) 2007-2026 Cppcheck team. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "fixture.h" +#include "refthunk.h" + +#include +#include + +class TestRefThunk : public TestFixture { +public: + TestRefThunk() : TestFixture("TestRefThunk") {} + +private: + void run() override { + TEST_CASE(callAccess); + TEST_CASE(getReference); + TEST_CASE(referenceConversion); + TEST_CASE(memberAccess); + TEST_CASE(mutation); + TEST_CASE(copyConstruct); + TEST_CASE(copyAssign); + TEST_CASE(rebind); + TEST_CASE(convertToConst); + TEST_CASE(functionArguments); + } + + void callAccess() const { + int x = 42; + const RefThunk p(x); + ASSERT_EQUALS(42, p()); + ASSERT(&p() == &x); + } + + void getReference() const { + int x = 1; + const RefThunk p(x); + ASSERT(&p.get() == &x); + p.get() = 2; + ASSERT_EQUALS(2, x); + } + + void referenceConversion() const { + int x = 1; + const RefThunk p(x); + int& ref = p; + ASSERT(&ref == &x); + ref = 2; + ASSERT_EQUALS(2, x); + } + + void memberAccess() const { + const std::string s = "abc"; + const RefThunk p(s); + ASSERT_EQUALS(3, p().size()); + ASSERT_EQUALS("abc", p()); + } + + void mutation() const { + std::string s = "abc"; + const RefThunk p(s); + p() += "d"; + p().push_back('e'); + ASSERT_EQUALS("abcde", s); + } + + void copyConstruct() const { + int x = 1; + const RefThunk p(x); + const RefThunk q(p); + ASSERT(&q() == &x); + } + + void copyAssign() const { + int x = 1; + int y = 2; + RefThunk p(x); + const RefThunk q(y); + ASSERT(&p() == &x); + p = q; + ASSERT(&p() == &y); + ASSERT_EQUALS(2, p()); + } + + void rebind() const { + int x = 1; + int y = 2; + RefThunk p(x); + ASSERT(&p() == &x); + // assignment rebinds, like std::reference_wrapper - it does not write through + p = y; + ASSERT(&p() == &y); + ASSERT_EQUALS(1, x); + } + + void convertToConst() const { + int x = 1; + const RefThunk p(x); + const RefThunk cp(p); + ASSERT(&cp() == &x); + const int& ref = cp; + ASSERT(&ref == &x); + } + + static std::size_t refArg(const std::string& s) { + return s.size(); + } + + void functionArguments() const { + std::string s = "abcd"; + const RefThunk p(s); + // implicit conversion to reference, like std::reference_wrapper + ASSERT_EQUALS(4, refArg(p)); + // explicit access through operator() + ASSERT_EQUALS(4, refArg(p())); + } +}; + +REGISTER_TEST(TestRefThunk) diff --git a/test/testrunner.vcxproj b/test/testrunner.vcxproj index 1c5230c5535..2ce6a97d9c4 100755 --- a/test/testrunner.vcxproj +++ b/test/testrunner.vcxproj @@ -87,6 +87,7 @@ + diff --git a/test/testsuppressions.cpp b/test/testsuppressions.cpp index 9460999adb1..fbdcb6307e5 100644 --- a/test/testsuppressions.cpp +++ b/test/testsuppressions.cpp @@ -117,6 +117,7 @@ class TestSuppressions : public TestFixture { TEST_CASE(addSuppressionDuplicate); TEST_CASE(updateSuppressionState); TEST_CASE(addSuppressionLineMultiple); + TEST_CASE(hashSuppression); TEST_CASE(suppressionsParseXmlFile); TEST_CASE(xmlMacroSuppressions); @@ -1959,6 +1960,36 @@ class TestSuppressions : public TestFixture { } } + void hashSuppression() const { + SuppressionList supprs; + SuppressionList::Suppression s; + s.errorId = "id"; + s.hash = 1; + ASSERT_EQUALS("", supprs.addSuppression(s)); + ASSERT_EQUALS("suppression 'id' already exists", supprs.addSuppression(s)); + ASSERT_EQUALS(true, supprs.updateSuppressionState(s)); + s.hash = 2; + ASSERT_EQUALS(false, supprs.updateSuppressionState(s)); + // same hash, different id + s.errorId = "id2"; + s.hash = 1; + ASSERT_EQUALS("", supprs.addSuppression(s)); + ASSERT_EQUALS(true, supprs.updateSuppressionState(s)); + + SuppressionList::ErrorMessage error = errorMessage("id"); + error.hash = 1; + ASSERT_EQUALS(true, supprs.isSuppressed(error)); + error.hash = 2; + ASSERT_EQUALS(false, supprs.isSuppressed(error)); + error.hash = 0; + ASSERT_EQUALS(false, supprs.isSuppressed(error)); + error.hash = 1; + error.errorId = "id2"; + ASSERT_EQUALS(true, supprs.isSuppressed(error)); + error.errorId = "id3"; + ASSERT_EQUALS(false, supprs.isSuppressed(error)); + } + void addSuppressionLineMultiple() const { SuppressionList supprlist; diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index fb89e164a74..85ee8430a77 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -1603,6 +1603,66 @@ class TestSymbolDatabase : public TestFixture { ASSERT(p->valueType()->originalTypeName == "ubFunctionPointer_fp"); ASSERT(p->valueType()->reference == Reference::None); } + { // function pointer returning a reference + GET_SYMBOL_DB("void foo(int& (*f)()) {}\n"); + const Variable* const p = db->getVariableFromVarId(1); + ASSERT(!p->isReference()); + ASSERT(p->isPointer()); + ASSERT(p->valueType()); + ASSERT(p->valueType()->pointer == 1); + } + { + GET_SYMBOL_DB("void foo(int&& (*f)()) {}\n"); + const Variable* const p = db->getVariableFromVarId(1); + ASSERT(!p->isReference()); + ASSERT(!p->isRValueReference()); + } + { + GET_SYMBOL_DB("struct S { int& (*f[2])(); };\n"); + const Variable* const p = db->getVariableFromVarId(1); + ASSERT(!p->isReference()); + ASSERT(p->isArray()); + } + { // pointer to member function returning a reference + GET_SYMBOL_DB("struct S { int& g(); };\n" + "void foo(int& (S::*pm)()) {}\n"); + const Variable* const p = db->getVariableFromVarId(1); + ASSERT(p); + ASSERT_EQUALS("pm", p->name()); + ASSERT(!p->isReference()); + } + { // parentheses that are no function declarator + GET_SYMBOL_DB("void foo(int& (r)) {}\n"); + const Variable* const p = db->functionScopes.front()->function->getArgumentVar(0); + ASSERT(p); + ASSERT(p->isReference()); + } + { + GET_SYMBOL_DB("void foo(int& UNUSED(r)) {}\n"); + const Variable* const p = db->functionScopes.front()->function->getArgumentVar(0); + ASSERT(p); + ASSERT(p->isReference()); + } + { // reference to function pointer + GET_SYMBOL_DB("void foo(int (*&f)()) {}\n"); + const Variable* const p = db->getVariableFromVarId(1); + ASSERT(p->isReference()); + ASSERT(p->isPointer()); + ASSERT(p->valueType()); + ASSERT(p->valueType()->reference == Reference::LValue); + } + { // reference to function returning a reference + GET_SYMBOL_DB("void foo(int& (&f)()) {}\n"); + const Variable* const p = db->getVariableFromVarId(1); + ASSERT(p->isReference()); + ASSERT(!p->isRValueReference()); + } + { + GET_SYMBOL_DB("void foo(int&& (&f)()) {}\n"); + const Variable* const p = db->getVariableFromVarId(1); + ASSERT(p->isReference()); + ASSERT(!p->isRValueReference()); + } } void VariableValueTypeTemplate() { @@ -2411,6 +2471,31 @@ class TestSymbolDatabase : public TestFixture { ASSERT(db && ctor && ctor->type == FunctionType::eMoveConstructor); ASSERT(ctor && ctor->retDef == nullptr); } + { + GET_SYMBOL_DB("class Foo { Foo(Foo&& (*f)()); };\n"); + const Function* ctor = tokenizer.tokens()->tokAt(3)->function(); + ASSERT(db && ctor && ctor->type == FunctionType::eConstructor); + } + { + GET_SYMBOL_DB("class Foo { Foo(Foo& (&f)()); };\n"); + const Function* ctor = tokenizer.tokens()->tokAt(3)->function(); + ASSERT(db && ctor && ctor->type == FunctionType::eConstructor); + } + { + GET_SYMBOL_DB("class Foo { Foo(Foo&& (&f)()); };\n"); + const Function* ctor = tokenizer.tokens()->tokAt(3)->function(); + ASSERT(db && ctor && ctor->type == FunctionType::eConstructor); + } + { + GET_SYMBOL_DB("class Foo { Foo(Foo (&f)()); };\n"); + const Function* ctor = tokenizer.tokens()->tokAt(3)->function(); + ASSERT(db && ctor && ctor->type == FunctionType::eConstructor); + } + { + GET_SYMBOL_DB("class Foo { Foo(Foo& (&)()); };\n"); + const Function* ctor = tokenizer.tokens()->tokAt(3)->function(); + ASSERT(db && ctor && ctor->type == FunctionType::eConstructor); + } { GET_SYMBOL_DB("void f() { extern void f(); }\n"); ASSERT(db && db->scopeList.size() == 2); @@ -9987,6 +10072,8 @@ class TestSymbolDatabase : public TestFixture { ASSERT_EQUALS("signed long", typeOf("a = (long)32;\n", "(")); ASSERT_EQUALS("signed long", typeOf("a = (long int)32;\n", "(")); ASSERT_EQUALS("signed long long", typeOf("a = (long long)32;\n", "(")); + ASSERT_EQUALS("signed int &", typeOf("void f(int& (*fp)()) { fp(); }\n", "( ) ;")); // #15094 + ASSERT_EQUALS("signed int &&", typeOf("void f(int&& (*fp)()) { fp(); }\n", "( ) ;")); ASSERT_EQUALS("long double", typeOf("a = (long double)32;\n", "(")); ASSERT_EQUALS("char", typeOf("a = static_cast(32);\n", "(")); ASSERT_EQUALS("", typeOf("a = (unsigned x)0;\n", "(")); diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 75a94c26aec..00e53ac1e0f 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -240,6 +240,7 @@ class TestTokenizer : public TestFixture { TEST_CASE(vardecl33); TEST_CASE(vardecl34); TEST_CASE(vardecl35); + TEST_CASE(vardecl36); TEST_CASE(vardecl_stl_1); TEST_CASE(vardecl_stl_2); TEST_CASE(vardecl_stl_3); @@ -2028,6 +2029,26 @@ class TestTokenizer : public TestFixture { "void S::func() const\n" "try { f(); }\n" "catch (...) { g(); }\n")); + + ASSERT_EQUALS("struct D : B {\n" // #15126 + "void f ( ) override { try { } catch ( ... ) { } }\n" + "void g ( ) final { try { } catch ( ... ) { } }\n" + "void i ( ) & override { try { } catch ( ... ) { } }\n" + "void j ( ) const && override { try { } catch ( ... ) { } }\n" + "auto k ( ) . std :: nullptr_t override { try { } catch ( ... ) { } }\n" + "auto l ( ) . W < decltype ( 1 ) > override { try { } catch ( ... ) { } }\n" + "} ;", + tokenizeAndStringify("struct D : B {\n" + " void f() override try {} catch (...) {}\n" + " void g() final try {} catch (...) {}\n" + " void i() & override try {} catch (...) {}\n" + " void j() const && override try {} catch (...) {}\n" + " auto k() -> std::nullptr_t override try {} catch (...) {}\n" + " auto l() -> W override try {} catch (...) {}\n" + "};\n")); + ASSERT_EQUALS("[test.cpp:6:5]: (debug) auto token with no type. [autoNoType]\n" + "[test.cpp:7:5]: (debug) auto token with no type. [autoNoType]\n", + errout_str()); } // Simplify "((..))" into "(..)" @@ -3035,6 +3056,38 @@ class TestTokenizer : public TestFixture { } } + void vardecl36() { + const char code[] = "struct S {\n" // #15086 + " bool f1() const;\n" + " bool f2() const;\n" + " int g() const;\n" + " int x, y;\n" + "};\n" + "bool S::f1() const {\n" + " const bool b = x ? g() < 0 : 0 > y;\n" + " return b;\n" + "}\n" + "bool S::f2() const {\n" + " const bool b = g() < x ? x != y : 0 > y;\n" + " return b;\n" + "}\n"; + const char expected[] = "struct S {\n" + "bool f1 ( ) const ;\n" + "bool f2 ( ) const ;\n" + "int g ( ) const ;\n" + "int x ; int y ;\n" + "} ;\n" + "bool S :: f1 ( ) const {\n" + "const bool b = x ? ( g ( ) < 0 ) : 0 > y ;\n" + "return b ;\n" + "}\n" + "bool S :: f2 ( ) const {\n" + "const bool b = g ( ) < x ? x != y : 0 > y ;\n" + "return b ;\n" + "}"; + ASSERT_EQUALS(expected, tokenizeAndStringify(code)); + } + void volatile_variables() { { const char code[] = "volatile int a=0;\n" diff --git a/test/testunusedvar.cpp b/test/testunusedvar.cpp index f25d544c906..78ecd45ccef 100644 --- a/test/testunusedvar.cpp +++ b/test/testunusedvar.cpp @@ -3370,6 +3370,14 @@ class TestUnusedVar : public TestFixture { " return a;\n" "}\n"); ASSERT_EQUALS("[test.cpp:5:14]: (style) Variable 'b[c]' is assigned a value that is never used. [unreadVariable]\n", errout_str()); + + functionVariableUsage("int f() {\n" // #14769 + " int i = 2;\n" + " const int *a, *c;\n" + " a = c = &i;\n" + " return *a;\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:4:11]: (style) Variable 'c' is assigned a value that is never used. [unreadVariable]\n", errout_str()); } void localvar24() { // ticket #1803 diff --git a/test/tools/htmlreport/test_htmlreport.py b/test/tools/htmlreport/test_htmlreport.py index f84fd279fb3..b8c73072a70 100755 --- a/test/tools/htmlreport/test_htmlreport.py +++ b/test/tools/htmlreport/test_htmlreport.py @@ -114,6 +114,32 @@ def testSeverityFilterBar(self): self.assertIn('onclick="toggleSeverity(this)"', report) output_directory.cleanup() + def testEscape(self): + with tempfile.TemporaryDirectory() as source_directory: + source_filename = os.path.join(source_directory, 'escape.c') + with open(source_filename, 'w') as source_file: + source_file.write('#error escape\n') + + with runCheck( + source_filename, + xml_version='2' + ) as (report, output_directory): + self.assertIn('<b>escape.c', report) + self.assertNotIn('', report) + + with open(os.path.join(output_directory.name, '0.html')) as input_file: + detail_contents = input_file.read() + self.assertIn('<b>escape.c', detail_contents) + self.assertIn('<--- #error <b>escape</b>', detail_contents) + self.assertNotIn('', detail_contents) + + with open(os.path.join(output_directory.name, 'stats.html')) as input_file: + stats_contents = input_file.read() + self.assertIn('<b>escape.c', stats_contents) + self.assertNotIn('', stats_contents) + + output_directory.cleanup() + @contextlib.contextmanager def runCheck(source_filename=None, xml_version='1', xml_filename=None, checkers_filename=None): diff --git a/tools/dmake/dmake.cpp b/tools/dmake/dmake.cpp index eaf0a727646..f9e638385e7 100644 --- a/tools/dmake/dmake.cpp +++ b/tools/dmake/dmake.cpp @@ -502,6 +502,7 @@ int main(int argc, char **argv) libfiles_h.emplace("findtoken.h"); libfiles_h.emplace("json.h"); libfiles_h.emplace("matchcompiler.h"); + libfiles_h.emplace("refthunk.h"); libfiles_h.emplace("precompiled.h"); libfiles_h.emplace("rule.h"); libfiles_h.emplace("smallvector.h");