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 | d94373453c69c6cfec952a0f7b427cacc78654d8 (patch) | |
tree | 43febdf719c103d19bd5d22d0be734e1574bc1e9 /jam-files/engine/modules | |
parent | cc9650b8b664d1f6836a0fa86a012401b51aafa0 (diff) | |
parent | a65a80c5d5b6fc4cbd32280f07cae9be71551b70 (diff) |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'jam-files/engine/modules')
-rw-r--r-- | jam-files/engine/modules/order.c | 144 | ||||
-rw-r--r-- | jam-files/engine/modules/path.c | 32 | ||||
-rw-r--r-- | jam-files/engine/modules/property-set.c | 110 | ||||
-rw-r--r-- | jam-files/engine/modules/readme.txt | 3 | ||||
-rw-r--r-- | jam-files/engine/modules/regex.c | 96 | ||||
-rw-r--r-- | jam-files/engine/modules/sequence.c | 42 | ||||
-rw-r--r-- | jam-files/engine/modules/set.c | 41 |
7 files changed, 468 insertions, 0 deletions
diff --git a/jam-files/engine/modules/order.c b/jam-files/engine/modules/order.c new file mode 100644 index 00000000..d77943a7 --- /dev/null +++ b/jam-files/engine/modules/order.c @@ -0,0 +1,144 @@ +/* Copyright Vladimir Prus 2004. 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 "../lists.h" +#include "../strings.h" +#include "../newstr.h" +#include "../variable.h" + + +/* Use quite klugy approach: when we add order dependency from 'a' to 'b', + just append 'b' to of value of variable 'a'. +*/ +LIST *add_pair( PARSE *parse, FRAME *frame ) +{ + LIST* arg = lol_get( frame->args, 0 ); + + var_set(arg->string, list_copy(0, arg->next), VAR_APPEND); + + return L0; +} + +/** Given a list and a value, returns position of that value in + the list, or -1 if not found. +*/ +int list_index(LIST* list, const char* value) +{ + int result = 0; + for(; list; list = list->next, ++result) { + if (strcmp(list->string, value) == 0) + return result; + } + return -1; +} + +enum colors { white, gray, black }; + +/* Main routite of topological sort. Calls itself recursively on all + adjacent vertices which were not yet visited. After that, 'current_vertex' + is added to '*result_ptr'. +*/ +void do_ts(int** graph, int current_vertex, int* colors, int** result_ptr) +{ + int i; + + colors[current_vertex] = gray; + for(i = 0; graph[current_vertex][i] != -1; ++i) { + int adjacent_vertex = graph[current_vertex][i]; + + if (colors[adjacent_vertex] == white) + do_ts(graph, adjacent_vertex, colors, result_ptr); + /* The vertex is either black, in which case we don't have to do + anything, a gray, in which case we have a loop. If we have a loop, + it's not clear what useful diagnostic we can emit, so we emit + nothing. */ + } + colors[current_vertex] = black; + **result_ptr = current_vertex; + (*result_ptr)++; +} + +void topological_sort(int** graph, int num_vertices, int* result) +{ + int i; + int* colors = (int*)BJAM_CALLOC(num_vertices, sizeof(int)); + for (i = 0; i < num_vertices; ++i) + colors[i] = white; + + for(i = 0; i < num_vertices; ++i) + if (colors[i] == white) + do_ts(graph, i, colors, &result); + + BJAM_FREE(colors); +} + +LIST *order( PARSE *parse, FRAME *frame ) +{ + LIST* arg = lol_get( frame->args, 0 ); + LIST* tmp; + LIST* result = 0; + int src; + + /* We need to create a graph of order dependencies between + the passed objects. We assume that there are no duplicates + passed to 'add_pair'. + */ + int length = list_length(arg); + int** graph = (int**)BJAM_CALLOC(length, sizeof(int*)); + int* order = (int*)BJAM_MALLOC((length+1)*sizeof(int)); + + for(tmp = arg, src = 0; tmp; tmp = tmp->next, ++src) { + /* For all object this one depend upon, add elements + to 'graph' */ + LIST* dependencies = var_get(tmp->string); + int index = 0; + + graph[src] = (int*)BJAM_CALLOC(list_length(dependencies)+1, sizeof(int)); + for(; dependencies; dependencies = dependencies->next) { + int dst = list_index(arg, dependencies->string); + if (dst != -1) + graph[src][index++] = dst; + } + graph[src][index] = -1; + } + + topological_sort(graph, length, order); + + { + int index = length-1; + for(; index >= 0; --index) { + int i; + tmp = arg; + for (i = 0; i < order[index]; ++i, tmp = tmp->next); + result = list_new(result, tmp->string); + } + } + + /* Clean up */ + { + int i; + for(i = 0; i < length; ++i) + BJAM_FREE(graph[i]); + BJAM_FREE(graph); + BJAM_FREE(order); + } + + return result; +} + +void init_order() +{ + { + char* args[] = { "first", "second", 0 }; + declare_native_rule("class@order", "add-pair", args, add_pair, 1); + } + + { + char* args[] = { "objects", "*", 0 }; + declare_native_rule("class@order", "order", args, order, 1); + } + + +} diff --git a/jam-files/engine/modules/path.c b/jam-files/engine/modules/path.c new file mode 100644 index 00000000..f5d09622 --- /dev/null +++ b/jam-files/engine/modules/path.c @@ -0,0 +1,32 @@ +/* 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" + +LIST *path_exists( PARSE *parse, FRAME *frame ) +{ + LIST* l = lol_get( frame->args, 0 ); + + time_t time; + timestamp(l->string, &time); + if (time != 0) + { + return list_new(0, newstr("true")); + } + else + { + return L0; + } +} + +void init_path() +{ + { + char* args[] = { "location", 0 }; + declare_native_rule("path", "exists", args, path_exists, 1); + } + +} diff --git a/jam-files/engine/modules/property-set.c b/jam-files/engine/modules/property-set.c new file mode 100644 index 00000000..2b0fb5d9 --- /dev/null +++ b/jam-files/engine/modules/property-set.c @@ -0,0 +1,110 @@ +/* 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 "../lists.h" +#include "../variable.h" +#include "../compile.h" + +LIST* get_grist(char* f) +{ + char* end = strchr(f, '>'); + string s[1]; + LIST* result; + + string_new(s); + + string_append_range(s, f, end+1); + result = list_new(0, newstr(s->value)); + + string_free(s); + return result; +} + +/* +rule create ( raw-properties * ) +{ + raw-properties = [ sequence.unique + [ sequence.insertion-sort $(raw-properties) ] ] ; + + local key = $(raw-properties:J=-:E=) ; + + if ! $(.ps.$(key)) + { + .ps.$(key) = [ new property-set $(raw-properties) ] ; + } + return $(.ps.$(key)) ; +} +*/ + +LIST *property_set_create( PARSE *parse, FRAME *frame ) +{ + LIST* properties = lol_get( frame->args, 0 ); + LIST* sorted = 0; +#if 0 + LIST* order_sensitive = 0; +#endif + LIST* unique; + LIST* tmp; + LIST* val; + string var[1]; + +#if 0 + /* Sort all properties which are not order sensitive */ + for(tmp = properties; tmp; tmp = tmp->next) { + LIST* g = get_grist(tmp->string); + LIST* att = call_rule("feature.attributes", frame, g, 0); + if (list_in(att, "order-sensitive")) { + order_sensitive = list_new( order_sensitive, tmp->string); + } else { + sorted = list_new( sorted, tmp->string); + } + list_free(att); + } + + sorted = list_sort(sorted); + sorted = list_append(sorted, order_sensitive); + unique = list_unique(sorted); +#endif + sorted = list_sort(properties); + unique = list_unique(sorted); + + string_new(var); + string_append(var, ".ps."); + + for(tmp = unique; tmp; tmp = tmp->next) { + string_append(var, tmp->string); + string_push_back(var, '-'); + } + val = var_get(var->value); + if (val == 0) + { + val = call_rule("new", frame, + list_append(list_new(0, "property-set"), unique), 0); + + var_set(newstr(var->value), list_copy(0, val), VAR_SET); + } + else + { + val = list_copy(0, val); + } + + string_free(var); + /* The 'unique' variable is freed in 'call_rule'. */ + list_free(sorted); + + return val; + +} + +void init_property_set() +{ + { + char* args[] = { "raw-properties", "*", 0 }; + declare_native_rule("property-set", "create", args, property_set_create, 1); + } +} diff --git a/jam-files/engine/modules/readme.txt b/jam-files/engine/modules/readme.txt new file mode 100644 index 00000000..2edf6e17 --- /dev/null +++ b/jam-files/engine/modules/readme.txt @@ -0,0 +1,3 @@ + +This directory constains sources which declare native +rules for Boost.Build modules.
\ No newline at end of file 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); + } +} diff --git a/jam-files/engine/modules/sequence.c b/jam-files/engine/modules/sequence.c new file mode 100644 index 00000000..bda80d94 --- /dev/null +++ b/jam-files/engine/modules/sequence.c @@ -0,0 +1,42 @@ +/* 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" + +# ifndef max +# define max( a,b ) ((a)>(b)?(a):(b)) +# endif + + +LIST *sequence_select_highest_ranked( PARSE *parse, FRAME *frame ) +{ + /* Returns all of 'elements' for which corresponding element in parallel */ + /* list 'rank' is equal to the maximum value in 'rank'. */ + + LIST* elements = lol_get( frame->args, 0 ); + LIST* rank = lol_get( frame->args, 1 ); + + LIST* result = 0; + LIST* tmp; + int highest_rank = -1; + + for (tmp = rank; tmp; tmp = tmp->next) + highest_rank = max(highest_rank, atoi(tmp->string)); + + for (; rank; rank = rank->next, elements = elements->next) + if (atoi(rank->string) == highest_rank) + result = list_new(result, elements->string); + + return result; +} + +void init_sequence() +{ + { + char* args[] = { "elements", "*", ":", "rank", "*", 0 }; + declare_native_rule("sequence", "select-highest-ranked", args, + sequence_select_highest_ranked, 1); + } + +} diff --git a/jam-files/engine/modules/set.c b/jam-files/engine/modules/set.c new file mode 100644 index 00000000..f8219403 --- /dev/null +++ b/jam-files/engine/modules/set.c @@ -0,0 +1,41 @@ +/* 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" + +/* + local result = ; + local element ; + for element in $(B) + { + if ! ( $(element) in $(A) ) + { + result += $(element) ; + } + } + return $(result) ; +*/ +LIST *set_difference( PARSE *parse, FRAME *frame ) +{ + + LIST* b = lol_get( frame->args, 0 ); + LIST* a = lol_get( frame->args, 1 ); + + LIST* result = 0; + for(; b; b = b->next) + { + if (!list_in(a, b->string)) + result = list_new(result, b->string); + } + return result; +} + +void init_set() +{ + { + char* args[] = { "B", "*", ":", "A", "*", 0 }; + declare_native_rule("set", "difference", args, set_difference, 1); + } + +} |