mirror of
https://github.com/boostorg/build.git
synced 2026-02-11 23:52:20 +00:00
95 lines
2.4 KiB
C
95 lines
2.4 KiB
C
#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;
|
|
}
|
|
|