mirror of
https://github.com/boostorg/build.git
synced 2026-02-14 12:42:11 +00:00
117 lines
3.0 KiB
C++
117 lines
3.0 KiB
C++
#include "jam.h"
|
|
#include "subst.h"
|
|
|
|
#include "builtins.h"
|
|
#include "frames.h"
|
|
#include "hash.h"
|
|
#include "lists.h"
|
|
|
|
#include <stddef.h>
|
|
|
|
|
|
typedef struct regex_entry
|
|
{
|
|
OBJECT * pattern;
|
|
regexp * regex;
|
|
} regex_entry;
|
|
|
|
static struct hash * regex_hash;
|
|
|
|
|
|
regexp * regex_compile( OBJECT * pattern )
|
|
{
|
|
int found;
|
|
regex_entry * e ;
|
|
|
|
if ( !regex_hash )
|
|
regex_hash = hashinit( sizeof( regex_entry ), "regex" );
|
|
|
|
e = (regex_entry *)hash_insert( regex_hash, pattern, &found );
|
|
if ( !found )
|
|
{
|
|
e->pattern = object_copy( pattern );
|
|
e->regex = regcomp( (char *)pattern );
|
|
}
|
|
|
|
return e->regex;
|
|
}
|
|
|
|
|
|
LIST * builtin_subst( FRAME * frame, int flags )
|
|
{
|
|
LIST * result = L0;
|
|
LIST * const arg1 = lol_get( frame->args, 0 );
|
|
LISTITER iter = list_begin( arg1 );
|
|
LISTITER const end = list_end( arg1 );
|
|
|
|
if ( iter != end && list_next( iter ) != end && list_next( list_next( iter )
|
|
) != end )
|
|
{
|
|
char const * const source = object_str( list_item( iter ) );
|
|
OBJECT * const pattern = list_item( list_next( iter ) );
|
|
regexp * const repat = regex_compile( pattern );
|
|
|
|
if ( regexec( repat, (char *)source) )
|
|
{
|
|
LISTITER subst = list_next( iter );
|
|
|
|
while ( ( subst = list_next( subst ) ) != end )
|
|
{
|
|
#define BUFLEN 4096
|
|
char buf[ BUFLEN + 1 ];
|
|
char const * in = object_str( list_item( subst ) );
|
|
char * out = buf;
|
|
|
|
for ( ; *in && out < buf + BUFLEN; ++in )
|
|
{
|
|
if ( *in == '\\' || *in == '$' )
|
|
{
|
|
++in;
|
|
if ( *in == 0 )
|
|
break;
|
|
if ( *in >= '0' && *in <= '9' )
|
|
{
|
|
unsigned int const n = *in - '0';
|
|
size_t const srclen = repat->endp[ n ] -
|
|
repat->startp[ n ];
|
|
size_t const remaining = buf + BUFLEN - out;
|
|
size_t const 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_push_back( result, object_new( buf ) );
|
|
#undef BUFLEN
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
static void free_regex( void * xregex, void * data )
|
|
{
|
|
regex_entry * const regex = (regex_entry *)xregex;
|
|
object_free( regex->pattern );
|
|
BJAM_FREE( regex->regex );
|
|
}
|
|
|
|
|
|
void regex_done()
|
|
{
|
|
if ( regex_hash )
|
|
{
|
|
hashenumerate( regex_hash, free_regex, (void *)0 );
|
|
hashdone( regex_hash );
|
|
}
|
|
}
|