diff options
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); +    } + +} | 
