blob: 75524ecc121ddcc9b3465377a0bbabd81da1e778 (
plain)
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
|
#include <stddef.h>
#include "jam.h"
#include "regexp.h"
#include "hash.h"
#include "newstr.h"
#include "lists.h"
#include "parse.h"
#include "compile.h"
#include "frames.h"
struct regex_entry
{
const char* pattern;
regexp* regex;
};
typedef struct regex_entry regex_entry;
static struct hash* regex_hash;
regexp* regex_compile( const char* pattern )
{
regex_entry entry, *e = &entry;
entry.pattern = pattern;
if ( !regex_hash )
regex_hash = hashinit(sizeof(regex_entry), "regex");
if ( hashenter( regex_hash, (HASHDATA **)&e ) )
e->regex = regcomp( (char*)pattern );
return e->regex;
}
LIST*
builtin_subst(
PARSE *parse,
FRAME *frame )
{
LIST* result = L0;
LIST* arg1 = lol_get( frame->args, 0 );
if ( arg1 && list_next(arg1) && list_next(list_next(arg1)) )
{
const char* source = arg1->string;
const char* pattern = list_next(arg1)->string;
regexp* repat = regex_compile( pattern );
if ( regexec( repat, (char*)source) )
{
LIST* subst = list_next(arg1);
while ((subst = list_next(subst)) != L0)
{
# define BUFLEN 4096
char buf[BUFLEN + 1];
const char* in = subst->string;
char* out = buf;
for ( in = subst->string; *in && out < buf + BUFLEN; ++in )
{
if ( *in == '\\' || *in == '$' )
{
++in;
if ( *in == 0 )
{
break;
}
else if ( *in >= '0' && *in <= '9' )
{
unsigned n = *in - '0';
const size_t srclen = repat->endp[n] - repat->startp[n];
const size_t remaining = buf + BUFLEN - out;
const size_t len = srclen < remaining ? srclen : remaining;
memcpy( out, repat->startp[n], len );
out += len;
continue;
}
/* fall through and copy the next character */
}
*out++ = *in;
}
*out = 0;
result = list_new( result, newstr( buf ) );
#undef BUFLEN
}
}
}
return result;
}
|