Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r77408 - in trunk/tools/build/v2/engine: . modules
From: steven_at_[hidden]
Date: 2012-03-19 14:17:40


Author: steven_watanabe
Date: 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
New Revision: 77408
URL: http://svn.boost.org/trac/boost/changeset/77408

Log:
Use dynamic arrays instead of linked lists. Reduces memory use about 10% overall.
Text files modified:
   trunk/tools/build/v2/engine/builtins.c | 293 ++++++++++++++++++---------------
   trunk/tools/build/v2/engine/class.c | 23 +-
   trunk/tools/build/v2/engine/command.c | 3
   trunk/tools/build/v2/engine/compile.c | 78 ++++----
   trunk/tools/build/v2/engine/execnt.c | 13
   trunk/tools/build/v2/engine/execunix.c | 9
   trunk/tools/build/v2/engine/filent.c | 10
   trunk/tools/build/v2/engine/filesys.c | 12
   trunk/tools/build/v2/engine/fileunix.c | 9
   trunk/tools/build/v2/engine/function.c | 266 +++++++++++++++++-------------
   trunk/tools/build/v2/engine/hcache.c | 57 +++---
   trunk/tools/build/v2/engine/headers.c | 17 +
   trunk/tools/build/v2/engine/jam.c | 19 +-
   trunk/tools/build/v2/engine/lists.c | 345 +++++++++++++++++++++++++--------------
   trunk/tools/build/v2/engine/lists.h | 17 +
   trunk/tools/build/v2/engine/make.c | 8
   trunk/tools/build/v2/engine/make1.c | 51 +++--
   trunk/tools/build/v2/engine/modules.c | 6
   trunk/tools/build/v2/engine/modules/order.c | 29 +-
   trunk/tools/build/v2/engine/modules/path.c | 4
   trunk/tools/build/v2/engine/modules/property-set.c | 17 +
   trunk/tools/build/v2/engine/modules/regex.c | 16 +
   trunk/tools/build/v2/engine/modules/sequence.c | 18 +
   trunk/tools/build/v2/engine/modules/set.c | 9
   trunk/tools/build/v2/engine/rules.c | 7
   trunk/tools/build/v2/engine/search.c | 22 +-
   trunk/tools/build/v2/engine/subst.c | 15
   trunk/tools/build/v2/engine/variable.c | 10
   trunk/tools/build/v2/engine/w32_getreg.c | 10
   29 files changed, 796 insertions(+), 597 deletions(-)

Modified: trunk/tools/build/v2/engine/builtins.c
==============================================================================
--- trunk/tools/build/v2/engine/builtins.c (original)
+++ trunk/tools/build/v2/engine/builtins.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -432,7 +432,7 @@
 {
     LIST * arg = lol_get( frame->args, 0 );
 
- LIST * result = 0;
+ LIST * result = L0;
     long lhs_value;
     long rhs_value;
     long result_value;
@@ -440,17 +440,18 @@
     char const * lhs;
     char const * op;
     char const * rhs;
+ LISTITER iter = list_begin( arg ), end = list_end( arg );
 
- if ( arg == 0 ) return L0;
- lhs = object_str( arg->value );
+ if ( iter == end ) return L0;
+ lhs = object_str( list_item( iter ) );
 
- arg = list_next( arg );
- if ( arg == 0 ) return L0;
- op = object_str( arg->value );
-
- arg = list_next( arg );
- if ( arg == 0 ) return L0;
- rhs = object_str( arg->value );
+ iter = list_next( iter );
+ if ( iter == end ) return L0;
+ op = object_str( list_item( iter ) );
+
+ iter = list_next( iter );
+ if ( iter == end ) return L0;
+ rhs = object_str( list_item( iter ) );
 
     lhs_value = atoi( lhs );
     rhs_value = atoi( rhs );
@@ -486,11 +487,12 @@
 {
     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->value );
+ TARGET * t = bindtarget( list_item( iter ) );
 
         /* If doing INCLUDES, switch to the TARGET's include */
         /* TARGET, creating it if needed. The internal include */
@@ -510,9 +512,10 @@
     }
 
     /* 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->value );
+ TARGET * s = bindtarget( list_item( iter ) );
         s->dependants = targetlist( s->dependants, targets );
     }
 
@@ -532,11 +535,11 @@
 {
     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->value );
+ TARGET * t = bindtarget( list_item( iter ) );
         t->rebuilds = targetlist( t->rebuilds, rebuilds );
     }
 
@@ -569,11 +572,12 @@
 
 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( object_str( lol_get( frame->args, 1 )->value ) ) );
+ exit( atoi( object_str( list_front( code ) ) ) );
     }
     else
     {
@@ -593,8 +597,9 @@
 LIST * builtin_flags( FRAME * frame, int flags )
 {
     LIST * l = lol_get( frame->args, 0 );
- for ( ; l; l = list_next( l ) )
- bindtarget( l->value )->flags |= flags;
+ LISTITER iter = list_begin( l ), end = list_end( l );
+ for ( ; iter != end; iter = list_next( iter ) )
+ bindtarget( list_item( iter ) )->flags |= flags;
     return L0;
 }
 
@@ -632,6 +637,7 @@
     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.
@@ -656,9 +662,10 @@
     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( object_str( l->value ), buf->value ) )
+ if ( !glob( object_str( list_item( iter ) ), buf->value ) )
         {
             globbing->results = list_new( globbing->results, object_copy( file ) );
             break;
@@ -673,17 +680,17 @@
 
 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, object_str( in->value ) );
+ string_copy( s, object_str( list_item( iter ) ) );
         downcase_inplace( s->value );
- result = list_append( result, list_new( 0, object_new( s->value ) ) );
- in = in->next;
+ result = list_append( result, list_new( L0, object_new( s->value ) ) );
     }
 
     string_free( s );
@@ -696,6 +703,7 @@
     LIST * l = lol_get( frame->args, 0 );
     LIST * r = lol_get( frame->args, 1 );
 
+ LISTITER iter, end;
     struct globbing globbing;
 
     globbing.results = L0;
@@ -711,8 +719,9 @@
     if ( globbing.case_insensitive )
         globbing.patterns = downcase_list( r );
 
- for ( ; l; l = list_next( l ) )
- file_dirscan( l->value, 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 );
@@ -812,24 +821,24 @@
 
             if ( has_wildcards( basename->value ) )
             {
- LIST * d;
                 OBJECT * b = object_new( basename->value );
- for ( d = dirs ; d; d = d->next )
- result = list_append( result, glob1( d->value, b ) );
+ 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
             {
- LIST * d;
+ LISTITER iter = list_begin( dirs ), end = list_end( dirs );
                 string file_string[ 1 ];
                 string_new( file_string );
 
                 /* No wildcard in basename. */
- for ( d = dirs ; d; d = d->next )
+ for ( ; iter != end; iter = list_next( iter ) )
                 {
                     OBJECT * p;
- path->f_dir.ptr = object_str( d->value );
- path->f_dir.len = strlen( object_str( d->value ) );
+ 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 );
 
                     p = object_new( file_string->value );
@@ -866,8 +875,9 @@
 {
     LIST * result = L0;
     LIST * l = lol_get( frame->args, 0 );
- for ( ; l; l = l->next )
- result = list_append( result, glob_recursive( object_str( l->value ) ) );
+ 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;
 }
 
@@ -880,22 +890,27 @@
 {
     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->value );
+ 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, object_str( r->value ) ) )
+ if ( regexec( re, object_str( list_item( r_iter ) ) ) )
             {
                 int i;
                 int top;
@@ -931,10 +946,10 @@
     
     string buf[ 1 ];
 
- const char * delimiters = object_str( l2->value );
+ const char * delimiters = object_str( list_front( l2 ) );
     char * t;
 
- string_copy( buf, object_str( l1->value ) );
+ string_copy( buf, object_str( list_front( l1 ) ) );
 
     t = strtok( buf->value, delimiters) ;
     while ( t )
@@ -951,15 +966,16 @@
 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->value );
+ 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",
- object_str( l->value ) );
+ object_str( list_item( iter ) ) );
 
     macro_headers( t );
   }
@@ -988,7 +1004,7 @@
 {
     LIST * arg0 = lol_get( frame->args, 0 );
     LIST * result = L0;
- module_t * source_module = bindmodule( arg0 ? arg0->value : 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 );
@@ -1017,7 +1033,7 @@
 {
     LIST * arg0 = lol_get( frame->args, 0 );
     LIST * result = L0;
- module_t * source_module = bindmodule( arg0 ? arg0->value : 0 );
+ module_t * source_module = bindmodule( !list_empty(arg0) ? list_front(arg0) : 0 );
 
     struct hash * vars = source_module->variables;
 
@@ -1037,7 +1053,7 @@
 {
     LIST * arg0 = lol_get( frame->args, 0 );
     LIST * result = L0;
- module_t * source_module = bindmodule( arg0 ? arg0->value : 0 );
+ module_t * source_module = bindmodule( !list_empty(arg0) ? list_front(arg0) : 0 );
     delete_module( source_module );
     return result;
 }
@@ -1090,27 +1106,27 @@
     LIST * localize = lol_get( frame->args, 4 );
 
     module_t * target_module =
- bindmodule( target_module_list ? target_module_list->value : 0 );
+ bindmodule( !list_empty( target_module_list ) ? list_front( target_module_list ) : 0 );
     module_t * source_module =
- bindmodule( source_module_list ? source_module_list->value : 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 * imported;
 
         if ( !source_module->rules ||
- !(r = (RULE *)hash_find( source_module->rules, source_name->value ) ) )
- unknown_rule( frame, "IMPORT", source_module, source_name->value );
+ !(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->value );
- if ( localize )
+ imported = import_rule( r, target_module, list_item( target_iter ) );
+ if ( !list_empty( localize ) )
             imported->module = target_module;
         /* This rule is really part of some other module. Just refer to it here,
          * but do not let it out.
@@ -1118,7 +1134,7 @@
         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" );
@@ -1147,14 +1163,15 @@
 {
     LIST * module_list = lol_get( frame->args, 0 );
     LIST * rules = lol_get( frame->args, 1 );
- module_t * m = bindmodule( module_list ? module_list->value : 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;
 
- if ( !m->rules || !(r = (RULE *)hash_find( m->rules, rules->value ) ) )
- unknown_rule( frame, "EXPORT", m, rules->value );
+ if ( !m->rules || !(r = (RULE *)hash_find( m->rules, list_item( iter ) ) ) )
+ unknown_rule( frame, "EXPORT", m, list_item( iter ) );
 
         r->exported = 1;
     }
@@ -1244,7 +1261,7 @@
 LIST * builtin_backtrace( FRAME * frame, int flags )
 {
     LIST * levels_arg = lol_get( frame->args, 0 );
- int levels = levels_arg ? atoi( object_str( levels_arg->value ) ) : (int)( (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 )
@@ -1286,7 +1303,7 @@
 LIST * builtin_caller_module( FRAME * frame, int flags )
 {
     LIST * levels_arg = lol_get( frame->args, 0 );
- int levels = levels_arg ? atoi( object_str( levels_arg->value ) ) : 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 )
@@ -1319,9 +1336,10 @@
 {
     LIST * result = list_copy( L0, 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( object_copy( arg1->value ) );
+ for ( ; iter != end; iter = list_next( iter ) )
+ mark_target_for_updating( object_copy( list_item( iter ) ) );
     return result;
 }
 
@@ -1350,11 +1368,12 @@
     int i;
     int original_noexec = 0;
     int original_quitquick = 0;
+ LISTITER iter, end;
         
 
- if ( log )
+ if ( !list_empty( log ) )
     {
- int fd = atoi( object_str( log->value ) );
+ 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 );
@@ -1362,7 +1381,7 @@
         dup2 ( fd, 1 );
     }
 
- if ( force )
+ if ( !list_empty( force ) )
     {
         original_noexec = globs.noexec;
         globs.noexec = 0;
@@ -1370,7 +1389,7 @@
         globs.quitquick = 0;
     }
 
- if ( continue_ )
+ if ( !list_empty( continue_ ) )
     {
         original_quitquick = globs.quitquick;
         globs.quitquick = 0;
@@ -1378,23 +1397,24 @@
 
     targets_count = list_length( targets );
     targets2 = (OBJECT * *)BJAM_MALLOC( targets_count * sizeof( OBJECT * ) );
- for (i = 0 ; targets; targets = list_next( targets ) )
- targets2[ i++ ] = targets->value;
+ iter = list_begin( targets ), end = list_end( targets );
+ for (i = 0 ; iter != end; iter = list_next( iter ) )
+ targets2[ i++ ] = list_item( iter );
     status |= make( targets_count, targets2, anyhow);
     BJAM_FREE( (void *)targets2 );
 
- 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. */
@@ -1419,7 +1439,7 @@
 {
     LIST * arg1 = lol_get( frame->args, 0 );
     LIST * arg2 = lol_get( frame->args, 1 );
- module_t * m = arg2 ? bindmodule( arg2->value ) : root_module();
+ module_t * m = !list_empty( arg2 ) ? bindmodule( list_front( arg2 ) ) : root_module();
     import_module( arg1, m );
     return L0;
 }
@@ -1428,7 +1448,7 @@
 LIST * builtin_imported_modules( FRAME * frame, int flags )
 {
     LIST * arg0 = lol_get( frame->args, 0 );
- return imported_modules( bindmodule( arg0 ? arg0->value : 0 ) );
+ return imported_modules( bindmodule( !list_empty( arg0 ) ? list_front( arg0 ) : 0 ) );
 }
 
 
@@ -1436,8 +1456,8 @@
 {
     LIST * arg1 = lol_get( frame->args, 0 );
     LIST * arg2 = lol_get( frame->args, 1 );
- module_t * const instance = bindmodule( arg1->value );
- module_t * const class_module = bindmodule( arg2->value );
+ module_t * const instance = bindmodule( list_front( arg1 ) );
+ module_t * const class_module = bindmodule( list_front( arg2 ) );
     instance->class_module = class_module;
     return L0;
 }
@@ -1471,6 +1491,7 @@
     int dotdots = 0;
     int rooted = 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
@@ -1478,16 +1499,16 @@
      */
     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 ( object_str( arg->value )[ 0 ] != '\0' )
+ if ( object_str( list_item( arg_iter ) )[ 0 ] != '\0' )
         {
             if ( in->size == 1 )
- rooted = ( ( object_str( arg->value )[ 0 ] == '/' ) ||
- ( object_str( arg->value )[ 0 ] == '\\' ) );
+ rooted = ( ( object_str( list_item( arg_iter ) )[ 0 ] == '/' ) ||
+ ( object_str( list_item( arg_iter ) )[ 0 ] == '\\' ) );
             else
                 string_append( in, "/" );
- string_append( in, object_str( arg->value ) );
+ string_append( in, object_str( list_item( arg_iter ) ) );
         }
     }
 
@@ -1568,7 +1589,7 @@
     string_free( out );
     string_free( in );
 
- return list_new( 0, result );
+ return list_new( L0, result );
 }
 
 
@@ -1577,10 +1598,10 @@
     LIST * module_name = lol_get( frame->args, 0 );
     LIST * rule_name = lol_get( frame->args, 1 );
 
- module_t * module = bindmodule( module_name->value );
+ module_t * module = bindmodule( list_front( module_name ) );
 
     native_rule_t * np;
- if ( module->native_rules && (np = (native_rule_t *)hash_find( module->native_rules, rule_name->value ) ) )
+ if ( module->native_rules && (np = (native_rule_t *)hash_find( module->native_rules, list_front( rule_name ) ) ) )
     {
         args_refer( np->arguments );
         new_rule_body( module, np->name, np->arguments, np->procedure, 1 );
@@ -1589,7 +1610,7 @@
     {
         backtrace_line( frame->prev );
         printf( "error: no native rule \"%s\" defined in module \"%s.\"\n",
- object_str( rule_name->value ), object_str( module->name ) );
+ object_str( list_front( rule_name ) ), object_str( module->name ) );
         backtrace( frame->prev );
         exit( 1 );
     }
@@ -1603,14 +1624,14 @@
     LIST * rule_name = lol_get( frame->args, 1 );
     LIST * version = lol_get( frame->args, 2 );
 
- module_t * module = bindmodule( module_name->value );
+ module_t * module = bindmodule( list_front( module_name ) );
 
     native_rule_t * np;
- if ( module->native_rules && (np = (native_rule_t *)hash_find( module->native_rules, rule_name->value ) ) )
+ if ( module->native_rules && (np = (native_rule_t *)hash_find( module->native_rules, list_front( rule_name ) ) ) )
     {
- int expected_version = atoi( object_str( version->value ) );
+ int expected_version = atoi( object_str( list_front( version ) ) );
         if ( np->version == expected_version )
- return list_new( 0, object_copy( constant_true ) );
+ return list_new( L0, object_copy( constant_true ) );
     }
     return L0;
 }
