Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/pcre2/src/pcre2_pattern_info.c
9898 views
1
/*************************************************
2
* Perl-Compatible Regular Expressions *
3
*************************************************/
4
5
/* PCRE is a library of functions to support regular expressions whose syntax
6
and semantics are as close as possible to those of the Perl 5 language.
7
8
Written by Philip Hazel
9
Original API code Copyright (c) 1997-2012 University of Cambridge
10
New API code Copyright (c) 2016-2024 University of Cambridge
11
12
-----------------------------------------------------------------------------
13
Redistribution and use in source and binary forms, with or without
14
modification, are permitted provided that the following conditions are met:
15
16
* Redistributions of source code must retain the above copyright notice,
17
this list of conditions and the following disclaimer.
18
19
* Redistributions in binary form must reproduce the above copyright
20
notice, this list of conditions and the following disclaimer in the
21
documentation and/or other materials provided with the distribution.
22
23
* Neither the name of the University of Cambridge nor the names of its
24
contributors may be used to endorse or promote products derived from
25
this software without specific prior written permission.
26
27
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37
POSSIBILITY OF SUCH DAMAGE.
38
-----------------------------------------------------------------------------
39
*/
40
41
42
#ifdef HAVE_CONFIG_H
43
#include "config.h"
44
#endif
45
46
#include "pcre2_internal.h"
47
48
49
/*************************************************
50
* Return info about compiled pattern *
51
*************************************************/
52
53
/*
54
Arguments:
55
code points to compiled code
56
what what information is required
57
where where to put the information; if NULL, return length
58
59
Returns: 0 when data returned
60
> 0 when length requested
61
< 0 on error or unset value
62
*/
63
64
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
65
pcre2_pattern_info(const pcre2_code *code, uint32_t what, void *where)
66
{
67
const pcre2_real_code *re = (const pcre2_real_code *)code;
68
69
if (where == NULL) /* Requests field length */
70
{
71
switch(what)
72
{
73
case PCRE2_INFO_ALLOPTIONS:
74
case PCRE2_INFO_ARGOPTIONS:
75
case PCRE2_INFO_BACKREFMAX:
76
case PCRE2_INFO_BSR:
77
case PCRE2_INFO_CAPTURECOUNT:
78
case PCRE2_INFO_DEPTHLIMIT:
79
case PCRE2_INFO_EXTRAOPTIONS:
80
case PCRE2_INFO_FIRSTCODETYPE:
81
case PCRE2_INFO_FIRSTCODEUNIT:
82
case PCRE2_INFO_HASBACKSLASHC:
83
case PCRE2_INFO_HASCRORLF:
84
case PCRE2_INFO_HEAPLIMIT:
85
case PCRE2_INFO_JCHANGED:
86
case PCRE2_INFO_LASTCODETYPE:
87
case PCRE2_INFO_LASTCODEUNIT:
88
case PCRE2_INFO_MATCHEMPTY:
89
case PCRE2_INFO_MATCHLIMIT:
90
case PCRE2_INFO_MAXLOOKBEHIND:
91
case PCRE2_INFO_MINLENGTH:
92
case PCRE2_INFO_NAMEENTRYSIZE:
93
case PCRE2_INFO_NAMECOUNT:
94
case PCRE2_INFO_NEWLINE:
95
return sizeof(uint32_t);
96
97
case PCRE2_INFO_FIRSTBITMAP:
98
return sizeof(const uint8_t *);
99
100
case PCRE2_INFO_JITSIZE:
101
case PCRE2_INFO_SIZE:
102
case PCRE2_INFO_FRAMESIZE:
103
return sizeof(size_t);
104
105
case PCRE2_INFO_NAMETABLE:
106
return sizeof(PCRE2_SPTR);
107
}
108
}
109
110
if (re == NULL) return PCRE2_ERROR_NULL;
111
112
/* Check that the first field in the block is the magic number. If it is not,
113
return with PCRE2_ERROR_BADMAGIC. */
114
115
if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;
116
117
/* Check that this pattern was compiled in the correct bit mode */
118
119
if ((re->flags & (PCRE2_CODE_UNIT_WIDTH/8)) == 0) return PCRE2_ERROR_BADMODE;
120
121
switch(what)
122
{
123
case PCRE2_INFO_ALLOPTIONS:
124
*((uint32_t *)where) = re->overall_options;
125
break;
126
127
case PCRE2_INFO_ARGOPTIONS:
128
*((uint32_t *)where) = re->compile_options;
129
break;
130
131
case PCRE2_INFO_BACKREFMAX:
132
*((uint32_t *)where) = re->top_backref;
133
break;
134
135
case PCRE2_INFO_BSR:
136
*((uint32_t *)where) = re->bsr_convention;
137
break;
138
139
case PCRE2_INFO_CAPTURECOUNT:
140
*((uint32_t *)where) = re->top_bracket;
141
break;
142
143
case PCRE2_INFO_DEPTHLIMIT:
144
*((uint32_t *)where) = re->limit_depth;
145
if (re->limit_depth == UINT32_MAX) return PCRE2_ERROR_UNSET;
146
break;
147
148
case PCRE2_INFO_EXTRAOPTIONS:
149
*((uint32_t *)where) = re->extra_options;
150
break;
151
152
case PCRE2_INFO_FIRSTCODETYPE:
153
*((uint32_t *)where) = ((re->flags & PCRE2_FIRSTSET) != 0)? 1 :
154
((re->flags & PCRE2_STARTLINE) != 0)? 2 : 0;
155
break;
156
157
case PCRE2_INFO_FIRSTCODEUNIT:
158
*((uint32_t *)where) = ((re->flags & PCRE2_FIRSTSET) != 0)?
159
re->first_codeunit : 0;
160
break;
161
162
case PCRE2_INFO_FIRSTBITMAP:
163
*((const uint8_t **)where) = ((re->flags & PCRE2_FIRSTMAPSET) != 0)?
164
&(re->start_bitmap[0]) : NULL;
165
break;
166
167
case PCRE2_INFO_FRAMESIZE:
168
*((size_t *)where) = offsetof(heapframe, ovector) +
169
re->top_bracket * 2 * sizeof(PCRE2_SIZE);
170
break;
171
172
case PCRE2_INFO_HASBACKSLASHC:
173
*((uint32_t *)where) = (re->flags & PCRE2_HASBKC) != 0;
174
break;
175
176
case PCRE2_INFO_HASCRORLF:
177
*((uint32_t *)where) = (re->flags & PCRE2_HASCRORLF) != 0;
178
break;
179
180
case PCRE2_INFO_HEAPLIMIT:
181
*((uint32_t *)where) = re->limit_heap;
182
if (re->limit_heap == UINT32_MAX) return PCRE2_ERROR_UNSET;
183
break;
184
185
case PCRE2_INFO_JCHANGED:
186
*((uint32_t *)where) = (re->flags & PCRE2_JCHANGED) != 0;
187
break;
188
189
case PCRE2_INFO_JITSIZE:
190
#ifdef SUPPORT_JIT
191
*((size_t *)where) = (re->executable_jit != NULL)?
192
PRIV(jit_get_size)(re->executable_jit) : 0;
193
#else
194
*((size_t *)where) = 0;
195
#endif
196
break;
197
198
case PCRE2_INFO_LASTCODETYPE:
199
*((uint32_t *)where) = ((re->flags & PCRE2_LASTSET) != 0)? 1 : 0;
200
break;
201
202
case PCRE2_INFO_LASTCODEUNIT:
203
*((uint32_t *)where) = ((re->flags & PCRE2_LASTSET) != 0)?
204
re->last_codeunit : 0;
205
break;
206
207
case PCRE2_INFO_MATCHEMPTY:
208
*((uint32_t *)where) = (re->flags & PCRE2_MATCH_EMPTY) != 0;
209
break;
210
211
case PCRE2_INFO_MATCHLIMIT:
212
*((uint32_t *)where) = re->limit_match;
213
if (re->limit_match == UINT32_MAX) return PCRE2_ERROR_UNSET;
214
break;
215
216
case PCRE2_INFO_MAXLOOKBEHIND:
217
*((uint32_t *)where) = re->max_lookbehind;
218
break;
219
220
case PCRE2_INFO_MINLENGTH:
221
*((uint32_t *)where) = re->minlength;
222
break;
223
224
case PCRE2_INFO_NAMEENTRYSIZE:
225
*((uint32_t *)where) = re->name_entry_size;
226
break;
227
228
case PCRE2_INFO_NAMECOUNT:
229
*((uint32_t *)where) = re->name_count;
230
break;
231
232
case PCRE2_INFO_NAMETABLE:
233
*((PCRE2_SPTR *)where) = (PCRE2_SPTR)((const char *)re +
234
sizeof(pcre2_real_code));
235
break;
236
237
case PCRE2_INFO_NEWLINE:
238
*((uint32_t *)where) = re->newline_convention;
239
break;
240
241
case PCRE2_INFO_SIZE:
242
*((size_t *)where) = re->blocksize;
243
break;
244
245
default: return PCRE2_ERROR_BADOPTION;
246
}
247
248
return 0;
249
}
250
251
252
253
/*************************************************
254
* Callout enumerator *
255
*************************************************/
256
257
/*
258
Arguments:
259
code points to compiled code
260
callback function called for each callout block
261
callout_data user data passed to the callback
262
263
Returns: 0 when successfully completed
264
< 0 on local error
265
!= 0 for callback error
266
*/
267
268
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
269
pcre2_callout_enumerate(const pcre2_code *code,
270
int (*callback)(pcre2_callout_enumerate_block *, void *), void *callout_data)
271
{
272
const pcre2_real_code *re = (const pcre2_real_code *)code;
273
pcre2_callout_enumerate_block cb;
274
PCRE2_SPTR cc;
275
#ifdef SUPPORT_UNICODE
276
BOOL utf;
277
#endif
278
279
if (re == NULL) return PCRE2_ERROR_NULL;
280
281
#ifdef SUPPORT_UNICODE
282
utf = (re->overall_options & PCRE2_UTF) != 0;
283
#endif
284
285
/* Check that the first field in the block is the magic number. If it is not,
286
return with PCRE2_ERROR_BADMAGIC. */
287
288
if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;
289
290
/* Check that this pattern was compiled in the correct bit mode */
291
292
if ((re->flags & (PCRE2_CODE_UNIT_WIDTH/8)) == 0) return PCRE2_ERROR_BADMODE;
293
294
cb.version = 0;
295
cc = (PCRE2_SPTR)((const uint8_t *)re + sizeof(pcre2_real_code))
296
+ re->name_count * re->name_entry_size;
297
298
while (TRUE)
299
{
300
int rc;
301
switch (*cc)
302
{
303
case OP_END:
304
return 0;
305
306
case OP_CHAR:
307
case OP_CHARI:
308
case OP_NOT:
309
case OP_NOTI:
310
case OP_STAR:
311
case OP_MINSTAR:
312
case OP_PLUS:
313
case OP_MINPLUS:
314
case OP_QUERY:
315
case OP_MINQUERY:
316
case OP_UPTO:
317
case OP_MINUPTO:
318
case OP_EXACT:
319
case OP_POSSTAR:
320
case OP_POSPLUS:
321
case OP_POSQUERY:
322
case OP_POSUPTO:
323
case OP_STARI:
324
case OP_MINSTARI:
325
case OP_PLUSI:
326
case OP_MINPLUSI:
327
case OP_QUERYI:
328
case OP_MINQUERYI:
329
case OP_UPTOI:
330
case OP_MINUPTOI:
331
case OP_EXACTI:
332
case OP_POSSTARI:
333
case OP_POSPLUSI:
334
case OP_POSQUERYI:
335
case OP_POSUPTOI:
336
case OP_NOTSTAR:
337
case OP_NOTMINSTAR:
338
case OP_NOTPLUS:
339
case OP_NOTMINPLUS:
340
case OP_NOTQUERY:
341
case OP_NOTMINQUERY:
342
case OP_NOTUPTO:
343
case OP_NOTMINUPTO:
344
case OP_NOTEXACT:
345
case OP_NOTPOSSTAR:
346
case OP_NOTPOSPLUS:
347
case OP_NOTPOSQUERY:
348
case OP_NOTPOSUPTO:
349
case OP_NOTSTARI:
350
case OP_NOTMINSTARI:
351
case OP_NOTPLUSI:
352
case OP_NOTMINPLUSI:
353
case OP_NOTQUERYI:
354
case OP_NOTMINQUERYI:
355
case OP_NOTUPTOI:
356
case OP_NOTMINUPTOI:
357
case OP_NOTEXACTI:
358
case OP_NOTPOSSTARI:
359
case OP_NOTPOSPLUSI:
360
case OP_NOTPOSQUERYI:
361
case OP_NOTPOSUPTOI:
362
cc += PRIV(OP_lengths)[*cc];
363
#ifdef SUPPORT_UNICODE
364
if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
365
#endif
366
break;
367
368
case OP_TYPESTAR:
369
case OP_TYPEMINSTAR:
370
case OP_TYPEPLUS:
371
case OP_TYPEMINPLUS:
372
case OP_TYPEQUERY:
373
case OP_TYPEMINQUERY:
374
case OP_TYPEUPTO:
375
case OP_TYPEMINUPTO:
376
case OP_TYPEEXACT:
377
case OP_TYPEPOSSTAR:
378
case OP_TYPEPOSPLUS:
379
case OP_TYPEPOSQUERY:
380
case OP_TYPEPOSUPTO:
381
cc += PRIV(OP_lengths)[*cc];
382
#ifdef SUPPORT_UNICODE
383
if (cc[-1] == OP_PROP || cc[-1] == OP_NOTPROP) cc += 2;
384
#endif
385
break;
386
387
#ifdef SUPPORT_WIDE_CHARS
388
case OP_XCLASS:
389
case OP_ECLASS:
390
cc += GET(cc, 1);
391
break;
392
#endif
393
394
case OP_MARK:
395
case OP_COMMIT_ARG:
396
case OP_PRUNE_ARG:
397
case OP_SKIP_ARG:
398
case OP_THEN_ARG:
399
cc += PRIV(OP_lengths)[*cc] + cc[1];
400
break;
401
402
case OP_CALLOUT:
403
cb.pattern_position = GET(cc, 1);
404
cb.next_item_length = GET(cc, 1 + LINK_SIZE);
405
cb.callout_number = cc[1 + 2*LINK_SIZE];
406
cb.callout_string_offset = 0;
407
cb.callout_string_length = 0;
408
cb.callout_string = NULL;
409
rc = callback(&cb, callout_data);
410
if (rc != 0) return rc;
411
cc += PRIV(OP_lengths)[*cc];
412
break;
413
414
case OP_CALLOUT_STR:
415
cb.pattern_position = GET(cc, 1);
416
cb.next_item_length = GET(cc, 1 + LINK_SIZE);
417
cb.callout_number = 0;
418
cb.callout_string_offset = GET(cc, 1 + 3*LINK_SIZE);
419
cb.callout_string_length =
420
GET(cc, 1 + 2*LINK_SIZE) - (1 + 4*LINK_SIZE) - 2;
421
cb.callout_string = cc + (1 + 4*LINK_SIZE) + 1;
422
rc = callback(&cb, callout_data);
423
if (rc != 0) return rc;
424
cc += GET(cc, 1 + 2*LINK_SIZE);
425
break;
426
427
default:
428
cc += PRIV(OP_lengths)[*cc];
429
break;
430
}
431
}
432
}
433
434
/* End of pcre2_pattern_info.c */
435
436