diff options
Diffstat (limited to 'tools/build/v2/engine/builtins.c')
-rw-r--r-- | tools/build/v2/engine/builtins.c | 924 |
1 files changed, 463 insertions, 461 deletions
diff --git a/tools/build/v2/engine/builtins.c b/tools/build/v2/engine/builtins.c index b28a484ec4..07eaa1534a 100644 --- a/tools/build/v2/engine/builtins.c +++ b/tools/build/v2/engine/builtins.c @@ -11,7 +11,7 @@ #include "builtins.h" #include "rules.h" #include "filesys.h" -#include "newstr.h" +#include "object.h" #include "regexp.h" #include "frames.h" #include "hash.h" @@ -25,6 +25,7 @@ #include "variable.h" #include "timestamp.h" #include "md5.h" +#include "constants.h" #include <ctype.h> #if defined(USE_EXECUNIX) @@ -65,38 +66,44 @@ */ #define P0 (PARSE *)0 -#define C0 (char *)0 +#define C0 (OBJECT *)0 #if defined( OS_NT ) || defined( OS_CYGWIN ) - LIST * builtin_system_registry ( PARSE *, FRAME * ); - LIST * builtin_system_registry_names( PARSE *, FRAME * ); + LIST * builtin_system_registry ( FRAME *, int ); + LIST * builtin_system_registry_names( FRAME *, int ); #endif -int glob( char * s, char * c ); +int glob( const char * s, const char * c ); void backtrace ( FRAME * ); void backtrace_line ( FRAME * ); -void print_source_line( PARSE * ); +void print_source_line( FRAME * ); -RULE * bind_builtin( char * name, LIST * (* f)( PARSE *, FRAME * ), int flags, char * * args ) +RULE * bind_builtin( const char * name_, LIST * (* f)( FRAME *, int flags ), int flags, const char * * args ) { - argument_list* arg_list = 0; + FUNCTION * func; + RULE * result; + OBJECT * name = object_new( name_ ); - if ( args ) - { - arg_list = args_new(); - lol_build( arg_list->data, args ); - } + func = function_builtin( f, flags, args ); + + result = new_rule_body( root_module(), name, func, 1 ); + + function_free( func ); + + object_free( name ); - return new_rule_body( root_module(), name, arg_list, - parse_make( f, P0, P0, P0, C0, C0, flags ), 1 ); + return result; } -RULE * duplicate_rule( char * name, RULE * other ) +RULE * duplicate_rule( const char * name_, RULE * other ) { - return import_rule( other, root_module(), name ); + OBJECT * name = object_new( name_ ); + RULE * result = import_rule( other, root_module(), name ); + object_free( name ); + return result; } @@ -116,7 +123,7 @@ void load_builtins() builtin_echo, 0, 0 ) ) ); { - char * args[] = { "message", "*", ":", "result-value", "?", 0 }; + const char * args[] = { "message", "*", ":", "result-value", "?", 0 }; duplicate_rule( "exit", duplicate_rule( "Exit", bind_builtin( "EXIT", @@ -124,13 +131,13 @@ void load_builtins() } { - char * args[] = { "directories", "*", ":", "patterns", "*", ":", "case-insensitive", "?", 0 }; + const char * args[] = { "directories", "*", ":", "patterns", "*", ":", "case-insensitive", "?", 0 }; duplicate_rule( "Glob", bind_builtin( "GLOB", builtin_glob, 0, args ) ); } { - char * args[] = { "patterns", "*", 0 }; + const char * args[] = { "patterns", "*", 0 }; bind_builtin( "GLOB-RECURSIVELY", builtin_glob_recursive, 0, args ); } @@ -140,7 +147,7 @@ void load_builtins() builtin_depends, 1, 0 ) ); { - char * args[] = { "targets", "*", ":", "targets-to-rebuild", "*", 0 }; + const char * args[] = { "targets", "*", ":", "targets-to-rebuild", "*", 0 }; bind_builtin( "REBUILDS", builtin_rebuilds, 0, args ); } @@ -154,7 +161,7 @@ void load_builtins() builtin_match, 0, 0 ) ); { - char * args[] = { "string", ":", "delimiters" }; + const char * args[] = { "string", ":", "delimiters" }; bind_builtin( "SPLIT_BY_CHARACTERS", builtin_split_by_characters, 0, 0 ); } @@ -194,13 +201,13 @@ void load_builtins() builtin_flags, T_FLAG_RMOLD, 0 ); { - char * args[] = { "targets", "*", 0 }; + const char * args[] = { "targets", "*", 0 }; bind_builtin( "UPDATE", builtin_update, 0, args ); } { - char * args[] = { "targets", "*", + const char * args[] = { "targets", "*", ":", "log", "?", ":", "ignore-minus-n", "?", ":", "ignore-minus-q", "?", 0 }; @@ -209,33 +216,33 @@ void load_builtins() } { - char * args[] = { "string", "pattern", "replacements", "+", 0 }; + const char * args[] = { "string", "pattern", "replacements", "+", 0 }; duplicate_rule( "subst", bind_builtin( "SUBST", builtin_subst, 0, args ) ); } { - char * args[] = { "module", "?", 0 }; + const char * args[] = { "module", "?", 0 }; bind_builtin( "RULENAMES", builtin_rulenames, 0, args ); } { - char * args[] = { "module", "?", 0 }; + const char * args[] = { "module", "?", 0 }; bind_builtin( "VARNAMES", builtin_varnames, 0, args ); } { - char * args[] = { "module", "?", 0 }; + const char * args[] = { "module", "?", 0 }; bind_builtin( "DELETE_MODULE", builtin_delete_module, 0, args ); } { - char * args[] = { "source_module", "?", + const char * args[] = { "source_module", "?", ":", "source_rules", "*", ":", "target_module", "?", ":", "target_rules", "*", @@ -245,104 +252,98 @@ void load_builtins() } { - char * args[] = { "module", "?", ":", "rules", "*", 0 }; + const char * args[] = { "module", "?", ":", "rules", "*", 0 }; bind_builtin( "EXPORT", builtin_export, 0, args ); } { - char * args[] = { "levels", "?", 0 }; + const char * args[] = { "levels", "?", 0 }; bind_builtin( "CALLER_MODULE", builtin_caller_module, 0, args ); } { - char * args[] = { "levels", "?", 0 }; + const char * args[] = { "levels", "?", 0 }; bind_builtin( "BACKTRACE", builtin_backtrace, 0, args ); } { - char * args[] = { 0 }; + const char * args[] = { 0 }; bind_builtin( "PWD", builtin_pwd, 0, args ); } { - char * args[] = { "target", "*", ":", "path", "*", 0 }; - bind_builtin( "SEARCH_FOR_TARGET", - builtin_search_for_target, 0, args ); - } - - { - char * args[] = { "modules_to_import", "+", ":", "target_module", "?", 0 }; + const char * args[] = { "modules_to_import", "+", ":", "target_module", "?", 0 }; bind_builtin( "IMPORT_MODULE", builtin_import_module, 0, args ); } { - char * args[] = { "module", "?", 0 }; + const char * args[] = { "module", "?", 0 }; bind_builtin( "IMPORTED_MODULES", builtin_imported_modules, 0, args ); } { - char * args[] = { "instance_module", ":", "class_module", 0 }; + const char * args[] = { "instance_module", ":", "class_module", 0 }; bind_builtin( "INSTANCE", builtin_instance, 0, args ); } { - char * args[] = { "sequence", "*", 0 }; + const char * args[] = { "sequence", "*", 0 }; bind_builtin( "SORT", builtin_sort, 0, args ); } { - char * args[] = { "path_parts", "*", 0 }; + const char * args[] = { "path_parts", "*", 0 }; bind_builtin( "NORMALIZE_PATH", builtin_normalize_path, 0, args ); } { - char * args[] = { "args", "*", 0 }; + const char * args[] = { "args", "*", 0 }; bind_builtin( "CALC", builtin_calc, 0, args ); } { - char * args[] = { "module", ":", "rule", 0 }; + const char * args[] = { "module", ":", "rule", 0 }; bind_builtin( "NATIVE_RULE", builtin_native_rule, 0, args ); } { - char * args[] = { "module", ":", "rule", ":", "version", 0 }; + const char * args[] = { "module", ":", "rule", ":", "version", 0 }; bind_builtin( "HAS_NATIVE_RULE", builtin_has_native_rule, 0, args ); } { - char * args[] = { "module", "*", 0 }; + const char * args[] = { "module", "*", 0 }; bind_builtin( "USER_MODULE", builtin_user_module, 0, args ); } { - char * args[] = { 0 }; + const char * args[] = { 0 }; bind_builtin( "NEAREST_USER_LOCATION", builtin_nearest_user_location, 0, args ); } { - char * args[] = { "file", 0 }; + const char * args[] = { "file", 0 }; bind_builtin( "CHECK_IF_FILE", builtin_check_if_file, 0, args ); } #ifdef HAVE_PYTHON { - char * args[] = { "python-module", ":", "function", ":", + const char * args[] = { "python-module", ":", "function", ":", "jam-module", ":", "rule-name", 0 }; bind_builtin( "PYTHON_IMPORT_RULE", builtin_python_import_rule, 0, args ); @@ -351,56 +352,56 @@ void load_builtins() # if defined( OS_NT ) || defined( OS_CYGWIN ) { - char * args[] = { "key_path", ":", "data", "?", 0 }; + const char * args[] = { "key_path", ":", "data", "?", 0 }; bind_builtin( "W32_GETREG", builtin_system_registry, 0, args ); } { - char * args[] = { "key_path", ":", "result-type", 0 }; + const char * args[] = { "key_path", ":", "result-type", 0 }; bind_builtin( "W32_GETREGNAMES", builtin_system_registry_names, 0, args ); } # endif { - char * args[] = { "command", ":", "*", 0 }; + const char * args[] = { "command", ":", "*", 0 }; duplicate_rule( "SHELL", bind_builtin( "COMMAND", builtin_shell, 0, args ) ); } { - char * args[] = { "string", 0 }; + const char * args[] = { "string", 0 }; bind_builtin( "MD5", builtin_md5, 0, args ) ; } { - char * args[] = { "name", ":", "mode", 0 }; + const char * args[] = { "name", ":", "mode", 0 }; bind_builtin( "FILE_OPEN", builtin_file_open, 0, args ); } { - char * args[] = { "string", ":", "width", 0 }; + const char * args[] = { "string", ":", "width", 0 }; bind_builtin( "PAD", builtin_pad, 0, args ); } { - char * args[] = { "targets", "*", 0 }; + const char * args[] = { "targets", "*", 0 }; bind_builtin( "PRECIOUS", builtin_precious, 0, args ); } { - char * args [] = { 0 }; + const char * args [] = { 0 }; bind_builtin( "SELF_PATH", builtin_self_path, 0, args ); } { - char * args [] = { "path", 0 }; + const char * args [] = { "path", 0 }; bind_builtin( "MAKEDIR", builtin_makedir, 0, args ); } @@ -420,11 +421,11 @@ void load_builtins() * The CALC rule performs simple mathematical operations on two arguments. */ -LIST * builtin_calc( PARSE * parse, FRAME * frame ) +LIST * builtin_calc( FRAME * frame, int flags ) { LIST * arg = lol_get( frame->args, 0 ); - LIST * result = 0; + LIST * result = L0; long lhs_value; long rhs_value; long result_value; @@ -432,17 +433,18 @@ LIST * builtin_calc( PARSE * parse, FRAME * frame ) char const * lhs; char const * op; char const * rhs; + LISTITER iter = list_begin( arg ), end = list_end( arg ); - if ( arg == 0 ) return L0; - lhs = arg->string; + if ( iter == end ) return L0; + lhs = object_str( list_item( iter ) ); - arg = list_next( arg ); - if ( arg == 0 ) return L0; - op = arg->string; + iter = list_next( iter ); + if ( iter == end ) return L0; + op = object_str( list_item( iter ) ); - arg = list_next( arg ); - if ( arg == 0 ) return L0; - rhs = arg->string; + iter = list_next( iter ); + if ( iter == end ) return L0; + rhs = object_str( list_item( iter ) ); lhs_value = atoi( lhs ); rhs_value = atoi( rhs ); @@ -461,7 +463,7 @@ LIST * builtin_calc( PARSE * parse, FRAME * frame ) } sprintf( buffer, "%ld", result_value ); - result = list_new( result, newstr( buffer ) ); + result = list_push_back( result, object_new( buffer ) ); return result; } @@ -474,21 +476,22 @@ LIST * builtin_calc( PARSE * parse, FRAME * frame ) * targets and sources as TARGETs. */ -LIST * builtin_depends( PARSE * parse, FRAME * frame ) +LIST * builtin_depends( FRAME * frame, int flags ) { LIST * targets = lol_get( frame->args, 0 ); LIST * sources = lol_get( frame->args, 1 ); - LIST * l; - - for ( l = targets; l; l = list_next( l ) ) + LISTITER iter, end; + + iter = list_begin( targets ), end = list_end( targets ); + for ( ; iter != end; iter = list_next( iter ) ) { - TARGET * t = bindtarget( l->string ); + TARGET * t = bindtarget( list_item( iter ) ); /* If doing INCLUDES, switch to the TARGET's include */ /* TARGET, creating it if needed. The internal include */ /* TARGET shares the name of its parent. */ - if ( parse->num ) + if ( flags ) { if ( !t->includes ) { @@ -502,9 +505,10 @@ LIST * builtin_depends( PARSE * parse, FRAME * frame ) } /* Enter reverse links */ - for ( l = sources; l; l = list_next( l ) ) + iter = list_begin( sources ), end = list_end( sources ); + for ( ; iter != end; iter = list_next( iter ) ) { - TARGET * s = bindtarget( l->string ); + TARGET * s = bindtarget( list_item( iter ) ); s->dependants = targetlist( s->dependants, targets ); } @@ -520,15 +524,15 @@ LIST * builtin_depends( PARSE * parse, FRAME * frame ) * argument. */ -LIST * builtin_rebuilds( PARSE * parse, FRAME * frame ) +LIST * builtin_rebuilds( FRAME * frame, int flags ) { LIST * targets = lol_get( frame->args, 0 ); LIST * rebuilds = lol_get( frame->args, 1 ); - LIST * l; + LISTITER iter = list_begin( targets ), end = list_end( targets ); - for ( l = targets; l; l = list_next( l ) ) + for ( ; iter != end; iter = list_next( iter ) ) { - TARGET * t = bindtarget( l->string ); + TARGET * t = bindtarget( list_item( iter ) ); t->rebuilds = targetlist( t->rebuilds, rebuilds ); } @@ -543,7 +547,7 @@ LIST * builtin_rebuilds( PARSE * parse, FRAME * frame ) * taken. */ -LIST * builtin_echo( PARSE * parse, FRAME * frame ) +LIST * builtin_echo( FRAME * frame, int flags ) { list_print( lol_get( frame->args, 0 ) ); printf( "\n" ); @@ -559,13 +563,14 @@ LIST * builtin_echo( PARSE * parse, FRAME * frame ) * with a failure status. */ -LIST * builtin_exit( PARSE * parse, FRAME * frame ) +LIST * builtin_exit( FRAME * frame, int flags ) { + LIST * code = lol_get( frame->args, 1 ); list_print( lol_get( frame->args, 0 ) ); printf( "\n" ); - if ( lol_get( frame->args, 1 ) ) + if ( !list_empty( code ) ) { - exit( atoi( lol_get( frame->args, 1 )->string ) ); + exit( atoi( object_str( list_front( code ) ) ) ); } else { @@ -582,11 +587,12 @@ LIST * builtin_exit( PARSE * parse, FRAME * frame ) * It binds each target as a TARGET. */ -LIST * builtin_flags( PARSE * parse, FRAME * frame ) +LIST * builtin_flags( FRAME * frame, int flags ) { LIST * l = lol_get( frame->args, 0 ); - for ( ; l; l = list_next( l ) ) - bindtarget( l->string )->flags |= parse->num; + LISTITER iter = list_begin( l ), end = list_end( l ); + for ( ; iter != end; iter = list_next( iter ) ) + bindtarget( list_item( iter ) )->flags |= flags; return L0; } @@ -612,10 +618,10 @@ static void downcase_inplace( char * p ) static void builtin_glob_back ( - void * closure, - char * file, - int status, - time_t time + void * closure, + OBJECT * file, + int status, + time_t time ) { PROFILE_ENTER( BUILTIN_GLOB_BACK ); @@ -624,15 +630,16 @@ static void builtin_glob_back LIST * l; PATHNAME f; string buf[ 1 ]; + LISTITER iter, end; /* Null out directory for matching. We wish we had file_dirscan() pass up a * PATHNAME. */ - path_parse( file, &f ); + path_parse( object_str( file ), &f ); f.f_dir.len = 0; /* For globbing, we unconditionally ignore current and parent directory - * items. Since they items always exist, there is no reason why caller of + * items. Since these items always exist, there is no reason why caller of * GLOB would want to see them. We could also change file_dirscan(), but * then paths with embedded "." and ".." would not work anywhere. */ @@ -648,11 +655,12 @@ static void builtin_glob_back if ( globbing->case_insensitive ) downcase_inplace( buf->value ); - for ( l = globbing->patterns; l; l = l->next ) + iter = list_begin( globbing->patterns ), end = list_end( globbing->patterns ); + for ( ; iter != end; iter = list_next( iter ) ) { - if ( !glob( l->string, buf->value ) ) + if ( !glob( object_str( list_item( iter ) ), buf->value ) ) { - globbing->results = list_new( globbing->results, newstr( file ) ); + globbing->results = list_push_back( globbing->results, object_copy( file ) ); break; } } @@ -665,17 +673,18 @@ static void builtin_glob_back static LIST * downcase_list( LIST * in ) { - LIST * result = 0; + LIST * result = L0; + LISTITER iter = list_begin( in ), end = list_end( in ); string s[ 1 ]; string_new( s ); - while ( in ) + for ( ; iter != end; iter = list_next( iter ) ) { - string_copy( s, in->string ); + string_append( s, object_str( list_item( iter ) ) ); downcase_inplace( s->value ); - result = list_append( result, list_new( 0, newstr( s->value ) ) ); - in = in->next; + result = list_push_back( result, object_new( s->value ) ); + string_truncate( s, 0 ); } string_free( s ); @@ -683,11 +692,12 @@ static LIST * downcase_list( LIST * in ) } -LIST * builtin_glob( PARSE * parse, FRAME * frame ) +LIST * builtin_glob( FRAME * frame, int flags ) { LIST * l = lol_get( frame->args, 0 ); LIST * r = lol_get( frame->args, 1 ); + LISTITER iter, end; struct globbing globbing; globbing.results = L0; @@ -703,8 +713,9 @@ LIST * builtin_glob( PARSE * parse, FRAME * frame ) if ( globbing.case_insensitive ) globbing.patterns = downcase_list( r ); - for ( ; l; l = list_next( l ) ) - file_dirscan( l->string, builtin_glob_back, &globbing ); + iter = list_begin( l ), end = list_end( l ); + for ( ; iter != end; iter = list_next( iter ) ) + file_dirscan( list_item( iter ), builtin_glob_back, &globbing ); if ( globbing.case_insensitive ) list_free( globbing.patterns ); @@ -724,19 +735,19 @@ static int has_wildcards( char const * str ) * If 'file' exists, append 'file' to 'list'. Returns 'list'. */ -static LIST * append_if_exists( LIST * list, char * file ) +static LIST * append_if_exists( LIST * list, OBJECT * file ) { time_t time; timestamp( file, &time ); return time > 0 - ? list_new( list, newstr( file ) ) + ? list_push_back( list, object_copy( file ) ) : list; } -LIST * glob1( char * dirname, char * pattern ) +LIST * glob1( OBJECT * dirname, OBJECT * pattern ) { - LIST * plist = list_new( L0, pattern ); + LIST * plist = list_new( object_copy(pattern) ); struct globbing globbing; globbing.results = L0; @@ -763,7 +774,7 @@ LIST * glob1( char * dirname, char * pattern ) } -LIST * glob_recursive( char * pattern ) +LIST * glob_recursive( const char * pattern ) { LIST * result = L0; @@ -771,7 +782,9 @@ LIST * glob_recursive( char * pattern ) if ( !has_wildcards( pattern ) ) { /* No metacharacters. Check if the path exists. */ - result = append_if_exists(result, pattern); + OBJECT * p = object_new( pattern ); + result = append_if_exists( result, p ); + object_free( p ); } else { @@ -798,27 +811,35 @@ LIST * glob_recursive( char * pattern ) dirs = has_wildcards( dirname->value ) ? glob_recursive( dirname->value ) - : list_new( dirs, dirname->value ); + : list_push_back( dirs, object_new( dirname->value ) ); if ( has_wildcards( basename->value ) ) { - for ( ; dirs; dirs = dirs->next ) - result = list_append( result, glob1( dirs->string, - basename->value ) ); + OBJECT * b = object_new( basename->value ); + LISTITER iter = list_begin( dirs ), end = list_end( dirs ); + for ( ; iter != end; iter = list_next( iter ) ) + result = list_append( result, glob1( list_item( iter ), b ) ); + object_free( b ); } else { + LISTITER iter = list_begin( dirs ), end = list_end( dirs ); string file_string[ 1 ]; string_new( file_string ); /* No wildcard in basename. */ - for ( ; dirs; dirs = dirs->next ) + for ( ; iter != end; iter = list_next( iter ) ) { - path->f_dir.ptr = dirs->string; - path->f_dir.len = strlen( dirs->string ); + OBJECT * p; + path->f_dir.ptr = object_str( list_item( iter ) ); + path->f_dir.len = strlen( object_str( list_item( iter ) ) ); path_build( path, file_string, 0 ); - result = append_if_exists( result, file_string->value ); + p = object_new( file_string->value ); + + result = append_if_exists( result, p ); + + object_free( p ); string_truncate( file_string, 0 ); } @@ -828,11 +849,15 @@ LIST * glob_recursive( char * pattern ) string_free( dirname ); string_free( basename ); + + list_free( dirs ); } else { /** No directory, just a pattern. */ - result = list_append( result, glob1( ".", pattern ) ); + OBJECT * p = object_new( pattern ); + result = list_append( result, glob1( constant_dot, p ) ); + object_free( p ); } } @@ -840,12 +865,13 @@ LIST * glob_recursive( char * pattern ) } -LIST * builtin_glob_recursive( PARSE * parse, FRAME * frame ) +LIST * builtin_glob_recursive( FRAME * frame, int flags ) { LIST * result = L0; LIST * l = lol_get( frame->args, 0 ); - for ( ; l; l = l->next ) - result = list_append( result, glob_recursive( l->string ) ); + LISTITER iter = list_begin( l ), end = list_end( l ); + for ( ; iter != end; iter = list_next( iter ) ) + result = list_append( result, glob_recursive( object_str( list_item( iter ) ) ) ); return result; } @@ -854,26 +880,31 @@ LIST * builtin_glob_recursive( PARSE * parse, FRAME * frame ) * builtin_match() - MATCH rule, regexp matching. */ -LIST * builtin_match( PARSE * parse, FRAME * frame ) +LIST * builtin_match( FRAME * frame, int flags ) { LIST * l; LIST * r; - LIST * result = 0; + LIST * result = L0; + LISTITER l_iter, l_end, r_iter, r_end; string buf[ 1 ]; string_new( buf ); /* For each pattern */ - for ( l = lol_get( frame->args, 0 ); l; l = l->next ) + l = lol_get( frame->args, 0 ); + l_iter = list_begin( l ), l_end = list_end( l ); + for (; l_iter != l_end; l_iter = list_next( l_iter ) ) { /* Result is cached and intentionally never freed. */ - regexp * re = regex_compile( l->string ); + regexp * re = regex_compile( list_item( l_iter ) ); /* For each string to match against. */ - for ( r = lol_get( frame->args, 1 ); r; r = r->next ) + r = lol_get( frame->args, 1 ); + r_iter = list_begin( r ), r_end = list_end( r ); + for ( ; r_iter != r_end; r_iter = list_next( r_iter ) ) { - if ( regexec( re, r->string ) ) + if ( regexec( re, object_str( list_item( r_iter ) ) ) ) { int i; int top; @@ -889,7 +920,7 @@ LIST * builtin_match( PARSE * parse, FRAME * frame ) for ( i = 1; i <= top; ++i ) { string_append_range( buf, re->startp[ i ], re->endp[ i ] ); - result = list_new( result, newstr( buf->value ) ); + result = list_push_back( result, object_new( buf->value ) ); string_truncate( buf, 0 ); } } @@ -900,41 +931,45 @@ LIST * builtin_match( PARSE * parse, FRAME * frame ) return result; } -LIST * builtin_split_by_characters( PARSE * parse, FRAME * frame ) +LIST * builtin_split_by_characters( FRAME * frame, int flags ) { LIST * l1 = lol_get( frame->args, 0 ); LIST * l2 = lol_get( frame->args, 1 ); - LIST * result = 0; + LIST * result = L0; + + string buf[ 1 ]; - char* s = strdup (l1->string); - char* delimiters = l2->string; - char* t; + const char * delimiters = object_str( list_front( l2 ) ); + char * t; - t = strtok (s, delimiters); - while (t) + string_copy( buf, object_str( list_front( l1 ) ) ); + + t = strtok( buf->value, delimiters) ; + while ( t ) { - result = list_new(result, newstr(t)); - t = strtok (NULL, delimiters); + result = list_push_back( result, object_new( t ) ); + t = strtok( NULL, delimiters ); } - free (s); + string_free( buf ); return result; } -LIST * builtin_hdrmacro( PARSE * parse, FRAME * frame ) +LIST * builtin_hdrmacro( FRAME * frame, int flags ) { LIST * l = lol_get( frame->args, 0 ); + LISTITER iter = list_begin( l ), end = list_end( l ); - for ( ; l; l = list_next( l ) ) + for ( ; iter != end; iter = list_next( iter ) ) { - TARGET * t = bindtarget( l->string ); + TARGET * t = bindtarget( list_item( iter ) ); /* Scan file for header filename macro definitions. */ if ( DEBUG_HEADER ) printf( "scanning '%s' for header file macro definitions\n", - l->string ); + object_str( list_item( iter ) ) ); macro_headers( t ); } @@ -955,15 +990,15 @@ static void add_rule_name( void * r_, void * result_ ) RULE * r = (RULE *)r_; LIST * * result = (LIST * *)result_; if ( r->exported ) - *result = list_new( *result, copystr( r->name ) ); + *result = list_push_back( *result, object_copy( r->name ) ); } -LIST * builtin_rulenames( PARSE * parse, FRAME * frame ) +LIST * builtin_rulenames( FRAME * frame, int flags ) { LIST * arg0 = lol_get( frame->args, 0 ); LIST * result = L0; - module_t * source_module = bindmodule( arg0 ? arg0->string : 0 ); + module_t * source_module = bindmodule( !list_empty( arg0 ) ? list_front( arg0 ) : 0 ); if ( source_module->rules ) hashenumerate( source_module->rules, add_rule_name, &result ); @@ -984,36 +1019,17 @@ LIST * builtin_rulenames( PARSE * parse, FRAME * frame ) static void add_hash_key( void * np, void * result_ ) { LIST * * result = (LIST * *)result_; - *result = list_new( *result, copystr( *(char * *)np ) ); + *result = list_push_back( *result, object_copy( *(OBJECT * *)np ) ); } -static struct hash * get_running_module_vars() -{ - struct hash * dummy; - struct hash * vars = NULL; - /* Get the global variables pointer (that of the currently running module). - */ - var_hash_swap( &vars ); - dummy = vars; - /* Put the global variables pointer in its right place. */ - var_hash_swap( &dummy ); - return vars; -} - - -LIST * builtin_varnames( PARSE * parse, FRAME * frame ) +LIST * builtin_varnames( FRAME * frame, int flags ) { LIST * arg0 = lol_get( frame->args, 0 ); LIST * result = L0; - module_t * source_module = bindmodule( arg0 ? arg0->string : 0 ); + module_t * source_module = bindmodule( !list_empty(arg0) ? list_front(arg0) : 0 ); - /* The running module _always_ has its 'variables' member set to NULL due to - * the way enter_module() and var_hash_swap() work. - */ - struct hash * vars = source_module == frame->module - ? get_running_module_vars() - : source_module->variables; + struct hash * vars = source_module->variables; if ( vars ) hashenumerate( vars, add_hash_key, &result ); @@ -1027,20 +1043,28 @@ LIST * builtin_varnames( PARSE * parse, FRAME * frame ) * Clears all rules and variables from the given module. */ -LIST * builtin_delete_module( PARSE * parse, FRAME * frame ) +LIST * builtin_delete_module( FRAME * frame, int flags ) { LIST * arg0 = lol_get( frame->args, 0 ); LIST * result = L0; - module_t * source_module = bindmodule( arg0 ? arg0->string : 0 ); + module_t * source_module = bindmodule( !list_empty(arg0) ? list_front(arg0) : 0 ); delete_module( source_module ); return result; } -static void unknown_rule( FRAME * frame, char * key, char * module_name, char * rule_name ) +static void unknown_rule( FRAME * frame, const char * key, module_t * module, OBJECT * rule_name ) { + const char * module_name = module->name ? object_str( module->name ) : ""; backtrace_line( frame->prev ); - printf( "%s error: rule \"%s\" unknown in module \"%s\"\n", key, rule_name, module_name ); + if ( module->name ) + { + printf( "%s error: rule \"%s\" unknown in module \"%s.\"\n", key, object_str( rule_name ), object_str( module->name ) ); + } + else + { + printf( "%s error: rule \"%s\" unknown in module \"\"\n", key, object_str( rule_name ) ); + } backtrace( frame->prev ); exit( 1 ); } @@ -1067,7 +1091,7 @@ static void unknown_rule( FRAME * frame, char * key, char * module_name, char * * variables. */ -LIST * builtin_import( PARSE * parse, FRAME * frame ) +LIST * builtin_import( FRAME * frame, int flags ) { LIST * source_module_list = lol_get( frame->args, 0 ); LIST * source_rules = lol_get( frame->args, 1 ); @@ -1076,37 +1100,35 @@ LIST * builtin_import( PARSE * parse, FRAME * frame ) LIST * localize = lol_get( frame->args, 4 ); module_t * target_module = - bindmodule( target_module_list ? target_module_list->string : 0 ); + bindmodule( !list_empty( target_module_list ) ? list_front( target_module_list ) : 0 ); module_t * source_module = - bindmodule( source_module_list ? source_module_list->string : 0 ); + bindmodule( !list_empty( source_module_list ) ? list_front( source_module_list ) : 0 ); - LIST * source_name; - LIST * target_name; + LISTITER source_iter = list_begin( source_rules ), source_end = list_end( source_rules ); + LISTITER target_iter = list_begin( target_rules ), target_end = list_end( target_rules ); - for ( source_name = source_rules, target_name = target_rules; - source_name && target_name; - source_name = list_next( source_name ), - target_name = list_next( target_name ) ) + for ( ; + source_iter != source_end && target_iter != target_end; + source_iter = list_next( source_iter ), + target_iter = list_next( target_iter ) ) { - RULE r_; - RULE * r = &r_; + RULE * r; RULE * imported; - r_.name = source_name->string; if ( !source_module->rules || - !hashcheck( source_module->rules, (HASHDATA * *)&r ) ) - unknown_rule( frame, "IMPORT", source_module->name, r_.name ); + !(r = (RULE *)hash_find( source_module->rules, list_item( source_iter ) ) ) ) + unknown_rule( frame, "IMPORT", source_module, list_item( source_iter ) ); - imported = import_rule( r, target_module, target_name->string ); - if ( localize ) - imported->module = target_module; + imported = import_rule( r, target_module, list_item( target_iter ) ); + if ( !list_empty( localize ) ) + rule_localize( imported, target_module ); /* This rule is really part of some other module. Just refer to it here, * but do not let it out. */ imported->exported = 0; } - if ( source_name || target_name ) + if ( source_iter != source_end || target_iter != target_end ) { backtrace_line( frame->prev ); printf( "import error: length of source and target rule name lists don't match!\n" ); @@ -1131,20 +1153,19 @@ LIST * builtin_import( PARSE * parse, FRAME * frame ) * is issued. */ -LIST * builtin_export( PARSE * parse, FRAME * frame ) +LIST * builtin_export( FRAME * frame, int flags ) { LIST * module_list = lol_get( frame->args, 0 ); LIST * rules = lol_get( frame->args, 1 ); - module_t * m = bindmodule( module_list ? module_list->string : 0 ); + module_t * m = bindmodule( !list_empty( module_list ) ? list_front( module_list ) : 0 ); - for ( ; rules; rules = list_next( rules ) ) + LISTITER iter = list_begin( rules ), end = list_end( rules ); + for ( ; iter != end; iter = list_next( iter ) ) { - RULE r_; - RULE * r = &r_; - r_.name = rules->string; + RULE * r; - if ( !m->rules || !hashcheck( m->rules, (HASHDATA * *)&r ) ) - unknown_rule( frame, "EXPORT", m->name, r_.name ); + if ( !m->rules || !(r = (RULE *)hash_find( m->rules, list_item( iter ) ) ) ) + unknown_rule( frame, "EXPORT", m, list_item( iter ) ); r->exported = 1; } @@ -1157,12 +1178,12 @@ LIST * builtin_export( PARSE * parse, FRAME * frame ) * indicated for a given procedure in debug output or an error backtrace. */ -static void get_source_line( PARSE * procedure, char * * file, int * line ) +static void get_source_line( FRAME * frame, const char * * file, int * line ) { - if ( procedure ) + if ( frame->file ) { - char * f = procedure->file; - int l = procedure->line; + const char * f = object_str( frame->file ); + int l = frame->line; if ( !strcmp( f, "+" ) ) { f = "jambase.c"; @@ -1179,12 +1200,12 @@ static void get_source_line( PARSE * procedure, char * * file, int * line ) } -void print_source_line( PARSE * p ) +void print_source_line( FRAME * frame ) { - char * file; + const char * file; int line; - get_source_line( p, &file, &line ); + get_source_line( frame, &file, &line ); if ( line < 0 ) printf( "(builtin):" ); else @@ -1205,7 +1226,7 @@ void backtrace_line( FRAME * frame ) } else { - print_source_line( frame->procedure ); + print_source_line( frame ); printf( " in %s\n", frame->rulename ); } } @@ -1231,23 +1252,31 @@ void backtrace( FRAME * frame ) * period. */ -LIST * builtin_backtrace( PARSE * parse, FRAME * frame ) +LIST * builtin_backtrace( FRAME * frame, int flags ) { LIST * levels_arg = lol_get( frame->args, 0 ); - int levels = levels_arg ? atoi( levels_arg->string ) : ( (unsigned int)(-1) >> 1 ) ; + int levels = !list_empty( levels_arg ) ? atoi( object_str( list_front( levels_arg ) ) ) : (int)( (unsigned int)(-1) >> 1 ) ; LIST * result = L0; for ( ; ( frame = frame->prev ) && levels ; --levels ) { - char * file; + const char * file; int line; char buf[32]; - get_source_line( frame->procedure, &file, &line ); + string module_name[1]; + get_source_line( frame, &file, &line ); sprintf( buf, "%d", line ); - result = list_new( result, newstr( file ) ); - result = list_new( result, newstr( buf ) ); - result = list_new( result, newstr( frame->module->name ) ); - result = list_new( result, newstr( frame->rulename ) ); + string_new( module_name ); + if ( frame->module->name ) + { + string_append( module_name, object_str( frame->module->name ) ); + string_append( module_name, "." ); + } + result = list_push_back( result, object_new( file ) ); + result = list_push_back( result, object_new( buf ) ); + result = list_push_back( result, object_new( module_name->value ) ); + result = list_push_back( result, object_new( frame->rulename ) ); + string_free( module_name ); } return result; } @@ -1265,10 +1294,10 @@ LIST * builtin_backtrace( PARSE * parse, FRAME * frame ) * behavior. */ -LIST * builtin_caller_module( PARSE * parse, FRAME * frame ) +LIST * builtin_caller_module( FRAME * frame, int flags ) { LIST * levels_arg = lol_get( frame->args, 0 ); - int levels = levels_arg ? atoi( levels_arg->string ) : 0 ; + int levels = !list_empty( levels_arg ) ? atoi( object_str( list_front( levels_arg ) ) ) : 0 ; int i; for ( i = 0; ( i < levels + 2 ) && frame->prev; ++i ) @@ -1276,16 +1305,8 @@ LIST * builtin_caller_module( PARSE * parse, FRAME * frame ) if ( frame->module == root_module() ) return L0; - - { - LIST * result; - string name; - string_copy( &name, frame->module->name ); - string_pop_back( &name ); - result = list_new( L0, newstr(name.value) ); - string_free( &name ); - return result; - } + else + return list_new( object_copy( frame->module->name ) ); } @@ -1295,7 +1316,7 @@ LIST * builtin_caller_module( PARSE * parse, FRAME * frame ) * Usage: pwd = [ PWD ] ; */ -LIST * builtin_pwd( PARSE * parse, FRAME * frame ) +LIST * builtin_pwd( FRAME * frame, int flags ) { return pwd(); } @@ -1305,13 +1326,14 @@ LIST * builtin_pwd( PARSE * parse, FRAME * frame ) * Adds targets to the list of target that jam will attempt to update. */ -LIST * builtin_update( PARSE * parse, FRAME * frame ) +LIST * builtin_update( FRAME * frame, int flags ) { - LIST * result = list_copy( L0, targets_to_update() ); + LIST * result = list_copy( targets_to_update() ); LIST * arg1 = lol_get( frame->args, 0 ); + LISTITER iter = list_begin( arg1 ), end = list_end( arg1 ); clear_targets_to_update(); - for ( ; arg1; arg1 = list_next( arg1 ) ) - mark_target_for_updating( newstr( arg1->string ) ); + for ( ; iter != end; iter = list_next( iter ) ) + mark_target_for_updating( object_copy( list_item( iter ) ) ); return result; } @@ -1325,34 +1347,30 @@ int last_update_now_status; Third parameter, if non-empty, specifies that the -n option should have no effect -- that is, all out-of-date targets should be rebuild. */ -LIST * builtin_update_now( PARSE * parse, FRAME * frame ) +LIST * builtin_update_now( FRAME * frame, int flags ) { LIST * targets = lol_get( frame->args, 0 ); LIST * log = lol_get( frame->args, 1 ); - LIST * force = lol_get (frame->args, 2); - LIST * continue_ = lol_get(frame->args, 3); - int status = 0; - int original_stdout; - int original_stderr; - int n; - int targets_count; - const char** targets2; - int i; - int original_noexec; - int original_quitquick; + LIST * force = lol_get( frame->args, 2 ); + LIST * continue_ = lol_get( frame->args, 3 ); + int status; + int original_stdout = 0; + int original_stderr = 0; + int original_noexec = 0; + int original_quitquick = 0; - if (log) + if ( !list_empty( log ) ) { - int fd = atoi(log->string); + int fd = atoi( object_str( list_front( log ) ) ); /* Redirect stdout and stderr, temporary, to the log file. */ - original_stdout = dup (0); - original_stderr = dup (1); - dup2 (fd, 0); - dup2 (fd, 1); + original_stdout = dup( 0 ); + original_stderr = dup( 1 ); + dup2 ( fd, 0 ); + dup2 ( fd, 1 ); } - if (force) + if ( !list_empty( force ) ) { original_noexec = globs.noexec; globs.noexec = 0; @@ -1360,95 +1378,83 @@ LIST * builtin_update_now( PARSE * parse, FRAME * frame ) globs.quitquick = 0; } - if (continue_) + if ( !list_empty( continue_ ) ) { original_quitquick = globs.quitquick; globs.quitquick = 0; } - targets_count = list_length( targets ); - targets2 = (const char * *)BJAM_MALLOC( targets_count * sizeof( char * ) ); - for (i = 0 ; targets; targets = list_next( targets ) ) - targets2[ i++ ] = targets->string; - status |= make( targets_count, targets2, anyhow); - free( targets ); + status = make( targets, anyhow ); - if (force) + if ( !list_empty( force ) ) { globs.noexec = original_noexec; globs.quitquick = original_quitquick; } - if (continue_) + if ( !list_empty( continue_ ) ) { globs.quitquick = original_quitquick; } - if (log) + if ( !list_empty( log ) ) { /* Flush whatever stdio might have buffered, while descriptions 0 and 1 still refer to the log file. */ - fflush (stdout); - fflush (stderr); - dup2 (original_stdout, 0); - dup2 (original_stderr, 1); - close (original_stdout); - close (original_stderr); + fflush( stdout ); + fflush( stderr ); + dup2( original_stdout, 0 ); + dup2( original_stderr, 1 ); + close( original_stdout ); + close( original_stderr ); } last_update_now_status = status; - if (status == 0) - return list_new (L0, newstr ("ok")); + if ( status == 0 ) + return list_new( object_copy( constant_ok ) ); else return L0; } -LIST * builtin_search_for_target( PARSE * parse, FRAME * frame ) -{ - LIST * arg1 = lol_get( frame->args, 0 ); - LIST * arg2 = lol_get( frame->args, 1 ); - TARGET * t = search_for_target( arg1->string, arg2 ); - return list_new( L0, t->name ); -} - -LIST * builtin_import_module( PARSE * parse, FRAME * frame ) +LIST * builtin_import_module( FRAME * frame, int flags ) { LIST * arg1 = lol_get( frame->args, 0 ); LIST * arg2 = lol_get( frame->args, 1 ); - module_t * m = arg2 ? bindmodule( arg2->string ) : root_module(); + module_t * m = !list_empty( arg2 ) ? bindmodule( list_front( arg2 ) ) : root_module(); import_module( arg1, m ); return L0; } -LIST * builtin_imported_modules( PARSE * parse, FRAME * frame ) +LIST * builtin_imported_modules( FRAME * frame, int flags ) { LIST * arg0 = lol_get( frame->args, 0 ); - return imported_modules( bindmodule( arg0 ? arg0->string : 0 ) ); + return imported_modules( bindmodule( !list_empty( arg0 ) ? list_front( arg0 ) : 0 ) ); } -LIST * builtin_instance( PARSE * parse, FRAME * frame ) +LIST * builtin_instance( FRAME * frame, int flags ) { LIST * arg1 = lol_get( frame->args, 0 ); LIST * arg2 = lol_get( frame->args, 1 ); - module_t * const instance = bindmodule( arg1->string ); - module_t * const class_module = bindmodule( arg2->string ); + module_t * const instance = bindmodule( list_front( arg1 ) ); + module_t * const class_module = bindmodule( list_front( arg2 ) ); instance->class_module = class_module; + module_set_fixed_variables( instance, class_module->num_fixed_variables ); return L0; } -LIST * builtin_sort( PARSE * parse, FRAME * frame ) +LIST * builtin_sort( FRAME * frame, int flags ) { LIST * arg1 = lol_get( frame->args, 0 ); return list_sort( arg1 ); } -LIST * builtin_normalize_path( PARSE * parse, FRAME * frame ) +LIST * builtin_normalize_path( FRAME * frame, int flags ) { LIST * arg = lol_get( frame->args, 0 ); @@ -1468,7 +1474,8 @@ LIST * builtin_normalize_path( PARSE * parse, FRAME * frame ) /* Number of '..' elements seen and not processed yet. */ int dotdots = 0; int rooted = 0; - char * result = 0; + OBJECT * result = 0; + LISTITER arg_iter = list_begin( arg ), arg_end = list_end( arg ); /* Make a copy of input: we should not change it. Prepend a '/' before it as * a guard for the algorithm later on and remember whether it was originally @@ -1476,16 +1483,16 @@ LIST * builtin_normalize_path( PARSE * parse, FRAME * frame ) */ string_new( in ); string_push_back( in, '/' ); - for ( ; arg; arg = list_next( arg ) ) + for ( ; arg_iter != arg_end; arg_iter = list_next( arg_iter ) ) { - if ( arg->string[ 0 ] != '\0' ) + if ( object_str( list_item( arg_iter ) )[ 0 ] != '\0' ) { if ( in->size == 1 ) - rooted = ( ( arg->string[ 0 ] == '/' ) || - ( arg->string[ 0 ] == '\\' ) ); + rooted = ( ( object_str( list_item( arg_iter ) )[ 0 ] == '/' ) || + ( object_str( list_item( arg_iter ) )[ 0 ] == '\\' ) ); else string_append( in, "/" ); - string_append( in, arg->string ); + string_append( in, object_str( list_item( arg_iter ) ) ); } } @@ -1544,7 +1551,12 @@ LIST * builtin_normalize_path( PARSE * parse, FRAME * frame ) */ if ( dotdots ) { - if ( rooted ) return L0; + if ( rooted ) + { + string_free( out ); + string_free( in ); + return L0; + } do string_append( out, "/.." ); while ( --dotdots ); @@ -1561,34 +1573,32 @@ LIST * builtin_normalize_path( PARSE * parse, FRAME * frame ) * the original path was rooted and we have an empty path we need to add * back the '/'. */ - result = newstr( out->size ? out->value + !rooted : ( rooted ? "/" : "." ) ); + result = object_new( out->size ? out->value + !rooted : ( rooted ? "/" : "." ) ); string_free( out ); string_free( in ); - return list_new( 0, result ); + return list_new( result ); } -LIST * builtin_native_rule( PARSE * parse, FRAME * frame ) +LIST * builtin_native_rule( FRAME * frame, int flags ) { LIST * module_name = lol_get( frame->args, 0 ); LIST * rule_name = lol_get( frame->args, 1 ); - module_t * module = bindmodule( module_name->string ); + module_t * module = bindmodule( list_front( module_name ) ); - native_rule_t n; - native_rule_t * np = &n; - n.name = rule_name->string; - if ( module->native_rules && hashcheck( module->native_rules, (HASHDATA * *)&np ) ) + native_rule_t * np; + if ( module->native_rules && (np = (native_rule_t *)hash_find( module->native_rules, list_front( rule_name ) ) ) ) { - new_rule_body( module, np->name, np->arguments, np->procedure, 1 ); + new_rule_body( module, np->name, np->procedure, 1 ); } else { backtrace_line( frame->prev ); - printf( "error: no native rule \"%s\" defined in module \"%s\"\n", - n.name, module->name ); + printf( "error: no native rule \"%s\" defined in module \"%s.\"\n", + object_str( list_front( rule_name ) ), object_str( module->name ) ); backtrace( frame->prev ); exit( 1 ); } @@ -1596,40 +1606,39 @@ LIST * builtin_native_rule( PARSE * parse, FRAME * frame ) } -LIST * builtin_has_native_rule( PARSE * parse, FRAME * frame ) +LIST * builtin_has_native_rule( FRAME * frame, int flags ) { LIST * module_name = lol_get( frame->args, 0 ); LIST * rule_name = lol_get( frame->args, 1 ); LIST * version = lol_get( frame->args, 2 ); - module_t * module = bindmodule( module_name->string ); + module_t * module = bindmodule( list_front( module_name ) ); - native_rule_t n; - native_rule_t * np = &n; - n.name = rule_name->string; - if ( module->native_rules && hashcheck( module->native_rules, (HASHDATA * *)&np ) ) + native_rule_t * np; + if ( module->native_rules && (np = (native_rule_t *)hash_find( module->native_rules, list_front( rule_name ) ) ) ) { - int expected_version = atoi( version->string ); + int expected_version = atoi( object_str( list_front( version ) ) ); if ( np->version == expected_version ) - return list_new( 0, newstr( "true" ) ); + return list_new( object_copy( constant_true ) ); } return L0; } -LIST * builtin_user_module( PARSE * parse, FRAME * frame ) +LIST * builtin_user_module( FRAME * frame, int flags ) { LIST * module_name = lol_get( frame->args, 0 ); - for ( ; module_name; module_name = module_name->next ) + LISTITER iter = list_begin( module_name ), end = list_end( module_name ); + for ( ; iter != end; iter = list_next( iter ) ) { - module_t * m = bindmodule( module_name->string ); + module_t * m = bindmodule( list_item( iter ) ); m->user_module = 1; } return L0; } -LIST * builtin_nearest_user_location( PARSE * parse, FRAME * frame ) +LIST * builtin_nearest_user_location( FRAME * frame, int flags ) { FRAME * nearest_user_frame = frame->module->user_module ? frame : frame->prev_user; @@ -1637,33 +1646,33 @@ LIST * builtin_nearest_user_location( PARSE * parse, FRAME * frame ) return L0; { - LIST * result = 0; - char * file; + LIST * result = L0; + const char * file; int line; char buf[32]; - get_source_line( nearest_user_frame->procedure, &file, &line ); + get_source_line( nearest_user_frame, &file, &line ); sprintf( buf, "%d", line ); - result = list_new( result, newstr( file ) ); - result = list_new( result, newstr( buf ) ); + result = list_push_back( result, object_new( file ) ); + result = list_push_back( result, object_new( buf ) ); return result; } } -LIST * builtin_check_if_file( PARSE * parse, FRAME * frame ) +LIST * builtin_check_if_file( FRAME * frame, int flags ) { LIST * name = lol_get( frame->args, 0 ); - return file_is_file( name->string ) == 1 - ? list_new( 0, newstr( "true" ) ) + return file_is_file( list_front( name ) ) == 1 + ? list_new( object_copy( constant_true ) ) : L0 ; } -LIST * builtin_md5( PARSE * parse, FRAME * frame ) +LIST * builtin_md5( FRAME * frame, int flags ) { LIST * l = lol_get( frame->args, 0 ); - char* s = l->string; + const char* s = object_str( list_front( l ) ); md5_state_t state; md5_byte_t digest[16]; @@ -1671,36 +1680,36 @@ LIST * builtin_md5( PARSE * parse, FRAME * frame ) int di; - md5_init(&state); - md5_append(&state, (const md5_byte_t *)s, strlen(s)); - md5_finish(&state, digest); + md5_init( &state ); + md5_append( &state, (const md5_byte_t *)s, strlen(s) ); + md5_finish( &state, digest ); for (di = 0; di < 16; ++di) - sprintf(hex_output + di * 2, "%02x", digest[di]); + sprintf( hex_output + di * 2, "%02x", digest[di] ); - return list_new (0, newstr(hex_output)); + return list_new( object_new( hex_output ) ); } -LIST *builtin_file_open( PARSE *parse, FRAME *frame ) +LIST *builtin_file_open( FRAME * frame, int flags ) { - char* name = lol_get(frame->args, 0)->string; - char* mode = lol_get(frame->args, 1)->string; + const char * name = object_str( list_front( lol_get( frame->args, 0 ) ) ); + const char * mode = object_str( list_front( lol_get( frame->args, 1 ) ) ); int fd; char buffer[sizeof("4294967295")]; - if (strcmp(mode, "w") == 0) + if ( strcmp(mode, "w") == 0 ) { - fd = open(name, O_WRONLY|O_CREAT|O_TRUNC, 0666); + fd = open( name, O_WRONLY|O_CREAT|O_TRUNC, 0666 ); } else { - fd = open(name, O_RDONLY); + fd = open( name, O_RDONLY ); } if (fd != -1) { - sprintf(buffer, "%d", fd); - return list_new(L0, newstr(buffer)); + sprintf( buffer, "%d", fd ); + return list_new( object_new( buffer ) ); } else { @@ -1708,52 +1717,53 @@ LIST *builtin_file_open( PARSE *parse, FRAME *frame ) } } -LIST *builtin_pad( PARSE *parse, FRAME *frame ) +LIST *builtin_pad( FRAME * frame, int flags ) { - char *string = lol_get(frame->args, 0)->string; - char *width_s = lol_get(frame->args, 1)->string; + OBJECT * string = list_front( lol_get( frame->args, 0 ) ); + const char * width_s = object_str( list_front( lol_get( frame->args, 1 ) ) ); - int current = strlen (string); - int desired = atoi(width_s); + int current = strlen( object_str( string ) ); + int desired = atoi( width_s ); if (current >= desired) - return list_new (L0, string); + return list_new( object_copy( string ) ); else { - char *buffer = malloc (desired + 1); + char * buffer = BJAM_MALLOC( desired + 1 ); int i; - LIST *result; + LIST * result; - strcpy (buffer, string); - for (i = current; i < desired; ++i) + strcpy( buffer, object_str( string ) ); + for ( i = current; i < desired; ++i ) buffer[i] = ' '; buffer[desired] = '\0'; - result = list_new (L0, newstr (buffer)); - free (buffer); + result = list_new( object_new( buffer ) ); + BJAM_FREE( buffer ); return result; } } -LIST *builtin_precious( PARSE *parse, FRAME *frame ) +LIST *builtin_precious( FRAME * frame, int flags ) { - LIST* targets = lol_get(frame->args, 0); + LIST * targets = lol_get(frame->args, 0); - for ( ; targets; targets = list_next( targets ) ) + LISTITER iter = list_begin( targets ), end = list_end( targets ); + for ( ; iter != end; iter = list_next( iter ) ) { - TARGET* t = bindtarget (targets->string); + TARGET* t = bindtarget( list_item( iter ) ); t->flags |= T_FLAG_PRECIOUS; } return L0; } -LIST *builtin_self_path( PARSE *parse, FRAME *frame ) +LIST *builtin_self_path( FRAME * frame, int flags ) { - extern char *saved_argv0; - char *p = executable_path (saved_argv0); - if (p) + extern const char * saved_argv0; + char * p = executable_path( saved_argv0 ); + if ( p ) { - LIST* result = list_new (0, newstr (p)); - free(p); + LIST* result = list_new( object_new( p ) ); + free( p ); return result; } else @@ -1762,13 +1772,13 @@ LIST *builtin_self_path( PARSE *parse, FRAME *frame ) } } -LIST *builtin_makedir( PARSE *parse, FRAME *frame ) +LIST *builtin_makedir( FRAME * frame, int flags ) { - LIST *path = lol_get(frame->args, 0); + LIST * path = lol_get( frame->args, 0 ); - if (file_mkdir(path->string) == 0) + if ( file_mkdir( object_str( list_front( path ) ) ) == 0 ) { - LIST *result = list_new (0, newstr(path->string)); + LIST * result = list_new( object_copy( list_front( path ) ) ); return result; } else @@ -1779,13 +1789,13 @@ LIST *builtin_makedir( PARSE *parse, FRAME *frame ) #ifdef HAVE_PYTHON -LIST * builtin_python_import_rule( PARSE * parse, FRAME * frame ) +LIST * builtin_python_import_rule( FRAME * frame, int flags ) { static int first_time = 1; - char * python_module = lol_get( frame->args, 0 )->string; - char * python_function = lol_get( frame->args, 1 )->string; - char * jam_module = lol_get( frame->args, 2 )->string; - char * jam_rule = lol_get( frame->args, 3 )->string; + const char * python_module = object_str( list_front( lol_get( frame->args, 0 ) ) ); + const char * python_function = object_str( list_front( lol_get( frame->args, 1 ) ) ); + OBJECT * jam_module = list_front( lol_get( frame->args, 2 ) ); + OBJECT * jam_rule = list_front( lol_get( frame->args, 3 ) ); PyObject * pName; PyObject * pModule; @@ -1799,29 +1809,19 @@ LIST * builtin_python_import_rule( PARSE * parse, FRAME * frame ) */ LIST * extra = 0; module_t * outer_module = frame->module; + LISTITER iter, end; first_time = 0; - if ( outer_module != root_module() ) - { - exit_module( outer_module ); - enter_module( root_module() ); - } - - extra = var_get( "EXTRA_PYTHONPATH" ); - - if ( outer_module != root_module() ) - { - exit_module( root_module() ); - enter_module( outer_module ); - } + extra = var_get( root_module(), constant_extra_pythonpath ); - for ( ; extra; extra = extra->next ) + iter = list_begin( extra ), end = list_end( extra ); + for ( ; iter != end; iter = list_next( iter ) ) { string buf[ 1 ]; string_new( buf ); string_append( buf, "import sys\nsys.path.append(\"" ); - string_append( buf, extra->string ); + string_append( buf, object_str( list_item( iter ) ) ); string_append( buf, "\")\n" ); PyRun_SimpleString( buf->value ); string_free( buf ); @@ -1840,12 +1840,7 @@ LIST * builtin_python_import_rule( PARSE * parse, FRAME * frame ) if ( pFunc && PyCallable_Check( pFunc ) ) { module_t * m = bindmodule( jam_module ); - RULE * r = bindrule( jam_rule, m ); - - /* Make pFunc owned. */ - Py_INCREF( pFunc ); - - r->python_function = pFunc; + new_rule_body( m, jam_rule, function_python( pFunc, 0 ), 0 ); } else { @@ -1866,7 +1861,7 @@ LIST * builtin_python_import_rule( PARSE * parse, FRAME * frame ) #endif -void lol_build( LOL * lol, char * * elements ) +void lol_build( LOL * lol, const char * * elements ) { LIST * l = L0; lol_init( lol ); @@ -1880,7 +1875,7 @@ void lol_build( LOL * lol, char * * elements ) } else { - l = list_new( l, newstr( *elements ) ); + l = list_push_back( l, object_new( *elements ) ); } ++elements; } @@ -1900,22 +1895,21 @@ void lol_build( LOL * lol, char * * elements ) PyObject* bjam_call( PyObject * self, PyObject * args ) { - FRAME inner[ 1 ]; - LIST * result; - PARSE * p; - char * rulename; + FRAME inner[ 1 ]; + LIST * result; + PARSE * p; + OBJECT * rulename; /* Build up the list of arg lists. */ frame_init( inner ); inner->prev = 0; inner->prev_user = 0; - inner->module = bindmodule( "python_interface" ); - inner->procedure = 0; + inner->module = bindmodule( constant_python_interface ); /* Extract the rule name and arguments from 'args'. */ /* PyTuple_GetItem returns borrowed reference. */ - rulename = PyString_AsString( PyTuple_GetItem( args, 0 ) ); + rulename = object_new( PyString_AsString( PyTuple_GetItem( args, 0 ) ) ); { int i = 1; int size = PyTuple_Size( args ); @@ -1924,7 +1918,7 @@ PyObject* bjam_call( PyObject * self, PyObject * args ) PyObject * a = PyTuple_GetItem( args, i ); if ( PyString_Check( a ) ) { - lol_add( inner->args, list_new( 0, newstr( + lol_add( inner->args, list_new( object_new( PyString_AsString( a ) ) ) ); } else if ( PySequence_Check( a ) ) @@ -1942,7 +1936,7 @@ PyObject* bjam_call( PyObject * self, PyObject * args ) printf( "Invalid parameter type passed from Python\n" ); exit( 1 ); } - l = list_new( l, newstr( s ) ); + l = list_push_back( l, object_new( s ) ); Py_DECREF( e ); } lol_add( inner->args, l ); @@ -1951,6 +1945,7 @@ PyObject* bjam_call( PyObject * self, PyObject * args ) } result = evaluate_rule( rulename, inner ); + object_free( rulename ); frame_free( inner ); @@ -1958,10 +1953,10 @@ PyObject* bjam_call( PyObject * self, PyObject * args ) { PyObject * pyResult = PyList_New( list_length( result ) ); int i = 0; - while ( result ) + LISTITER iter = list_begin( result ), end = list_end( result ); + for ( ; iter != end; iter = list_next( iter ) ) { - PyList_SetItem( pyResult, i, PyString_FromString( result->string ) ); - result = list_next( result ); + PyList_SetItem( pyResult, i, PyString_FromString( object_str( list_item( iter ) ) ) ); i += 1; } list_free( result ); @@ -1988,6 +1983,8 @@ PyObject * bjam_import_rule( PyObject * self, PyObject * args ) PyObject * bjam_signature = NULL; module_t * m; RULE * r; + OBJECT * module_name; + OBJECT * rule_name; if ( !PyArg_ParseTuple( args, "ssO|O:import_rule", &module, &rule, &func, &bjam_signature ) ) @@ -2000,29 +1997,15 @@ PyObject * bjam_import_rule( PyObject * self, PyObject * args ) return NULL; } - m = bindmodule( *module ? module : 0 ); - r = bindrule( rule, m ); - - /* Make pFunc owned. */ - Py_INCREF( func ); - - r->python_function = func; - r->arguments = 0; - - if (bjam_signature) + module_name = *module ? object_new( module ) : 0; + m = bindmodule( module_name ); + if( module_name ) { - argument_list * arg_list = args_new(); - Py_ssize_t i; - - Py_ssize_t s = PySequence_Size (bjam_signature); - for (i = 0; i < s; ++i) - { - PyObject* v = PySequence_GetItem (bjam_signature, i); - lol_add(arg_list->data, list_from_python (v)); - Py_DECREF(v); - } - r->arguments = arg_list; + object_free( module_name ); } + rule_name = object_new( rule ); + new_rule_body( m, rule_name, function_python( func, bjam_signature ), 0 ); + object_free( rule_name ); Py_INCREF( Py_None ); return Py_None; @@ -2048,6 +2031,8 @@ PyObject * bjam_define_action( PyObject * self, PyObject * args ) LIST * bindlist = L0; int n; int i; + OBJECT * name_str; + FUNCTION * body_func; if ( !PyArg_ParseTuple( args, "ssO!i:define_action", &name, &body, &PyList_Type, &bindlist_python, &flags ) ) @@ -2063,10 +2048,14 @@ PyObject * bjam_define_action( PyObject * self, PyObject * args ) "bind list has non-string type" ); return NULL; } - bindlist = list_new( bindlist, PyString_AsString( next ) ); + bindlist = list_push_back( bindlist, object_new( PyString_AsString( next ) ) ); } - new_rule_actions( root_module(), name, newstr( body ), bindlist, flags ); + name_str = object_new( name ); + body_func = function_compile_actions( body, constant_builtin, -1 ); + new_rule_actions( root_module(), name_str, body_func, bindlist, flags ); + function_free( body_func ); + object_free( name_str ); Py_INCREF( Py_None ); return Py_None; @@ -2083,17 +2072,20 @@ PyObject * bjam_variable( PyObject * self, PyObject * args ) LIST * value; PyObject * result; int i; + OBJECT * varname; + LISTITER iter, end; if ( !PyArg_ParseTuple( args, "s", &name ) ) return NULL; - enter_module( root_module() ); - value = var_get( name ); - exit_module( root_module() ); + varname = object_new( name ); + value = var_get( root_module(), varname ); + object_free( varname ); + iter = list_begin( value ), end = list_end( value ); result = PyList_New( list_length( value ) ); - for ( i = 0; value; value = list_next( value ), ++i ) - PyList_SetItem( result, i, PyString_FromString( value->string ) ); + for ( i = 0; iter != end; iter = list_next( iter ), ++i ) + PyList_SetItem( result, i, PyString_FromString( object_str( list_item( iter ) ) ) ); return result; } @@ -2106,19 +2098,28 @@ PyObject * bjam_backtrace( PyObject * self, PyObject * args ) for ( ; f = f->prev; ) { - PyObject * tuple = PyTuple_New( 4 ); - char * file; - int line; - char buf[ 32 ]; + PyObject * tuple = PyTuple_New( 4 ); + const char * file; + int line; + char buf[ 32 ]; + string module_name[1]; - get_source_line( f->procedure, &file, &line ); + get_source_line( f, &file, &line ); sprintf( buf, "%d", line ); + string_new( module_name ); + if ( f->module->name ) + { + string_append( module_name, object_str( f->module->name ) ); + string_append( module_name, "." ); + } /* PyTuple_SetItem steals reference. */ PyTuple_SetItem( tuple, 0, PyString_FromString( file ) ); PyTuple_SetItem( tuple, 1, PyString_FromString( buf ) ); - PyTuple_SetItem( tuple, 2, PyString_FromString( f->module->name ) ); - PyTuple_SetItem( tuple, 3, PyString_FromString( f->rulename ) ); + PyTuple_SetItem( tuple, 2, PyString_FromString( module_name->value ) ); + PyTuple_SetItem( tuple, 3, PyString_FromString( f->rulename ) ); + + string_free( module_name ); PyList_Append( result, tuple ); Py_DECREF( tuple ); @@ -2128,9 +2129,10 @@ PyObject * bjam_backtrace( PyObject * self, PyObject * args ) PyObject * bjam_caller( PyObject * self, PyObject * args ) { - PyObject *result = PyString_FromString( - frame_before_python_call->prev->module->name); - return result; + const char * s = frame_before_python_call->prev->module->name ? + object_str( frame_before_python_call->prev->module->name ) : + ""; + return PyString_FromString( s ); } #endif /* #ifdef HAVE_PYTHON */ @@ -2189,7 +2191,7 @@ PyObject * bjam_caller( PyObject * self, PyObject * args ) * should Windows ever 'fix' this feature. * (03.06.2008.) (Jurko) */ - static FILE * windows_popen_wrapper( char * command, char * mode ) + static FILE * windows_popen_wrapper( const char * command, const char * mode ) { int extra_command_quotes_needed = ( strchr( command, '"' ) != 0 ); string quoted_command; @@ -2214,18 +2216,18 @@ PyObject * bjam_caller( PyObject * self, PyObject * args ) #endif -static char * rtrim(char *s) +static char * rtrim( char * s ) { - char *p = s; - while(*p) ++p; - for(--p; p >= s && isspace(*p); *p-- = 0); + char * p = s; + while ( *p ) ++p; + for ( --p; p >= s && isspace( *p ); *p-- = 0 ); return s; } -LIST * builtin_shell( PARSE * parse, FRAME * frame ) +LIST * builtin_shell( FRAME * frame, int flags ) { LIST * command = lol_get( frame->args, 0 ); - LIST * result = 0; + LIST * result = L0; string s; int ret; char buffer[ 1024 ]; @@ -2239,17 +2241,17 @@ LIST * builtin_shell( PARSE * parse, FRAME * frame ) { int a = 1; LIST * arg = lol_get( frame->args, a ); - while ( arg ) + while ( !list_empty( arg ) ) { - if ( strcmp( "exit-status", arg->string ) == 0 ) + if ( strcmp( "exit-status", object_str( list_front( arg ) ) ) == 0 ) { exit_status_opt = 1; } - else if ( strcmp( "no-output", arg->string ) == 0 ) + else if ( strcmp( "no-output", object_str( list_front( arg ) ) ) == 0 ) { no_output_opt = 1; } - else if ( strcmp("strip-eol", arg->string) == 0 ) + else if ( strcmp("strip-eol", object_str( list_front( arg ) ) ) == 0 ) { strip_eol_opt = 1; } @@ -2263,7 +2265,7 @@ LIST * builtin_shell( PARSE * parse, FRAME * frame ) */ fflush( NULL ); - p = popen( command->string, "r" ); + p = popen( object_str( list_front( command ) ), "r" ); if ( p == NULL ) return L0; @@ -2283,7 +2285,7 @@ LIST * builtin_shell( PARSE * parse, FRAME * frame ) exit_status = pclose( p ); /* The command output is returned first. */ - result = list_new( L0, newstr( s.value ) ); + result = list_new( object_new( s.value ) ); string_free( &s ); /* The command exit result next. */ @@ -2294,7 +2296,7 @@ LIST * builtin_shell( PARSE * parse, FRAME * frame ) else exit_status = -1; sprintf( buffer, "%d", exit_status ); - result = list_new( result, newstr( buffer ) ); + result = list_push_back( result, object_new( buffer ) ); } return result; @@ -2302,7 +2304,7 @@ LIST * builtin_shell( PARSE * parse, FRAME * frame ) #else /* #ifdef HAVE_POPEN */ -LIST * builtin_shell( PARSE * parse, FRAME * frame ) +LIST * builtin_shell( FRAME * frame, int flags ) { return L0; } |