xref: /aosp_15_r20/external/cronet/third_party/re2/src/app/_re2.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2022 The RE2 Authors.  All Rights Reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4 
5 #include <memory>
6 #include <string>
7 
8 #include <emscripten/bind.h>
9 #include "re2/prog.h"
10 #include "re2/re2.h"
11 #include "re2/regexp.h"
12 
13 namespace re2_app {
14 
15 struct Info {
16   std::string pattern;
17   std::string error;
18   std::string prefix;
19   bool prefix_foldcase = false;
20   std::string accel_prefix;
21   bool accel_prefix_foldcase = false;
22   int num_captures;
23   bool is_one_pass;
24   bool can_bit_state;
25   std::string bytecode;
26   std::string bytemap;
27 };
28 
GetInfo(const std::string & pattern)29 Info GetInfo(const std::string& pattern) {
30   Info info;
31   info.pattern = pattern;
32 
33   RE2::Options options;
34   re2::RegexpStatus status;
35   re2::Regexp* regexp = re2::Regexp::Parse(
36       pattern, static_cast<re2::Regexp::ParseFlags>(options.ParseFlags()),
37       &status);
38   if (regexp == nullptr) {
39     info.error = "failed to parse pattern: " + status.Text();
40     return info;
41   }
42 
43   std::string prefix;
44   bool prefix_foldcase;
45   re2::Regexp* suffix;
46   if (regexp->RequiredPrefix(&prefix, &prefix_foldcase, &suffix)) {
47     info.prefix = prefix;
48     info.prefix_foldcase = prefix_foldcase;
49   } else {
50     suffix = regexp->Incref();
51   }
52 
53   std::unique_ptr<re2::Prog> prog(suffix->CompileToProg(options.max_mem()));
54   if (prog == nullptr) {
55     info.error = "failed to compile forward Prog";
56     suffix->Decref();
57     regexp->Decref();
58     return info;
59   }
60 
61   if (regexp->RequiredPrefixForAccel(&prefix, &prefix_foldcase)) {
62     info.accel_prefix = prefix;
63     info.accel_prefix_foldcase = prefix_foldcase;
64   }
65 
66   info.num_captures = suffix->NumCaptures();
67   info.is_one_pass = prog->IsOnePass();
68   info.can_bit_state = prog->CanBitState();
69   info.bytecode = prog->Dump();
70   info.bytemap = prog->DumpByteMap();
71 
72   suffix->Decref();
73   regexp->Decref();
74   return info;
75 }
76 
EMSCRIPTEN_BINDINGS(_re2)77 EMSCRIPTEN_BINDINGS(_re2) {
78   emscripten::value_object<Info>("Info")
79       .field("pattern", &Info::pattern)
80       .field("error", &Info::error)
81       .field("prefix", &Info::prefix)
82       .field("prefix_foldcase", &Info::prefix_foldcase)
83       .field("accel_prefix", &Info::accel_prefix)
84       .field("accel_prefix_foldcase", &Info::accel_prefix_foldcase)
85       .field("num_captures", &Info::num_captures)
86       .field("is_one_pass", &Info::is_one_pass)
87       .field("can_bit_state", &Info::can_bit_state)
88       .field("bytecode", &Info::bytecode)
89       .field("bytemap", &Info::bytemap);
90 
91   emscripten::function("getInfo", &GetInfo);
92 }
93 
94 }  // namespace re2_app
95