summaryrefslogtreecommitdiff
path: root/jam-files/engine/modules
diff options
context:
space:
mode:
authorKenneth Heafield <github@kheafield.com>2012-05-12 14:01:52 -0400
committerKenneth Heafield <github@kheafield.com>2012-05-12 14:01:52 -0400
commit3faecf9a00512dcbc8712c4bca9adae72fb64410 (patch)
tree9761b50d12f81a675fb7cbc663ceebad15079f78 /jam-files/engine/modules
parentc806a8fff63043f63773874986301f2822a2b552 (diff)
Give in and copy bjam into cdec source code
Diffstat (limited to 'jam-files/engine/modules')
-rw-r--r--jam-files/engine/modules/order.c144
-rw-r--r--jam-files/engine/modules/path.c32
-rw-r--r--jam-files/engine/modules/property-set.c110
-rw-r--r--jam-files/engine/modules/readme.txt3
-rw-r--r--jam-files/engine/modules/regex.c96
-rw-r--r--jam-files/engine/modules/sequence.c42
-rw-r--r--jam-files/engine/modules/set.c41
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);
+ }
+
+}