diff --git a/historic/jam/src/builtins.c b/historic/jam/src/builtins.c index c801a23e1..a68cb7322 100644 --- a/historic/jam/src/builtins.c +++ b/historic/jam/src/builtins.c @@ -234,6 +234,11 @@ load_builtins() builtin_instance, 0, args ); } + { + char * args[] = { "sequence", "*", 0 }; + bind_builtin( "SORT", + builtin_sort, 0, args ); + } } /* @@ -898,6 +903,15 @@ LIST *builtin_instance( PARSE *parse, FRAME *frame ) return L0; } +LIST* +builtin_sort( PARSE *parse, FRAME *frame ) +{ + LIST* arg1 = lol_get( frame->args, 0 ); + + return list_sort(arg1); +} + + static void lol_build( LOL* lol, char** elements ) { LIST* l = L0; diff --git a/historic/jam/src/builtins.h b/historic/jam/src/builtins.h index bb95aa1e4..421c54b24 100644 --- a/historic/jam/src/builtins.h +++ b/historic/jam/src/builtins.h @@ -36,6 +36,7 @@ LIST *builtin_search_for_target( PARSE *parse, FRAME *args ); LIST *builtin_import_module( PARSE *parse, FRAME *args ); LIST *builtin_imported_modules( PARSE *parse, FRAME *frame ); LIST *builtin_instance( PARSE *parse, FRAME *frame ); +LIST *builtin_sort( PARSE *parse, FRAME *frame ); void backtrace( FRAME *frame ); diff --git a/historic/jam/src/lists.c b/historic/jam/src/lists.c index c75c544e8..d89b3d61a 100644 --- a/historic/jam/src/lists.c +++ b/historic/jam/src/lists.c @@ -133,6 +133,85 @@ list_sublist( return nl; } +LIST * +list_sort( + LIST *l) +{ + + LIST* first = 0; + LIST* second = 0; + LIST* merged = l; + LIST* result; + + if (!l) + return L0; + + for(;;) { + + /* Split the list in two */ + LIST** dst = &first; + LIST* src = merged; + + for(;;) { + + *dst = list_append(*dst, list_new(0, src->string)); + + if (!src->next) + break; + + if (strcmp(src->string, src->next->string) > 0) + { + if (dst == &first) + dst = &second; + else + dst = &first; + } + + src = src->next; + } + + if (merged != l) + list_free( merged ); + merged = 0; + + if (second == 0) { + result = first; + break; + } + + + /* Merge lists 'first' and 'second' into 'merged' and free + 'first'/'second'. */ + { + LIST* f = first; + LIST* s = second; + + while(f && s) + { + if (strcmp(f->string, s->string) < 0) + { + merged = list_append( merged, list_new(0, f->string )); + f = f->next; + } + else + { + merged = list_append( merged, list_new(0, s->string )); + s = s->next; + } + } + + merged = list_copy( merged, f ); + merged = list_copy( merged, s ); + list_free( first ); + list_free( second ); + first = 0; + second = 0; + } + } + + return result; +} + /* * list_free() - free a list of strings */ diff --git a/historic/jam/src/lists.h b/historic/jam/src/lists.h index 57bd4d300..d6a3e2a09 100644 --- a/historic/jam/src/lists.h +++ b/historic/jam/src/lists.h @@ -80,6 +80,7 @@ void list_print( LIST *l ); int list_length( LIST *l ); LIST * list_sublist( LIST *l, int start, int count ); LIST * list_pop_front( LIST *l ); +LIST * list_sort( LIST *l); # define list_next( l ) ((l)->next) diff --git a/jam_src/builtins.c b/jam_src/builtins.c index c801a23e1..a68cb7322 100644 --- a/jam_src/builtins.c +++ b/jam_src/builtins.c @@ -234,6 +234,11 @@ load_builtins() builtin_instance, 0, args ); } + { + char * args[] = { "sequence", "*", 0 }; + bind_builtin( "SORT", + builtin_sort, 0, args ); + } } /* @@ -898,6 +903,15 @@ LIST *builtin_instance( PARSE *parse, FRAME *frame ) return L0; } +LIST* +builtin_sort( PARSE *parse, FRAME *frame ) +{ + LIST* arg1 = lol_get( frame->args, 0 ); + + return list_sort(arg1); +} + + static void lol_build( LOL* lol, char** elements ) { LIST* l = L0; diff --git a/jam_src/builtins.h b/jam_src/builtins.h index bb95aa1e4..421c54b24 100644 --- a/jam_src/builtins.h +++ b/jam_src/builtins.h @@ -36,6 +36,7 @@ LIST *builtin_search_for_target( PARSE *parse, FRAME *args ); LIST *builtin_import_module( PARSE *parse, FRAME *args ); LIST *builtin_imported_modules( PARSE *parse, FRAME *frame ); LIST *builtin_instance( PARSE *parse, FRAME *frame ); +LIST *builtin_sort( PARSE *parse, FRAME *frame ); void backtrace( FRAME *frame ); diff --git a/jam_src/lists.c b/jam_src/lists.c index c75c544e8..d89b3d61a 100644 --- a/jam_src/lists.c +++ b/jam_src/lists.c @@ -133,6 +133,85 @@ list_sublist( return nl; } +LIST * +list_sort( + LIST *l) +{ + + LIST* first = 0; + LIST* second = 0; + LIST* merged = l; + LIST* result; + + if (!l) + return L0; + + for(;;) { + + /* Split the list in two */ + LIST** dst = &first; + LIST* src = merged; + + for(;;) { + + *dst = list_append(*dst, list_new(0, src->string)); + + if (!src->next) + break; + + if (strcmp(src->string, src->next->string) > 0) + { + if (dst == &first) + dst = &second; + else + dst = &first; + } + + src = src->next; + } + + if (merged != l) + list_free( merged ); + merged = 0; + + if (second == 0) { + result = first; + break; + } + + + /* Merge lists 'first' and 'second' into 'merged' and free + 'first'/'second'. */ + { + LIST* f = first; + LIST* s = second; + + while(f && s) + { + if (strcmp(f->string, s->string) < 0) + { + merged = list_append( merged, list_new(0, f->string )); + f = f->next; + } + else + { + merged = list_append( merged, list_new(0, s->string )); + s = s->next; + } + } + + merged = list_copy( merged, f ); + merged = list_copy( merged, s ); + list_free( first ); + list_free( second ); + first = 0; + second = 0; + } + } + + return result; +} + /* * list_free() - free a list of strings */ diff --git a/jam_src/lists.h b/jam_src/lists.h index 57bd4d300..d6a3e2a09 100644 --- a/jam_src/lists.h +++ b/jam_src/lists.h @@ -80,6 +80,7 @@ void list_print( LIST *l ); int list_length( LIST *l ); LIST * list_sublist( LIST *l, int start, int count ); LIST * list_pop_front( LIST *l ); +LIST * list_sort( LIST *l); # define list_next( l ) ((l)->next) diff --git a/new/builtin.jam b/new/builtin.jam index 363237b6c..385f45375 100644 --- a/new/builtin.jam +++ b/new/builtin.jam @@ -487,6 +487,7 @@ xclass searched-lib-generator : generator generators.register [ xnew searched-lib-generator ] ; + xclass compile-action : action { import sequence ; diff --git a/new/sequence.jam b/new/sequence.jam index 2ef13c325..aedcb1b5c 100644 --- a/new/sequence.jam +++ b/new/sequence.jam @@ -57,40 +57,47 @@ rule less ( a b ) # insertion-sort s using the BinaryPredicate ordered. rule insertion-sort ( s * : ordered * ) { - local caller = [ CALLER_MODULE ] ; - ordered ?= sequence.less ; - local result = $(s[1]) ; - if $(ordered) = sequence.less + if ! $(ordered) { - local head tail ; - for local x in $(s[2-]) - { - head = ; - tail = $(result) ; - while $(tail) && ( $(tail[1]) < $(x) ) - { - head += $(tail[1]) ; - tail = $(tail[2-]) ; - } - result = $(head) $(x) $(tail) ; - } + return [ SORT $(s) ] ; } - else - { - for local x in $(s[2-]) + else + { + local caller = [ CALLER_MODULE ] ; + ordered ?= sequence.less ; + local result = $(s[1]) ; + if $(ordered) = sequence.less { local head tail ; - tail = $(result) ; - while $(tail) && [ modules.call-in $(caller) : $(ordered) $(tail[1]) $(x) ] + for local x in $(s[2-]) { - head += $(tail[1]) ; - tail = $(tail[2-]) ; + head = ; + tail = $(result) ; + while $(tail) && ( $(tail[1]) < $(x) ) + { + head += $(tail[1]) ; + tail = $(tail[2-]) ; + } + result = $(head) $(x) $(tail) ; } - result = $(head) $(x) $(tail) ; } - } - - return $(result) ; + else + { + for local x in $(s[2-]) + { + local head tail ; + tail = $(result) ; + while $(tail) && [ modules.call-in $(caller) : $(ordered) $(tail[1]) $(x) ] + { + head += $(tail[1]) ; + tail = $(tail[2-]) ; + } + result = $(head) $(x) $(tail) ; + } + } + + return $(result) ; + } } # merge two ordered sequences using the BinaryPredicate ordered. diff --git a/new/testing.jam b/new/testing.jam index b72ecdd2b..60c88ed60 100644 --- a/new/testing.jam +++ b/new/testing.jam @@ -16,7 +16,7 @@ import toolset ; feature.feature testing.launcher : : optional free ; xclass unit-test-target-class : typed-target -{ +{ rule __init__ ( name : project : sources * : requirements * : default-build * ) { diff --git a/v2/tools/builtin.jam b/v2/tools/builtin.jam index 363237b6c..385f45375 100644 --- a/v2/tools/builtin.jam +++ b/v2/tools/builtin.jam @@ -487,6 +487,7 @@ xclass searched-lib-generator : generator generators.register [ xnew searched-lib-generator ] ; + xclass compile-action : action { import sequence ; diff --git a/v2/tools/testing.jam b/v2/tools/testing.jam index b72ecdd2b..60c88ed60 100644 --- a/v2/tools/testing.jam +++ b/v2/tools/testing.jam @@ -16,7 +16,7 @@ import toolset ; feature.feature testing.launcher : : optional free ; xclass unit-test-target-class : typed-target -{ +{ rule __init__ ( name : project : sources * : requirements * : default-build * ) { diff --git a/v2/util/sequence.jam b/v2/util/sequence.jam index 2ef13c325..aedcb1b5c 100644 --- a/v2/util/sequence.jam +++ b/v2/util/sequence.jam @@ -57,40 +57,47 @@ rule less ( a b ) # insertion-sort s using the BinaryPredicate ordered. rule insertion-sort ( s * : ordered * ) { - local caller = [ CALLER_MODULE ] ; - ordered ?= sequence.less ; - local result = $(s[1]) ; - if $(ordered) = sequence.less + if ! $(ordered) { - local head tail ; - for local x in $(s[2-]) - { - head = ; - tail = $(result) ; - while $(tail) && ( $(tail[1]) < $(x) ) - { - head += $(tail[1]) ; - tail = $(tail[2-]) ; - } - result = $(head) $(x) $(tail) ; - } + return [ SORT $(s) ] ; } - else - { - for local x in $(s[2-]) + else + { + local caller = [ CALLER_MODULE ] ; + ordered ?= sequence.less ; + local result = $(s[1]) ; + if $(ordered) = sequence.less { local head tail ; - tail = $(result) ; - while $(tail) && [ modules.call-in $(caller) : $(ordered) $(tail[1]) $(x) ] + for local x in $(s[2-]) { - head += $(tail[1]) ; - tail = $(tail[2-]) ; + head = ; + tail = $(result) ; + while $(tail) && ( $(tail[1]) < $(x) ) + { + head += $(tail[1]) ; + tail = $(tail[2-]) ; + } + result = $(head) $(x) $(tail) ; } - result = $(head) $(x) $(tail) ; } - } - - return $(result) ; + else + { + for local x in $(s[2-]) + { + local head tail ; + tail = $(result) ; + while $(tail) && [ modules.call-in $(caller) : $(ordered) $(tail[1]) $(x) ] + { + head += $(tail[1]) ; + tail = $(tail[2-]) ; + } + result = $(head) $(x) $(tail) ; + } + } + + return $(result) ; + } } # merge two ordered sequences using the BinaryPredicate ordered.