chipper 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. data/README.rdoc +51 -0
  2. data/ext/extconf.rb +58 -0
  3. data/ext/libstemmer_c/Makefile +10 -0
  4. data/ext/libstemmer_c/examples/stemwords.c +209 -0
  5. data/ext/libstemmer_c/include/libstemmer.h +79 -0
  6. data/ext/libstemmer_c/libstemmer/libstemmer.c +95 -0
  7. data/ext/libstemmer_c/libstemmer/libstemmer_utf8.c +95 -0
  8. data/ext/libstemmer_c/libstemmer/modules.h +190 -0
  9. data/ext/libstemmer_c/libstemmer/modules_utf8.h +121 -0
  10. data/ext/libstemmer_c/mkinc.mak +82 -0
  11. data/ext/libstemmer_c/mkinc_utf8.mak +52 -0
  12. data/ext/libstemmer_c/runtime/api.c +66 -0
  13. data/ext/libstemmer_c/runtime/api.h +26 -0
  14. data/ext/libstemmer_c/runtime/header.h +58 -0
  15. data/ext/libstemmer_c/runtime/utilities.c +478 -0
  16. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_danish.c +337 -0
  17. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_danish.h +16 -0
  18. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_dutch.c +624 -0
  19. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_dutch.h +16 -0
  20. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_english.c +1117 -0
  21. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_english.h +16 -0
  22. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_finnish.c +762 -0
  23. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_finnish.h +16 -0
  24. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_french.c +1246 -0
  25. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_french.h +16 -0
  26. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_german.c +521 -0
  27. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_german.h +16 -0
  28. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_hungarian.c +1230 -0
  29. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_hungarian.h +16 -0
  30. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_italian.c +1065 -0
  31. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_italian.h +16 -0
  32. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_norwegian.c +297 -0
  33. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_norwegian.h +16 -0
  34. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_porter.c +749 -0
  35. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_porter.h +16 -0
  36. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_portuguese.c +1017 -0
  37. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_portuguese.h +16 -0
  38. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_spanish.c +1093 -0
  39. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_spanish.h +16 -0
  40. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_swedish.c +307 -0
  41. data/ext/libstemmer_c/src_c/stem_ISO_8859_1_swedish.h +16 -0
  42. data/ext/libstemmer_c/src_c/stem_ISO_8859_2_romanian.c +998 -0
  43. data/ext/libstemmer_c/src_c/stem_ISO_8859_2_romanian.h +16 -0
  44. data/ext/libstemmer_c/src_c/stem_KOI8_R_russian.c +700 -0
  45. data/ext/libstemmer_c/src_c/stem_KOI8_R_russian.h +16 -0
  46. data/ext/libstemmer_c/src_c/stem_UTF_8_danish.c +339 -0
  47. data/ext/libstemmer_c/src_c/stem_UTF_8_danish.h +16 -0
  48. data/ext/libstemmer_c/src_c/stem_UTF_8_dutch.c +634 -0
  49. data/ext/libstemmer_c/src_c/stem_UTF_8_dutch.h +16 -0
  50. data/ext/libstemmer_c/src_c/stem_UTF_8_english.c +1125 -0
  51. data/ext/libstemmer_c/src_c/stem_UTF_8_english.h +16 -0
  52. data/ext/libstemmer_c/src_c/stem_UTF_8_finnish.c +768 -0
  53. data/ext/libstemmer_c/src_c/stem_UTF_8_finnish.h +16 -0
  54. data/ext/libstemmer_c/src_c/stem_UTF_8_french.c +1256 -0
  55. data/ext/libstemmer_c/src_c/stem_UTF_8_french.h +16 -0
  56. data/ext/libstemmer_c/src_c/stem_UTF_8_german.c +527 -0
  57. data/ext/libstemmer_c/src_c/stem_UTF_8_german.h +16 -0
  58. data/ext/libstemmer_c/src_c/stem_UTF_8_hungarian.c +1234 -0
  59. data/ext/libstemmer_c/src_c/stem_UTF_8_hungarian.h +16 -0
  60. data/ext/libstemmer_c/src_c/stem_UTF_8_italian.c +1073 -0
  61. data/ext/libstemmer_c/src_c/stem_UTF_8_italian.h +16 -0
  62. data/ext/libstemmer_c/src_c/stem_UTF_8_norwegian.c +299 -0
  63. data/ext/libstemmer_c/src_c/stem_UTF_8_norwegian.h +16 -0
  64. data/ext/libstemmer_c/src_c/stem_UTF_8_porter.c +755 -0
  65. data/ext/libstemmer_c/src_c/stem_UTF_8_porter.h +16 -0
  66. data/ext/libstemmer_c/src_c/stem_UTF_8_portuguese.c +1023 -0
  67. data/ext/libstemmer_c/src_c/stem_UTF_8_portuguese.h +16 -0
  68. data/ext/libstemmer_c/src_c/stem_UTF_8_romanian.c +1004 -0
  69. data/ext/libstemmer_c/src_c/stem_UTF_8_romanian.h +16 -0
  70. data/ext/libstemmer_c/src_c/stem_UTF_8_russian.c +694 -0
  71. data/ext/libstemmer_c/src_c/stem_UTF_8_russian.h +16 -0
  72. data/ext/libstemmer_c/src_c/stem_UTF_8_spanish.c +1097 -0
  73. data/ext/libstemmer_c/src_c/stem_UTF_8_spanish.h +16 -0
  74. data/ext/libstemmer_c/src_c/stem_UTF_8_swedish.c +309 -0
  75. data/ext/libstemmer_c/src_c/stem_UTF_8_swedish.h +16 -0
  76. data/ext/libstemmer_c/src_c/stem_UTF_8_turkish.c +2205 -0
  77. data/ext/libstemmer_c/src_c/stem_UTF_8_turkish.h +16 -0
  78. data/ext/re2/bitstate.cc +378 -0
  79. data/ext/re2/compile.cc +1138 -0
  80. data/ext/re2/dfa.cc +2086 -0
  81. data/ext/re2/filtered_re2.cc +100 -0
  82. data/ext/re2/filtered_re2.h +99 -0
  83. data/ext/re2/hash.cc +231 -0
  84. data/ext/re2/mimics_pcre.cc +185 -0
  85. data/ext/re2/nfa.cc +709 -0
  86. data/ext/re2/onepass.cc +614 -0
  87. data/ext/re2/parse.cc +2202 -0
  88. data/ext/re2/perl_groups.cc +119 -0
  89. data/ext/re2/prefilter.cc +671 -0
  90. data/ext/re2/prefilter.h +105 -0
  91. data/ext/re2/prefilter_tree.cc +398 -0
  92. data/ext/re2/prefilter_tree.h +130 -0
  93. data/ext/re2/prog.cc +341 -0
  94. data/ext/re2/prog.h +376 -0
  95. data/ext/re2/re2.cc +1180 -0
  96. data/ext/re2/re2.h +837 -0
  97. data/ext/re2/regexp.cc +920 -0
  98. data/ext/re2/regexp.h +632 -0
  99. data/ext/re2/rune.cc +258 -0
  100. data/ext/re2/set.cc +113 -0
  101. data/ext/re2/set.h +55 -0
  102. data/ext/re2/simplify.cc +393 -0
  103. data/ext/re2/stringpiece.cc +87 -0
  104. data/ext/re2/stringpiece.h +182 -0
  105. data/ext/re2/tostring.cc +341 -0
  106. data/ext/re2/unicode_casefold.cc +469 -0
  107. data/ext/re2/unicode_casefold.h +75 -0
  108. data/ext/re2/unicode_groups.cc +4851 -0
  109. data/ext/re2/unicode_groups.h +64 -0
  110. data/ext/re2/valgrind.cc +24 -0
  111. data/ext/re2/variadic_function.h +346 -0
  112. data/ext/re2/walker-inl.h +244 -0
  113. data/ext/src/chipper.cc +626 -0
  114. data/ext/src/version.h +1 -0
  115. data/ext/stemmer.rb +40 -0
  116. data/ext/util/arena.h +103 -0
  117. data/ext/util/atomicops.h +79 -0
  118. data/ext/util/benchmark.h +41 -0
  119. data/ext/util/flags.h +27 -0
  120. data/ext/util/logging.h +78 -0
  121. data/ext/util/mutex.h +190 -0
  122. data/ext/util/pcre.h +679 -0
  123. data/ext/util/random.h +29 -0
  124. data/ext/util/sparse_array.h +451 -0
  125. data/ext/util/sparse_set.h +177 -0
  126. data/ext/util/test.h +57 -0
  127. data/ext/util/thread.h +26 -0
  128. data/ext/util/utf.h +43 -0
  129. data/ext/util/util.h +127 -0
  130. data/ext/util/valgrind.h +4517 -0
  131. data/test/helper.rb +5 -0
  132. data/test/test_entities.rb +57 -0
  133. data/test/test_tokens.rb +118 -0
  134. metadata +199 -0