@@ -1619,9 +1640,10 @@
 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->value );
+ module_t * m = bindmodule( list_item( iter ) );
         m->user_module = 1;
     }
     return L0;
@@ -1636,7 +1658,7 @@
         return L0;
 
     {
- LIST * result = 0;
+ LIST * result = L0;
         const char * file;
         int line;
         char buf[32];
@@ -1653,8 +1675,8 @@
 LIST * builtin_check_if_file( FRAME * frame, int flags )
 {
     LIST * name = lol_get( frame->args, 0 );
- return file_is_file( name->value ) == 1
- ? list_new( 0, object_copy( constant_true ) )
+ return file_is_file( list_front( name ) ) == 1
+ ? list_new( L0, object_copy( constant_true ) )
         : L0 ;
 }
 
@@ -1662,7 +1684,7 @@
 LIST * builtin_md5( FRAME * frame, int flags )
 {
     LIST * l = lol_get( frame->args, 0 );
- const char* s = object_str( l->value );
+ const char* s = object_str( list_front( l ) );
 
     md5_state_t state;
     md5_byte_t digest[16];
@@ -1682,8 +1704,8 @@
 
 LIST *builtin_file_open( FRAME * frame, int flags )
 {
- const char * name = object_str( lol_get( frame->args, 0 )->value );
- const char * mode = object_str( lol_get( frame->args, 1 )->value );
+ 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")];
 
@@ -1709,8 +1731,8 @@
 
 LIST *builtin_pad( FRAME * frame, int flags )
 {
- OBJECT * string = lol_get( frame->args, 0 )->value;
- const char * width_s = object_str( lol_get( frame->args, 1 )->value );
+ 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( object_str( string ) );
     int desired = atoi( width_s );
@@ -1736,9 +1758,10 @@
 {
     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->value );
+ TARGET* t = bindtarget( list_item( iter ) );
         t->flags |= T_FLAG_PRECIOUS;
     }
 
@@ -1751,7 +1774,7 @@
     char * p = executable_path( saved_argv0 );
     if ( p )
     {
- LIST* result = list_new( 0, object_new( p ) );
+ LIST* result = list_new( L0, object_new( p ) );
         free( p );
         return result;
     }
@@ -1765,9 +1788,9 @@
 {
     LIST * path = lol_get( frame->args, 0 );
 
- if ( file_mkdir( object_str( path->value ) ) == 0 )
+ if ( file_mkdir( object_str( list_front( path ) ) ) == 0 )
     {
- LIST * result = list_new ( L0, object_copy( path->value ) );
+ LIST * result = list_new ( L0, object_copy( list_front( path ) ) );
         return result;
     }
     else
@@ -1781,10 +1804,10 @@
 LIST * builtin_python_import_rule( FRAME * frame, int flags )
 {
     static int first_time = 1;
- const char * python_module = object_str( lol_get( frame->args, 0 )->value );
- const char * python_function = object_str( lol_get( frame->args, 1 )->value );
- OBJECT * jam_module = lol_get( frame->args, 2 )->value;
- OBJECT * jam_rule = lol_get( frame->args, 3 )->value;
+ 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;
@@ -1798,17 +1821,19 @@
          */
         LIST * extra = 0;
         module_t * outer_module = frame->module;
+ LISTITER iter, end;
 
         first_time = 0;
 
         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, object_str( extra->value ) );
+ string_append( buf, object_str( list_item( iter ) ) );
             string_append( buf, "\")\n" );
             PyRun_SimpleString( buf->value );
             string_free( buf );
@@ -1945,10 +1970,10 @@
     {
         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( object_str( result->value ) ) );
- result = list_next( result );
+ PyList_SetItem( pyResult, i, PyString_FromString( object_str( list_item( iter ) ) ) );
             i += 1;
         }
         list_free( result );
@@ -2086,6 +2111,7 @@
     PyObject * result;
     int i;
     OBJECT * varname;
+ LISTITER iter, end;
 
     if ( !PyArg_ParseTuple( args, "s", &name ) )
         return NULL;
@@ -2093,10 +2119,11 @@
     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( object_str( value->value ) ) );
+ for ( i = 0; iter != end; iter = list_next( iter ), ++i )
+ PyList_SetItem( result, i, PyString_FromString( object_str( list_item( iter ) ) ) );
 
     return result;
 }
@@ -2238,7 +2265,7 @@
 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 ];
