Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/thirdparty/pcre2/src/pcre2_pattern_info.c
21520 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
#include "pcre2_internal.h"
43
44
45
46
/*************************************************
47
* Return info about compiled pattern *
48
*************************************************/
49
50
/*
51
Arguments:
52
code points to compiled code
53
what what information is required
54
where where to put the information; if NULL, return length
55
56
Returns: 0 when data returned
57
> 0 when length requested
58
< 0 on error or unset value
59
*/
60
61
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
62
pcre2_pattern_info(const pcre2_code *code, uint32_t what, void *where)
63
{
64
const pcre2_real_code *re = (const pcre2_real_code *)code;
65
66
if (where == NULL) /* Requests field length */
67
{
68
switch(what)
69
{
70
case PCRE2_INFO_ALLOPTIONS:
71
case PCRE2_INFO_ARGOPTIONS:
72
case PCRE2_INFO_BACKREFMAX:
73
case PCRE2_INFO_BSR:
74
case PCRE2_INFO_CAPTURECOUNT:
75
case PCRE2_INFO_DEPTHLIMIT:
76
case PCRE2_INFO_EXTRAOPTIONS:
77
case PCRE2_INFO_FIRSTCODETYPE:
78
case PCRE2_INFO_FIRSTCODEUNIT:
79
case PCRE2_INFO_HASBACKSLASHC:
80
case PCRE2_INFO_HASCRORLF:
81
case PCRE2_INFO_HEAPLIMIT:
82
case PCRE2_INFO_JCHANGED:
83
case PCRE2_INFO_LASTCODETYPE:
84
case PCRE2_INFO_LASTCODEUNIT:
85
case PCRE2_INFO_MATCHEMPTY:
86
case PCRE2_INFO_MATCHLIMIT:
87
case PCRE2_INFO_MAXLOOKBEHIND:
88
case PCRE2_INFO_MINLENGTH:
89
case PCRE2_INFO_NAMEENTRYSIZE:
90
case PCRE2_INFO_NAMECOUNT:
91
case PCRE2_INFO_NEWLINE:
92
return sizeof(uint32_t);
93
94
case PCRE2_INFO_FIRSTBITMAP:
95
return sizeof(const uint8_t *);
96
97
case PCRE2_INFO_JITSIZE:
98
case PCRE2_INFO_SIZE:
99
case PCRE2_INFO_FRAMESIZE:
100
return sizeof(size_t);
101
102
case PCRE2_INFO_NAMETABLE:
103
return sizeof(PCRE2_SPTR);
104
}
105
}
106
107
if (re == NULL) return PCRE2_ERROR_NULL;
108
109
/* Check that the first field in the block is the magic number. If it is not,
110
return with PCRE2_ERROR_BADMAGIC. */
111
112
if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;
113
114
/* Check that this pattern was compiled in the correct bit mode */
115
116
if ((re->flags & (PCRE2_CODE_UNIT_WIDTH/8)) == 0) return PCRE2_ERROR_BADMODE;
117
118
switch(what)
119
{
120
case PCRE2_INFO_ALLOPTIONS:
121
*((uint32_t *)where) = re->overall_options;
122
break;
123
124
case PCRE2_INFO_ARGOPTIONS:
125
*((uint32_t *)where) = re->compile_options;
126
break;
127
128
case PCRE2_INFO_BACKREFMAX:
129
*((uint32_t *)where) = re->top_backref;
130
break;
131
132
case PCRE2_INFO_BSR:
133
*((uint32_t *)where) = re->bsr_convention;
134
break;
135
136
case PCRE2_INFO_CAPTURECOUNT:
137
*((uint32_t *)where) = re->top_bracket;
138
break;
139
140
case PCRE2_INFO_DEPTHLIMIT:
141
*((uint32_t *)where) = re->limit_depth;
142
if (re->limit_depth == UINT32_MAX) return PCRE2_ERROR_UNSET;
143
break;
144
145
case PCRE2_INFO_EXTRAOPTIONS:
146
*((uint32_t *)where) = re->extra_options;
147
break;
148
149
case PCRE2_INFO_FIRSTCODETYPE:
150
*((uint32_t *)where) = ((re->flags & PCRE2_FIRSTSET) != 0)? 1 :
151
((re->flags & PCRE2_STARTLINE) != 0)? 2 : 0;
152
break;
153
154
case PCRE2_INFO_FIRSTCODEUNIT:
155
*((uint32_t *)where) = ((re->flags & PCRE2_FIRSTSET) != 0)?
156
re->first_codeunit : 0;
157
break;
158
159
case PCRE2_INFO_FIRSTBITMAP:
160
*((const uint8_t **)where) = ((re->flags & PCRE2_FIRSTMAPSET) != 0)?
161
&(re->start_bitmap[0]) : NULL;
162
break;
163
164
case PCRE2_INFO_FRAMESIZE:
165
*((size_t *)where) = offsetof(heapframe, ovector) +
166
re->top_bracket * 2 * sizeof(PCRE2_SIZE);
167
break;
168
169
case PCRE2_INFO_HASBACKSLASHC:
170
*((uint32_t *)where) = (re->flags & PCRE2_HASBKC) != 0;
171
break;
172
173
case PCRE2_INFO_HASCRORLF:
174
*((uint32_t *)where) = (re->flags & PCRE2_HASCRORLF) != 0;
175
break;
176
177
case PCRE2_INFO_HEAPLIMIT:
178
*((uint32_t *)where) = re->limit_heap;
179
if (re->limit_heap == UINT32_MAX) return PCRE2_ERROR_UNSET;
180
break;
181
182
case PCRE2_INFO_JCHANGED:
183
*((uint32_t *)where) = (re->flags & PCRE2_JCHANGED) != 0;
184
break;
185
186
case PCRE2_INFO_JITSIZE:
187
#ifdef SUPPORT_JIT
188
*((size_t *)where) = (re->executable_jit != NULL)?
189
PRIV(jit_get_size)(re->executable_jit) : 0;
190
#else
191
*((size_t *)where) = 0;
192
#endif
193
break;
194
195
case PCRE2_INFO_LASTCODETYPE:
196
*((uint32_t *)where) = ((re->flags & PCRE2_LASTSET) != 0)? 1 : 0;
197
break;
198
199
case PCRE2_INFO_LASTCODEUNIT:
200
*((uint32_t *)where) = ((re->flags & PCRE2_LASTSET) != 0)?
201
re->last_codeunit : 0;
202
break;
203
204
case PCRE2_INFO_MATCHEMPTY:
205
*((uint32_t *)where) = (re->flags & PCRE2_MATCH_EMPTY) != 0;
206
break;
207
208
case PCRE2_INFO_MATCHLIMIT:
209
*((uint32_t *)where) = re->limit_match;
210
if (re->limit_match == UINT32_MAX) return PCRE2_ERROR_UNSET;
211
break;
212
213
case PCRE2_INFO_MAXLOOKBEHIND:
214
*((uint32_t *)where) = re->max_lookbehind;
215
break;
216
217
case PCRE2_INFO_MINLENGTH:
218
*((uint32_t *)where) = re->minlength;
219
break;
220
221
case PCRE2_INFO_NAMEENTRYSIZE:
222
*((uint32_t *)where) = re->name_entry_size;
223
break;
224
225
case PCRE2_INFO_NAMECOUNT:
226
*((uint32_t *)where) = re->name_count;
227
break;
228
229
case PCRE2_INFO_NAMETABLE:
230
*((PCRE2_SPTR *)where) = (PCRE2_SPTR)((const char *)re +
231
sizeof(pcre2_real_code));
232
break;
233
234
case PCRE2_INFO_NEWLINE:
235
*((uint32_t *)where) = re->newline_convention;
236
break;
237
238
case PCRE2_INFO_SIZE:
239
*((size_t *)where) = re->blocksize;
240
break;
241
242
default: return PCRE2_ERROR_BADOPTION;
243
}
244
245
return 0;
246
}
247
248
249
250
/*************************************************
251
* Callout enumerator *
252
*************************************************/
253
254
/*
255
Arguments:
256
code points to compiled code
257
callback function called for each callout block
258
callout_data user data passed to the callback
259
260
Returns: 0 when successfully completed
261
< 0 on local error
262
!= 0 for callback error
263
*/
264
265
PCRE2_EXP_DEFN int PCRE2_CALL_CONVENTION
266
pcre2_callout_enumerate(const pcre2_code *code,
267
int (*callback)(pcre2_callout_enumerate_block *, void *), void *callout_data)
268
{
269
const pcre2_real_code *re = (const pcre2_real_code *)code;
270
pcre2_callout_enumerate_block cb;
271
PCRE2_SPTR cc;
272
#ifdef SUPPORT_UNICODE
273
BOOL utf;
274
#endif
275
276
if (re == NULL) return PCRE2_ERROR_NULL;
277
278
#ifdef SUPPORT_UNICODE
279
utf = (re->overall_options & PCRE2_UTF) != 0;
280
#endif
281
282
/* Check that the first field in the block is the magic number. If it is not,
283
return with PCRE2_ERROR_BADMAGIC. */
284
285
if (re->magic_number != MAGIC_NUMBER) return PCRE2_ERROR_BADMAGIC;
286
287
/* Check that this pattern was compiled in the correct bit mode */
288
289
if ((re->flags & (PCRE2_CODE_UNIT_WIDTH/8)) == 0) return PCRE2_ERROR_BADMODE;
290
291
cb.version = 0;
292
cc = (PCRE2_SPTR)((uint8_t *)re + re->code_start);
293
294
while (TRUE)
295
{
296
int rc;
297
switch (*cc)
298
{
299
case OP_END:
300
return 0;
301
302
case OP_CHAR:
303
case OP_CHARI:
304
case OP_NOT:
305
case OP_NOTI:
306
case OP_STAR:
307
case OP_MINSTAR:
308
case OP_PLUS:
309
case OP_MINPLUS:
310
case OP_QUERY:
311
case OP_MINQUERY:
312
case OP_UPTO:
313
case OP_MINUPTO:
314
case OP_EXACT:
315
case OP_POSSTAR:
316
case OP_POSPLUS:
317
case OP_POSQUERY:
318
case OP_POSUPTO:
319
case OP_STARI:
320
case OP_MINSTARI:
321
case OP_PLUSI:
322
case OP_MINPLUSI:
323
case OP_QUERYI:
324
case OP_MINQUERYI:
325
case OP_UPTOI:
326
case OP_MINUPTOI:
327
case OP_EXACTI:
328
case OP_POSSTARI:
329
case OP_POSPLUSI:
330
case OP_POSQUERYI:
331
case OP_POSUPTOI:
332
case OP_NOTSTAR:
333
case OP_NOTMINSTAR:
334
case OP_NOTPLUS:
335
case OP_NOTMINPLUS:
336
case OP_NOTQUERY:
337
case OP_NOTMINQUERY:
338
case OP_NOTUPTO:
339
case OP_NOTMINUPTO:
340
case OP_NOTEXACT:
341
case OP_NOTPOSSTAR:
342
case OP_NOTPOSPLUS:
343
case OP_NOTPOSQUERY:
344
case OP_NOTPOSUPTO:
345
case OP_NOTSTARI:
346
case OP_NOTMINSTARI:
347
case OP_NOTPLUSI:
348
case OP_NOTMINPLUSI:
349
case OP_NOTQUERYI:
350
case OP_NOTMINQUERYI:
351
case OP_NOTUPTOI:
352
case OP_NOTMINUPTOI:
353
case OP_NOTEXACTI:
354
case OP_NOTPOSSTARI:
355
case OP_NOTPOSPLUSI:
356
case OP_NOTPOSQUERYI:
357
case OP_NOTPOSUPTOI:
358
cc += PRIV(OP_lengths)[*cc];
359
#ifdef SUPPORT_UNICODE
360
if (utf && HAS_EXTRALEN(cc[-1])) cc += GET_EXTRALEN(cc[-1]);
361
#endif
362
break;
363
364
case OP_TYPESTAR:
365
case OP_TYPEMINSTAR:
366
case OP_TYPEPLUS:
367
case OP_TYPEMINPLUS:
368
case OP_TYPEQUERY:
369
case OP_TYPEMINQUERY:
370
case OP_TYPEUPTO:
371
case OP_TYPEMINUPTO:
372
case OP_TYPEEXACT:
373
case OP_TYPEPOSSTAR:
374
case OP_TYPEPOSPLUS:
375
case OP_TYPEPOSQUERY:
376
case OP_TYPEPOSUPTO:
377
cc += PRIV(OP_lengths)[*cc];
378
#ifdef SUPPORT_UNICODE
379
if (cc[-1] == OP_PROP || cc[-1] == OP_NOTPROP) cc += 2;
380
#endif
381
break;
382
383
#ifdef SUPPORT_WIDE_CHARS
384
case OP_XCLASS:
385
case OP_ECLASS:
386
cc += GET(cc, 1);
387
break;
388
#endif
389
390
case OP_MARK:
391
case OP_COMMIT_ARG:
392
case OP_PRUNE_ARG:
393
case OP_SKIP_ARG:
394
case OP_THEN_ARG:
395
cc += PRIV(OP_lengths)[*cc] + cc[1];
396
break;
397
398
case OP_CALLOUT:
399
cb.pattern_position = GET(cc, 1);
400
cb.next_item_length = GET(cc, 1 + LINK_SIZE);
401
cb.callout_number = cc[1 + 2*LINK_SIZE];
402
cb.callout_string_offset = 0;
403
cb.callout_string_length = 0;
404
cb.callout_string = NULL;
405
rc = callback(&cb, callout_data);
406
if (rc != 0) return rc;
407
cc += PRIV(OP_lengths)[*cc];
408
break;
409
410
case OP_CALLOUT_STR:
411
cb.pattern_position = GET(cc, 1);
412
cb.next_item_length = GET(cc, 1 + LINK_SIZE);
413
cb.callout_number = 0;
414
cb.callout_string_offset = GET(cc, 1 + 3*LINK_SIZE);
415
cb.callout_string_length =
416
GET(cc, 1 + 2*LINK_SIZE) - (1 + 4*LINK_SIZE) - 2;
417
cb.callout_string = cc + (1 + 4*LINK_SIZE) + 1;
418
rc = callback(&cb, callout_data);
419
if (rc != 0) return rc;
420
cc += GET(cc, 1 + 2*LINK_SIZE);
421
break;
422
423
default:
424
cc += PRIV(OP_lengths)[*cc];
425
break;
426
}
427
}
428
}
429
430
/* End of pcre2_pattern_info.c */
431
432