1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1985-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * Glenn Fowler <gsf@research.att.com> *
18 * David Korn <dgk@research.att.com> *
19 * Phong Vo <kpv@research.att.com> *
21 ***********************************************************************/
25 * posix regex decompiler
31 #define ismeta(c,t,e,d) (state.magic[c] && state.magic[c][(t)+(e)] >= T_META || (c) == (d))
32 #define meta(f,c,t,e,d) do { if (ismeta(c,t,e,d)) sfputc(f, '\\'); sfputc(f, c); } while (0)
35 detrie(Trie_node_t
* x
, Sfio_t
* sp
, char* b
, char* p
, char* e
, int delimiter
)
37 register Trie_node_t
* y
;
52 for (y
= x
->sib
; y
; y
= y
->sib
)
56 sfwrite(sp
, b
, p
- b
);
58 detrie(y
, sp
, b
, p
, e
, delimiter
);
64 sfwrite(sp
, b
, p
- b
);
72 decomp(register Rex_t
* e
, Sfio_t
* sp
, int type
, int delimiter
, regflags_t flags
)
86 unsigned char ic
[2*UCHAR_MAX
];
87 unsigned char nc
[2*UCHAR_MAX
];
94 if (decomp(e
->re
.group
.expr
.binary
.left
, sp
, type
, delimiter
, flags
))
97 if (e
->re
.group
.expr
.binary
.right
&& decomp(e
->re
.group
.expr
.binary
.right
, sp
, type
, delimiter
, flags
))
101 sfprintf(sp
, "\\%d", e
->lo
);
112 meta(sp
, '<', type
, 1, delimiter
);
115 meta(sp
, '<', type
, 1, delimiter
);
128 if (e
->hi
== RE_DUP_INF
)
135 sfprintf(sp
, "{%d,}", e
->lo
);
138 sfprintf(sp
, "{%d,%d}", e
->lo
, e
->hi
);
147 if (decomp(e
->re
.group
.expr
.rex
, sp
, type
, delimiter
, flags
))
152 nb
= ne
= ib
= ie
= -2;
156 for (m
= 0; m
<= UCHAR_MAX
; m
++)
157 if (settst(e
->re
.charclass
, m
))
163 else if (m
== delimiter
)
167 else if (ne
== (m
- 1))
188 else if (m
== delimiter
)
192 else if (ie
== (m
- 1))
225 if ((t
- ic
+ 1) < (s
- nc
+ (nc
[0] == '^')))
232 if (cd
< 0 && delimiter
> 0)
234 if (flags
& REG_ESCAPE
)
236 sfputc(sp
, delimiter
);
238 sfwrite(sp
, ic
, t
- ic
);
246 if (cd
> 0 && delimiter
> 0)
248 if (flags
& REG_ESCAPE
)
250 sfputc(sp
, delimiter
);
254 sfwrite(sp
, nc
+ 1, s
- nc
- 1);
258 sfwrite(sp
, nc
, s
- nc
);
265 meta(sp
, e
->re
.onechar
, type
, 0, delimiter
);
273 if (e
->hi
== RE_DUP_INF
)
277 else if (e
->lo
== 1 && ismeta('+', type
, 0, delimiter
))
278 meta(sp
, '+', type
, 1, delimiter
);
281 meta(sp
, '{', type
, 1, delimiter
);
282 sfprintf(sp
, "%d,", e
->lo
);
283 meta(sp
, '}', type
, 1, delimiter
);
286 else if (e
->hi
!= 1 || e
->lo
== 0 && !ismeta('?', type
, 0, delimiter
))
288 meta(sp
, '{', type
, 1, delimiter
);
289 sfprintf(sp
, "%d,%d", e
->lo
, e
->hi
);
290 meta(sp
, '}', type
, 1, delimiter
);
293 meta(sp
, '?', type
, 1, delimiter
);
300 t
= (s
= e
->re
.string
.base
) + e
->re
.string
.size
;
304 meta(sp
, c
, type
, 0, delimiter
);
309 for (c
= 0; c
<= UCHAR_MAX
; c
++)
310 if (e
->re
.trie
.root
[c
])
318 detrie(e
->re
.trie
.root
[c
], sp
, pfx
, pfx
, &pfx
[sizeof(pfx
)], delimiter
);
324 if (decomp(e
->re
.group
.expr
.rex
, sp
, type
, delimiter
, flags
))
332 if (decomp(e
->re
.group
.expr
.binary
.left
, sp
, type
, delimiter
, flags
))
335 if (decomp(e
->re
.group
.expr
.binary
.right
, sp
, type
, delimiter
, flags
))
341 meta(sp
, '(', type
, 1, delimiter
);
342 if (decomp(e
->re
.group
.expr
.rex
, sp
, type
, delimiter
, flags
))
344 meta(sp
, ')', type
, 1, delimiter
);
346 case REX_GROUP_AHEAD
:
347 case REX_GROUP_AHEAD_NOT
:
348 case REX_GROUP_BEHIND
:
349 case REX_GROUP_BEHIND_NOT
:
350 meta(sp
, '(', type
, 1, delimiter
);
352 if (decomp(e
->re
.group
.expr
.rex
, sp
, type
, delimiter
, flags
))
354 meta(sp
, ')', type
, 1, delimiter
);
357 meta(sp
, '(', type
, 1, delimiter
);
359 if (e
->re
.group
.expr
.binary
.left
&& decomp(e
->re
.group
.expr
.binary
.left
, sp
, type
, delimiter
, flags
))
361 if (q
= e
->re
.group
.expr
.binary
.right
)
364 if (q
->re
.group
.expr
.binary
.left
&& decomp(q
->re
.group
.expr
.binary
.left
, sp
, type
, delimiter
, flags
))
367 if (q
->re
.group
.expr
.binary
.right
&& decomp(q
->re
.group
.expr
.binary
.right
, sp
, type
, delimiter
, flags
))
370 meta(sp
, ')', type
, 1, delimiter
);
373 meta(sp
, '(', type
, 1, delimiter
);
375 if (decomp(e
->re
.group
.expr
.rex
, sp
, type
, delimiter
, flags
))
377 meta(sp
, ')', type
, 1, delimiter
);
382 sfprintf(sp
, "<ERROR:REX_%d>", e
->type
);
385 } while (e
= e
->next
);
390 * reconstruct pattern from compiled re p into sp
394 regdecomp(regex_t
* p
, regflags_t flags
, char* buf
, size_t n
)
402 if (!(sp
= sfstropen()))
404 if (flags
== (regflags_t
)~0)
405 flags
= p
->env
->flags
;
406 switch (flags
& (REG_AUGMENTED
|REG_EXTENDED
|REG_SHELL
))
412 case REG_AUGMENTED
|REG_EXTENDED
:
425 if (flags
& REG_DELIMITED
)
428 sfputc(sp
, delimiter
);
432 if (decomp(p
->env
->rex
, sp
, type
, delimiter
, flags
))
437 sfputc(sp
, delimiter
);
438 if ((r
= sfstrtell(sp
) + 1) <= n
)
440 if (!(s
= sfstruse(sp
)))