Coverage Report

Created: 2025-01-24 06:31

/src/cppcheck/lib/settings.h
Line
Count
Source (jump to first uncovered line)
1
/* -*- C++ -*-
2
 * Cppcheck - A tool for static C/C++ code analysis
3
 * Copyright (C) 2007-2024 Cppcheck team.
4
 *
5
 * This program is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18
19
//---------------------------------------------------------------------------
20
#ifndef settingsH
21
#define settingsH
22
//---------------------------------------------------------------------------
23
24
#include "addoninfo.h"
25
#include "config.h"
26
#include "errortypes.h"
27
#include "library.h"
28
#include "platform.h"
29
#include "standards.h"
30
#include "suppressions.h"
31
32
#include <algorithm>
33
#include <atomic>
34
#include <cstddef>
35
#include <cstdint>
36
#include <functional>
37
#include <list>
38
#include <map>
39
#include <set>
40
#include <string>
41
#include <tuple>
42
#include <vector>
43
#include <unordered_set>
44
#include <utility>
45
46
#if defined(USE_WINDOWS_SEH) || defined(USE_UNIX_SIGNAL_HANDLING)
47
#include <cstdio>
48
#endif
49
50
enum class SHOWTIME_MODES : std::uint8_t;
51
namespace ValueFlow {
52
    class Value;
53
}
54
55
/// @addtogroup Core
56
/// @{
57
58
template<typename T>
59
class SimpleEnableGroup {
60
    uint32_t mFlags = 0;
61
public:
62
2.98k
    uint32_t intValue() const {
63
2.98k
        return mFlags;
64
2.98k
    }
SimpleEnableGroup<Severity>::intValue() const
Line
Count
Source
62
1.99k
    uint32_t intValue() const {
63
1.99k
        return mFlags;
64
1.99k
    }
SimpleEnableGroup<Checks>::intValue() const
Line
Count
Source
62
996
    uint32_t intValue() const {
63
996
        return mFlags;
64
996
    }
65
    void clear() {
66
        mFlags = 0;
67
    }
68
996
    void fill() {
69
996
        mFlags = 0xFFFFFFFF;
70
996
    }
71
130k
    bool isEnabled(T flag) const {
72
130k
        return (mFlags & (1U << (uint32_t)flag)) != 0;
73
130k
    }
SimpleEnableGroup<Certainty>::isEnabled(Certainty) const
Line
Count
Source
71
21.3k
    bool isEnabled(T flag) const {
72
21.3k
        return (mFlags & (1U << (uint32_t)flag)) != 0;
73
21.3k
    }
SimpleEnableGroup<Severity>::isEnabled(Severity) const
Line
Count
Source
71
106k
    bool isEnabled(T flag) const {
72
106k
        return (mFlags & (1U << (uint32_t)flag)) != 0;
73
106k
    }
SimpleEnableGroup<Checks>::isEnabled(Checks) const
Line
Count
Source
71
2.52k
    bool isEnabled(T flag) const {
72
2.52k
        return (mFlags & (1U << (uint32_t)flag)) != 0;
73
2.52k
    }
74
5.97k
    void enable(T flag) {
75
5.97k
        mFlags |= (1U << (uint32_t)flag);
76
5.97k
    }
SimpleEnableGroup<Certainty>::enable(Certainty)
Line
Count
Source
74
1.99k
    void enable(T flag) {
75
1.99k
        mFlags |= (1U << (uint32_t)flag);
76
1.99k
    }
SimpleEnableGroup<Checks>::enable(Checks)
Line
Count
Source
74
1.99k
    void enable(T flag) {
75
1.99k
        mFlags |= (1U << (uint32_t)flag);
76
1.99k
    }
SimpleEnableGroup<Severity>::enable(Severity)
Line
Count
Source
74
1.99k
    void enable(T flag) {
75
1.99k
        mFlags |= (1U << (uint32_t)flag);
76
1.99k
    }
77
2.98k
    void enable(SimpleEnableGroup<T> group) {
78
2.98k
        mFlags |= group.intValue();
79
2.98k
    }
SimpleEnableGroup<Severity>::enable(SimpleEnableGroup<Severity>)
Line
Count
Source
77
1.99k
    void enable(SimpleEnableGroup<T> group) {
78
1.99k
        mFlags |= group.intValue();
79
1.99k
    }
SimpleEnableGroup<Checks>::enable(SimpleEnableGroup<Checks>)
Line
Count
Source
77
996
    void enable(SimpleEnableGroup<T> group) {
78
996
        mFlags |= group.intValue();
79
996
    }
80
996
    void disable(T flag) {
81
996
        mFlags &= ~(1U << (uint32_t)flag);
82
996
    }
Unexecuted instantiation: SimpleEnableGroup<Certainty>::disable(Certainty)
SimpleEnableGroup<Severity>::disable(Severity)
Line
Count
Source
80
996
    void disable(T flag) {
81
996
        mFlags &= ~(1U << (uint32_t)flag);
82
996
    }
83
0
    void disable(SimpleEnableGroup<T> group) {
84
0
        mFlags &= ~(group.intValue());
85
0
    }
Unexecuted instantiation: SimpleEnableGroup<Severity>::disable(SimpleEnableGroup<Severity>)
Unexecuted instantiation: SimpleEnableGroup<Checks>::disable(SimpleEnableGroup<Checks>)
86
2.98k
    void setEnabled(T flag, bool enabled) {
87
2.98k
        if (enabled)
88
2.98k
            enable(flag);
89
0
        else
90
0
            disable(flag);
91
2.98k
    }
SimpleEnableGroup<Severity>::setEnabled(Severity, bool)
Line
Count
Source
86
996
    void setEnabled(T flag, bool enabled) {
87
996
        if (enabled)
88
996
            enable(flag);
89
0
        else
90
0
            disable(flag);
91
996
    }
SimpleEnableGroup<Certainty>::setEnabled(Certainty, bool)
Line
Count
Source
86
1.99k
    void setEnabled(T flag, bool enabled) {
87
1.99k
        if (enabled)
88
1.99k
            enable(flag);
89
0
        else
90
0
            disable(flag);
91
1.99k
    }
92
};
93
94
95
/**
96
 * @brief This is just a container for general settings so that we don't need
97
 * to pass individual values to functions or constructors now or in the
98
 * future when we might have even more detailed settings.
99
 */
