-
Notifications
You must be signed in to change notification settings - Fork 7
/
php_pcre.pir
508 lines (442 loc) · 12.3 KB
/
php_pcre.pir
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
# Copyright (C) 2008, The Perl Foundation.
=head1 NAME
php_pcre.pir - PHP pcre Library
=head1 DESCRIPTION
=head2 Functions
=over 4
=cut
.HLL 'pipp'
.include 'src/common/php_MACRO.pir'
.include 'cclass.pasm'
.sub '__onload' :anon :load :init
push_eh _handler
load_bytecode "pcre.pir" # load_bytecode "pcre.pbc" gives failures
load_bytecode "libpcre.pir" # load_bytecode "libpcre.pbc" gives failures
$P0 = get_global ['PCRE'], 'init'
$P1 = $P0()
new $P0, 'PhpInteger'
set $P0, 0
set_hll_global 'pcre_error_code', $P0
new $P0, 'Hash'
set_hll_global 'pcre_cache', $P0
__init()
_handler:
.end
# options PCRE
.const int PCRE_CASELESS = 0x00000001
.const int PCRE_MULTILINE = 0x00000002
.const int PCRE_DOTALL = 0x00000004
.const int PCRE_EXTENDED = 0x00000008
.const int PCRE_ANCHORED = 0x00000010
.const int PCRE_DOLLAR_ENDONLY = 0x00000020
.const int PCRE_EXTRA = 0x00000040
.const int PCRE_NOTBOL = 0x00000080
.const int PCRE_NOTEOL = 0x00000100
.const int PCRE_UNGREEDY = 0x00000200
.const int PCRE_NOTEMPTY = 0x00000400
.const int PCRE_UTF8 = 0x00000800
.const int PCRE_NO_AUTO_CAPTURE = 0x00001000
.const int PCRE_NO_UTF8_CHECK = 0x00002000
.const int PCRE_AUTO_CALLOUT = 0x00004000
.const int PCRE_PARTIAL = 0x00008000
.const int PCRE_DFA_SHORTEST = 0x00010000
.const int PCRE_DFA_RESTART = 0x00020000
.const int PCRE_FIRSTLINE = 0x00040000
.const int PCRE_DUPNAMES = 0x00080000
.const int PCRE_NEWLINE_CR = 0x00100000
.const int PCRE_NEWLINE_LF = 0x00200000
.const int PCRE_NEWLINE_CRLF = 0x00300000
.const int PCRE_NEWLINE_ANY = 0x00400000
.const int PCRE_NEWLINE_ANYCRLF = 0x00500000
.const int PCRE_BSR_ANYCRLF = 0x00800000
.const int PCRE_BSR_UNICODE = 0x01000000
.const int PREG_PATTERN_ORDER = 1
.const int PREG_SET_ORDER = 2
.const int PREG_OFFSET_CAPTURE = 0x100
.const int PREG_SPLIT_NO_EMPTY = 1
.const int PREG_SPLIT_DELIM_CAPTURE = 2
.const int PREG_SPLIT_OFFSET_CAPTURE = 4
.const int PREG_REPLACE_EVAL = 1
.const int PREG_GREP_INVERT = 1
.const int PHP_PCRE_NO_ERROR = 0
.const int PHP_PCRE_INTERNAL_ERROR = 1
.const int PHP_PCRE_BACKTRACK_LIMIT_ERROR = 2
.const int PHP_PCRE_RECURSION_LIMIT_ERROR = 3
.const int PHP_PCRE_BAD_UTF8_ERROR = 4
.sub '__init' :anon
.REGISTER_LONG_CONSTANT('PREG_PATTERN_ORDER', PREG_PATTERN_ORDER)
.REGISTER_LONG_CONSTANT('PREG_SET_ORDER', PREG_SET_ORDER)
.REGISTER_LONG_CONSTANT('PREG_OFFSET_CAPTURE', PREG_OFFSET_CAPTURE)
.REGISTER_LONG_CONSTANT('PREG_SPLIT_NO_EMPTY', PREG_SPLIT_NO_EMPTY)
.REGISTER_LONG_CONSTANT('PREG_SPLIT_DELIM_CAPTURE', PREG_SPLIT_DELIM_CAPTURE)
.REGISTER_LONG_CONSTANT('PREG_SPLIT_OFFSET_CAPTURE', PREG_SPLIT_OFFSET_CAPTURE)
.REGISTER_LONG_CONSTANT('PREG_GREP_INVERT', PREG_GREP_INVERT)
.REGISTER_LONG_CONSTANT('PREG_NO_ERROR', PHP_PCRE_NO_ERROR)
.REGISTER_LONG_CONSTANT('PREG_INTERNAL_ERROR', PHP_PCRE_INTERNAL_ERROR)
.REGISTER_LONG_CONSTANT('PREG_BACKTRACK_LIMIT_ERROR', PHP_PCRE_BACKTRACK_LIMIT_ERROR)
.REGISTER_LONG_CONSTANT('PREG_RECURSION_LIMIT_ERROR', PHP_PCRE_RECURSION_LIMIT_ERROR)
.REGISTER_LONG_CONSTANT('PREG_BAD_UTF8_ERROR', PHP_PCRE_BAD_UTF8_ERROR)
$P0 = get_global ['PCRE'], 'version'
$S0= $P0()
.REGISTER_STRING_CONSTANT('PCRE_VERSION', $S0)
.end
.sub 'pcre_get_compiled_regex_cache' :anon
.param string regex
.local pmc cache
.local pmc code
cache = get_hll_global 'pcre_cache'
$I0 = exists cache[regex]
unless $I0 goto L0
code = cache[regex]
.return (code)
L0:
null code
$I1 = length regex
$I0 = find_not_cclass .CCLASS_WHITESPACE, regex, 0, $I1
unless $I0 == $I1 goto L1
error(E_WARNING, "Empty regular expression")
.return (code)
L1:
.local string delimiter
delimiter = substr regex, $I0, 1
.local int start_pat
start_pat = $I0 + 1
$I0 = is_cclass .CCLASS_ALPHANUMERIC, delimiter, 0
if $I0 goto L2
if delimiter == "\\" goto L2
goto L3
L2:
error(E_WARNING, "Delimiter must not be alphanumeric or backslash")
.return (code)
L3:
.local string start_delimiter, end_delimiter
start_delimiter = delimiter
$I0 = index '([{<)]}>', delimiter
if $I0 < 0 goto L4
delimiter = substr ')]}>([{<', $I0, 1
L4:
end_delimiter = delimiter
$I1 = length regex
$I0 = start_pat
unless start_delimiter == end_delimiter goto L5
L6:
unless $I0 < $I1 goto L7
$S0 = substr regex, $I0, 1
unless $S0 == "\\" goto L8
inc $I0
goto L9
L8:
if $S0 == delimiter goto L10
L9:
inc $I0
goto L6
L7:
error(E_WARNING, "No ending delimiter '", delimiter, "' found")
.return (code)
L5:
.local int brackets
brackets = 1
L11:
unless $I0 < $I1 goto L7
$S0 = substr regex, $I0, 1
unless $S0 == "\\" goto L12
inc $I0
goto L13
L12:
unless $S0 == end_delimiter goto L14
dec brackets
if brackets <= 0 goto L10
goto L13
L14:
unless $S0 == start_delimiter goto L13
inc brackets
L13:
inc $I0
goto L11
L10:
.local string pat
$I1 = $I0 - start_pat
pat = substr regex, start_pat, $I1
.local string options
inc $I0
options = substr regex, $I0
.local int coptions, poptions, do_study
coptions = 0
poptions = 0
do_study = 0
$I0 = 0
$I1 = length options
L20:
unless $I0 < $I1 goto L21
$S0 = substr options, $I0, 1
unless $S0 == 'i' goto L23
coptions |= PCRE_CASELESS
goto L22
L23:
unless $S0 == 'm' goto L24
coptions |= PCRE_MULTILINE
goto L22
L24:
unless $S0 == 's' goto L25
coptions |= PCRE_DOTALL
goto L22
L25:
unless $S0 == 'x' goto L26
coptions |= PCRE_EXTENDED
goto L22
L26:
unless $S0 == 'A' goto L27
coptions |= PCRE_ANCHORED
goto L22
L27:
unless $S0 == 'D' goto L28
coptions |= PCRE_DOLLAR_ENDONLY
goto L22
L28:
unless $S0 == 'S' goto L29
do_study = 1
goto L22
L29:
unless $S0 == 'U' goto L30
coptions |= PCRE_UNGREEDY
goto L22
L30:
unless $S0 == 'X' goto L31
coptions |= PCRE_EXTRA
goto L22
L31:
unless $S0 == 'u' goto L32
coptions |= PCRE_UTF8
goto L22
L32:
unless $S0 == 'X' goto L33
poptions |= PREG_REPLACE_EVAL
goto L22
L33:
if $S0 == ' ' goto L22
if $S0 == "\n" goto L22
error(E_WARNING, "Unknown modifier '", $S0, "'")
.return (code)
L22:
inc $I0
goto L20
L21:
.local string error
.local int errptr
$P0 = get_global ['PCRE'], 'compile'
(code, error, errptr)= $P0(pat, coptions)
unless null code goto L34
# error(E_WARNING, "Compilation failed: ", error, " at offset ", errptr)
.return (code)
L34:
cache[regex] = code
.return (code)
.end
=item C<array preg_grep(string regex, array input [, int flags])>
Searches array and returns entries which match regex
NOT IMPLEMENTED.
=cut
.sub 'preg_grep'
.param pmc args :slurpy
.local string regex
.local pmc input
.local int flags
flags = 0
($I0, regex, input, flags) = parse_parameters('sa|l', args :flat)
if $I0 goto L1
.RETURN_NULL()
L1:
.local pmc pce
pce = pcre_get_compiled_regex_cache(regex)
unless null pce goto L2
.RETURN_FALSE()
L2:
.tailcall preg_grep_impl(pce, input, flags)
.end
.sub 'preg_grep_impl' :anon
.param pmc pce
.param pmc input
.param int flags
not_implemented()
.end
=item C<int preg_last_error()>
Returns the error code of the last regexp execution.
=cut
.sub 'preg_last_error'
.param pmc args :slurpy
($I0) = parse_parameters('', args :flat)
if $I0 goto L1
.RETURN_NULL()
L1:
$P0 = get_hll_global 'pcre_error_code'
.return ($P0)
.end
=item C<int preg_match(string pattern, string subject [, array subpatterns [, int flags [, int offset]]])>
Perform a Perl-style regular expression match
STILL INCOMPLETE (see pcre_match_impl).
=cut
.sub 'preg_match'
.param pmc args :slurpy
.local string regex
.local string subject
.local pmc subpats
.local int flags
.local int start_offset
flags = 0
start_offset = 0
($I0, regex, subject, subpats, flags, start_offset) = parse_parameters('ss|zll', args :flat)
if $I0 goto L1
.RETURN_NULL()
L1:
.local pmc pce
pce = pcre_get_compiled_regex_cache(regex)
unless null pce goto L2
.RETURN_FALSE()
L2:
.local int use_flags
use_flags = 0
$I0 = args
unless $I0 >= 4 goto L3
use_flags = 1
L3:
.tailcall pcre_match_impl(pce, subject, subpats, 0, use_flags, flags, start_offset)
.end
.sub 'pcre_match_impl' :anon
.param pmc pce
.param string subject
.param pmc subpats
.param int _global
.param int use_flags
.param int flags
.param int start_offset
.local int ok
.local pmc result
$P0 = get_global ['PCRE'], 'match'
(ok, result)= $P0(pce, subject, 0, 0)
unless ok < 0 goto L1
.RETURN_LONG(0)
L1:
.RETURN_LONG(1)
.end
=item C<int preg_match_all(string pattern, string subject, array subpatterns [, int flags [, int offset]])>
Perform a Perl-style global regular expression match
STILL INCOMPLETE (see pcre_match_impl).
=cut
.sub 'preg_match_all'
.param pmc args :slurpy
.local string regex
.local string subject
.local pmc subpats
.local int flags
.local int start_offset
flags = 0
start_offset = 0
($I0, regex, subject, subpats, flags, start_offset) = parse_parameters('ss|zll', args :flat)
if $I0 goto L1
.RETURN_NULL()
L1:
.local pmc pce
pce = pcre_get_compiled_regex_cache(regex)
unless null pce goto L2
.RETURN_FALSE()
L2:
.local int use_flags
use_flags = 0
$I0 = args
unless $I0 >= 4 goto L3
use_flags = 1
L3:
.tailcall pcre_match_impl(pce, subject, subpats, 1, use_flags, flags, start_offset)
.end
=item C<string preg_quote(string str [, string delim_char])>
Quote regular expression characters plus an optional character
=cut
.sub 'preg_quote'
.param pmc args :slurpy
.local string in_str
.local string delim
delim = ''
($I0, in_str, delim) = parse_parameters('s|s', args :flat)
if $I0 goto L1
.RETURN_NULL()
L1:
unless in_str == '' goto L2
.RETURN_EMPTY_STRING()
L2:
if delim == '' goto L3
delim = substr delim, 0, 1
L3:
$S0 = ''
$P0 = split '', in_str
L4:
unless $P0 goto L5
$S1 = shift $P0
$I0 = index '.\+*?[^]$(){}=!<>|:', $S1
if $I0 < 0 goto L6
concat $S0, "\\"
concat $S0, $S1
goto L4
L6:
unless $S1 == "\0" goto L7
concat $S0, "\\000"
goto L4
L7:
unless $S1 == delim goto L8
concat $S0, "\\"
L8:
concat $S0, $S1
goto L4
L5:
.RETURN_STRING($S0)
.end
=item C<string preg_replace(mixed regex, mixed replace, mixed subject [, int limit [, count]])>
Perform Perl-style regular expression replacement.
NOT IMPLEMENTED.
=cut
.sub 'preg_replace'
not_implemented()
.end
=item C<string preg_replace_callback(mixed regex, mixed callback, mixed subject [, int limit [, count]])>
Perform Perl-style regular expression replacement using replacement callback.
NOT IMPLEMENTED.
=cut
.sub 'preg_replace_callback'
not_implemented()
.end
=item C<array preg_split(string pattern, string subject [, int limit [, int flags]])>
Split string into an array using a perl-style regular expression as a delimiter
NOT IMPLEMENTED.
=cut
.sub 'preg_split'
.param pmc args :slurpy
.local string regex
.local string subject
.local int limit
.local int flags
limit = -1
flags = 0
($I0, regex, subject, limit, flags) = parse_parameters('ss|ll', args :flat)
if $I0 goto L1
.RETURN_NULL()
L1:
.local pmc pce
pce = pcre_get_compiled_regex_cache(regex)
unless null pce goto L2
.RETURN_FALSE()
L2:
.tailcall pcre_split_impl(pce, subject, limit, flags)
.end
.sub 'pcre_split_impl' :anon
.param pmc pce
.param string subject
.param int limit
.param int flags
not_implemented()
.end
=back
=cut
# Local Variables:
# mode: pir
# fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir: