diff options
author | Patrick Simianer <simianer@cl.uni-heidelberg.de> | 2012-05-13 03:35:30 +0200 |
---|---|---|
committer | Patrick Simianer <simianer@cl.uni-heidelberg.de> | 2012-05-13 03:35:30 +0200 |
commit | 670a8f984fc6d8342180c59ae9e96b0b76f34d3d (patch) | |
tree | 9f2ce7eec1a77e56b3bb1ad0ad40f212d7a996b0 /jam-files/engine/modules/regex.c | |
parent | eb3ee28dc0eb1d3e5ed01ba0df843be329ae450d (diff) | |
parent | 2f64af3e06a518b93f7ca2c30a9d0aeb2c947031 (diff) |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'jam-files/engine/modules/regex.c')
-rw-r--r-- | jam-files/engine/modules/regex.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/jam-files/engine/modules/regex.c b/jam-files/engine/modules/regex.c new file mode 100644 index 00000000..d048ba1d --- /dev/null +++ b/jam-files/engine/modules/regex.c @@ -0,0 +1,96 @@ +/* Copyright Vladimir Prus 2003. Distributed under the Boost */ +/* Software License, Version 1.0. (See accompanying */ +/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */ + +#include "../native.h" +#include "../timestamp.h" +#include "../newstr.h" +#include "../strings.h" +#include "../regexp.h" +#include "../compile.h" + +/* +rule transform ( list * : pattern : indices * ) +{ + indices ?= 1 ; + local result ; + for local e in $(list) + { + local m = [ MATCH $(pattern) : $(e) ] ; + if $(m) + { + result += $(m[$(indices)]) ; + } + } + return $(result) ; +} +*/ +LIST *regex_transform( PARSE *parse, FRAME *frame ) +{ + LIST* l = lol_get( frame->args, 0 ); + LIST* pattern = lol_get( frame->args, 1 ); + LIST* indices_list = lol_get(frame->args, 2); + int* indices = 0; + int size; + int* p; + LIST* result = 0; + + string buf[1]; + string_new(buf); + + if (indices_list) + { + size = list_length(indices_list); + indices = (int*)BJAM_MALLOC(size*sizeof(int)); + for(p = indices; indices_list; indices_list = indices_list->next) + { + *p++ = atoi(indices_list->string); + } + } + else + { + size = 1; + indices = (int*)BJAM_MALLOC(sizeof(int)); + *indices = 1; + } + + { + /* Result is cached and intentionally never freed */ + regexp *re = regex_compile( pattern->string ); + + for(; l; l = l->next) + { + if( regexec( re, l->string ) ) + { + int i = 0; + for(; i < size; ++i) + { + int index = indices[i]; + /* Skip empty submatches. Not sure it's right in all cases, + but surely is right for the case for which this routine + is optimized -- header scanning. + */ + if (re->startp[index] != re->endp[index]) + { + string_append_range( buf, re->startp[index], re->endp[index] ); + result = list_new( result, newstr( buf->value ) ); + string_truncate( buf, 0 ); + } + } + } + } + string_free( buf ); + } + + BJAM_FREE(indices); + + return result; +} + +void init_regex() +{ + { + char* args[] = { "list", "*", ":", "pattern", ":", "indices", "*", 0 }; + declare_native_rule("regex", "transform", args, regex_transform, 2); + } +} |