100
class CPPCHECKLIB WARN_UNUSED Settings {
101
private:
102
103
    /** @brief terminate checking */
104
    static std::atomic<bool> mTerminated;
105
106
public:
107
    Settings();
108
109
    static std::string loadCppcheckCfg(Settings& settings, Suppressions& suppressions, bool debug = false);
110
111
    static std::pair<std::string, std::string> getNameAndVersion(const std::string& productName);
112
113
    /** @brief addons, either filename of python/json file or json data */
114
    std::unordered_set<std::string> addons;
115
116
    /** @brief the loaded addons infos */
117
    std::vector<AddonInfo> addonInfos;
118
119
    /** @brief Path to the python interpreter to be used to run addons. */
120
    std::string addonPython;
121
122
    /** @brief Paths used as base for conversion to relative paths. */
123
    std::vector<std::string> basePaths;
124
125
    /** @brief --cppcheck-build-dir. Always uses / as path separator. No trailing path separator. */
126
    std::string buildDir;
127
128
    /** @brief check all configurations (false if -D or --max-configs is used */
129
    bool checkAllConfigurations = true;
130
131
    /** Is the 'configuration checking' wanted? */
132
    bool checkConfiguration{};
133
134
    /**
135
     * Check code in the headers, this is on by default but can
136
     * be turned off to save CPU */
137
    bool checkHeaders = true;
138
139
    /** Check for incomplete info in library files? */
140
    bool checkLibrary{};
141
142
    /** @brief The maximum time in seconds for the checks of a single file */
143
    int checksMaxTime{};
144
145
    /** @brief --checkers-report=<filename> : Generate report of executed checkers */
146
    std::string checkersReportFilename;
147
148
    /** @brief check unknown function return values */
149
    std::set<std::string> checkUnknownFunctionReturn;
150
151
    /** Check unused/uninstantiated templates */
152
    bool checkUnusedTemplates = true;
153
154
    /** Use Clang */
155
    bool clang{};
156
157
    /** Custom Clang executable */
158
    std::string clangExecutable = "clang";
159
160
    /** Use clang-tidy */
161
    bool clangTidy{};
162
163
    /** Internal: Clear the simplecpp non-existing include cache */
164
    bool clearIncludeCache{};
165
166
    /** @brief include paths excluded from checking the configuration */
167
    std::set<std::string> configExcludePaths;
168
169
    /** cppcheck.cfg: Custom product name */
170
    std::string cppcheckCfgProductName;
171
172
    /** cppcheck.cfg: About text */
173
    std::string cppcheckCfgAbout;
174
175
    /** @brief check Emacs marker to detect extension-less and *.h files as C++ */
176
    bool cppHeaderProbe{};
177
178
    /** @brief Are we running from DACA script? */
179
    bool daca{};
180
181
    /** @brief Is --debug-clang-output given? */
182
    bool debugClangOutput{};
183
184
    /** @brief Internal: Is --debug-lookup or --debug-lookup=all given? */
185
    bool debuglookup{};
186
187
    /** @brief Internal: Is --debug-lookup=addon given? */
188
    bool debuglookupAddon{};
189
190
    /** @brief Internal: Is --debug-lookup=config given? */
191
    bool debuglookupConfig{};
192
193
    /** @brief Internal: Is --debug-lookup=library given? */
194
    bool debuglookupLibrary{};
195
196
    /** @brief Internal: Is --debug-lookup=platform given? */
197
    bool debuglookupPlatform{};
198
199
    /** @brief Is --debug-normal given? */
200
    bool debugnormal{};
201
202
    /** @brief Is --debug-simplified given? */
203
    bool debugSimplified{};
204
205
    /** @brief Is --debug-template given? */
206
    bool debugtemplate{};
207
208
    /** @brief Is --debug-warnings given? */
209
    bool debugwarnings{};
210
211
    /** @brief Is --dump given? */
212
    bool dump{};
213
214
    /** @brief Do not filter duplicated errors. */
215
    bool emitDuplicates{};
216
217
    /** @brief Name of the language that is enforced. Empty per default. */
218
    Standards::Language enforcedLang{};
219
220
#if defined(USE_WINDOWS_SEH) || defined(USE_UNIX_SIGNAL_HANDLING)
221
    /** @brief Is --exception-handling given */
222
    bool exceptionHandling{};
223
224
    FILE* exceptionOutput = stdout;
225
#endif
226
227
    enum class ExecutorType : std::uint8_t
228
    {
229
#ifdef HAS_THREADING_MODEL_THREAD
230
        Thread,
231
#endif
232
#ifdef HAS_THREADING_MODEL_FORK
233
        Process
234
#endif
235
    };
236
237
    ExecutorType executor;
238
239
    // argv[0]
240
    std::string exename;
241
242
    /** @brief If errors are found, this value is returned from main().
243
        Default value is 0. */
244
    int exitCode{};
245
246
    /** @brief List of --file-filter for analyzing special files */
247
    std::vector<std::string> fileFilters;
248
249
    /** @brief Force checking the files with "too many" configurations (--force). */
250
    bool force{};
251
252
    /** @brief List of include paths, e.g. "my/includes/" which should be used
253
        for finding include files inside source files. (-I) */
254
    std::list<std::string> includePaths;
255
256
    /** @brief Is --inline-suppr given? */
257
    bool inlineSuppressions{};
258
259
    /** @brief How many processes/threads should do checking at the same
260
        time. Default is 1. (-j N) */
261
    unsigned int jobs = 1;
262
263
    /** @brief --library= */
264
    std::list<std::string> libraries;
265
266
    /** Library */
267
    Library library;
268
269
    /** @brief Load average value */
270
    int loadAverage{};
271
272
    /** @brief Maximum number of configurations to check before bailing.
273
        Default is 12. (--max-configs=N) */
274
    int maxConfigs = 12;
275
276
    /** @brief --max-ctu-depth */
277
    int maxCtuDepth = 2;
278
279
    /** @brief max template recursion */
280
    int maxTemplateRecursion = 100;
281
282
    /** @brief write results (--output-file=&lt;file&gt;) */
283
    std::string outputFile;
284
285
    enum class OutputFormat : std::uint8_t {text, plist, sarif, xml};
286
    OutputFormat outputFormat = OutputFormat::text;
287
288
    Platform platform;
289
290
    /** @brief pid of cppcheck. Intention is that this is set in the main process. */
291
    int pid;
292
293
    /** @brief plist output (--plist-output=&lt;dir&gt;) */
294
    std::string plistOutput;
295
296
    /** @brief Extra arguments for Cppcheck Premium addon */
297
    std::string premiumArgs;
298
299
    /** Is checker id enabled by premiumArgs */
300
    bool isPremiumEnabled(const char id[]) const;
301
302
    /** @brief Using -E for debugging purposes */
303
    bool preprocessOnly{};
304
305
    /** @brief Is --quiet given? */
306
    bool quiet{};
307
308
    /** @brief Use relative paths in output. */
309
    bool relativePaths{};
310
311
    /** @brief --report-progress */
312
    int reportProgress{-1};
313
314
#ifdef HAVE_RULES
315
    /** Rule */
316
    struct CPPCHECKLIB Rule {
317
        std::string tokenlist = "normal"; // use normal tokenlist
318
        std::string pattern;
319
        std::string id = "rule"; // default id
320
        std::string summary;
321
        Severity severity = Severity::style; // default severity
322
    };
323
324
    /**
325
     * @brief Extra rules
326
     */
327
    std::list<Rule> rules;
328
#endif
329
330
    /**
331
     * @brief Safety certified behavior
332
     * Show checkers report when Cppcheck finishes
333
     * Make cppcheck checking more strict about critical errors
334
     * - returns nonzero if there is critical errors
335
     * - a critical error id is not suppressed (by mistake?) with glob pattern
336
     */
337
    bool safety = false;
338
339
    /** Do not only check how interface is used. Also check that interface is safe. */
340
    struct CPPCHECKLIB SafeChecks {
341
342
        static const char XmlRootName[];
343
        static const char XmlClasses[];
344
        static const char XmlExternalFunctions[];
345
        static const char XmlInternalFunctions[];
346
        static const char XmlExternalVariables[];
347
348
0
        void clear() {
349
0
            classes = externalFunctions = internalFunctions = externalVariables = false;
350
0
        }
351
352
        /**
353
         * Public interface of classes
354
         * - public function parameters can have any value
355
         * - public functions can be called in any order
356
         * - public variables can have any value
357
         */
358
        bool classes{};
359
360
        /**
361
         * External functions
362
         * - external functions can be called in any order
363
         * - function parameters can have any values
364
         */
365
        bool externalFunctions{};
366
367
        /**
368
         * Experimental: assume that internal functions can be used in any way
369
         * This is only available in the GUI.
370
         */
371
        bool internalFunctions{};
372
373
        /**
374
         * Global variables that can be modified outside the TU.
375
         * - Such variable can have "any" value
376
         */
377
        bool externalVariables{};
378
    };
379
380
    SafeChecks safeChecks;
381
382
    SimpleEnableGroup<Severity> severity;
383
    SimpleEnableGroup<Certainty> certainty;
384
    SimpleEnableGroup<Checks> checks;
385
386
    /** @brief show timing information (--showtime=file|summary|top5) */
387
    SHOWTIME_MODES showtime{};
388
389
    /** Struct contains standards settings */
390
    Standards standards;
391
392
    /** @brief suppressions */
393
    Suppressions supprs;
394
395
    /** @brief The output format in which the errors are printed in text mode,
396
        e.g. "{severity} {file}:{line} {message} {id}" */
397
    std::string templateFormat;
398
399
    /** @brief The output format in which the error locations are printed in
400
     *  text mode, e.g. "{file}:{line} {info}" */
401
    std::string templateLocation;
402
403
    /** @brief The maximum time in seconds for the template instantiation */
404
    std::size_t templateMaxTime{};
405
406
    /** @brief The maximum time in seconds for the typedef simplification */
407
    std::size_t typedefMaxTime{};
408
409
    /** @brief defines given by the user */
410
    std::string userDefines;
411
412
    /** @brief undefines given by the user */
413
    std::set<std::string> userUndefs;
414
415
    /** @brief forced includes given by the user */
416
    std::list<std::string> userIncludes;
417
418
    // TODO: adjust all options so 0 means "disabled" and -1 "means "unlimited"
419
    struct ValueFlowOptions
420
    {
421
        /** @brief the maximum iterations to execute */
422
        std::size_t maxIterations = 4;
423
424
        /** @brief maximum numer if-branches */
425
        int maxIfCount = -1;
426
427
        /** @brief maximum number of sets of arguments to pass to subfuncions */
428
        int maxSubFunctionArgs = 256;
429
430
        /** @brief Experimental: maximum execution time */
431
        int maxTime = -1;
432
433
        /** @brief Control if condition expression analysis is performed */
434
        bool doConditionExpressionAnalysis = true;
435
436
        /** @brief Maximum performed for-loop count */
437
        int maxForLoopCount = 10000;
438
439
        /** @brief Maximum performed forward branches */
440
        int maxForwardBranches = -1;
441
442
        /** @brief Maximum performed alignof recursion */
443
        int maxAlignOfRecursion = 100;
444
445
        /** @brief Maximum performed sizeof recursion */
446
        int maxSizeOfRecursion = 100;
447
448
        /** @brief Maximum expression varid depth */
449
        int maxExprVarIdDepth = 4;
450
    };
451
452
    /** @brief The ValueFlow options */
453
    ValueFlowOptions vfOptions;
454
455
    /** @brief Is --verbose given? */
456
    bool verbose{};
457
458
    /** @brief write XML results (--xml) */
459
    bool xml{};
460
461
    /** @brief XML version (--xml-version=..) */
462
    int xml_version = 2;
463
464
    /**
465
     * @brief return true if a included file is to be excluded in Preprocessor::getConfigs
466
     * @return true for the file to be excluded.
467
     */
468
0
    bool configurationExcluded(const std::string &file) const {
469
0
        return std::any_of(configExcludePaths.begin(), configExcludePaths.end(), [&file](const std::string& path) {
470
0
            return file.length() >= path.length() && file.compare(0, path.length(), path) == 0;
471
0
        });
472
0
    }
473
474
    /**
475
     * @brief Enable extra checks by id. See isEnabled()
476
     * @param str single id or list of id values to be enabled
477
     * or empty string to enable all. e.g. "style,possibleError"
478
     * @return error message. empty upon success
479
     */
480
    std::string addEnabled(const std::string &str);
481
482
    /**
483
     * @brief Disable extra checks by id
484
     * @param str single id or list of id values to be enabled
485
     * or empty string to enable all. e.g. "style,possibleError"
486
     * @return error message. empty upon success
487
     */
488
    std::string removeEnabled(const std::string &str);
489
490
    /**
491
     * @brief Returns true if given value can be shown
492
     * @return true if the value can be shown
493
     */
494
    bool isEnabled(const ValueFlow::Value *value, bool inconclusiveCheck=false) const;
495
496
    /** Is library specified? */
497
722
    bool hasLib(const std::string &lib) const {
498
722
        return std::find(libraries.cbegin(), libraries.cend(), lib) != libraries.cend();
499
722
    }
500
501
    /** @brief Request termination of checking */
502
0
    static void terminate(bool t = true) {
503
0
        Settings::mTerminated = t;
504
0
    }
505
506
    /** @brief termination requested? */
507
162k
    static bool terminated() {
508
162k
        return Settings::mTerminated;
509
162k
    }
510
511
    std::set<std::string> summaryReturn;
512
513
    void loadSummaries();
514
515
3.15k
    bool useSingleJob() const {
516
3.15k
        return jobs == 1;
517
3.15k
    }
518
519
    enum class CheckLevel : std::uint8_t {
520
        reduced,
521
        normal,
522
        exhaustive
523
    };
524
    CheckLevel checkLevel = CheckLevel::exhaustive;
525
526
    void setCheckLevel(CheckLevel level);
527
528
    using ExecuteCmdFn = std::function<int (std::string,std::vector<std::string>,std::string,std::string&)>;
529
    void setMisraRuleTexts(const ExecuteCmdFn& executeCommand);
530
    void setMisraRuleTexts(const std::string& data);
531
    std::string getMisraRuleText(const std::string& id, const std::string& text) const;
532
533
    static ExecutorType defaultExecutor();
534
535
private:
536
    static std::string parseEnabled(const std::string &str, std::tuple<SimpleEnableGroup<Severity>, SimpleEnableGroup<Checks>> &groups);
537
    std::string applyEnabled(const std::string &str, bool enable);
538
    std::map<std::string, std::string> mMisraRuleTexts;
539
};
540
541
/// @}
542
//---------------------------------------------------------------------------
543
#endif // settingsH