data/ext/util/pcre.h ADDED
@@ -0,0 +1,679 @@
1
+ // Copyright 2003-2010 Google Inc. 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
+ // This is a variant of PCRE's pcrecpp.h, originally written at Google.
6
+ // The main changes are the addition of the HitLimit method and
7
+ // compilation as PCRE in namespace re2.
8
+
9
+ // C++ interface to the pcre regular-expression library. PCRE supports
10
+ // Perl-style regular expressions (with extensions like \d, \w, \s,
11
+ // ...).
12
+ //
13
+ // -----------------------------------------------------------------------
14
+ // REGEXP SYNTAX:
15
+ //
16
+ // This module uses the pcre library and hence supports its syntax
17
+ // for regular expressions:
18
+ //
19
+ // http://www.google.com/search?q=pcre
20
+ //
21
+ // The syntax is pretty similar to Perl's. For those not familiar
22
+ // with Perl's regular expressions, here are some examples of the most
23
+ // commonly used extensions:
24
+ //
25
+ // "hello (\\w+) world" -- \w matches a "word" character
26
+ // "version (\\d+)" -- \d matches a digit
27
+ // "hello\\s+world" -- \s matches any whitespace character
28
+ // "\\b(\\w+)\\b" -- \b matches empty string at a word boundary
29
+ // "(?i)hello" -- (?i) turns on case-insensitive matching
30
+ // "/\\*(.*?)\\*/" -- .*? matches . minimum no. of times possible
31
+ //
32
+ // -----------------------------------------------------------------------
33
+ // MATCHING INTERFACE:
34
+ //
35
+ // The "FullMatch" operation checks that supplied text matches a
36
+ // supplied pattern exactly.
37
+ //
38
+ // Example: successful match
39
+ // CHECK(PCRE::FullMatch("hello", "h.*o"));
40
+ //
41
+ // Example: unsuccessful match (requires full match):
42
+ // CHECK(!PCRE::FullMatch("hello", "e"));
43
+ //
44
+ // -----------------------------------------------------------------------
45
+ // UTF-8 AND THE MATCHING INTERFACE:
46
+ //
47
+ // By default, pattern and text are plain text, one byte per character.
48
+ // The UTF8 flag, passed to the constructor, causes both pattern
49
+ // and string to be treated as UTF-8 text, still a byte stream but
50
+ // potentially multiple bytes per character. In practice, the text
51
+ // is likelier to be UTF-8 than the pattern, but the match returned
52
+ // may depend on the UTF8 flag, so always use it when matching
53
+ // UTF8 text. E.g., "." will match one byte normally but with UTF8
54
+ // set may match up to three bytes of a multi-byte character.
55
+ //
56
+ // Example:
57
+ // PCRE re(utf8_pattern, PCRE::UTF8);
58
+ // CHECK(PCRE::FullMatch(utf8_string, re));
59
+ //
60
+ // -----------------------------------------------------------------------
61
+ // MATCHING WITH SUB-STRING EXTRACTION:
62
+ //
63
+ // You can supply extra pointer arguments to extract matched subpieces.
64
+ //
65
+ // Example: extracts "ruby" into "s" and 1234 into "i"
66
+ // int i;
67
+ // string s;
68
+ // CHECK(PCRE::FullMatch("ruby:1234", "(\\w+):(\\d+)", &s, &i));
69
+ //
70
+ // Example: fails because string cannot be stored in integer
71
+ // CHECK(!PCRE::FullMatch("ruby", "(.*)", &i));
72
+ //
73
+ // Example: fails because there aren't enough sub-patterns:
74
+ // CHECK(!PCRE::FullMatch("ruby:1234", "\\w+:\\d+", &s));
75
+ //
76
+ // Example: does not try to extract any extra sub-patterns
77
+ // CHECK(PCRE::FullMatch("ruby:1234", "(\\w+):(\\d+)", &s));
78
+ //
79
+ // Example: does not try to extract into NULL
80
+ // CHECK(PCRE::FullMatch("ruby:1234", "(\\w+):(\\d+)", NULL, &i));
81
+ //
82
+ // Example: integer overflow causes failure
83
+ // CHECK(!PCRE::FullMatch("ruby:1234567891234", "\\w+:(\\d+)", &i));
84
+ //
85
+ // -----------------------------------------------------------------------
86
+ // PARTIAL MATCHES
87
+ //
88
+ // You can use the "PartialMatch" operation when you want the pattern
89
+ // to match any substring of the text.
90
+ //
91
+ // Example: simple search for a string:
92
+ // CHECK(PCRE::PartialMatch("hello", "ell"));
93
+ //
94
+ // Example: find first number in a string
95
+ // int number;
96
+ // CHECK(PCRE::PartialMatch("x*100 + 20", "(\\d+)", &number));
97
+ // CHECK_EQ(number, 100);
98
+ //
99
+ // -----------------------------------------------------------------------
100
+ // PPCRE-COMPILED PCREGULAR EXPPCRESSIONS
101
+ //
102
+ // PCRE makes it easy to use any string as a regular expression, without
103
+ // requiring a separate compilation step.
104
+ //
105
+ // If speed is of the essence, you can create a pre-compiled "PCRE"
106
+ // object from the pattern and use it multiple times. If you do so,
107
+ // you can typically parse text faster than with sscanf.
108
+ //
109
+ // Example: precompile pattern for faster matching:
110
+ // PCRE pattern("h.*o");
111
+ // while (ReadLine(&str)) {
112
+ // if (PCRE::FullMatch(str, pattern)) ...;
113
+ // }
114
+ //
115
+ // -----------------------------------------------------------------------
116
+ // SCANNING TEXT INCPCREMENTALLY
117
+ //
118
+ // The "Consume" operation may be useful if you want to repeatedly
119
+ // match regular expressions at the front of a string and skip over
120
+ // them as they match. This requires use of the "StringPiece" type,
121
+ // which represents a sub-range of a real string.
122
+ //
123
+ // Example: read lines of the form "var = value" from a string.
124
+ // string contents = ...; // Fill string somehow
125
+ // StringPiece input(contents); // Wrap a StringPiece around it
126
+ //
127
+ // string var;
128
+ // int value;
129
+ // while (PCRE::Consume(&input, "(\\w+) = (\\d+)\n", &var, &value)) {
130
+ // ...;
131
+ // }
132
+ //
133
+ // Each successful call to "Consume" will set "var/value", and also
134
+ // advance "input" so it points past the matched text. Note that if the
135
+ // regular expression matches an empty string, input will advance
136
+ // by 0 bytes. If the regular expression being used might match
137
+ // an empty string, the loop body must check for this case and either
138
+ // advance the string or break out of the loop.
139
+ //
140
+ // The "FindAndConsume" operation is similar to "Consume" but does not
141
+ // anchor your match at the beginning of the string. For example, you
142
+ // could extract all words from a string by repeatedly calling
143
+ // PCRE::FindAndConsume(&input, "(\\w+)", &word)
144
+ //
145
+ // -----------------------------------------------------------------------
146
+ // PARSING HEX/OCTAL/C-RADIX NUMBERS
147
+ //
148
+ // By default, if you pass a pointer to a numeric value, the
149
+ // corresponding text is interpreted as a base-10 number. You can
150
+ // instead wrap the pointer with a call to one of the operators Hex(),
151
+ // Octal(), or CRadix() to interpret the text in another base. The
152
+ // CRadix operator interprets C-style "0" (base-8) and "0x" (base-16)
153
+ // prefixes, but defaults to base-10.
154
+ //
155
+ // Example:
156
+ // int a, b, c, d;
157
+ // CHECK(PCRE::FullMatch("100 40 0100 0x40", "(.*) (.*) (.*) (.*)",
158
+ // Octal(&a), Hex(&b), CRadix(&c), CRadix(&d));
159
+ // will leave 64 in a, b, c, and d.
160
+
161
+ #include "util/util.h"
162
+ #include "re2/stringpiece.h"
163
+
164
+ #ifdef USEPCRE
165
+ #include <pcre.h>
166
+ namespace re2 {
167
+ const bool UsingPCRE = true;
168
+ } // namespace re2
169
+ #else
170
+ namespace re2 {
171
+ const bool UsingPCRE = false;
172
+ struct pcre;
173
+ struct pcre_extra { int flags, match_limit, match_limit_recursion; };
174
+ #define pcre_free(x) {}
175
+ #define PCRE_EXTRA_MATCH_LIMIT 0
176
+ #define PCRE_EXTRA_MATCH_LIMIT_RECURSION 0
177
+ #define PCRE_ANCHORED 0
178
+ #define PCRE_NOTEMPTY 0
179
+ #define PCRE_ERROR_NOMATCH 1
180
+ #define PCRE_ERROR_MATCHLIMIT 2
181
+ #define PCRE_ERROR_RECURSIONLIMIT 3
182
+ #define PCRE_INFO_CAPTURECOUNT 0
183
+ #define pcre_compile(a,b,c,d,e) ({ (void)(a); (void)(b); *(c)=""; *(d)=0; (void)(e); ((pcre*)0); })
184
+ #define pcre_exec(a, b, c, d, e, f, g, h) ({ (void)(a); (void)(b); (void)(c); (void)(d); (void)(e); (void)(f); (void)(g); (void)(h); 0; })
185
+ #define pcre_fullinfo(a, b, c, d) ({ (void)(a); (void)(b); (void)(c); *(d) = 0; 0; })
186
+ } // namespace re2
187
+ #endif
188
+
189
+ namespace re2 {
190
+
191
+ class PCRE_Options;
192
+
193
+ // Interface for regular expression matching. Also corresponds to a
194
+ // pre-compiled regular expression. An "PCRE" object is safe for
195
+ // concurrent use by multiple threads.
196
+ class PCRE {
197
+ public:
198
+ // We convert user-passed pointers into special Arg objects
199
+ class Arg;
200
+
201
+ // Marks end of arg list.
202
+ // ONLY USE IN OPTIONAL ARG DEFAULTS.
203
+ // DO NOT PASS EXPLICITLY.
204
+ static Arg no_more_args;
205
+
206
+ // Options are same value as those in pcre. We provide them here
207
+ // to avoid users needing to include pcre.h and also to isolate
208
+ // users from pcre should we change the underlying library.
209
+ // Only those needed by Google programs are exposed here to
210
+ // avoid collision with options employed internally by regexp.cc
211
+ // Note that some options have equivalents that can be specified in
212
+ // the regexp itself. For example, prefixing your regexp with
213
+ // "(?s)" has the same effect as the PCRE_DOTALL option.
214
+ enum Option {
215
+ None = 0x0000,
216
+ UTF8 = 0x0800, // == PCRE_UTF8
217
+ EnabledCompileOptions = UTF8,
218
+ EnabledExecOptions = 0x0000, // TODO: use to replace anchor flag
219
+ };
220
+
221
+ // We provide implicit conversions from strings so that users can
222
+ // pass in a string or a "const char*" wherever an "PCRE" is expected.
223
+ PCRE(const char* pattern);
224
+ PCRE(const char* pattern, Option option);
225
+ PCRE(const string& pattern);
226
+ PCRE(const string& pattern, Option option);
227
+ PCRE(const char *pattern, const PCRE_Options& re_option);
228
+ PCRE(const string& pattern, const PCRE_Options& re_option);
229
+
230
+ ~PCRE();
231
+
232
+ // The string specification for this PCRE. E.g.
233
+ // PCRE re("ab*c?d+");
234
+ // re.pattern(); // "ab*c?d+"
235
+ const string& pattern() const { return pattern_; }
236
+
237
+ // If PCRE could not be created properly, returns an error string.
238
+ // Else returns the empty string.
239
+ const string& error() const { return *error_; }
240
+
241
+ // Whether the PCRE has hit a match limit during execution.
242
+ // Not thread safe. Intended only for testing.
243
+ // If hitting match limits is a problem,
244
+ // you should be using PCRE2 (re2/re2.h)
245
+ // instead of checking this flag.
246
+ bool HitLimit();
247
+ void ClearHitLimit();
248
+
249
+ /***** The useful part: the matching interface *****/
250
+
251
+ // Matches "text" against "pattern". If pointer arguments are
252
+ // supplied, copies matched sub-patterns into them.
253
+ //
254
+ // You can pass in a "const char*" or a "string" for "text".
255
+ // You can pass in a "const char*" or a "string" or a "PCRE" for "pattern".
256
+ //
257
+ // The provided pointer arguments can be pointers to any scalar numeric
258
+ // type, or one of:
259
+ // string (matched piece is copied to string)
260
+ // StringPiece (StringPiece is mutated to point to matched piece)
261
+ // T (where "bool T::ParseFrom(const char*, int)" exists)
262
+ // (void*)NULL (the corresponding matched sub-pattern is not copied)
263
+ //
264
+ // Returns true iff all of the following conditions are satisfied:
265
+ // a. "text" matches "pattern" exactly
266
+ // b. The number of matched sub-patterns is >= number of supplied pointers
267
+ // c. The "i"th argument has a suitable type for holding the
268
+ // string captured as the "i"th sub-pattern. If you pass in
269
+ // NULL for the "i"th argument, or pass fewer arguments than
270
+ // number of sub-patterns, "i"th captured sub-pattern is
271
+ // ignored.
272
+ //
273
+ // CAVEAT: An optional sub-pattern that does not exist in the
274
+ // matched string is assigned the empty string. Therefore, the
275
+ // following will return false (because the empty string is not a
276
+ // valid number):
277
+ // int number;
278
+ // PCRE::FullMatch("abc", "[a-z]+(\\d+)?", &number);
279
+ struct FullMatchFunctor {
280
+ bool operator ()(const StringPiece& text, const PCRE& re, // 3..16 args
281
+ const Arg& ptr1 = no_more_args,
282
+ const Arg& ptr2 = no_more_args,
283
+ const Arg& ptr3 = no_more_args,
284
+ const Arg& ptr4 = no_more_args,
285
+ const Arg& ptr5 = no_more_args,
286
+ const Arg& ptr6 = no_more_args,
287
+ const Arg& ptr7 = no_more_args,
288
+ const Arg& ptr8 = no_more_args,
289
+ const Arg& ptr9 = no_more_args,
290
+ const Arg& ptr10 = no_more_args,
291
+ const Arg& ptr11 = no_more_args,
292
+ const Arg& ptr12 = no_more_args,
293
+ const Arg& ptr13 = no_more_args,
294
+ const Arg& ptr14 = no_more_args,
295
+ const Arg& ptr15 = no_more_args,
296
+ const Arg& ptr16 = no_more_args) const;
297
+ };
298
+
299
+ static const FullMatchFunctor FullMatch;
300
+
301
+ // Exactly like FullMatch(), except that "pattern" is allowed to match
302
+ // a substring of "text".
303
+ struct PartialMatchFunctor {
304
+ bool operator ()(const StringPiece& text, const PCRE& re, // 3..16 args
305
+ const Arg& ptr1 = no_more_args,
306
+ const Arg& ptr2 = no_more_args,
307
+ const Arg& ptr3 = no_more_args,
308
+ const Arg& ptr4 = no_more_args,
309
+ const Arg& ptr5 = no_more_args,
310
+ const Arg& ptr6 = no_more_args,
311
+ const Arg& ptr7 = no_more_args,
312
+ const Arg& ptr8 = no_more_args,
313
+ const Arg& ptr9 = no_more_args,
314
+ const Arg& ptr10 = no_more_args,
315
+ const Arg& ptr11 = no_more_args,
316
+ const Arg& ptr12 = no_more_args,
317
+ const Arg& ptr13 = no_more_args,
318
+ const Arg& ptr14 = no_more_args,
319
+ const Arg& ptr15 = no_more_args,
320
+ const Arg& ptr16 = no_more_args) const;
321
+ };
322
+
323
+ static const PartialMatchFunctor PartialMatch;
324
+
325
+ // Like FullMatch() and PartialMatch(), except that pattern has to
326
+ // match a prefix of "text", and "input" is advanced past the matched
327
+ // text. Note: "input" is modified iff this routine returns true.
328
+ struct ConsumeFunctor {
329
+ bool operator ()(StringPiece* input, const PCRE& pattern, // 3..16 args
330
+ const Arg& ptr1 = no_more_args,
331
+ const Arg& ptr2 = no_more_args,
332
+ const Arg& ptr3 = no_more_args,
333
+ const Arg& ptr4 = no_more_args,
334
+ const Arg& ptr5 = no_more_args,
335
+ const Arg& ptr6 = no_more_args,
336
+ const Arg& ptr7 = no_more_args,
337
+ const Arg& ptr8 = no_more_args,
338
+ const Arg& ptr9 = no_more_args,
339
+ const Arg& ptr10 = no_more_args,
340
+ const Arg& ptr11 = no_more_args,
341
+ const Arg& ptr12 = no_more_args,
342
+ const Arg& ptr13 = no_more_args,
343
+ const Arg& ptr14 = no_more_args,
344
+ const Arg& ptr15 = no_more_args,
345
+ const Arg& ptr16 = no_more_args) const;
346
+ };
347
+
348
+ static const ConsumeFunctor Consume;
349
+
350
+ // Like Consume(..), but does not anchor the match at the beginning of the
351
+ // string. That is, "pattern" need not start its match at the beginning of
352
+ // "input". For example, "FindAndConsume(s, "(\\w+)", &word)" finds the next
353
+ // word in "s" and stores it in "word".
354
+ struct FindAndConsumeFunctor {
355
+ bool operator ()(StringPiece* input, const PCRE& pattern,
356
+ const Arg& ptr1 = no_more_args,
357
+ const Arg& ptr2 = no_more_args,
358
+ const Arg& ptr3 = no_more_args,
359
+ const Arg& ptr4 = no_more_args,
360
+ const Arg& ptr5 = no_more_args,
361
+ const Arg& ptr6 = no_more_args,
362
+ const Arg& ptr7 = no_more_args,
363
+ const Arg& ptr8 = no_more_args,
364
+ const Arg& ptr9 = no_more_args,
365
+ const Arg& ptr10 = no_more_args,
366
+ const Arg& ptr11 = no_more_args,
367
+ const Arg& ptr12 = no_more_args,
368
+ const Arg& ptr13 = no_more_args,
369
+ const Arg& ptr14 = no_more_args,
370
+ const Arg& ptr15 = no_more_args,
371
+ const Arg& ptr16 = no_more_args) const;
372
+ };
373
+
374
+ static const FindAndConsumeFunctor FindAndConsume;
375
+
376
+ // Replace the first match of "pattern" in "str" with "rewrite".
377
+ // Within "rewrite", backslash-escaped digits (\1 to \9) can be
378
+ // used to insert text matching corresponding parenthesized group
379
+ // from the pattern. \0 in "rewrite" refers to the entire matching
380
+ // text. E.g.,
381
+ //
382
+ // string s = "yabba dabba doo";
383
+ // CHECK(PCRE::Replace(&s, "b+", "d"));
384
+ //
385
+ // will leave "s" containing "yada dabba doo"
386
+ //
387
+ // Returns true if the pattern matches and a replacement occurs,
388
+ // false otherwise.
389
+ static bool Replace(string *str,
390
+ const PCRE& pattern,
391
+ const StringPiece& rewrite);
392
+
393
+ // Like Replace(), except replaces all occurrences of the pattern in
394
+ // the string with the rewrite. Replacements are not subject to
395
+ // re-matching. E.g.,
396
+ //
397
+ // string s = "yabba dabba doo";
398
+ // CHECK(PCRE::GlobalReplace(&s, "b+", "d"));
399
+ //
400
+ // will leave "s" containing "yada dada doo"
401
+ //
402
+ // Returns the number of replacements made.
403
+ static int GlobalReplace(string *str,
404
+ const PCRE& pattern,
405
+ const StringPiece& rewrite);
406
+
407
+ // Like Replace, except that if the pattern matches, "rewrite"
408
+ // is copied into "out" with substitutions. The non-matching
409
+ // portions of "text" are ignored.
410
+ //
411
+ // Returns true iff a match occurred and the extraction happened
412
+ // successfully; if no match occurs, the string is left unaffected.
413
+ static bool Extract(const StringPiece &text,
414
+ const PCRE& pattern,
415
+ const StringPiece &rewrite,
416
+ string *out);
417
+
418
+ // Check that the given @p rewrite string is suitable for use with
419
+ // this PCRE. It checks that:
420
+ // * The PCRE has enough parenthesized subexpressions to satisfy all
421
+ // of the \N tokens in @p rewrite, and
422
+ // * The @p rewrite string doesn't have any syntax errors
423
+ // ('\' followed by anything besides [0-9] and '\').
424
+ // Making this test will guarantee that "replace" and "extract"
425
+ // operations won't LOG(ERROR) or fail because of a bad rewrite
426
+ // string.
427
+ // @param rewrite The proposed rewrite string.
428
+ // @param error An error message is recorded here, iff we return false.
429
+ // Otherwise, it is unchanged.
430
+ // @return true, iff @p rewrite is suitable for use with the PCRE.
431
+ bool CheckRewriteString(const StringPiece& rewrite, string* error) const;
432
+
433
+ // Returns a copy of 'unquoted' with all potentially meaningful
434
+ // regexp characters backslash-escaped. The returned string, used
435
+ // as a regular expression, will exactly match the original string.
436
+ // For example,
437
+ // 1.5-2.0?
438
+ // becomes:
439
+ // 1\.5\-2\.0\?
440
+ static string QuoteMeta(const StringPiece& unquoted);
441
+
442
+ /***** Generic matching interface (not so nice to use) *****/
443
+
444
+ // Type of match (TODO: Should be restructured as an Option)
445
+ enum Anchor {
446
+ UNANCHORED, // No anchoring
447
+ ANCHOR_START, // Anchor at start only
448
+ ANCHOR_BOTH, // Anchor at start and end
449
+ };
450
+
451
+ // General matching routine. Stores the length of the match in
452
+ // "*consumed" if successful.
453
+ bool DoMatch(const StringPiece& text,
454
+ Anchor anchor,
455
+ int* consumed,
456
+ const Arg* const* args, int n) const;
457
+
458
+ // Return the number of capturing subpatterns, or -1 if the
459
+ // regexp wasn't valid on construction.
460
+ int NumberOfCapturingGroups() const;
461
+
462
+ private:
463
+ void Init(const char* pattern, Option option, int match_limit,
464
+ int stack_limit, bool report_errors);
465
+
466
+ // Match against "text", filling in "vec" (up to "vecsize" * 2/3) with
467
+ // pairs of integers for the beginning and end positions of matched
468
+ // text. The first pair corresponds to the entire matched text;
469
+ // subsequent pairs correspond, in order, to parentheses-captured
470
+ // matches. Returns the number of pairs (one more than the number of
471
+ // the last subpattern with a match) if matching was successful
472
+ // and zero if the match failed.
473
+ // I.e. for PCRE("(foo)|(bar)|(baz)") it will return 2, 3, and 4 when matching
474
+ // against "foo", "bar", and "baz" respectively.
475
+ // When matching PCRE("(foo)|hello") against "hello", it will return 1.
476
+ // But the values for all subpattern are filled in into "vec".
477
+ int TryMatch(const StringPiece& text,
478
+ int startpos,
479
+ Anchor anchor,
480
+ bool empty_ok,
481
+ int *vec,
482
+ int vecsize) const;
483
+
484
+ // Append the "rewrite" string, with backslash subsitutions from "text"
485
+ // and "vec", to string "out".
486
+ bool Rewrite(string *out,
487
+ const StringPiece &rewrite,
488
+ const StringPiece &text,
489
+ int *vec,
490
+ int veclen) const;
491
+
492
+ // internal implementation for DoMatch
493
+ bool DoMatchImpl(const StringPiece& text,
494
+ Anchor anchor,
495
+ int* consumed,
496
+ const Arg* const args[],
497
+ int n,
498
+ int* vec,
499
+ int vecsize) const;
500
+
501
+ // Compile the regexp for the specified anchoring mode
502
+ pcre* Compile(Anchor anchor);
503
+
504
+ string pattern_;
505
+ Option options_;
506
+ pcre* re_full_; // For full matches
507
+ pcre* re_partial_; // For partial matches
508
+ const string* error_; // Error indicator (or empty string)
509
+ bool report_errors_; // Silences error logging if false
510
+ int match_limit_; // Limit on execution resources
511
+ int stack_limit_; // Limit on stack resources (bytes)
512
+ mutable int32_t hit_limit_; // Hit limit during execution (bool)?
513
+ DISALLOW_EVIL_CONSTRUCTORS(PCRE);
514
+ };
515
+
516
+ // PCRE_Options allow you to set the PCRE::Options, plus any pcre
517
+ // "extra" options. The only extras are match_limit, which limits
518
+ // the CPU time of a match, and stack_limit, which limits the
519
+ // stack usage. Setting a limit to <= 0 lets PCRE pick a sensible default
520
+ // that should not cause too many problems in production code.
521
+ // If PCRE hits a limit during a match, it may return a false negative,
522
+ // but (hopefully) it won't crash.
523
+ //
524
+ // NOTE: If you are handling regular expressions specified by
525
+ // (external or internal) users, rather than hard-coded ones,
526
+ // you should be using PCRE2, which uses an alternate implementation
527
+ // that avoids these issues. See http://go/re2quick.
528
+ class PCRE_Options {
529
+ public:
530
+ // constructor
531
+ PCRE_Options() : option_(PCRE::None), match_limit_(0), stack_limit_(0), report_errors_(true) {}
532
+ // accessors
533
+ PCRE::Option option() const { return option_; }
534
+ void set_option(PCRE::Option option) {
535
+ option_ = option;
536
+ }
537
+ int match_limit() const { return match_limit_; }
538
+ void set_match_limit(int match_limit) {
539
+ match_limit_ = match_limit;
540
+ }
541
+ int stack_limit() const { return stack_limit_; }
542
+ void set_stack_limit(int stack_limit) {
543
+ stack_limit_ = stack_limit;
544
+ }
545
+
546
+ // If the regular expression is malformed, an error message will be printed
547
+ // iff report_errors() is true. Default: true.
548
+ bool report_errors() const { return report_errors_; }
549
+ void set_report_errors(bool report_errors) {
550
+ report_errors_ = report_errors;
551
+ }
552
+ private:
553
+ PCRE::Option option_;
554
+ int match_limit_;
555
+ int stack_limit_;
556
+ bool report_errors_;
557
+ };
558
+
559
+
560
+ /***** Implementation details *****/
561
+
562
+ // Hex/Octal/Binary?
563
+
564
+ // Special class for parsing into objects that define a ParseFrom() method
565
+ template <class T>
566
+ class _PCRE_MatchObject {
567
+ public:
568
+ static inline bool Parse(const char* str, int n, void* dest) {
569
+ if (dest == NULL) return true;
570
+ T* object = reinterpret_cast<T*>(dest);
571
+ return object->ParseFrom(str, n);
572
+ }
573
+ };
574
+
575
+ class PCRE::Arg {
576
+ public:
577
+ // Empty constructor so we can declare arrays of PCRE::Arg
578
+ Arg();
579
+
580
+ // Constructor specially designed for NULL arguments
581
+ Arg(void*);
582
+
583
+ typedef bool (*Parser)(const char* str, int n, void* dest);
584
+
585
+ // Type-specific parsers
586
+ #define MAKE_PARSER(type,name) \
587
+ Arg(type* p) : arg_(p), parser_(name) { } \
588
+ Arg(type* p, Parser parser) : arg_(p), parser_(parser) { } \
589
+
590
+
591
+ MAKE_PARSER(char, parse_char);
592
+ MAKE_PARSER(unsigned char, parse_uchar);
593
+ MAKE_PARSER(short, parse_short);
594
+ MAKE_PARSER(unsigned short, parse_ushort);
595
+ MAKE_PARSER(int, parse_int);
596
+ MAKE_PARSER(unsigned int, parse_uint);
597
+ MAKE_PARSER(long, parse_long);
598
+ MAKE_PARSER(unsigned long, parse_ulong);
599
+ MAKE_PARSER(long long, parse_longlong);
600
+ MAKE_PARSER(unsigned long long, parse_ulonglong);
601
+ MAKE_PARSER(float, parse_float);
602
+ MAKE_PARSER(double, parse_double);
603
+ MAKE_PARSER(string, parse_string);
604
+ MAKE_PARSER(StringPiece, parse_stringpiece);
605
+
606
+ #undef MAKE_PARSER
607
+
608
+ // Generic constructor
609
+ template <class T> Arg(T*, Parser parser);
610
+ // Generic constructor template
611
+ template <class T> Arg(T* p)
612
+ : arg_(p), parser_(_PCRE_MatchObject<T>::Parse) {
613
+ }
614
+
615
+ // Parse the data
616
+ bool Parse(const char* str, int n) const;
617
+
618
+ private:
619
+ void* arg_;
620
+ Parser parser_;
621
+
622
+ static bool parse_null (const char* str, int n, void* dest);
623
+ static bool parse_char (const char* str, int n, void* dest);
624
+ static bool parse_uchar (const char* str, int n, void* dest);
625
+ static bool parse_float (const char* str, int n, void* dest);
626
+ static bool parse_double (const char* str, int n, void* dest);
627
+ static bool parse_string (const char* str, int n, void* dest);
628
+ static bool parse_stringpiece (const char* str, int n, void* dest);
629
+
630
+ #define DECLARE_INTEGER_PARSER(name) \
631
+ private: \
632
+ static bool parse_ ## name(const char* str, int n, void* dest); \
633
+ static bool parse_ ## name ## _radix( \
634
+ const char* str, int n, void* dest, int radix); \
635
+ public: \
636
+ static bool parse_ ## name ## _hex(const char* str, int n, void* dest); \
637
+ static bool parse_ ## name ## _octal(const char* str, int n, void* dest); \
638
+ static bool parse_ ## name ## _cradix(const char* str, int n, void* dest)
639
+
640
+ DECLARE_INTEGER_PARSER(short);
641
+ DECLARE_INTEGER_PARSER(ushort);
642
+ DECLARE_INTEGER_PARSER(int);
643
+ DECLARE_INTEGER_PARSER(uint);
644
+ DECLARE_INTEGER_PARSER(long);
645
+ DECLARE_INTEGER_PARSER(ulong);
646
+ DECLARE_INTEGER_PARSER(longlong);
647
+ DECLARE_INTEGER_PARSER(ulonglong);
648
+
649
+ #undef DECLARE_INTEGER_PARSER
650
+ };
651
+
652
+ inline PCRE::Arg::Arg() : arg_(NULL), parser_(parse_null) { }
653
+ inline PCRE::Arg::Arg(void* p) : arg_(p), parser_(parse_null) { }
654
+
655
+ inline bool PCRE::Arg::Parse(const char* str, int n) const {
656
+ return (*parser_)(str, n, arg_);
657
+ }
658
+
659
+ // This part of the parser, appropriate only for ints, deals with bases
660
+ #define MAKE_INTEGER_PARSER(type, name) \
661
+ inline PCRE::Arg Hex(type* ptr) { \
662
+ return PCRE::Arg(ptr, PCRE::Arg::parse_ ## name ## _hex); } \
663
+ inline PCRE::Arg Octal(type* ptr) { \
664
+ return PCRE::Arg(ptr, PCRE::Arg::parse_ ## name ## _octal); } \
665
+ inline PCRE::Arg CRadix(type* ptr) { \
666
+ return PCRE::Arg(ptr, PCRE::Arg::parse_ ## name ## _cradix); }
667
+
668
+ MAKE_INTEGER_PARSER(short, short);
669
+ MAKE_INTEGER_PARSER(unsigned short, ushort);
670
+ MAKE_INTEGER_PARSER(int, int);
671
+ MAKE_INTEGER_PARSER(unsigned int, uint);
672
+ MAKE_INTEGER_PARSER(long, long);
673
+ MAKE_INTEGER_PARSER(unsigned long, ulong);
674
+ MAKE_INTEGER_PARSER(long long, longlong);
675
+ MAKE_INTEGER_PARSER(unsigned long long, ulonglong);
676
+
677
+ #undef MAKE_INTEGER_PARSER
678
+
679
+ } // namespace re2