xref: /aosp_15_r20/external/regex-re2/re2/testing/exhaustive_tester.h (revision ccdc9c3e24c519bfa4832a66aa2e83a52c19f295)
1*ccdc9c3eSSadaf Ebrahimi // Copyright 2009 The RE2 Authors.  All Rights Reserved.
2*ccdc9c3eSSadaf Ebrahimi // Use of this source code is governed by a BSD-style
3*ccdc9c3eSSadaf Ebrahimi // license that can be found in the LICENSE file.
4*ccdc9c3eSSadaf Ebrahimi 
5*ccdc9c3eSSadaf Ebrahimi #ifndef RE2_TESTING_EXHAUSTIVE_TESTER_H_
6*ccdc9c3eSSadaf Ebrahimi #define RE2_TESTING_EXHAUSTIVE_TESTER_H_
7*ccdc9c3eSSadaf Ebrahimi 
8*ccdc9c3eSSadaf Ebrahimi #include <stdint.h>
9*ccdc9c3eSSadaf Ebrahimi #include <string>
10*ccdc9c3eSSadaf Ebrahimi #include <vector>
11*ccdc9c3eSSadaf Ebrahimi 
12*ccdc9c3eSSadaf Ebrahimi #include "util/util.h"
13*ccdc9c3eSSadaf Ebrahimi #include "re2/testing/regexp_generator.h"
14*ccdc9c3eSSadaf Ebrahimi #include "re2/testing/string_generator.h"
15*ccdc9c3eSSadaf Ebrahimi 
16*ccdc9c3eSSadaf Ebrahimi namespace re2 {
17*ccdc9c3eSSadaf Ebrahimi 
18*ccdc9c3eSSadaf Ebrahimi // Doing this simplifies the logic below.
19*ccdc9c3eSSadaf Ebrahimi #ifndef __has_feature
20*ccdc9c3eSSadaf Ebrahimi #define __has_feature(x) 0
21*ccdc9c3eSSadaf Ebrahimi #endif
22*ccdc9c3eSSadaf Ebrahimi 
23*ccdc9c3eSSadaf Ebrahimi #if !defined(NDEBUG)
24*ccdc9c3eSSadaf Ebrahimi // We are in a debug build.
25*ccdc9c3eSSadaf Ebrahimi const bool RE2_DEBUG_MODE = true;
26*ccdc9c3eSSadaf Ebrahimi #elif __has_feature(address_sanitizer) || __has_feature(memory_sanitizer) || __has_feature(thread_sanitizer)
27*ccdc9c3eSSadaf Ebrahimi // Not a debug build, but still under sanitizers.
28*ccdc9c3eSSadaf Ebrahimi const bool RE2_DEBUG_MODE = true;
29*ccdc9c3eSSadaf Ebrahimi #else
30*ccdc9c3eSSadaf Ebrahimi const bool RE2_DEBUG_MODE = false;
31*ccdc9c3eSSadaf Ebrahimi #endif
32*ccdc9c3eSSadaf Ebrahimi 
33*ccdc9c3eSSadaf Ebrahimi // Exhaustive regular expression test: generate all regexps within parameters,
34*ccdc9c3eSSadaf Ebrahimi // then generate all strings of a given length over a given alphabet,
35*ccdc9c3eSSadaf Ebrahimi // then check that NFA, DFA, and PCRE agree about whether each regexp matches
36*ccdc9c3eSSadaf Ebrahimi // each possible string, and if so, where the match is.
37*ccdc9c3eSSadaf Ebrahimi //
38*ccdc9c3eSSadaf Ebrahimi // Can also be used in a "random" mode that generates a given number
39*ccdc9c3eSSadaf Ebrahimi // of random regexp and strings, allowing testing of larger expressions
40*ccdc9c3eSSadaf Ebrahimi // and inputs.
41*ccdc9c3eSSadaf Ebrahimi class ExhaustiveTester : public RegexpGenerator {
42*ccdc9c3eSSadaf Ebrahimi  public:
ExhaustiveTester(int maxatoms,int maxops,const std::vector<string> & alphabet,const std::vector<string> & ops,int maxstrlen,const std::vector<string> & stralphabet,const string & wrapper,const string & topwrapper)43*ccdc9c3eSSadaf Ebrahimi   ExhaustiveTester(int maxatoms,
44*ccdc9c3eSSadaf Ebrahimi                    int maxops,
45*ccdc9c3eSSadaf Ebrahimi                    const std::vector<string>& alphabet,
46*ccdc9c3eSSadaf Ebrahimi                    const std::vector<string>& ops,
47*ccdc9c3eSSadaf Ebrahimi                    int maxstrlen,
48*ccdc9c3eSSadaf Ebrahimi                    const std::vector<string>& stralphabet,
49*ccdc9c3eSSadaf Ebrahimi                    const string& wrapper,
50*ccdc9c3eSSadaf Ebrahimi                    const string& topwrapper)
51*ccdc9c3eSSadaf Ebrahimi     : RegexpGenerator(maxatoms, maxops, alphabet, ops),
52*ccdc9c3eSSadaf Ebrahimi       strgen_(maxstrlen, stralphabet),
53*ccdc9c3eSSadaf Ebrahimi       wrapper_(wrapper),
54*ccdc9c3eSSadaf Ebrahimi       topwrapper_(topwrapper),
55*ccdc9c3eSSadaf Ebrahimi       regexps_(0), tests_(0), failures_(0),
56*ccdc9c3eSSadaf Ebrahimi       randomstrings_(0), stringseed_(0), stringcount_(0)  { }
57*ccdc9c3eSSadaf Ebrahimi 
regexps()58*ccdc9c3eSSadaf Ebrahimi   int regexps()  { return regexps_; }
tests()59*ccdc9c3eSSadaf Ebrahimi   int tests()    { return tests_; }
failures()60*ccdc9c3eSSadaf Ebrahimi   int failures() { return failures_; }
61*ccdc9c3eSSadaf Ebrahimi 
62*ccdc9c3eSSadaf Ebrahimi   // Needed for RegexpGenerator interface.
63*ccdc9c3eSSadaf Ebrahimi   void HandleRegexp(const string& regexp);
64*ccdc9c3eSSadaf Ebrahimi 
65*ccdc9c3eSSadaf Ebrahimi   // Causes testing to generate random input strings.
RandomStrings(int32_t seed,int32_t count)66*ccdc9c3eSSadaf Ebrahimi   void RandomStrings(int32_t seed, int32_t count) {
67*ccdc9c3eSSadaf Ebrahimi     randomstrings_ = true;
68*ccdc9c3eSSadaf Ebrahimi     stringseed_ = seed;
69*ccdc9c3eSSadaf Ebrahimi     stringcount_ = count;
70*ccdc9c3eSSadaf Ebrahimi   }
71*ccdc9c3eSSadaf Ebrahimi 
72*ccdc9c3eSSadaf Ebrahimi  private:
73*ccdc9c3eSSadaf Ebrahimi   StringGenerator strgen_;
74*ccdc9c3eSSadaf Ebrahimi   string wrapper_;      // Regexp wrapper - either empty or has one %s.
75*ccdc9c3eSSadaf Ebrahimi   string topwrapper_;   // Regexp top-level wrapper.
76*ccdc9c3eSSadaf Ebrahimi   int regexps_;   // Number of HandleRegexp calls
77*ccdc9c3eSSadaf Ebrahimi   int tests_;     // Number of regexp tests.
78*ccdc9c3eSSadaf Ebrahimi   int failures_;  // Number of tests failed.
79*ccdc9c3eSSadaf Ebrahimi 
80*ccdc9c3eSSadaf Ebrahimi   bool randomstrings_;  // Whether to use random strings
81*ccdc9c3eSSadaf Ebrahimi   int32_t stringseed_;  // If so, the seed.
82*ccdc9c3eSSadaf Ebrahimi   int stringcount_;     // If so, how many to generate.
83*ccdc9c3eSSadaf Ebrahimi 
84*ccdc9c3eSSadaf Ebrahimi   ExhaustiveTester(const ExhaustiveTester&) = delete;
85*ccdc9c3eSSadaf Ebrahimi   ExhaustiveTester& operator=(const ExhaustiveTester&) = delete;
86*ccdc9c3eSSadaf Ebrahimi };
87*ccdc9c3eSSadaf Ebrahimi 
88*ccdc9c3eSSadaf Ebrahimi // Runs an exhaustive test on the given parameters.
89*ccdc9c3eSSadaf Ebrahimi void ExhaustiveTest(int maxatoms, int maxops,
90*ccdc9c3eSSadaf Ebrahimi                     const std::vector<string>& alphabet,
91*ccdc9c3eSSadaf Ebrahimi                     const std::vector<string>& ops,
92*ccdc9c3eSSadaf Ebrahimi                     int maxstrlen,
93*ccdc9c3eSSadaf Ebrahimi                     const std::vector<string>& stralphabet,
94*ccdc9c3eSSadaf Ebrahimi                     const string& wrapper,
95*ccdc9c3eSSadaf Ebrahimi                     const string& topwrapper);
96*ccdc9c3eSSadaf Ebrahimi 
97*ccdc9c3eSSadaf Ebrahimi // Runs an exhaustive test using the given parameters and
98*ccdc9c3eSSadaf Ebrahimi // the basic egrep operators.
99*ccdc9c3eSSadaf Ebrahimi void EgrepTest(int maxatoms, int maxops, const string& alphabet,
100*ccdc9c3eSSadaf Ebrahimi                int maxstrlen, const string& stralphabet,
101*ccdc9c3eSSadaf Ebrahimi                const string& wrapper);
102*ccdc9c3eSSadaf Ebrahimi 
103*ccdc9c3eSSadaf Ebrahimi }  // namespace re2
104*ccdc9c3eSSadaf Ebrahimi 
105*ccdc9c3eSSadaf Ebrahimi #endif  // RE2_TESTING_EXHAUSTIVE_TESTER_H_
106