@@ -2252,17 +2279,17 @@
     {
         int a = 1;
         LIST * arg = lol_get( frame->args, a );
- while ( arg )
+ while ( !list_empty( arg ) )
         {
- if ( strcmp( "exit-status", object_str( arg->value ) ) == 0 )
+ if ( strcmp( "exit-status", object_str( list_front( arg ) ) ) == 0 )
             {
                 exit_status_opt = 1;
             }
- else if ( strcmp( "no-output", object_str( arg->value ) ) == 0 )
+ else if ( strcmp( "no-output", object_str( list_front( arg ) ) ) == 0 )
             {
                 no_output_opt = 1;
             }
- else if ( strcmp("strip-eol", object_str( arg->value ) ) == 0 )
+ else if ( strcmp("strip-eol", object_str( list_front( arg ) ) ) == 0 )
             {
                 strip_eol_opt = 1;
             }
@@ -2276,7 +2303,7 @@
      */
     fflush( NULL );
 
- p = popen( object_str( command->value ), "r" );
+ p = popen( object_str( list_front( command ) ), "r" );
     if ( p == NULL )
         return L0;
 

Modified: trunk/tools/build/v2/engine/class.c
==============================================================================
--- trunk/tools/build/v2/engine/class.c (original)
+++ trunk/tools/build/v2/engine/class.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -17,11 +17,12 @@
 
 static void check_defined( LIST * class_names )
 {
- for ( ; class_names; class_names = class_names->next )
+ LISTITER iter = list_begin( class_names ), end = list_end( class_names );
+ for ( ; iter != end; iter = list_next( iter ) )
     {
- if ( !hash_find( classes, class_names->value ) )
+ if ( !hash_find( classes, list_item( iter ) ) )
         {
- printf( "Class %s is not defined\n", object_str( class_names->value ) );
+ printf( "Class %s is not defined\n", object_str( list_item( iter ) ) );
             abort();
         }
     }
@@ -113,23 +114,24 @@
 
 OBJECT * make_class_module( LIST * xname, LIST * bases, FRAME * frame )
 {
- OBJECT * name = class_module_name( xname->value );
- OBJECT * * pp = &xname->value;
+ OBJECT * name = class_module_name( list_front( xname ) );
+ OBJECT * * pp;
     module_t * class_module = 0;
     module_t * outer_module = frame->module;
     int found;
+ LISTITER iter, end;
 
     if ( !classes )
         classes = hashinit( sizeof( OBJECT * ), "classes" );
 
- pp = (OBJECT * *)hash_insert( classes, xname->value, &found );
+ pp = (OBJECT * *)hash_insert( classes, list_front( xname ), &found );
     if ( !found )
     {
- *pp = object_copy( xname->value );
+ *pp = object_copy( list_front( xname ) );
     }
     else
     {
- printf( "Class %s already defined\n", object_str( xname->value ) );
+ printf( "Class %s already defined\n", object_str( list_front( xname ) ) );
         abort();
     }
     check_defined( bases );
@@ -139,8 +141,9 @@
     var_set( class_module, constant_name, xname, VAR_SET );
     var_set( class_module, constant_bases, bases, VAR_SET );
 
- for ( ; bases; bases = bases->next )
- import_base_rules( class_module, bases->value );
+ iter = list_begin( bases ), end = list_end( bases );
+ for ( ; iter != end; iter = list_next( iter ) )
+ import_base_rules( class_module, list_item( iter ) );
 
     return name;
 }

Modified: trunk/tools/build/v2/engine/command.c
==============================================================================
--- trunk/tools/build/v2/engine/command.c (original)
+++ trunk/tools/build/v2/engine/command.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -33,8 +33,9 @@
 CMD * cmd_new( RULE * rule, LIST * targets, LIST * sources, LIST * shell )
 {
     CMD * cmd = (CMD *)BJAM_MALLOC( sizeof( CMD ) );
+ LISTITER iter = list_begin( shell ), end = list_end( shell );
     /* Lift line-length limitation entirely when JAMSHELL is just "%". */
- int no_limit = ( shell && !strcmp(object_str(shell->value),"%") && !list_next(shell) );
+ int no_limit = ( iter != end && !strcmp( object_str( list_item( iter ) ), "%") && list_next( iter ) == end );
     int max_line = MAXLINE;
     FRAME frame[1];
 

Modified: trunk/tools/build/v2/engine/compile.c
==============================================================================
--- trunk/tools/build/v2/engine/compile.c (original)
+++ trunk/tools/build/v2/engine/compile.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -115,7 +115,7 @@
 }
 
 
-static void argument_error( const char * message, RULE * rule, FRAME * frame, LIST * arg )
+static void argument_error( const char * message, RULE * rule, FRAME * frame, OBJECT * arg )
 {
     LOL * actual = frame->args;
     assert( rule->procedure != 0 );
@@ -124,7 +124,7 @@
     lol_print( rule->arguments->data );
     printf( " )\n* called with: ( " );
     lol_print( actual );
- printf( " )\n* %s %s\n", message, arg ? object_str ( arg->value ) : "" );
+ printf( " )\n* %s %s\n", message, arg ? object_str ( arg ) : "" );
     function_location( rule->procedure, &frame->file, &frame->line );
     print_source_line( frame );
     printf( "see definition of rule '%s' being called\n", object_str( rule->name ) );
@@ -157,11 +157,12 @@
  * lists.
  */
 
-static char arg_modifier( LIST * formal )
+static char arg_modifier( LISTITER iter, LISTITER end )
 {
- if ( formal->next )
+ iter = list_next( iter );
+ if ( iter != end )
     {
- const char * next = object_str( formal->next->value );
+ const char * next = object_str( list_item( iter ) );
         if ( next && ( next[ 0 ] != 0 ) && ( next[ 1 ] == 0 ) )
             return next[ 0 ];
     }
@@ -188,10 +189,11 @@
     LIST * values,
     FRAME * caller,
     RULE * called,
- LIST * arg_name
+ OBJECT * arg_name
 )
 {
     static module_t * typecheck = 0;
+ LISTITER iter, end;
 
     /* If nothing to check, bail now. */
     if ( !values || !type_name )
@@ -206,7 +208,7 @@
     if ( !typecheck->rules || !hash_find( typecheck->rules, type_name ) )
         return;
 
- while ( values != 0 )
+ for ( iter = list_begin( values ), end = list_end( values ); iter != end; iter = list_next( iter ) )
     {
         LIST *error;
         FRAME frame[1];
@@ -216,14 +218,13 @@
         frame->prev_user = caller->module->user_module ? caller : caller->prev_user;
 
         /* Prepare the argument list */
- lol_add( frame->args, list_new( L0, object_copy( values->value ) ) );
+ lol_add( frame->args, list_new( L0, object_copy( list_item( iter ) ) ) );
         error = evaluate_rule( type_name, frame );
 
- if ( error )
- argument_error( object_str( error->value ), called, caller, arg_name );
+ if ( !list_empty( error ) )
+ argument_error( object_str( list_front( error ) ), called, caller, arg_name );
 
         frame_free( frame );
- values = values->next;
     }
 }
 
@@ -250,55 +251,59 @@
             OBJECT * type_name = 0;
 
             LIST *formal;
- for ( formal = lol_get( all_formal, n ); formal; formal = formal->next )
+ LISTITER formal_iter, formal_end;
+ LISTITER actual_iter = list_begin( actual ), actual_end = list_end( actual );
+ for ( formal = lol_get( all_formal, n ),
+ formal_iter = list_begin( formal ), formal_end = list_end( formal );
+ formal_iter != formal_end; formal_iter = list_next( formal_iter ) )
             {
- OBJECT * name = formal->value;
+ OBJECT * name = list_item( formal_iter );
 
                 if ( is_type_name( object_str( name ) ) )
                 {
                     if ( type_name )
- argument_error( "missing argument name before type name:", rule, frame, formal );
+ argument_error( "missing argument name before type name:", rule, frame, name );
 
- if ( !formal->next )
- argument_error( "missing argument name after type name:", rule, frame, formal );
+ if ( list_next( formal_iter ) == formal_end )
+ argument_error( "missing argument name after type name:", rule, frame, name );
 
- type_name = formal->value;
+ type_name = name;
                 }
                 else
                 {
- LIST* value = 0;
+ LIST* value = L0;
                     char modifier;
- LIST* arg_name = formal; /* hold the argument name for type checking */
+ OBJECT* arg_name = list_item( formal_iter ); /* hold the argument name for type checking */
                     int multiple = 0;
 
                     /* Stop now if a variable number of arguments are specified */
                     if ( object_str( name )[0] == '*' && object_str( name )[1] == 0 )
                         return locals;
 
- modifier = arg_modifier( formal );
+ modifier = arg_modifier( formal_iter, formal_end );
 
- if ( !actual && modifier != '?' && modifier != '*' )
- argument_error( "missing argument", rule, frame, formal );
+ if ( actual_iter == actual_end && modifier != '?' && modifier != '*' )
+ argument_error( "missing argument", rule, frame, name );
 
                     switch ( modifier )
                     {
                     case '+':
                     case '*':
- value = list_copy( 0, actual );
+ value = list_copy_range( actual, actual_iter, actual_end );
                         multiple = 1;
- actual = 0;
+ actual_iter = actual_end;
                         /* skip an extra element for the modifier */
- formal = formal->next;
+ formal_iter = list_next( formal_iter );
                         break;
                     case '?':
                         /* skip an extra element for the modifier */
- formal = formal->next;
+ formal_iter = list_next( formal_iter );
                         /* fall through */
                     default:
- if ( actual ) /* in case actual is missing */
+ if ( actual_iter != actual_end ) /* in case actual is missing */
                         {
- value = list_new( 0, object_copy( actual->value ) );
- actual = actual->next;
+ value = list_new( L0, object_copy( list_item( actual_iter ) ) );
+ actual_iter = list_next( actual_iter );
                         }
                     }
 
@@ -309,9 +314,9 @@
                 }
             }
 
- if ( actual )
+ if ( actual_iter != actual_end )
             {
- argument_error( "extra argument", rule, frame, actual );
+ argument_error( "extra argument", rule, frame, list_item( actual_iter ) );
             }
         }
     }
@@ -386,8 +391,8 @@
             if (args->multiple)
                 value = list_to_python(args->value);
             else {
- if (args->value)
- value = PyString_FromString(object_str(args->value->value));
+ if (!list_empty(args->value))
+ value = PyString_FromString(object_str(list_front(args->value)));
             }
 
             if (value)
@@ -403,10 +408,11 @@
         {
             PyObject * arg = PyList_New(0);
             LIST* l = lol_get( frame->args, i);
+ LISTITER iter = list_begin( l ), end = list_end( l );
             
- for ( ; l; l = l->next )
+ for ( ; iter != end; iter = list_next( iter ) )
             {
- PyObject * v = PyString_FromString(object_str(l->value));
+ PyObject * v = PyString_FromString(object_str(list_item(iter)));
                 PyList_Append( arg, v );
                 Py_DECREF(v);
             }
@@ -446,7 +452,7 @@
         {
             OBJECT *s = python_to_string(py_result);
             if (s)
- result = list_new(0, s);
+ result = list_new(L0, s);
             else
                 /* We have tried all we could. Return empty list. There are
                    cases, e.g. feature.feature function that should return

Modified: trunk/tools/build/v2/engine/execnt.c
==============================================================================
--- trunk/tools/build/v2/engine/execnt.c (original)
+++ trunk/tools/build/v2/engine/execnt.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -220,7 +220,7 @@
      * for a JAMSHELL setting of "%", indicating that the command should be
      * invoked directly.
      */
- if ( shell && !strcmp( object_str( shell->value ), "%" ) && !list_next( shell ) )
+ if ( !list_empty( shell ) && !strcmp( object_str( list_front( shell ) ), "%" ) && list_next( list_begin( shell ) ) == list_end( shell ) )
     {
         raw_cmd = 1;
         shell = 0;
@@ -290,8 +290,8 @@
 
         if ( DEBUG_EXECCMD )
         {
- if ( shell )
- printf( "using user-specified shell: %s", object_str( shell->value ) );
+ if ( !list_empty( shell ) )
+ printf( "using user-specified shell: %s", object_str( list_front( shell ) ) );
             else
                 printf( "Executing through .bat file\n" );
         }
@@ -305,16 +305,17 @@
         int i;
         char jobno[ 4 ];
         int gotpercent = 0;
+ LISTITER shell_iter = list_begin( shell ), shell_end = list_end( shell );
 
         sprintf( jobno, "%d", slot + 1 );
 
- for ( i = 0; shell && ( i < MAXARGC ); ++i, shell = list_next( shell ) )
+ for ( i = 0; shell_iter != shell_end && ( i < MAXARGC ); ++i, shell_iter = list_next( shell_iter ) )
         {
- switch ( object_str( shell->value )[ 0 ] )
+ switch ( object_str( list_item( shell_iter ) )[ 0 ] )
             {
                 case '%': argv[ i ] = command; ++gotpercent; break;
                 case '!': argv[ i ] = jobno; break;
- default : argv[ i ] = object_str( shell->value );
+ default : argv[ i ] = object_str( list_item( shell_iter ) );
             }
             if ( DEBUG_EXECCMD )
                 printf( "argv[%d] = '%s'\n", i, argv[ i ] );

Modified: trunk/tools/build/v2/engine/execunix.c
==============================================================================
--- trunk/tools/build/v2/engine/execunix.c (original)
+++ trunk/tools/build/v2/engine/execunix.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -140,21 +140,22 @@
     /* Forumulate argv. If shell was defined, be prepared for % and ! subs.
      * Otherwise, use stock /bin/sh on unix or cmd.exe on NT.
      */
- if ( shell )
+ if ( !list_empty( shell ) )
     {
         int i;
         char jobno[4];
         int gotpercent = 0;
+ LISTITER iter = list_begin( shell ), end = list_end( shell );
 
         sprintf( jobno, "%d", slot + 1 );
 
- for ( i = 0; shell && i < MAXARGC; ++i, shell = list_next( shell ) )
+ for ( i = 0; iter != end && i < MAXARGC; ++i, iter = list_next( iter ) )
         {
- switch ( object_str( shell->value )[0] )
+ switch ( object_str( list_item( iter ) )[0] )
             {
                 case '%': argv[ i ] = string; ++gotpercent; break;
                 case '!': argv[ i ] = jobno; break;
- default : argv[ i ] = object_str( shell->value );
+ default : argv[ i ] = object_str( list_item( iter ) );
             }
             if ( DEBUG_EXECCMD )
                 printf( "argv[%d] = '%s'\n", i, argv[ i ] );

Modified: trunk/tools/build/v2/engine/filent.c
==============================================================================
--- trunk/tools/build/v2/engine/filent.c (original)
+++ trunk/tools/build/v2/engine/filent.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -226,14 +226,14 @@
     }
 
     /* Now enter contents of directory */
- if ( d->files )
+ if ( !list_empty( d->files ) )
     {
         LIST * files = d->files;
- while ( files )
+ LISTITER iter = list_begin( files ), end = list_end( files );
+ for ( ; iter != end; iter = list_next( iter ) )
         {
- file_info_t * ff = file_info( files->value );
- (*func)( closure, files->value, 1 /* stat()'ed */, ff->time );
- files = list_next( files );
+ file_info_t * ff = file_info( list_item( iter ) );
+ (*func)( closure, list_item( iter ), 1 /* stat()'ed */, ff->time );
         }
     }
 

Modified: trunk/tools/build/v2/engine/filesys.c
==============================================================================
--- trunk/tools/build/v2/engine/filesys.c (original)
+++ trunk/tools/build/v2/engine/filesys.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -55,7 +55,7 @@
         finfo->is_dir = 0;
         finfo->size = 0;
         finfo->time = 0;
- finfo->files = 0;
+ finfo->files = L0;
     }
 
     object_free( filename );
@@ -67,13 +67,13 @@
 
 static void remove_files_atexit(void)
 {
- /* we do pop front in case this exit function is called
- more than once */
- while ( files_to_remove )
+ LISTITER iter = list_begin( files_to_remove ), end = list_end( files_to_remove );
+ for ( ; iter != end; iter = list_next( iter ) )
     {
- remove( object_str( files_to_remove->value ) );
- files_to_remove = list_pop_front( files_to_remove );
+ remove( object_str( list_item( iter ) ) );
     }
+ list_free( files_to_remove );
+ files_to_remove = L0;
 }
 
 static void free_file_info ( void * xfile, void * data )

Modified: trunk/tools/build/v2/engine/fileunix.c
==============================================================================
--- trunk/tools/build/v2/engine/fileunix.c (original)
+++ trunk/tools/build/v2/engine/fileunix.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -139,7 +139,7 @@
         return;
     }
 
- if ( ! d->files )
+ if ( list_empty( d->files ) )
     {
         LIST* files = L0;
         PATHNAME f;
@@ -201,12 +201,13 @@
     }
 
     /* Now enter contents of directory */
- if ( d->files )
+ if ( !list_empty( d->files ) )
     {
         LIST * files = d->files;
- while ( files )
+ LISTITER iter = list_begin( files ), end = list_end( files );
+ for ( ; iter != end; iter = list_next( iter ) )
         {
- file_info_t * ff = file_info( files->value );
+ file_info_t * ff = file_info( list_item( iter ) );
             (*func)( closure, ff->name, 1 /* stat()'ed */, ff->time );
             files = list_next( files );
         }

Modified: trunk/tools/build/v2/engine/function.c
==============================================================================
--- trunk/tools/build/v2/engine/function.c (original)
+++ trunk/tools/build/v2/engine/function.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -56,7 +56,8 @@
 
 #define INSTR_JUMP_NOT_GLOB 19
 
-#define INSTR_TRY_POP_FRONT 20
+#define INSTR_FOR_INIT 56
+#define INSTR_FOR_LOOP 20
 
 #define INSTR_SET_RESULT 21
 #define INSTR_RETURN 22
@@ -390,7 +391,7 @@
     frame->file = file;
     frame->line = line;
     
- if ( !first )
+ if ( list_empty( first ) )
     {
         backtrace_line( frame );
         printf( "warning: rulename %s expands to empty string\n", unexpanded );
@@ -406,7 +407,7 @@
         return result;
     }
 
- rulename = object_copy( first->value );
+ rulename = object_copy( list_front( first ) );
 
     frame_init( inner );
 
@@ -465,8 +466,8 @@
     PATHPART join; /* :J -- join list with char */
 } VAR_EDITS;
 
-static LIST * apply_modifiers_impl( LIST * result, string * buf, VAR_EDITS * edits, int n, LIST * iter, LIST * end );
-static void get_iters( subscript_t subscript, LIST * * first, LIST * * last, int length );
+static LIST * apply_modifiers_impl( LIST * result, string * buf, VAR_EDITS * edits, int n, LISTITER iter, LISTITER end );
+static void get_iters( subscript_t subscript, LISTITER * first, LISTITER * last, int length );
 static void var_edit_file( const char * in, string * out, VAR_EDITS * edits );
 static void var_edit_shift( string * out, size_t pos, VAR_EDITS * edits );
 static int var_edit_parse( const char * mods, VAR_EDITS * edits, int havezeroed );
@@ -661,10 +662,10 @@
     if ( total != 0 )
     {
         VAR_EDITS * out = stack_allocate( s, total * sizeof(VAR_EDITS) );
- LIST * * iter = stack_allocate( s, n * sizeof(LIST *) );
+ LISTITER * iter = stack_allocate( s, n * sizeof(LIST *) );
         for (i = 0; i < n; ++i )
         {
- iter[i] = args[i];
+ iter[i] = list_begin( args[i] );
         }
         i = 0;
         {
@@ -674,19 +675,19 @@
             havezeroed = 0;
             for (i = 0; i < n; ++i )
             {
- havezeroed = var_edit_parse( object_str( iter[i]->value ), out, havezeroed );
+ havezeroed = var_edit_parse( object_str( list_item( iter[i] ) ), out, havezeroed );
             }
             ++out;
             while ( --i >= 0 )
             {
- if ( iter[i]->next )
+ if ( list_next( iter[i] ) != list_end( args[i] ) )
                 {
- iter[i] = iter[i]->next;
+ iter[i] = list_next( iter[i] );
                     goto loop;
                 }
                 else
                 {
- iter[i] = args[i];
+ iter[i] = list_begin( args[i] );
                 }
             }
         }
@@ -702,7 +703,7 @@
     VAR_EDITS * edits = (VAR_EDITS *)( (LIST * *)stack_get( s ) + 1 );
     string buf[1];
     string_new( buf );
- result = apply_modifiers_impl( result, buf, edits, n, value, L0 );
+ result = apply_modifiers_impl( result, buf, edits, n, list_begin( value ), list_end( value ) );
     string_free( buf );
     return result;
 }
@@ -775,16 +776,17 @@
     LIST * result = L0;
     int length = list_length( value );
     string buf[1];
+ LISTITER indices_iter = list_begin( indices ), indices_end = list_end( indices );
     string_new( buf );
- for ( ; indices; indices = list_next( indices ) )
+ for ( ; indices_iter != indices_end; indices_iter = list_next( indices_iter ) )
     {
- LIST * iter = value;
- LIST * end;
- subscript_t subscript = parse_subscript( object_str( indices->value ) );
+ LISTITER iter = list_begin( value );
+ LISTITER end = list_end( value );
+ subscript_t subscript = parse_subscript( object_str( list_item( indices_iter ) ) );
         get_iters( subscript, &iter, &end, length );
         for ( ; iter != end; iter = list_next( iter ) )
         {
- result = list_new( result, object_copy( iter->value ) );
+ result = list_new( result, object_copy( list_item( iter ) ) );
         }
     }
     string_free( buf );
@@ -796,12 +798,12 @@
  * The results are written to *first and *last.
  */
 
-static void get_iters( subscript_t subscript, LIST * * first, LIST * * last, int length )
+static void get_iters( subscript_t subscript, LISTITER * first, LISTITER * last, int length )
 {
     int start;
     int size;
- LIST * iter;
- LIST * end;
+ LISTITER iter;
+ LISTITER end;
     {
 
         if ( subscript.sub1 < 0 )
@@ -864,22 +866,22 @@
     return result;
 }
 
-static LIST * apply_modifiers_non_empty( LIST * result, string * buf, VAR_EDITS * edits, int n, LIST * begin, LIST * end )
+static LIST * apply_modifiers_non_empty( LIST * result, string * buf, VAR_EDITS * edits, int n, LISTITER begin, LISTITER end )
 {
     int i;
- LIST * iter;
+ LISTITER iter;
     for ( i = 0; i < n; ++i )
     {
         if ( edits[i].join.ptr )
         {
- var_edit_file( object_str( begin->value ), buf, edits + i );
+ var_edit_file( object_str( list_item( begin ) ), buf, edits + i );
             var_edit_shift( buf, 0, edits + i );
             for ( iter = list_next( begin ); iter != end; iter = list_next( iter ) )
             {
                 size_t size;
                 string_append( buf, edits[i].join.ptr );
                 size = buf->size;
- var_edit_file( object_str( iter->value ), buf, edits + i );
+ var_edit_file( object_str( list_item( iter ) ), buf, edits + i );
                 var_edit_shift( buf, size, edits + i );
             }
             result = list_new( result, object_new( buf->value ) );
@@ -887,9 +889,9 @@
         }
         else
         {
- for ( iter = begin; iter != end; iter = iter->next )
+ for ( iter = begin; iter != end; iter = list_next( iter ) )
             {
- var_edit_file( object_str( iter->value ), buf, edits + i );
+ var_edit_file( object_str( list_item( iter ) ), buf, edits + i );
                 var_edit_shift( buf, 0, edits + i );
                 result = list_new( result, object_new( buf->value ) );
                 string_truncate( buf, 0 );
@@ -899,7 +901,7 @@
     return result;
 }
 
-static LIST * apply_modifiers_impl( LIST * result, string * buf, VAR_EDITS * edits, int n, LIST * iter, LIST * end )
+static LIST * apply_modifiers_impl( LIST * result, string * buf, VAR_EDITS * edits, int n, LISTITER iter, LISTITER end )
 {
     if ( iter != end )
     {
@@ -919,12 +921,13 @@
     VAR_EDITS * edits = (VAR_EDITS *)((LIST * *)stack_get( s ) + 2);
     int length = list_length( value );
     string buf[1];
+ LISTITER indices_iter = list_begin( indices ), indices_end = list_end( indices );
     string_new( buf );
- for ( ; indices; indices = list_next( indices ) )
+ for ( ; indices_iter != indices_end; indices_iter = list_next( indices_iter ) )
     {
- LIST * iter = value;
- LIST * end;
- subscript_t sub = parse_subscript( object_str( indices->value ) );
+ LISTITER iter = list_begin( value );
+ LISTITER end = list_end( value );
+ subscript_t sub = parse_subscript( object_str( list_item( indices_iter ) ) );
         get_iters( sub, &iter, &end, length );
         result = apply_modifiers_impl( result, buf, edits, n, iter, end );
     }
@@ -934,7 +937,7 @@
 
 typedef struct expansion_item
 {
- LIST * elem;
+ LISTITER elem;
     LIST * saved;
     int size;
 } expansion_item;
@@ -949,11 +952,11 @@
     for ( i = 0; i < length; ++i )
     {
         int max = 0;
- LIST * l;
- if ( !elem[i].elem ) return result;
- for ( l = elem[i].elem; l; l = l->next )
+ LISTITER iter = elem[i].elem, end = list_end( elem[i].saved );
+ if ( iter == end ) return result;
+ for ( ; iter != end; iter = list_next( iter ) )
         {
- int len = strlen( object_str( l->value ) );
+ int len = strlen( object_str( list_item( iter ) ) );
             if ( len > max ) max = len;
         }
         size += max;
@@ -966,20 +969,20 @@
         for ( ; i < length; ++i )
         {
             elem[i].size = buf->size;
- string_append( buf, object_str( elem[i].elem->value ) );
+ string_append( buf, object_str( list_item( elem[i].elem ) ) );
         }
         result = list_new( result, object_new( buf->value ) );
         while ( --i >= 0 )
         {
- if(elem[i].elem->next)
+ if( list_next( elem[i].elem ) != list_end( elem[i].saved ) )
             {
- elem[i].elem = elem[i].elem->next;
+ elem[i].elem = list_next( elem[i].elem );
                 string_truncate( buf, elem[i].size );
                 goto loop;
             }
             else
             {
- elem[i].elem = elem[i].saved;
+ elem[i].elem = list_begin( elem[i].saved );
             }
         }
     }
@@ -990,17 +993,17 @@
 static void combine_strings( STACK * s, int n, string * out )
 {
     int i;
- LIST * l;
     for ( i = 0; i < n; ++i )
     {
         LIST * values = stack_pop( s );
- if ( values )
+ LISTITER iter = list_begin( values ), end = list_end( values );
+ if ( iter != end )
         {
- string_append( out, object_str( values->value ) );
- for ( l = list_next( values ); l; l = list_next( l ) )
+ string_append( out, object_str( list_item( iter ) ) );
+ for ( iter = list_next( iter ); iter != end; iter = list_next( iter ) )
             {
                 string_push_back( out, ' ' );
- string_append( out, object_str( l->value ) );
+ string_append( out, object_str( list_item( iter ) ) );
             }
             list_free( values );
         }
@@ -2108,26 +2111,29 @@
     }
 }
 
-static void compile_parse( PARSE * parse, compiler * c, int result_location )
+static void compile_append_chain( PARSE * parse, compiler * c )
 {
- if ( parse->type == PARSE_APPEND )
+ assert( parse->type == PARSE_APPEND );
+ if ( parse->left->type == PARSE_NULL )
     {
- /*
- * append is associative, so flip the parse tree of chained
- * appends around to keep the stack from getting too deep.
- */
         compile_parse( parse->right, c, RESULT_STACK );
- while ( parse->left->type == PARSE_APPEND )
- {
- compile_parse( parse->left->right, c, RESULT_STACK );
- compile_emit( c, INSTR_PUSH_APPEND, 0 );
- parse = parse->left;
- }
- if ( parse->left->type != PARSE_NULL )
- {
+ }
+ else
+ {
+ if ( parse->left->type == PARSE_APPEND )
+ compile_append_chain( parse->left, c );
+ else
             compile_parse( parse->left, c, RESULT_STACK );
- compile_emit( c, INSTR_PUSH_APPEND, 0 );
- }
+ compile_parse( parse->right, c, RESULT_STACK );
+ compile_emit( c, INSTR_PUSH_APPEND, 0 );
+ }
+}
+
+static void compile_parse( PARSE * parse, compiler * c, int result_location )
+{
+ if ( parse->type == PARSE_APPEND )
+ {
+ compile_append_chain( parse, c );
         adjust_result( c, RESULT_STACK, result_location );
     }
     else if ( parse->type == PARSE_EVAL )
@@ -2173,8 +2179,9 @@
             compile_emit( c, INSTR_SWAP, 1 );
         }
 
+ compile_emit( c, INSTR_FOR_INIT, 0 );
         compile_set_label( c, top );
- compile_emit_branch( c, INSTR_TRY_POP_FRONT, end );
+ compile_emit_branch( c, INSTR_FOR_LOOP, end );
         compile_emit( c, INSTR_SET, var );
         compile_emit( c, INSTR_POP, 0 );
 
@@ -2696,10 +2703,11 @@
         case INSTR_PUSH_GROUP:
         {
             LIST * value = L0;
+ LISTITER iter, end;
             l = stack_pop( s );
- for ( r = l; r; r = list_next( r ) )
+ for ( iter = list_begin( l ), end = list_end( l ); iter != end; iter = list_next( iter ) )
             {
- LIST * one = function_get_named_variable( function, frame, r->value );
+ LIST * one = function_get_named_variable( function, frame, list_item( iter ) );
                 value = list_append( value, one );
             }
             list_free( l );
@@ -2711,7 +2719,7 @@
         {
             r = stack_pop( s );
             l = stack_pop( s );
- stack_push( s, list_append( r, l ) );
+ stack_push( s, list_append( l, r ) );
             break;
         }
 
@@ -2839,18 +2847,29 @@
          * For
          */
         
- case INSTR_TRY_POP_FRONT:
+ case INSTR_FOR_INIT:
         {
- l = stack_pop( s );
- if( !l )
+ l = stack_top( s );
+ *(LISTITER *)stack_allocate( s, sizeof( LISTITER ) ) =
+ list_begin( l );
+ break;
+ }
+
+ case INSTR_FOR_LOOP:
+ {
+ LISTITER iter = *(LISTITER *)stack_get( s );
+ stack_deallocate( s, sizeof( LISTITER ) );
+ l = stack_top( s );
+ if( iter == list_end( l ) )
             {
+ list_free( stack_pop( s ) );
                 code += code->arg;
             }
             else
             {
- r = list_new( L0, object_copy( l->value ) );
- l = list_pop_front( l );
- stack_push( s, l );
+ r = list_new( L0, object_copy( list_item( iter ) ) );
+ iter = list_next( iter );
+ *(LISTITER *)stack_allocate( s, sizeof( LISTITER ) ) = iter;
                 stack_push( s, r );
             }
             break;
@@ -2866,8 +2885,8 @@
             const char * match;
             l = stack_pop( s );
             r = stack_top( s );
- pattern = l ? object_str( l->value ) : "";
- match = r ? object_str( r->value ) : "";
+ pattern = !list_empty( l ) ? object_str( list_front( l ) ) : "";
+ match = !list_empty( r ) ? object_str( list_front( r ) ) : "";
             if( glob( pattern, match ) )
             {
                 code += code->arg;
@@ -2936,10 +2955,11 @@
         case INSTR_PUSH_LOCAL_GROUP:
         {
             LIST * value = stack_pop( s );
+ LISTITER iter, end;
             l = stack_pop( s );
- for( r = l; r; r = list_next( r ) )
+ for( iter = list_begin( l ), end = list_end( l ); iter != end; iter = list_next( iter ) )
             {
- LIST * saved = function_swap_named_variable( function, frame, r->value, list_copy( L0, value ) );
+ LIST * saved = function_swap_named_variable( function, frame, list_item( iter ), list_copy( L0, value ) );
                 stack_push( s, saved );
             }
             list_free( value );
@@ -2949,12 +2969,13 @@
 
         case INSTR_POP_LOCAL_GROUP:
         {
+ LISTITER iter, end;
             r = stack_pop( s );
             l = list_reverse( r );
             list_free( r );
- for( r = l; r; r = list_next( r ) )
+ for( iter = list_begin( l ), end = list_end( l ); iter != end; iter = list_next( iter ) )
             {
- function_set_named_variable( function, frame, r->value, stack_pop( s ) );
+ function_set_named_variable( function, frame, list_item( iter ), stack_pop( s ) );
             }
             list_free( l );
             break;
@@ -2967,13 +2988,13 @@
         case INSTR_PUSH_ON:
         {
             LIST * targets = stack_top( s );
- if ( targets )
+ if ( !list_empty( targets ) )
             {
                 /*
                  * FIXME: push the state onto the stack instead of
                  * using pushsettings.
                  */
- TARGET * t = bindtarget( targets->value );
+ TARGET * t = bindtarget( list_front( targets ) );
                 pushsettings( frame->module, t->settings );
             }
             else
@@ -2992,9 +3013,9 @@
         {
             LIST * result = stack_pop( s );
             LIST * targets = stack_pop( s );
- if ( targets )
+ if ( !list_empty( targets ) )
             {
- TARGET * t = bindtarget( targets->value );
+ TARGET * t = bindtarget( list_front( targets ) );
                 popsettings( frame->module, t->settings );
             }
             list_free( targets );
@@ -3007,15 +3028,15 @@
             LIST * targets = stack_pop( s );
             LIST * value = stack_pop( s );
             LIST * vars = stack_pop( s );
- LIST * ts;
- for ( ts = targets; ts; ts = list_next( ts ) )
+ LISTITER iter = list_begin( targets ), end = list_end( targets );
+ for ( ; iter != end; iter = list_next( iter ) )
             {
- TARGET * t = bindtarget( ts->value );
- LIST * l;
+ TARGET * t = bindtarget( list_item( iter ) );
+ LISTITER vars_iter = list_begin( vars ), vars_end = list_end( vars );
 
- for ( l = vars; l; l = list_next( l ) )
- t->settings = addsettings( t->settings, VAR_SET, l->value,
- list_copy( L0, value ) );
+ for ( ; vars_iter != vars_end; vars_iter = list_next( vars_iter ) )
+ t->settings = addsettings( t->settings, VAR_SET, list_item( vars_iter ),
+ list_copy( L0, value ) );
             }
             list_free( vars );
             list_free( targets );
@@ -3028,15 +3049,15 @@
             LIST * targets = stack_pop( s );
             LIST * value = stack_pop( s );
             LIST * vars = stack_pop( s );
- LIST * ts;
- for ( ts = targets; ts; ts = list_next( ts ) )
+ LISTITER iter = list_begin( targets ), end = list_end( targets );
+ for ( ; iter != end; iter = list_next( iter ) )
             {
- TARGET * t = bindtarget( ts->value );
- LIST * l;
+ TARGET * t = bindtarget( list_item( iter ) );
+ LISTITER vars_iter = list_begin( vars ), vars_end = list_end( vars );
 
- for ( l = vars; l; l = list_next( l ) )
- t->settings = addsettings( t->settings, VAR_APPEND, l->value,
- list_copy( L0, value ) );
+ for ( ; vars_iter != vars_end; vars_iter = list_next( vars_iter ) )
+ t->settings = addsettings( t->settings, VAR_APPEND, list_item( vars_iter ),
+ list_copy( L0, value ) );
             }
             list_free( vars );
             list_free( targets );
@@ -3049,15 +3070,15 @@
             LIST * targets = stack_pop( s );
             LIST * value = stack_pop( s );
             LIST * vars = stack_pop( s );
- LIST * ts;
- for ( ts = targets; ts; ts = list_next( ts ) )
+ LISTITER iter = list_begin( targets ), end = list_end( targets );
+ for ( ; iter != end; iter = list_next( iter ) )
             {
- TARGET * t = bindtarget( ts->value );
- LIST * l;
+ TARGET * t = bindtarget( list_item( iter ) );
+ LISTITER vars_iter = list_begin( vars ), vars_end = list_end( vars );
 
- for ( l = vars; l; l = list_next( l ) )
- t->settings = addsettings( t->settings, VAR_DEFAULT, l->value,
- list_copy( L0, value ) );
+ for ( ; vars_iter != vars_end; vars_iter = list_next( vars_iter ) )
+ t->settings = addsettings( t->settings, VAR_DEFAULT, list_item( vars_iter ),
+ list_copy( L0, value ) );
             }
             list_free( vars );
             list_free( targets );
@@ -3090,8 +3111,9 @@
         {
             LIST * value = stack_pop( s );
             LIST * vars = stack_pop( s );
- for( r = vars; r; r = list_next( r ) )
- function_set_named_variable( function, frame, r->value, list_copy( L0, value ) );
+ LISTITER iter = list_begin( vars ), end = list_end( vars );
+ for( ; iter != end; iter = list_next( iter ) )
+ function_set_named_variable( function, frame, list_item( iter ), list_copy( L0, value ) );
             list_free( vars );
             stack_push( s, value );
             break;
@@ -3101,8 +3123,9 @@
         {
             LIST * value = stack_pop( s );
             LIST * vars = stack_pop( s );
- for( r = vars; r; r = list_next( r ) )
- function_append_named_variable( function, frame, r->value, list_copy( L0, value ) );
+ LISTITER iter = list_begin( vars ), end = list_end( vars );
+ for( ; iter != end; iter = list_next( iter ) )
+ function_append_named_variable( function, frame, list_item( iter ), list_copy( L0, value ) );
             list_free( vars );
             stack_push( s, value );
             break;
@@ -3112,8 +3135,9 @@
         {
             LIST * value = stack_pop( s );
             LIST * vars = stack_pop( s );
- for( r = vars; r; r = list_next( r ) )
- function_default_named_variable( function, frame, r->value, list_copy( L0, value ) );
+ LISTITER iter = list_begin( vars ), end = list_end( vars );
+ for( ; iter != end; iter = list_next( iter ) )
+ function_default_named_variable( function, frame, list_item( iter ), list_copy( L0, value ) );
             list_free( vars );
             stack_push( s, value );
             break;
@@ -3199,9 +3223,10 @@
             LIST * vars = stack_pop( s );
             int n = expand_modifiers( s, code->arg );
             LIST * result = L0;
- for( l = vars; l; l = list_next( l ) )
+ LISTITER iter = list_begin( vars ), end = list_end( vars );
+ for( ; iter != end; iter = list_next( iter ) )
             {
- stack_push( s, function_get_named_variable( function, frame, l->value ) );
+ stack_push( s, function_get_named_variable( function, frame, list_item( iter ) ) );
                 result = list_append( result, apply_modifiers( s, n ) );
                 list_free( stack_pop( s ) );
             }
@@ -3217,9 +3242,10 @@
         {
             LIST * vars = stack_pop( s );
             LIST * result = L0;
- for( l = vars; l; l = list_next( l ) )
+ LISTITER iter = list_begin( vars ), end = list_end( vars );
+ for( ; iter != end; iter = list_next( iter ) )
             {
- stack_push( s, function_get_named_variable( function, frame, l->value ) );
+ stack_push( s, function_get_named_variable( function, frame, list_item( iter ) ) );
                 result = list_append( result, apply_subscript( s ) );
                 list_free( stack_pop( s ) );
             }
@@ -3236,10 +3262,11 @@
             LIST * r = stack_pop( s );
             int n = expand_modifiers( s, code->arg );
             LIST * result = L0;
+ LISTITER iter = list_begin( vars ), end = list_end( vars );
             stack_push( s, r );
- for( l = vars; l; l = list_next( l ) )
+ for( ; iter != end; iter = list_next( iter ) )
             {
- stack_push( s, function_get_named_variable( function, frame, l->value ) );
+ stack_push( s, function_get_named_variable( function, frame, list_item( iter ) ) );
                 result = list_append( result, apply_subscript_and_modifiers( s, n ) );
                 list_free( stack_pop( s ) );
             }
@@ -3261,7 +3288,8 @@
             int i;
             for( i = 0; i < code->arg; ++i )
             {
- items[i].elem = items[i].saved = stack_pos[i];
+ items[i].saved = stack_pos[i];
+ items[i].elem = list_begin( items[i].saved );
             }
             result = expand( items, code->arg );
             stack_deallocate( s, buffer_size );
@@ -3277,9 +3305,9 @@
         {
             LIST * nt = stack_pop( s );
 
- if ( nt )
+ if ( !list_empty( nt ) )
             {
- TARGET * t = bindtarget( nt->value );
+ TARGET * t = bindtarget( list_front( nt ) );
                 list_free( nt );
 
                 /* DWA 2001/10/22 - Perforce Jam cleared the arguments here, which
@@ -3315,7 +3343,7 @@
             LIST * module_name = stack_pop( s );
 
             module_t * outer_module = frame->module;
- frame->module = module_name ? bindmodule( module_name->value ) : root_module();
+ frame->module = !list_empty( module_name ) ? bindmodule( list_front( module_name ) ) : root_module();
 
             list_free( module_name );
 
@@ -3366,7 +3394,7 @@
             FILE * out_file = 0;
             string_new( buf );
             combine_strings( s, code->arg, buf );
- out = object_str( stack_top( s )->value );
+ out = object_str( list_front( stack_top( s ) ) );
 
             /* For stdout/stderr we will create a temp file and generate
                 * a command that outputs the content as needed.

Modified: trunk/tools/build/v2/engine/hcache.c
==============================================================================
--- trunk/tools/build/v2/engine/hcache.c (original)
+++ trunk/tools/build/v2/engine/hcache.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -78,9 +78,9 @@
     {
         LIST * hcachevar = var_get( root_module(), constant_HCACHEFILE );
 
- if ( hcachevar )
+ if ( !list_empty( hcachevar ) )
         {
- TARGET * t = bindtarget( hcachevar->value );
+ TARGET * t = bindtarget( list_front( hcachevar ) );
 
             pushsettings( root_module(), t->settings );
             /* Do not expect the cache file to be generated, so pass 0 as the
@@ -91,8 +91,7 @@
             t->boundname = search( t->name, &t->time, 0, 0 );
             popsettings( root_module(), t->settings );
 
- if ( hcachevar )
- name = object_copy( t->boundname );
+ name = object_copy( t->boundname );
         }
     }
     return name ? object_str( name ) : 0;
@@ -108,9 +107,9 @@
 {
     int age = 100;
     LIST * var = var_get( root_module(), constant_HCACHEMAXAGE );
- if ( var )
+ if ( !list_empty( var ) )
     {
- age = atoi( object_str( var->value ) );
+ age = atoi( object_str( list_front( var ) ) );
         if ( age < 0 )
             age = 0;
     }
@@ -241,7 +240,7 @@
         cachedata.age = atoi( object_str( age_str ) ) + 1;
 
         count = atoi( object_str( includes_count_str ) );
- for ( l = 0, i = 0; i < count; ++i )
+ for ( l = L0, i = 0; i < count; ++i )
         {
             OBJECT * s = read_netstring( f );
             if ( !s )
@@ -262,7 +261,7 @@
         }
 
         count = atoi( object_str( hdrscan_count_str ) );
- for ( l = 0, i = 0; i < count; ++i )
+ for ( l = L0, i = 0; i < count; ++i )
         {
             OBJECT * s = read_netstring( f );
             if ( !s )
@@ -329,7 +328,7 @@
     c = hcachelist;
     for ( c = hcachelist; c; c = c->next )
     {
- LIST * l;
+ LISTITER iter, end;
         char time_str[ 30 ];
         char age_str[ 30 ];
         char includes_count_str[ 30 ];
@@ -350,11 +349,13 @@
         write_netstring( f, time_str );
         write_netstring( f, age_str );
         write_netstring( f, includes_count_str );
- for ( l = c->includes; l; l = list_next( l ) )
- write_netstring( f, object_str( l->value ) );
+ for ( iter = list_begin( c->includes ), end = list_end( c->includes );
+ iter != end; iter = list_next( iter ) )
+ write_netstring( f, object_str( list_item( iter ) ) );
         write_netstring( f, hdrscan_count_str );
- for ( l = c->hdrscan; l; l = list_next( l ) )
- write_netstring( f, object_str( l->value ) );
+ for ( iter = list_begin( c->hdrscan ), end = list_end( c->hdrscan );
+ iter != end; iter = list_next( iter ) )
+ write_netstring( f, object_str( list_item( iter ) ) );
         fputs( "\n", f );
         ++header_count;
     }
@@ -394,19 +395,21 @@
         if ( c->time == t->time )
         {
             LIST *l1 = hdrscan, *l2 = c->hdrscan;
- while ( l1 && l2 )
+ LISTITER iter1 = list_begin( l1 ), end1 = list_end( l1 ),
+ iter2 = list_begin( l2 ), end2 = list_end( l2 );
+ while ( iter1 != end1 && iter2 != end2 )
             {
- if (l1->value != l2->value)
+ if ( list_item( iter1 ) != list_item( iter2 ) )
                 {
- l1 = NULL;
+ iter1 = end1;
                 }
                 else
                 {
- l1 = list_next( l1 );
- l2 = list_next( l2 );
+ iter1 = list_next( iter1 );
+ iter2 = list_next( iter2 );
                 }
             }
- if ( l1 || l2 )
+ if ( iter1 != end1 || iter2 != end2 )
             {
                 if (DEBUG_HEADER)
                     printf( "HDRSCAN out of date in cache for %s\n",
@@ -422,8 +425,8 @@
 
                 list_free( c->includes );
                 list_free( c->hdrscan );
- c->includes = 0;
- c->hdrscan = 0;
+ c->includes = L0;
+ c->hdrscan = L0;
             }
             else
             {
@@ -432,7 +435,7 @@
                         object_str( t->boundname ) );
                 c->age = 0;
                 ++hits;
- l = list_copy( 0, c->includes );
+ l = list_copy( L0, c->includes );
                 return l;
             }
         }
@@ -443,8 +446,8 @@
                     object_str( t->boundname ) );
             list_free( c->includes );
             list_free( c->hdrscan );
- c->includes = 0;
- c->hdrscan = 0;
+ c->includes = L0;
+ c->hdrscan = L0;
         }
     }
     else
@@ -461,12 +464,12 @@
 
     /* 'c' points at the cache entry. Its out of date. */
 
- l = headers1( 0, t->boundname, rec, re );
+ l = headers1( L0, t->boundname, rec, re );
 
     c->time = t->time;
     c->age = 0;
- c->includes = list_copy( 0, l );
- c->hdrscan = list_copy( 0, hdrscan );
+ c->includes = list_copy( L0, l );
+ c->hdrscan = list_copy( L0, hdrscan );
 
     return l;
 }

Modified: trunk/tools/build/v2/engine/headers.c
==============================================================================
--- trunk/tools/build/v2/engine/headers.c (original)
+++ trunk/tools/build/v2/engine/headers.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -62,25 +62,28 @@
     LIST * hdrscan;
     LIST * hdrrule;
         #ifndef OPT_HEADER_CACHE_EXT
- LIST * headlist = 0;
+ LIST * headlist = L0;
         #endif
     regexp * re[ MAXINC ];
     int rec = 0;
+ LISTITER iter, end;
 
- if ( !( hdrscan = var_get( root_module(), constant_HDRSCAN ) ) )
+ hdrscan = var_get( root_module(), constant_HDRSCAN );
+ if ( list_empty( hdrscan ) )
         return;
 
- if ( !( hdrrule = var_get( root_module(), constant_HDRRULE ) ) )
+ hdrrule = var_get( root_module(), constant_HDRRULE );
+ if ( list_empty( hdrrule ) )
         return;
 
     if ( DEBUG_HEADER )
         printf( "header scan %s\n", object_str( t->name ) );
 
     /* Compile all regular expressions in HDRSCAN */
- while ( ( rec < MAXINC ) && hdrscan )
+ iter = list_begin( hdrscan ), end = list_end( hdrscan );
+ for ( ; ( rec < MAXINC ) && iter != end; iter = list_next( iter ) )
     {
- re[ rec++ ] = regex_compile( hdrscan->value );
- hdrscan = list_next( hdrscan );
+ re[ rec++ ] = regex_compile( list_item( iter ) );
     }
 
     /* Doctor up call to HDRRULE rule */
@@ -101,7 +104,7 @@
              * $(<) */
             lol_add( frame->args, list_new( L0, object_copy( t->boundname ) ) );
 
- list_free( evaluate_rule( hdrrule->value, frame ) );
+ list_free( evaluate_rule( list_front( hdrrule ), frame ) );
         }
 
         /* Clean up. */

Modified: trunk/tools/build/v2/engine/jam.c
==============================================================================
--- trunk/tools/build/v2/engine/jam.c (original)
+++ trunk/tools/build/v2/engine/jam.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -521,7 +521,7 @@
             }
         }
 
- if (!targets_to_update())
+ if ( list_empty( targets_to_update() ) )
         {
             mark_target_for_updating( constant_all );
         }
@@ -569,12 +569,12 @@
         {
             LIST *p = L0;
             p = var_get ( root_module(), constant_PARALLELISM );
- if ( p )
+ if ( !list_empty( p ) )
             {
- int j = atoi( object_str( p->value ) );
+ int j = atoi( object_str( list_front( p ) ) );
                 if ( j == -1 )
                 {
- printf( "Invalid value of PARALLELISM: %s\n", object_str( p->value ) );
+ printf( "Invalid value of PARALLELISM: %s\n", object_str( list_front( p ) ) );
                 }
                 else
                 {
@@ -587,9 +587,9 @@
         {
             LIST *p = L0;
             p = var_get( root_module(), constant_KEEP_GOING );
- if ( p )
+ if ( !list_empty( p ) )
             {
- int v = atoi( object_str( p->value ) );
+ int v = atoi( object_str( list_front( p ) ) );
                 if ( v == 0 )
                     globs.quitquick = 1;
                 else
@@ -602,14 +602,15 @@
             PROFILE_ENTER( MAIN_MAKE );
 
             LIST * targets = targets_to_update();
- if (targets)
+ if ( !list_empty( targets ) )
             {
                 int targets_count = list_length( targets );
+ LISTITER iter = list_begin( targets ), end = list_end( targets );
                 OBJECT * * targets2 = (OBJECT * *)
                     BJAM_MALLOC( targets_count * sizeof( OBJECT * ) );
                 int n = 0;
- for ( ; targets; targets = list_next( targets ) )
- targets2[ n++ ] = targets->value;
+ for ( ; iter != end; iter = list_next( iter ) )
+ targets2[ n++ ] = list_item( iter );
                 status |= make( targets_count, targets2, anyhow );
                 BJAM_FREE( (void *)targets2 );
             }

Modified: trunk/tools/build/v2/engine/lists.c
==============================================================================
--- trunk/tools/build/v2/engine/lists.c (original)
+++ trunk/tools/build/v2/engine/lists.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -7,25 +7,63 @@
 # include "jam.h"
 # include "object.h"
 # include "lists.h"
+# include "assert.h"
 
 /*
  * lists.c - maintain lists of objects
  *
- * This implementation essentially uses a singly linked list, but
- * guarantees that the head element of every list has a valid pointer
- * to the tail of the list, so the new elements can efficiently and
- * properly be appended to the end of a list.
- *
- * To avoid massive allocation, list_free() just tacks the whole freed
- * chain onto freelist and list_new() looks on freelist first for an
- * available list struct. list_free() does not free the strings in the
- * chain: it lazily lets list_new() do so.
- *
  * 08/23/94 (seiwald) - new list_append()
  * 09/07/00 (seiwald) - documented lol_*() functions
  */
 
-static LIST *freelist = 0; /* junkpile for list_free() */
+struct freelist_node { struct freelist_node *next; };
+
+static struct freelist_node *freelist[32]; /* junkpile for list_free() */
+
+static unsigned get_bucket( unsigned size )
+{
+ unsigned bucket = 0;
+ while ( size > ( 1u << bucket ) ) ++bucket;
+ return bucket;
+}
+
+static LIST * list_alloc( unsigned size )
+{
+ unsigned bucket = get_bucket( size );
+ if ( freelist[ bucket ] )
+ {
+ struct freelist_node * result = freelist[ bucket ];
+ freelist[ bucket ] = result->next;
+ return (LIST *)result;
+ }
+ else
+ {
+ return (LIST *)BJAM_MALLOC( sizeof( LIST ) + ( 1u << bucket ) * sizeof( OBJECT * ) );
+ }
+}
+
+static void list_dealloc( LIST * l )
+{
+ unsigned size = list_length( l );
+ unsigned bucket;
+ struct freelist_node * node = (struct freelist_node *)l;
+
+ if ( size == 0 ) return;
+
+ bucket = get_bucket( size );;
+
+#ifdef BJAM_NO_MEM_CACHE
+
+ BJAM_FREE( node );
+
+#else
+
+ node->next = freelist[ bucket ];
+ freelist[ bucket ] = node;
+
+#endif
+
+}
 
 /*
  * list_append() - append a list onto another one, returning total
@@ -33,60 +71,66 @@
 
 LIST * list_append( LIST * l, LIST * nl )
 {
- if ( !nl )
+ if ( list_empty( nl ) )
     {
         /* Just return l */
     }
- else if ( !l )
+ else if ( list_empty( l ) )
     {
         l = nl;
     }
     else
     {
- /* Graft two non-empty lists. */
- l->tail->next = nl;
- l->tail = nl->tail;
+ l = list_copy( l, nl );
+ list_free( nl );
     }
 
     return l;
 }
 
+LISTITER list_begin( LIST * l )
+{
+ if ( l )
+ return (LISTITER)( (char *)l + sizeof(LIST) );
+ else
+ return 0;
+}
+
+LISTITER list_end( LIST * l )
+{
+ if ( l )
+ return list_begin( l ) + l->impl.size;
+ else
+ return 0;
+}
+
 /*
  * list_new() - tack a string onto the end of a list of strings
  */
 
 LIST * list_new( LIST * head, OBJECT * value )
 {
- LIST * l;
+ unsigned int size = list_length( head );
+ unsigned int i;
 
     if ( DEBUG_LISTS )
         printf( "list > %s <\n", object_str( value ) );
 
- /* Get list struct from freelist, if one available. */
- /* Otherwise allocate. */
- /* If from freelist, must free string first */
-
- if ( freelist )
- {
- l = freelist;
- object_free( l->value );
- freelist = freelist->next;
+ /* If the size is a power of 2, reallocate. */
+ if ( size == 0 )
+ {
+ head = list_alloc( 1 );
     }
- else
+ else if ( ( ( size - 1 ) & size ) == 0 )
     {
- l = (LIST *)BJAM_MALLOC( sizeof( LIST ) );
+ LIST * l = list_alloc( size + 1 );
+ memcpy( l, head, sizeof( LIST ) + size * sizeof( OBJECT * ) );
+ list_dealloc( head );
+ head = l;
     }
 
- /* If first on chain, head points here. */
- /* If adding to chain, tack us on. */
- /* Tail must point to this new, last element. */
-
- if ( !head ) head = l;
- else head->tail->next = l;
- head->tail = l;
- l->next = 0;
-
- l->value = value;
+ list_begin( head )[ size ] = value;
+ head->impl.size = size + 1;
 
     return head;
 }
@@ -98,23 +142,64 @@
 
 LIST * list_copy( LIST * l, LIST * nl )
 {
- for ( ; nl; nl = list_next( nl ) )
- l = list_new( l, object_copy( nl->value ) );
+ int l_size = list_length( l );
+ int nl_size = list_length( nl );
+ int size = l_size + nl_size;
+ unsigned bucket;
+ int i;
+
+ if ( size == 0 ) return L0;
+
+ bucket = get_bucket( size );
+ if ( bucket == 0 || l_size <= ( 1u << (bucket - 1) ) )
+ {
+ LIST * result = list_alloc( size );
+ memcpy( list_begin( result ), list_begin( l ), l_size * sizeof( OBJECT * ) );
+ list_dealloc( l );
+ l = result;
+ }
+
+ l->impl.size = size;
+ for ( i = 0; i < nl_size; ++i )
+ {
+ list_begin( l )[ i + l_size ] = object_copy( list_begin( nl )[ i ] );
+ }
     return l;
 }
 
 
+LIST * list_copy_range( LIST *l, LISTITER first, LISTITER last )
+{
+ if ( first == last )
+ {
+ return L0;
+ }
+ else
+ {
+ int size = last - first;
+ LIST * result = list_alloc( size );
+ LISTITER dest = list_begin( result );
+ result->impl.size = size;
+ for ( ; first != last; ++first, ++dest )
+ {
+ *dest = object_copy( *first );
+ }
+ return result;
+ }
+}
+
+
 /*
  * list_sublist() - copy a subset of a list of strings.
  */
 
 LIST * list_sublist( LIST * l, int start, int count )
 {
- LIST * nl = 0;
- for ( ; l && start--; l = list_next( l ) );
- for ( ; l && count--; l = list_next( l ) )
- nl = list_new( nl, object_copy( l->value ) );
- return nl;
+ int end = start + count;
+ int size = list_length( l );
+ if ( start >= size ) return L0;
+ if ( end > size ) end = size;
+ return list_copy_range( l, list_begin( l ) + start, list_begin( l ) + end );
 }
 
 
@@ -130,29 +215,15 @@
 {
     int len;
     int ii;
- OBJECT * * objects;
- LIST * listp;
- LIST * result = 0;
+ LIST * result;
 
     if ( !l )
         return L0;
 
     len = list_length( l );
- objects = (OBJECT * *)BJAM_MALLOC( len * sizeof(OBJECT*) );
-
- listp = l;
- for ( ii = 0; ii < len; ++ii )
- {
- objects[ ii ] = listp->value;
- listp = listp->next;
- }
-
- qsort( objects, len, sizeof( OBJECT * ), str_ptr_compare );
-
- for ( ii = 0; ii < len; ++ii )
- result = list_append( result, list_new( 0, object_copy( objects[ ii ] ) ) );
+ result = list_copy( L0, l );
 
- BJAM_FREE( objects );
+ qsort( list_begin( result ), len, sizeof( OBJECT * ), str_ptr_compare );
 
     return result;
 }
@@ -164,24 +235,15 @@
 
 void list_free( LIST * head )
 {
-#ifdef BJAM_NO_MEM_CACHE
- LIST *l, *tmp;
- for( l = head; l; )
+ if ( !list_empty( head ) )
     {
- object_free( l->value );
- l->value = 0;
- tmp = l;
- l = l->next;
- BJAM_FREE( tmp );
- }
-#else
- /* Just tack onto freelist. */
- if ( head )
- {
- head->tail->next = freelist;
- freelist = head;
+ LISTITER iter = list_begin( head ), end = list_end( head );
+ for ( ; iter != end; iter = list_next( iter ) )
+ {
+ object_free( list_item( iter ) );
+ }
+ list_dealloc( head );
     }
-#endif
 }
 
 
@@ -191,40 +253,64 @@
 
 LIST * list_pop_front( LIST * l )
 {
- LIST * result = l->next;
- if ( result )
+ unsigned size = list_length( l );
+ assert( size != 0 );
+ --size;
+ object_free( list_front( l ) );
+
+ if ( size == 0 )
     {
- result->tail = l->tail;
- l->next = L0;
- l->tail = l;
+ list_dealloc( l );
+ return L0;
+ }
+ else if ( ( ( size - 1 ) & size ) == 0 )
+ {
+ LIST * nl = list_alloc( size );
+ nl->impl.size = size;
+ memcpy( list_begin( nl ), list_begin( l ) + 1, size * sizeof( OBJECT * ) );
+ list_dealloc( l );
+ return nl;
+ }
+ else
+ {
+ l->impl.size = size;
+ memmove( list_begin( l ), list_begin( l ) + 1, size * sizeof( OBJECT * ) );
+ return l;
     }
- list_free( l );
- return result;
 }
 
 LIST * list_reverse( LIST * l )
 {
- LIST * result = L0;
- for ( ; l; l = l->next )
+ int size = list_length( l );
+ if ( size == 0 ) return L0;
+ else
     {
- result = list_append( list_new(L0, object_copy( l->value ) ), result );
+ LIST * result = list_alloc( size );
+ int i;
+ result->impl.size = size;
+ for ( i = 0; i < size; ++i )
+ {
+ list_begin( result )[ i ] = object_copy( list_begin( l )[ size - i - 1 ] );
+ }
+ return result;
     }
- return result;
 }
 
 int list_cmp( LIST * t, LIST * s )
 {
     int status = 0;
+ LISTITER t_it = list_begin( t ), t_end = list_end( t );
+ LISTITER s_it = list_begin( s ), s_end = list_end( s );
 
- while ( !status && ( t || s ) )
+ while ( !status && ( t_it != t_end || s_it != s_end ) )
     {
- const char *st = t ? object_str( t->value ) : "";
- const char *ss = s ? object_str( s->value ) : "";
+ const char *st = t_it != t_end ? object_str( list_item( t_it ) ) : "";
+ const char *ss = s_it != s_end ? object_str( list_item( s_it ) ) : "";
 
         status = strcmp( st, ss );
 
- t = t ? list_next( t ) : t;
- s = s ? list_next( s ) : s;
+ t_it = t_it != t_end ? list_next( t_it ) : t_it;
+ s_it = s_it != s_end ? list_next( s_it ) : s_it;
     }
 
     return status;
@@ -232,9 +318,10 @@
 
 int list_is_sublist( LIST * sub, LIST * l )
 {
- for ( ; sub; sub = sub->next )
+ LISTITER iter = list_begin( sub ), end = list_end( sub );
+ for ( ; iter != end; iter = list_next( iter ) )
     {
- if ( !list_in( l, sub->value ) )
+ if ( !list_in( l, list_item( iter ) ) )
             return 0;
     }
     return 1;
@@ -246,12 +333,14 @@
 
 void list_print( LIST * l )
 {
- LIST * p = 0;
- for ( ; l; p = l, l = list_next( l ) )
- if ( p )
- printf( "%s ", object_str( p->value ) );
- if ( p )
- printf( "%s", object_str( p->value ) );
+ LISTITER iter = list_begin( l ), end = list_end( l );
+ if ( iter != end )
+ {
+ printf( "%s", object_str( list_item( iter ) ) );
+ iter = list_next( iter );
+ for ( ; iter != end; iter = list_next( iter ) )
+ printf( " %s", object_str( list_item( iter ) ) );
+ }
 }
 
 
@@ -261,16 +350,18 @@
 
 int list_length( LIST * l )
 {
- int n = 0;
- for ( ; l; l = list_next( l ), ++n );
- return n;
+ if ( l )
+ return l->impl.size;
+ else
+ return 0;
 }
 
 
 int list_in( LIST * l, OBJECT * value )
 {
- for ( ; l; l = l->next )
- if ( object_equal( l->value, value ) )
+ LISTITER iter = list_begin( l ), end = list_end( l );
+ for ( ; iter != end; iter = list_next( iter ) )
+ if ( object_equal( list_item( iter ), value ) )
             return 1;
     return 0;
 }
@@ -278,15 +369,16 @@
 
 LIST * list_unique( LIST * sorted_list )
 {
- LIST * result = 0;
- LIST * last_added = 0;
+ LIST * result = L0;
+ OBJECT * last_added = 0;
 
- for ( ; sorted_list; sorted_list = sorted_list->next )
+ LISTITER iter = list_begin( sorted_list ), end = list_end( sorted_list );
+ for ( ; iter != end; iter = list_next( iter ) )
     {
- if ( !last_added || !object_equal( sorted_list->value, last_added->value ) )
+ if ( !last_added || !object_equal( list_item( iter ), last_added ) )
         {
- result = list_new( result, object_copy( sorted_list->value ) );
- last_added = sorted_list;
+ result = list_new( result, object_copy( list_item( iter ) ) );
+ last_added = list_item( iter );
         }
     }
     return result;
@@ -294,14 +386,18 @@
 
 void list_done()
 {
- LIST *l, *tmp;
- for( l = freelist; l; )
+ int i;
+ int total = 0;
+ for ( i = 0; i < sizeof( freelist ) / sizeof( freelist[ 0 ] ); ++i )
     {
- object_free( l->value );
- l->value = 0;
- tmp = l;
- l = l->next;
- BJAM_FREE( tmp );
+ struct freelist_node *l, *tmp;
+ int bytes;
+ for( l = freelist[ i ]; l; )
+ {
+ tmp = l;
+ l = l->next;
+ BJAM_FREE( tmp );
+ }
     }
 }
 
@@ -346,7 +442,7 @@
 
 LIST * lol_get( LOL * lol, int i )
 {
- return i < lol->count ? lol->list[ i ] : 0;
+ return i < lol->count ? lol->list[ i ] : L0;
 }
 
 
@@ -371,10 +467,11 @@
 PyObject *list_to_python(LIST *l)
 {
     PyObject *result = PyList_New(0);
+ LISTITER iter = list_begin( l ), end = list_end( l );
 
- for (; l; l = l->next)
+ for (; iter != end; iter = list_next( iter ) )
     {
- PyObject* s = PyString_FromString(object_str(l->value));
+ PyObject* s = PyString_FromString(object_str(list_item(iter)));
         PyList_Append(result, s);
         Py_DECREF(s);
     }
@@ -384,7 +481,7 @@
 
 LIST *list_from_python(PyObject *l)
 {
- LIST * result = 0;
+ LIST * result = L0;
 
     Py_ssize_t i, n;
     n = PySequence_Size(l);

Modified: trunk/tools/build/v2/engine/lists.h
==============================================================================
--- trunk/tools/build/v2/engine/lists.h (original)
+++ trunk/tools/build/v2/engine/lists.h 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -58,11 +58,14 @@
 typedef struct _list LIST;
 
 struct _list {
- LIST *next;
- LIST *tail; /* only valid in head node */
- OBJECT *value; /* private copy */
+ union {
+ int size;
+ OBJECT *align;
+ } impl;
 };
 
+typedef OBJECT * * LISTITER;
+
 /*
  * LOL - list of LISTs
  */
@@ -78,6 +81,7 @@
 
 LIST * list_append( LIST *l, LIST *nl );
 LIST * list_copy( LIST *l, LIST *nl );
+LIST * list_copy_range( LIST *l, LISTITER first, LISTITER last );
 void list_free( LIST *head );
 LIST * list_new( LIST *head, OBJECT *string );
 void list_print( LIST *l );
@@ -92,7 +96,12 @@
 int list_is_sublist( LIST * sub, LIST * l );
 void list_done();
 
-# define list_next( l ) ((l)->next)
+LISTITER list_begin( LIST * );
+LISTITER list_end( LIST * );
+# define list_next( it ) ((it) + 1)
+# define list_item( it ) (*(it))
+# define list_empty( l ) ( (l) == L0 )
+# define list_front( l ) list_item( list_begin( l ) )
 
 # define L0 ((LIST *)0)
 

Modified: trunk/tools/build/v2/engine/make.c
==============================================================================
--- trunk/tools/build/v2/engine/make.c (original)
+++ trunk/tools/build/v2/engine/make.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -319,9 +319,9 @@
 #ifdef OPT_SEMAPHORE
     {
         LIST * var = var_get( root_module(), constant_JAM_SEMAPHORE );
- if ( var )
+ if ( !list_empty( var ) )
         {
- TARGET * semaphore = bindtarget( var->value );
+ TARGET * semaphore = bindtarget( list_front( var ) );
             semaphore->progress = T_MAKE_SEMAPHORE;
             t->semaphore = semaphore;
         }
@@ -793,7 +793,7 @@
 }
 
 
-static LIST * targets_to_update_ = 0;
+static LIST * targets_to_update_ = L0;
 
 
 void mark_target_for_updating( OBJECT * target )
@@ -811,5 +811,5 @@
 void clear_targets_to_update()
 {
     list_free( targets_to_update_ );
- targets_to_update_ = 0;
+ targets_to_update_ = L0;
 }

Modified: trunk/tools/build/v2/engine/make1.c
==============================================================================
--- trunk/tools/build/v2/engine/make1.c (original)
+++ trunk/tools/build/v2/engine/make1.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -532,7 +532,7 @@
             ( !( cmd->rule->actions->flags & RULE_QUIETLY ) && DEBUG_MAKE ) )
         {
             rule_name = object_str( cmd->rule->name );
- target = object_str( lol_get( &cmd->args, 0 )->value );
+ target = object_str( list_front( lol_get( &cmd->args, 0 ) ) );
             if ( globs.noexec )
                 out_action( rule_name, target, cmd->buf->value, "", "", EXIT_OK );
         }
@@ -696,7 +696,7 @@
     timing_rule = var_get( root_module(), constant_TIMING_RULE );
     popsettings( root_module(), target->settings );
 
- if ( timing_rule )
+ if ( !list_empty( timing_rule ) )
     {
         /* rule timing-rule ( args * : target : start end user system ) */
 
@@ -705,7 +705,7 @@
         frame_init( frame );
 
         /* args * :: $(__TIMING_RULE__[2-]) */
- lol_add( frame->args, list_copy( L0, timing_rule->next ) );
+ lol_add( frame->args, list_copy_range( timing_rule, list_next( list_begin( timing_rule ) ), list_end( timing_rule ) ) );
 
         /* target :: the name of the target */
         lol_add( frame->args, list_new( L0, object_copy( target->name ) ) );
@@ -718,7 +718,7 @@
             outf_double( time->system ) ) );
 
         /* Call the rule. */
- evaluate_rule( timing_rule->value, frame );
+ evaluate_rule( list_front( timing_rule ), frame );
 
         /* Clean up. */
         frame_free( frame );
@@ -747,7 +747,7 @@
     action_rule = var_get( root_module(), constant_ACTION_RULE );
     popsettings( root_module(), target->settings );
 
- if ( action_rule )
+ if ( !list_empty( action_rule ) )
     {
         /* rule action-rule (
             args * :
@@ -760,7 +760,7 @@
         frame_init( frame );
 
         /* args * :: $(__ACTION_RULE__[2-]) */
- lol_add( frame->args, list_copy( L0, action_rule->next ) );
+ lol_add( frame->args, list_copy_range( action_rule, list_next( list_begin( action_rule ) ), list_end( action_rule ) ) );
 
         /* target :: the name of the target */
         lol_add( frame->args, list_new( L0, object_copy( target->name ) ) );
@@ -782,7 +782,7 @@
             lol_add( frame->args, L0 );
 
         /* Call the rule. */
- evaluate_rule( action_rule->value, frame );
+ evaluate_rule( list_front( action_rule ), frame );
 
         /* Clean up. */
         frame_free( frame );
@@ -872,16 +872,17 @@
     if (status != EXEC_CMD_OK)
     {
         LIST * targets = lol_get( &cmd->args, 0 );
- for ( ; targets; targets = list_next( targets ) )
+ LISTITER iter = list_begin( targets ), end = list_end( targets );
+ for ( ; iter != end; iter = list_next( iter ) )
         {
             int need_unlink = 1;
- TARGET* t = bindtarget ( targets->value );
+ TARGET* t = bindtarget ( list_item( iter ) );
             if (t->flags & T_FLAG_PRECIOUS)
             {
                 need_unlink = 0;
             }
- if (need_unlink && !unlink( object_str( targets->value ) ) )
- printf( "...removing %s\n", object_str( targets->value ) );
+ if (need_unlink && !unlink( object_str( list_item( iter ) ) ) )
+ printf( "...removing %s\n", object_str( list_item( iter ) ) );
         }
     }
 
@@ -934,7 +935,7 @@
 static CMD * make1cmds( TARGET * t )
 {
     CMD * cmds = 0;
- LIST * shell = 0;
+ LIST * shell = L0;
     module_t * settings_module = 0;
     TARGET * settings_target = 0;
     ACTIONS * a0;
@@ -980,14 +981,14 @@
         /* If doing only updated (or existing) sources, but none have been
          * updated (or exist), skip this action.
          */
- if ( !ns && ( actions->flags & ( RULE_NEWSRCS | RULE_EXISTING ) ) )
+ if ( list_empty( ns ) && ( actions->flags & ( RULE_NEWSRCS | RULE_EXISTING ) ) )
         {
             list_free( nt );
             continue;
         }
 
         swap_settings( &settings_module, &settings_target, rule->module, t );
- if ( !shell )
+ if ( list_empty( shell ) )
         {
             shell = var_get( rule->module, constant_JAMSHELL ); /* shell is per-target */
         }
@@ -1098,11 +1099,11 @@
         /* Prohibit duplicates for RULE_TOGETHER. */
         if ( flags & RULE_TOGETHER )
         {
- LIST * m;
- for ( m = l; m; m = m->next )
- if ( object_equal( m->value, t->boundname ) )
+ LISTITER iter = list_begin( l ), end = list_end( l );
+ for ( ; iter != end; iter = list_next( iter ) )
+ if ( object_equal( list_item( iter ), t->boundname ) )
                     break;
- if ( m )
+ if ( iter != end )
                 continue;
         }
 
@@ -1122,14 +1123,16 @@
 {
     SETTINGS * settings = 0;
 
- for ( ; vars; vars = list_next( vars ) )
+ LISTITER vars_iter = list_begin( vars ), vars_end = list_end( vars );
+ for ( ; vars_iter != vars_end; vars_iter = list_next( vars_iter ) )
     {
- LIST * l = var_get( module, vars->value );
- LIST * nl = 0;
+ LIST * l = var_get( module, list_item( vars_iter ) );
+ LIST * nl = L0;
+ 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->value );
+ TARGET * t = bindtarget( list_item( iter ) );
 
             /* Make sure the target is bound. */
             if ( t->binding == T_BIND_UNBOUND )
@@ -1140,7 +1143,7 @@
         }
 
         /* Add to settings chain. */
- settings = addsettings( settings, VAR_SET, vars->value, nl );
+ settings = addsettings( settings, VAR_SET, list_item( vars_iter ), nl );
     }
 
     return settings;

Modified: trunk/tools/build/v2/engine/modules.c
==============================================================================
--- trunk/tools/build/v2/engine/modules.c (original)
+++ trunk/tools/build/v2/engine/modules.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -152,15 +152,17 @@
     PROFILE_ENTER( IMPORT_MODULE );
 
     struct hash * h;
+ LISTITER iter, end;
 
     if ( !target_module->imported_modules )
         target_module->imported_modules = hashinit( sizeof( char * ), "imported" );
     h = target_module->imported_modules;
 
- for ( ; module_names; module_names = module_names->next )
+ iter = list_begin( module_names ), end = list_end( module_names );
+ for ( ; iter != end; iter = list_next( iter ) )
     {
         int found;
- OBJECT * s = module_names->value;
+ OBJECT * s = list_item( iter );
         OBJECT * * ss = (OBJECT * *)hash_insert( h, s, &found );
         if( !found )
         {

Modified: trunk/tools/build/v2/engine/modules/order.c
==============================================================================
--- trunk/tools/build/v2/engine/modules/order.c (original)
+++ trunk/tools/build/v2/engine/modules/order.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -15,8 +15,9 @@
 LIST *add_pair( FRAME *frame, int flags )
 {
     LIST* arg = lol_get( frame->args, 0 );
+ LISTITER iter = list_begin( arg ), end = list_end( arg );
 
- var_set(frame->module, arg->value, list_copy(0, arg->next), VAR_APPEND);
+ var_set( frame->module, list_item( iter ), list_copy_range( arg, list_next( iter ), end ), VAR_APPEND );
 
     return L0;
 }
@@ -27,8 +28,9 @@
 int list_index(LIST* list, OBJECT* value)
 {
     int result = 0;
- for(; list; list = list->next, ++result) {
- if (object_equal(list->value, value))
+ LISTITER iter = list_begin(list), end = list_end(list);
+ for(; iter != end; iter = list_next(iter), ++result) {
+ if (object_equal(list_item(iter), value))
             return result;
     }
     return -1;
@@ -76,10 +78,10 @@
 
 LIST *order( FRAME *frame, int flags )
 {
- LIST* arg = lol_get( frame->args, 0 );
- LIST* tmp;
- LIST* result = 0;
+ LIST* arg = lol_get( frame->args, 0 );
+ LIST* result = L0;
     int src;
+ LISTITER iter = list_begin(arg), end = list_end(arg);
 
     /* We need to create a graph of order dependencies between
        the passed objects. We assume that there are no duplicates
@@ -89,15 +91,16 @@
     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(src = 0; iter != end; iter = list_next(iter), ++src) {
         /* For all object this one depend upon, add elements
            to 'graph' */
- LIST* dependencies = var_get(frame->module, tmp->value);
+ LIST* dependencies = var_get(frame->module, list_item(iter));
         int index = 0;
+ LISTITER dep_iter = list_begin(dependencies), dep_end = list_end(dependencies);
 
         graph[src] = (int*)BJAM_CALLOC(list_length(dependencies)+1, sizeof(int));
- for(; dependencies; dependencies = dependencies->next) {
- int dst = list_index(arg, dependencies->value);
+ for(; dep_iter != dep_end; dep_iter = list_next(dep_iter)) {
+ int dst = list_index(arg, list_item(dep_iter));
             if (dst != -1)
                 graph[src][index++] = dst;
         }
@@ -110,9 +113,9 @@
         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, object_copy(tmp->value));
+ iter = list_begin(arg), end = list_end(arg);
+ for (i = 0; i < order[index]; ++i, iter = list_next(iter));
+ result = list_new(result, object_copy(list_item(iter)));
         }
     }
 

Modified: trunk/tools/build/v2/engine/modules/path.c
==============================================================================
--- trunk/tools/build/v2/engine/modules/path.c (original)
+++ trunk/tools/build/v2/engine/modules/path.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -11,10 +11,10 @@
     LIST* l = lol_get( frame->args, 0 );
 
     time_t time;
- timestamp(l->value, &time);
+ timestamp(list_front(l), &time);
     if (time != 0)
     {
- return list_new(0, object_new("true"));
+ return list_new(L0, object_new("true"));
     }
     else
     {

Modified: trunk/tools/build/v2/engine/modules/property-set.c
==============================================================================
--- trunk/tools/build/v2/engine/modules/property-set.c (original)
+++ trunk/tools/build/v2/engine/modules/property-set.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -44,15 +44,15 @@
 LIST *property_set_create( FRAME *frame, int flags )
 {
     LIST* properties = lol_get( frame->args, 0 );
- LIST* sorted = 0;
+ LIST* sorted = L0;
 #if 0
     LIST* order_sensitive = 0;
 #endif
     LIST* unique;
- LIST* tmp;
     LIST* val;
     string var[1];
     OBJECT* name;
+ LISTITER iter, end;
 
 #if 0
     /* Sort all properties which are not order sensitive */
@@ -77,25 +77,26 @@
     string_new(var);
     string_append(var, ".ps.");
 
- for(tmp = unique; tmp; tmp = tmp->next) {
- string_append(var, object_str( tmp->value ));
+ iter = list_begin( unique ), end = list_end( unique );
+ for( ; iter != end; iter = list_next( iter ) ) {
+ string_append(var, object_str( list_item( iter ) ));
         string_push_back(var, '-');
     }
     name = object_new(var->value);
     val = var_get(frame->module, name);
- if (val == 0)
+ if (list_empty(val))
     {
         OBJECT* rulename = object_new("new");
         val = call_rule(rulename, frame,
- list_append(list_new(0, object_new("property-set")), unique), 0);
+ list_append(list_new(L0, object_new("property-set")), unique), 0);
         object_free(rulename);
 
- var_set(frame->module, name, list_copy(0, val), VAR_SET);
+ var_set(frame->module, name, list_copy(L0, val), VAR_SET);
     }
     else
     {
         list_free(unique);
- val = list_copy(0, val);
+ val = list_copy(L0, val);
     }
     object_free(name);
 

Modified: trunk/tools/build/v2/engine/modules/regex.c
==============================================================================
--- trunk/tools/build/v2/engine/modules/regex.c (original)
+++ trunk/tools/build/v2/engine/modules/regex.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -33,18 +33,19 @@
     int* indices = 0;
     int size;
     int* p;
- LIST* result = 0;
+ LIST* result = L0;
 
     string buf[1];
     string_new(buf);
 
- if (indices_list)
+ if (!list_empty(indices_list))
     {
+ LISTITER iter = list_begin(indices_list), end = list_end(indices_list);
         size = list_length(indices_list);
         indices = (int*)BJAM_MALLOC(size*sizeof(int));
- for(p = indices; indices_list; indices_list = indices_list->next)
+ for(p = indices; iter != end; iter = list_next(iter))
         {
- *p++ = atoi(object_str(indices_list->value));
+ *p++ = atoi(object_str(list_item(iter)));
         }
     }
     else
@@ -56,11 +57,12 @@
 
     {
         /* Result is cached and intentionally never freed */
- regexp *re = regex_compile( pattern->value );
+ regexp *re = regex_compile( list_front( pattern ) );
 
- for(; l; l = l->next)
+ LISTITER iter = list_begin( l ), end = list_end( l );
+ for( ; iter != end; iter = list_next( iter ) )
         {
- if( regexec( re, object_str( l->value ) ) )
+ if( regexec( re, object_str( list_item( iter ) ) ) )
             {
                 int i = 0;
                 for(; i < size; ++i)

Modified: trunk/tools/build/v2/engine/modules/sequence.c
==============================================================================
--- trunk/tools/build/v2/engine/modules/sequence.c (original)
+++ trunk/tools/build/v2/engine/modules/sequence.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -17,17 +17,21 @@
 
     LIST* elements = lol_get( frame->args, 0 );
     LIST* rank = lol_get( frame->args, 1 );
+ LISTITER iter, end, elements_iter, elements_end;
     
- LIST* result = 0;
+ LIST* result = L0;
     LIST* tmp;
     int highest_rank = -1;
 
- for (tmp = rank; tmp; tmp = tmp->next)
- highest_rank = max(highest_rank, atoi(object_str(tmp->value)));
-
- for (; rank; rank = rank->next, elements = elements->next)
- if (atoi(object_str(rank->value)) == highest_rank)
- result = list_new(result, object_copy(elements->value));
+ iter = list_begin(rank), end = list_end(rank);
+ for (; iter != end; iter = list_next(iter))
+ highest_rank = max(highest_rank, atoi(object_str(list_item(iter))));
+
+ iter = list_begin(rank), end = list_end(rank);
+ elements_iter = list_begin(elements), elements_end = list_end(elements);
+ for (; iter != end; iter = list_next(iter), elements_iter = list_next(elements_iter))
+ if (atoi(object_str(list_item(iter))) == highest_rank)
+ result = list_new(result, object_copy(list_item(elements_iter)));
 
     return result;
 }

Modified: trunk/tools/build/v2/engine/modules/set.c
==============================================================================
--- trunk/tools/build/v2/engine/modules/set.c (original)
+++ trunk/tools/build/v2/engine/modules/set.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -23,11 +23,12 @@
     LIST* b = lol_get( frame->args, 0 );
     LIST* a = lol_get( frame->args, 1 );
 
- LIST* result = 0;
- for(; b; b = b->next)
+ LIST* result = L0;
+ LISTITER iter = list_begin( b ), end = list_end( b );
+ for( ; iter != end; iter = list_next( iter ) )
     {
- if (!list_in(a, b->value))
- result = list_new(result, object_copy(b->value));
+ if (!list_in(a, list_item(iter)))
+ result = list_new(result, object_copy(list_item(iter)));
     }
     return result;
 }

Modified: trunk/tools/build/v2/engine/rules.c
==============================================================================
--- trunk/tools/build/v2/engine/rules.c (original)
+++ trunk/tools/build/v2/engine/rules.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -237,8 +237,9 @@
 
 TARGETS * targetlist( TARGETS * chain, LIST * target_names )
 {
- for ( ; target_names; target_names = list_next( target_names ) )
- chain = targetentry( chain, bindtarget( target_names->value ) );
+ LISTITER iter = list_begin( target_names ), end = list_end( target_names );
+ for ( ; iter != end; iter = list_next( iter ) )
+ chain = targetentry( chain, bindtarget( list_item( iter ) ) );
     return chain;
 }
 
@@ -404,7 +405,7 @@
     SETTINGS * copy = 0;
     SETTINGS * v;
     for ( v = head; v; v = v->next )
- copy = addsettings( copy, VAR_SET, v->symbol, list_copy( 0, v->value ) );
+ copy = addsettings( copy, VAR_SET, v->symbol, list_copy( L0, v->value ) );
     return copy;
 }
 

Modified: trunk/tools/build/v2/engine/search.c
==============================================================================
--- trunk/tools/build/v2/engine/search.c (original)
+++ trunk/tools/build/v2/engine/search.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -40,7 +40,7 @@
 )
 {
     LIST * bind_rule = var_get( root_module(), constant_BINDRULE );
- if ( bind_rule )
+ if ( !list_empty( bind_rule ) )
     {
         OBJECT * target = object_copy( target_ );
         OBJECT * boundname = object_copy( boundname_ );
@@ -55,7 +55,7 @@
 
             lol_add( frame->args, list_new( L0, boundname ) );
             if ( lol_get( frame->args, 1 ) )
- list_free( evaluate_rule( bind_rule->value, frame ) );
+ list_free( evaluate_rule( list_front( bind_rule ), frame ) );
 
             /* Clean up */
             frame_free( frame );
@@ -117,11 +117,12 @@
     f->f_grist.ptr = 0;
     f->f_grist.len = 0;
 
- if ( ( varlist = var_get( root_module(), constant_LOCATE ) ) )
+ varlist = var_get( root_module(), constant_LOCATE );
+ if ( !list_empty( varlist ) )
     {
         OBJECT * key;
- f->f_root.ptr = object_str( varlist->value );
- f->f_root.len = strlen( object_str( varlist->value ) );
+ f->f_root.ptr = object_str( list_front( varlist ) );
+ f->f_root.len = strlen( object_str( list_front( varlist ) ) );
 
         path_build( f, buf, 1 );
 
@@ -135,17 +136,18 @@
         object_free( key );
         found = 1;
     }
- else if ( varlist = var_get( root_module(), constant_SEARCH ) )
+ else if ( varlist = var_get( root_module(), constant_SEARCH ), !list_empty( varlist ) )
     {
- while ( varlist )
+ LISTITER iter = list_begin( varlist ), end = list_end( varlist );
+ for ( ; iter != end; iter = list_next( iter ) )
         {
             BINDING * ba;
             file_info_t *ff;
             OBJECT * key;
             OBJECT * test_path;
 
- f->f_root.ptr = object_str( varlist->value );
- f->f_root.len = strlen( object_str( varlist->value ) );
+ f->f_root.ptr = object_str( list_item( iter ) );
+ f->f_root.len = strlen( object_str( list_item( iter ) ) );
 
             string_truncate( buf, 0 );
             path_build( f, buf, 1 );
@@ -180,8 +182,6 @@
                 }
             }
             object_free( key );
-
- varlist = list_next( varlist );
         }
     }
 

Modified: trunk/tools/build/v2/engine/subst.c
==============================================================================
--- trunk/tools/build/v2/engine/subst.c (original)
+++ trunk/tools/build/v2/engine/subst.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -40,26 +40,27 @@
 {
   LIST* result = L0;
   LIST* arg1 = lol_get( frame->args, 0 );
+ LISTITER iter = list_begin( arg1 ), end = list_end( arg1 );
 
- if ( arg1 && list_next(arg1) && list_next(list_next(arg1)) )
+ if ( iter != end && list_next( iter ) != end && list_next( list_next( iter ) ) != end )
   {
 
- const char* source = object_str( arg1->value );
- OBJECT * pattern = list_next(arg1)->value;
+ const char* source = object_str( list_item( iter ) );
+ OBJECT * pattern = list_item( list_next( iter ) );
       regexp* repat = regex_compile( pattern );
 
       if ( regexec( repat, (char*)source) )
       {
- LIST* subst = list_next(arg1);
+ LISTITER subst = list_next( iter );
 
- while ((subst = list_next(subst)) != L0)
+ while ( ( subst = list_next( subst ) ) != end )
           {
 # define BUFLEN 4096
               char buf[BUFLEN + 1];
- const char* in = object_str( subst->value );
+ const char* in = object_str( list_item( subst ) );
               char* out = buf;
 
- for ( in = object_str( subst->value ); *in && out < buf + BUFLEN; ++in )
+ for ( ; *in && out < buf + BUFLEN; ++in )
               {
                   if ( *in == '\\' || *in == '$' )
                   {

Modified: trunk/tools/build/v2/engine/variable.c
==============================================================================
--- trunk/tools/build/v2/engine/variable.c (original)
+++ trunk/tools/build/v2/engine/variable.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -160,7 +160,7 @@
 }
 
 
-static LIST * saved_var = 0;
+static LIST * saved_var = L0;
 
 /*
  * var_get() - get value of a user defined symbol.
@@ -170,7 +170,7 @@
 
 LIST * var_get( struct module_t * module, OBJECT * symbol )
 {
- LIST * result = 0;
+ LIST * result = L0;
 #ifdef OPT_AT_FILES
     /* Some "fixed" variables... */
     if ( object_equal( symbol, constant_TMPDIR ) )
@@ -246,7 +246,7 @@
 
     case VAR_DEFAULT:
         /* Set only if unset */
- if ( !v->value )
+ if ( list_empty( v->value ) )
             v->value = value;
         else
             list_free( value );
@@ -286,7 +286,7 @@
     if ( !found )
     {
         v->symbol = object_copy( symbol );
- v->value = 0;
+ v->value = L0;
     }
 
     return v;
@@ -320,7 +320,7 @@
 void var_done( struct module_t * module )
 {
     list_free( saved_var );
- saved_var = 0;
+ saved_var = L0;
     hashenumerate( module->variables, delete_var_, (void *)0 );
     hashdone( module->variables );
 }

Modified: trunk/tools/build/v2/engine/w32_getreg.c
==============================================================================
--- trunk/tools/build/v2/engine/w32_getreg.c (original)
+++ trunk/tools/build/v2/engine/w32_getreg.c 2012-03-19 14:17:36 EDT (Mon, 19 Mar 2012)
@@ -59,7 +59,7 @@
 
 LIST * builtin_system_registry( FRAME * frame, int flags )
 {
- char const* path = object_str( lol_get(frame->args, 0)->value );
+ char const* path = object_str( list_front( lol_get(frame->args, 0) ) );
     LIST* result = L0;
     HKEY key = get_key(&path);
 
@@ -71,10 +71,10 @@
         DWORD type;
         BYTE data[MAX_REGISTRY_DATA_LENGTH];
         DWORD len = sizeof(data);
- LIST const* const field = lol_get(frame->args, 1);
+ LIST * const field = lol_get(frame->args, 1);
 
         if ( ERROR_SUCCESS ==
- RegQueryValueEx(key, field ? object_str( field->value ) : 0, 0, &type, data, &len) )
+ RegQueryValueEx(key, field ? object_str( list_front( field ) ) : 0, 0, &type, data, &len) )
         {
             switch (type)
             {
@@ -186,8 +186,8 @@
 
 LIST * builtin_system_registry_names( FRAME * frame, int flags )
 {
- char const* path = object_str( lol_get(frame->args, 0)->value );
- char const* result_type = object_str( lol_get(frame->args, 1)->value );
+ char const* path = object_str( list_front( lol_get(frame->args, 0) ) );
+ char const* result_type = object_str( list_front( lol_get(frame->args, 1) ) );
 
     HKEY key = get_key(&path);
 


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk