2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-13 12:22:17 +00:00

Fix memory leaks. Make sure that newstr and copystr are always used as needed.

[SVN r75502]
This commit is contained in:
Steven Watanabe
2011-11-16 03:00:54 +00:00
parent 889fff3e70
commit 86278a4624
39 changed files with 1545 additions and 710 deletions

View File

@@ -81,6 +81,8 @@ void print_source_line( PARSE * );
RULE * bind_builtin( char * name, LIST * (* f)( PARSE *, FRAME * ), int flags, char * * args )
{
PARSE * p;
RULE * result;
argument_list* arg_list = 0;
if ( args )
@@ -89,8 +91,13 @@ RULE * bind_builtin( char * name, LIST * (* f)( PARSE *, FRAME * ), int flags, c
lol_build( arg_list->data, args );
}
return new_rule_body( root_module(), name, arg_list,
parse_make( f, P0, P0, P0, C0, C0, flags ), 1 );
p = parse_make( f, P0, P0, P0, C0, C0, flags );
result = new_rule_body( root_module(), name, arg_list, p, 1 );
parse_free( p );
return result;
}
@@ -736,7 +743,7 @@ static LIST * append_if_exists( LIST * list, char * file )
LIST * glob1( char * dirname, char * pattern )
{
LIST * plist = list_new( L0, pattern );
LIST * plist = list_new( L0, newstr(pattern) );
struct globbing globbing;
globbing.results = L0;
@@ -798,24 +805,26 @@ LIST * glob_recursive( char * pattern )
dirs = has_wildcards( dirname->value )
? glob_recursive( dirname->value )
: list_new( dirs, dirname->value );
: list_new( dirs, newstr( dirname->value ) );
if ( has_wildcards( basename->value ) )
{
for ( ; dirs; dirs = dirs->next )
result = list_append( result, glob1( dirs->string,
LIST * d;
for ( d = dirs ; d; d = d->next )
result = list_append( result, glob1( d->string,
basename->value ) );
}
else
{
LIST * d;
string file_string[ 1 ];
string_new( file_string );
/* No wildcard in basename. */
for ( ; dirs; dirs = dirs->next )
for ( d = dirs ; d; d = d->next )
{
path->f_dir.ptr = dirs->string;
path->f_dir.len = strlen( dirs->string );
path->f_dir.ptr = d->string;
path->f_dir.len = strlen( d->string );
path_build( path, file_string, 0 );
result = append_if_exists( result, file_string->value );
@@ -828,6 +837,8 @@ LIST * glob_recursive( char * pattern )
string_free( dirname );
string_free( basename );
list_free( dirs );
}
else
{
@@ -1311,7 +1322,7 @@ LIST * builtin_update( PARSE * parse, FRAME * frame )
LIST * arg1 = lol_get( frame->args, 0 );
clear_targets_to_update();
for ( ; arg1; arg1 = list_next( arg1 ) )
mark_target_for_updating( newstr( arg1->string ) );
mark_target_for_updating( copystr( arg1->string ) );
return result;
}
@@ -1371,7 +1382,7 @@ LIST * builtin_update_now( PARSE * parse, FRAME * frame )
for (i = 0 ; targets; targets = list_next( targets ) )
targets2[ i++ ] = targets->string;
status |= make( targets_count, targets2, anyhow);
free( targets );
BJAM_FREE( (void *)targets2 );
if (force)
{
@@ -1409,7 +1420,7 @@ LIST * builtin_search_for_target( PARSE * parse, FRAME * frame )
LIST * arg1 = lol_get( frame->args, 0 );
LIST * arg2 = lol_get( frame->args, 1 );
TARGET * t = search_for_target( arg1->string, arg2 );
return list_new( L0, t->name );
return list_new( L0, copystr( t->name ) );
}
@@ -1582,6 +1593,7 @@ LIST * builtin_native_rule( PARSE * parse, FRAME * frame )
n.name = rule_name->string;
if ( module->native_rules && hashcheck( module->native_rules, (HASHDATA * *)&np ) )
{
args_refer( np->arguments );
new_rule_body( module, np->name, np->arguments, np->procedure, 1 );
}
else
@@ -1716,7 +1728,7 @@ LIST *builtin_pad( PARSE *parse, FRAME *frame )
int current = strlen (string);
int desired = atoi(width_s);
if (current >= desired)
return list_new (L0, string);
return list_new (L0, copystr( string ) );
else
{
char *buffer = malloc (desired + 1);
@@ -2063,7 +2075,7 @@ PyObject * bjam_define_action( PyObject * self, PyObject * args )
"bind list has non-string type" );
return NULL;
}
bindlist = list_new( bindlist, PyString_AsString( next ) );
bindlist = list_new( bindlist, newstr( PyString_AsString( next ) ) );
}
new_rule_actions( root_module(), name, newstr( body ), bindlist, flags );

View File

@@ -89,16 +89,21 @@ static void import_base_rule( void * r_, void * d_ )
static void import_base_rules( module_t * class, char * base )
{
module_t * base_module = bindmodule( class_module_name( base ) );
char * module_name = class_module_name( base );
module_t * base_module = bindmodule( module_name );
LIST * imported;
struct import_base_data d;
d.base_name = base;
d.base_module = base_module;
d.class_module = class;
freestr( module_name );
if ( base_module->rules )
hashenumerate( base_module->rules, import_base_rule, &d );
import_module( imported_modules( base_module ), class );
imported = imported_modules( base_module );
import_module( imported, class );
list_free( imported );
}
@@ -112,14 +117,14 @@ char * make_class_module( LIST * xname, LIST * bases, FRAME * frame )
if ( !classes )
classes = hashinit( sizeof( char * ), "classes" );
if ( hashcheck( classes, (HASHDATA * *)&pp ) )
if ( hashenter( classes, (HASHDATA * *)&pp ) )
{
printf( "Class %s already defined\n", xname->string );
abort();
*pp = copystr( xname->string );
}
else
{
hashenter( classes, (HASHDATA * *)&pp );
printf( "Class %s already defined\n", xname->string );
abort();
}
check_defined( bases );
@@ -139,3 +144,18 @@ char * make_class_module( LIST * xname, LIST * bases, FRAME * frame )
return name;
}
static void free_class( void * xclass, void * data )
{
freestr( *(char **)xclass );
}
void class_done( void )
{
if( classes )
{
hashenumerate( classes, free_class, (void *)0 );
hashdone( classes );
classes = 0;
}
}

View File

@@ -9,5 +9,6 @@
#include "frames.h"
char* make_class_module(LIST* xname, LIST* bases, FRAME* frame);
void class_done( void );
#endif

View File

@@ -340,6 +340,7 @@ LIST * compile_include( PARSE * parse, FRAME * frame )
/* We don't expect that file to be included is generated by some
action. Therefore, pass 0 as third argument.
If the name resolves to directory, let it error out. */
freestr( t->boundname );
t->boundname = search( t->name, &t->time, 0, 0 );
popsettings( t->settings );
@@ -403,6 +404,7 @@ LIST * compile_class( PARSE * p, FRAME * frame )
class_module = make_class_module( name, bases, frame );
evaluate_in_module( class_module, p->right, frame );
freestr( class_module );
return L0;
}
@@ -657,7 +659,7 @@ static void type_check
enter_module( typecheck );
/* Prepare the argument list */
lol_add( frame->args, list_new( L0, values->string ) );
lol_add( frame->args, list_new( L0, copystr( values->string ) ) );
error = evaluate_rule( type_name, frame );
exit_module( typecheck );
@@ -742,7 +744,7 @@ collect_arguments( RULE* rule, FRAME* frame )
default:
if ( actual ) /* in case actual is missing */
{
value = list_new( 0, actual->string );
value = list_new( 0, copystr( actual->string ) );
actual = actual->next;
}
}
@@ -878,7 +880,7 @@ call_python_function(RULE* r, FRAME* frame)
if (!s) {
fprintf( stderr, "Non-string object returned by Python call.\n" );
} else {
result = list_new (result, s);
result = list_new (result, newstr( s ) );
}
}
}
@@ -890,7 +892,7 @@ call_python_function(RULE* r, FRAME* frame)
{
char *s = python_to_string(py_result);
if (s)
result = list_new(0, s);
result = list_new(0, newstr( s ) );
else
/* We have tried all we could. Return empty list. There are
cases, e.g. feature.feature function that should return
@@ -956,8 +958,8 @@ evaluate_rule(
return result;
}
rulename = l->string;
rule = bindrule( l->string, frame->module );
rulename = rule->name;
#ifdef HAVE_PYTHON
if ( rule->python_function )
@@ -1063,6 +1065,7 @@ evaluate_rule(
action->rule = rule;
action->targets = targetlist( (TARGETS *)0, lol_get( frame->args, 0 ) );
action->sources = targetlist( (TARGETS *)0, lol_get( frame->args, 1 ) );
action->refs = 1;
/* If we have a group of targets all being built using the same action
* then we must not allow any of them to be used as sources unless they
@@ -1109,6 +1112,8 @@ evaluate_rule(
/* Append this action to the actions of each target. */
for ( t = action->targets; t; t = t->next )
t->target->actions = actionlist( t->target->actions, action );
action_free( action );
}
/* Now recursively compile any parse tree associated with this rule.

View File

@@ -38,6 +38,8 @@ void exec_cmd
int exec_wait();
void exec_done( void );
#define EXEC_CMD_OK 0
#define EXEC_CMD_FAIL 1
#define EXEC_CMD_INTR 2

View File

@@ -1293,4 +1293,10 @@ static void close_alert( HANDLE process )
}
}
void exec_done( void )
{
}
#endif /* USE_EXECNT */

View File

@@ -566,4 +566,15 @@ int exec_wait()
return 1;
}
void exec_done( void )
{
int i;
for( i = 0; i < MAXJOBS; ++i )
{
if( ! cmdtab[i].action ) break;
BJAM_FREE( cmdtab[i].action );
BJAM_FREE( cmdtab[i].target );
}
}
# endif /* USE_EXECUNIX */

View File

@@ -158,4 +158,9 @@ int exec_wait()
return 0;
}
void exec_done( void )
{
}
# endif /* VMS */

View File

@@ -71,9 +71,17 @@ static void remove_files_atexit(void)
}
}
static void free_file_info ( void * xfile, void * data )
{
file_info_t * file = (file_info_t *)xfile;
freestr( file->name );
list_free( file->files );
}
void file_done()
{
remove_files_atexit();
hashenumerate( filecache_hash, free_file_info, (void *)0 );
hashdone( filecache_hash );
}

View File

@@ -393,6 +393,12 @@ hashdone( struct hash *hp )
hash_mem_free( hp->items.datalen, (char *)hp );
}
char *
hashname ( struct hash * hp )
{
return hp->name;
}
static void * hash_mem_alloc(size_t datalen, size_t size)
{
if (sizeof(HASHDATA) == datalen)

View File

@@ -18,6 +18,7 @@ int hashitem ( struct hash * hp, HASHDATA * * data, int enter );
void hashdone ( struct hash * hp );
void hashenumerate( struct hash * hp, void (* f)( void *, void * ), void * data );
int hash_free ( struct hash * hp, HASHDATA * data);
char * hashname ( struct hash * hp );
#define hashenter( hp, data ) ( !hashitem( hp, data, !0 ) )
#define hashcheck( hp, data ) hashitem( hp, data, 0 )

View File

@@ -86,6 +86,7 @@ static char * cache_name( void )
* third argument to search. Expect the location to be specified via
* LOCATE, so pass 0 as the fourth arugment.
*/
freestr( t->boundname );
t->boundname = search( t->name, &t->time, 0, 0 );
popsettings( t->settings );
@@ -179,6 +180,9 @@ void hcache_init()
int header_count = 0;
char * hcachename;
if ( hcachehash )
return;
hcachehash = hashinit( sizeof( HCACHEDATA ), "hcache" );
if ( !( hcachename = cache_name() ) )
@@ -303,10 +307,10 @@ void hcache_done()
return;
if ( !( hcachename = cache_name() ) )
return;
goto cleanup;
if ( !( f = fopen( hcachename, "wb" ) ) )
return;
goto cleanup;
maxage = cache_maxage();
@@ -352,6 +356,17 @@ void hcache_done()
hcachename, header_count, queries ? 100.0 * hits / queries : 0 );
fclose ( f );
cleanup:
for ( c = hcachelist; c; c = c->next )
{
list_free( c->includes );
list_free( c->hdrscan );
freestr( c->boundname );
}
hcachelist = 0;
hashdone( hcachehash );
}

View File

@@ -85,7 +85,7 @@ headers( TARGET *t )
{
FRAME frame[1];
frame_init( frame );
lol_add( frame->args, list_new( L0, t->name ) );
lol_add( frame->args, list_new( L0, copystr( t->name ) ) );
#ifdef OPT_HEADER_CACHE_EXT
lol_add( frame->args, hcache( t, rec, re, hdrscan ) );
#else
@@ -96,7 +96,7 @@ headers( TARGET *t )
{
/* The third argument to HDRRULE is the bound name of
* $(<) */
lol_add( frame->args, list_new( L0, t->boundname ) );
lol_add( frame->args, list_new( L0, copystr( t->boundname ) ) );
list_free( evaluate_rule( hdrrule->string, frame ) );
}

View File

@@ -211,6 +211,8 @@ int anyhow = 0;
extern PyObject * bjam_caller ( PyObject * self, PyObject * args );
#endif
void regex_done();
char *saved_argv0;
int main( int argc, char * * argv, char * * arg_environ )
@@ -541,7 +543,7 @@ int main( int argc, char * * argv, char * * arg_environ )
for ( ; targets; targets = list_next( targets ) )
targets2[ n++ ] = targets->string;
status |= make( targets_count, targets2, anyhow );
free( targets );
BJAM_FREE( (void *)targets2 );
}
else
{
@@ -557,11 +559,24 @@ int main( int argc, char * * argv, char * * arg_environ )
if ( DEBUG_PROFILE )
profile_dump();
#ifdef OPT_HEADER_CACHE_EXT
hcache_done();
#endif
clear_targets_to_update();
/* Widely scattered cleanup. */
var_done();
file_done();
rules_done();
stamps_done();
search_done();
class_done();
modules_done();
regex_done();
exec_done();
list_done();
str_done();
/* Close cmdout. */

File diff suppressed because it is too large Load Diff

View File

@@ -1,27 +1,36 @@
/* A Bison parser, made by GNU Bison 1.875. */
/* A Bison parser, made by GNU Bison 2.4.3. */
/* Skeleton parser for Yacc-like parsing with Bison,
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
/* Skeleton interface for Bison's Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2009, 2010 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* As a special exception, when this file is copied by Bison into a
Bison output file, you may use that output file without restriction.
This special exception was added by the Free Software Foundation
in version 1.24 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
@@ -77,6 +86,7 @@
STRING = 303
};
#endif
/* Tokens. */
#define _BANG_t 258
#define _BANG_EQUALS_t 259
#define _AMPER_t 260
@@ -127,14 +137,13 @@
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef int YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif
extern YYSTYPE yylval;

View File

@@ -325,9 +325,9 @@ arg : ARG
* This needs to be split cleanly out of 'rule'
*/
func : arg lol
func : ARG lol
{ $$.parse = prule( $1.string, $2.parse ); }
| ON_t arg arg lol
| ON_t arg ARG lol
{ $$.parse = pon( $2.parse, prule( $3.string, $4.parse ) ); }
| ON_t arg RETURN_t list
{ $$.parse = pon( $2.parse, $4.parse ); }
@@ -369,3 +369,5 @@ bindlist : /* empty */
| BIND_t list
{ $$.parse = $2.parse; }
;

View File

@@ -281,9 +281,9 @@ arg : ARG
* This needs to be split cleanly out of 'rule'
*/
func : arg lol
func : ARG lol
{ $$.parse = prule( $1.string, $2.parse ); }
| `on` arg arg lol
| `on` arg ARG lol
{ $$.parse = pon( $2.parse, prule( $3.string, $4.parse ) ); }
| `on` arg `return` list
{ $$.parse = pon( $2.parse, $4.parse ); }

View File

@@ -150,7 +150,7 @@ LIST * list_sort( LIST * l )
qsort( strings, len, sizeof( char * ), str_ptr_compare );
for ( ii = 0; ii < len; ++ii )
result = list_append( result, list_new( 0, strings[ ii ] ) );
result = list_append( result, list_new( 0, copystr( strings[ ii ] ) ) );
BJAM_FREE( strings );
@@ -164,12 +164,24 @@ LIST * list_sort( LIST * l )
void list_free( LIST * head )
{
#ifdef BJAM_NO_MEM_CACHE
LIST *l, *tmp;
for( l = head; l; )
{
freestr( l->string );
l->string = 0;
tmp = l;
l = l->next;
BJAM_FREE( tmp );
}
#else
/* Just tack onto freelist. */
if ( head )
{
head->tail->next = freelist;
freelist = head;
}
#endif
}
@@ -236,13 +248,26 @@ LIST * list_unique( LIST * sorted_list )
{
if ( !last_added || strcmp( sorted_list->string, last_added->string ) != 0 )
{
result = list_new( result, sorted_list->string );
result = list_new( result, copystr( sorted_list->string ) );
last_added = sorted_list;
}
}
return result;
}
void list_done()
{
LIST *l, *tmp;
for( l = freelist; l; )
{
freestr( l->string );
l->string = 0;
tmp = l;
l = l->next;
BJAM_FREE( tmp );
}
}
/*
* lol_init() - initialize a LOL (list of lists).

View File

@@ -85,6 +85,7 @@ LIST * list_pop_front( LIST *l );
LIST * list_sort( LIST *l);
LIST * list_unique( LIST *sorted_list);
int list_in(LIST* l, char* value);
void list_done();
# define list_next( l ) ((l)->next)

View File

@@ -155,10 +155,6 @@ int make( int n_targets, char const * * targets, int anyhow )
counts->cantmake > 1 ? "s" : "" );
}
#ifdef OPT_HEADER_CACHE_EXT
hcache_done();
#endif
status = counts->cantfind || counts->cantmake;
{
@@ -290,6 +286,7 @@ void make0
if ( ( t->binding == T_BIND_UNBOUND ) && !( t->flags & T_FLAG_NOTFILE ) )
{
char * another_target;
freestr( t->boundname );
t->boundname = search( t->name, &t->time, &another_target,
t->flags & T_FLAG_ISFILE );
/* If it was detected that this target refers to an already existing and
@@ -797,7 +794,7 @@ static LIST * targets_to_update_ = 0;
void mark_target_for_updating( char * target )
{
targets_to_update_ = list_new( targets_to_update_, target );
targets_to_update_ = list_new( targets_to_update_, newstr( target ) );
}

View File

@@ -567,6 +567,7 @@ static void make1c( state * pState )
( t->status == EXEC_CMD_OK ) &&
!t->rescanned )
{
TARGET * saved_includes;
TARGET * target_to_rescan = t;
SETTINGS * s;
@@ -576,6 +577,7 @@ static void make1c( state * pState )
target_to_rescan = t->original_target;
/* Clean current includes. */
saved_includes = target_to_rescan->includes;
target_to_rescan->includes = 0;
s = copysettings( target_to_rescan->settings );
@@ -586,6 +588,10 @@ static void make1c( state * pState )
if ( target_to_rescan->includes )
{
/* Link the old includes on to make sure that it gets
* cleaned up correctly.
*/
target_to_rescan->includes->includes = saved_includes;
target_to_rescan->includes->rescanned = 1;
/* Tricky. The parents have already been processed, but they
* have not seen the internal node, because it was just
@@ -604,6 +610,10 @@ static void make1c( state * pState )
/* Will be processed below. */
additional_includes = target_to_rescan->includes;
}
else
{
target_to_rescan->includes = saved_includes;
}
}
if ( additional_includes )
@@ -678,7 +688,7 @@ static void call_timing_rule( TARGET * target, timing_info * time )
lol_add( frame->args, list_copy( L0, timing_rule->next ) );
/* target :: the name of the target */
lol_add( frame->args, list_new( L0, target->name ) );
lol_add( frame->args, list_new( L0, copystr( target->name ) ) );
/* start end user system :: info about the action command */
lol_add( frame->args, list_new( list_new( list_new( list_new( L0,
@@ -733,7 +743,7 @@ static void call_action_rule
lol_add( frame->args, list_copy( L0, action_rule->next ) );
/* target :: the name of the target */
lol_add( frame->args, list_new( L0, target->name ) );
lol_add( frame->args, list_new( L0, copystr( target->name ) ) );
/* command status start end user system :: info about the action command */
lol_add( frame->args,
@@ -1139,6 +1149,7 @@ static void make1bind( TARGET * t )
return;
pushsettings( t->settings );
freestr( t->boundname );
t->boundname = search( t->name, &t->time, 0, ( t->flags & T_FLAG_ISFILE ) );
t->binding = t->time ? T_BIND_EXISTS : T_BIND_MISSING;
popsettings( t->settings );

View File

@@ -14,6 +14,7 @@
#include "rules.h"
#include "variable.h"
#include "strings.h"
#include "native.h"
#include <assert.h>
static struct hash * module_hash = 0;
@@ -89,16 +90,44 @@ static void delete_rule_( void * xrule, void * data )
}
static void delete_native_rule( void * xrule, void * data )
{
native_rule_t * rule = (native_rule_t *)xrule;
if ( rule->arguments )
args_free( rule->arguments );
freestr( rule->name );
if ( rule->procedure )
parse_free( rule->procedure );
}
static void delete_imported_modules( void * xmodule_name, void * data )
{
freestr( *(char * *)xmodule_name );
}
void delete_module( module_t * m )
{
/* Clear out all the rules. */
if ( m->rules )
{
char * name;
hashenumerate( m->rules, delete_rule_, (void *)0 );
name = hashname( m->rules );
hashdone( m->rules );
freestr( name );
m->rules = 0;
}
if ( m->native_rules )
{
char * name;
hashenumerate( m->native_rules, delete_native_rule, (void *)0 );
hashdone( m->native_rules );
m->native_rules = 0;
}
if ( m->variables )
{
var_hash_swap( &m->variables );
@@ -106,9 +135,35 @@ void delete_module( module_t * m )
var_hash_swap( &m->variables );
m->variables = 0;
}
if ( m->imported_modules )
{
hashenumerate( m->imported_modules, delete_imported_modules, (void *)0 );
hashdone( m->imported_modules );
m->imported_modules = 0;
}
}
static void delete_module_( void * xmodule, void * data )
{
module_t *m = (module_t *)xmodule;
delete_module( m );
if ( m->name )
{
freestr( m->name );
}
}
void modules_done()
{
hashenumerate( module_hash, delete_module_, (void *)0 );
hashdone( module_hash );
module_hash = 0;
}
module_t * root_module()
{
static module_t * root = 0;
@@ -143,7 +198,10 @@ void import_module( LIST * module_names, module_t * target_module )
{
char * s = module_names->string;
char * * ss = &s;
hashenter( h, (HASHDATA * *)&ss );
if( hashenter( h, (HASHDATA * *)&ss ) )
{
*ss = copystr( s );
}
}
PROFILE_EXIT( IMPORT_MODULE );

View File

@@ -32,6 +32,7 @@ LIST* imported_modules(module_t* module);
struct hash* demand_rules( module_t* );
void modules_done();
#endif

View File

@@ -112,7 +112,7 @@ LIST *order( PARSE *parse, FRAME *frame )
int i;
tmp = arg;
for (i = 0; i < order[index]; ++i, tmp = tmp->next);
result = list_new(result, tmp->string);
result = list_new(result, copystr(tmp->string));
}
}

View File

@@ -59,9 +59,9 @@ LIST *property_set_create( PARSE *parse, FRAME *frame )
LIST* g = get_grist(tmp->string);
LIST* att = call_rule("feature.attributes", frame, g, 0);
if (list_in(att, "order-sensitive")) {
order_sensitive = list_new( order_sensitive, tmp->string);
order_sensitive = list_new( order_sensitive, copystr(tmp->string));
} else {
sorted = list_new( sorted, tmp->string);
sorted = list_new( sorted, copystr(tmp->string));
}
list_free(att);
}
@@ -84,12 +84,13 @@ LIST *property_set_create( PARSE *parse, FRAME *frame )
if (val == 0)
{
val = call_rule("new", frame,
list_append(list_new(0, "property-set"), unique), 0);
list_append(list_new(0, newstr("property-set")), unique), 0);
var_set(newstr(var->value), list_copy(0, val), VAR_SET);
var_set(var->value, list_copy(0, val), VAR_SET);
}
else
{
list_free(unique);
val = list_copy(0, val);
}

View File

@@ -3,6 +3,7 @@
/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */
#include "../native.h"
#include "../newstr.h"
# ifndef max
# define max( a,b ) ((a)>(b)?(a):(b))
@@ -26,7 +27,7 @@ LIST *sequence_select_highest_ranked( PARSE *parse, FRAME *frame )
for (; rank; rank = rank->next, elements = elements->next)
if (atoi(rank->string) == highest_rank)
result = list_new(result, elements->string);
result = list_new(result, copystr(elements->string));
return result;
}

View File

@@ -3,6 +3,7 @@
/* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */
#include "../native.h"
#include "../newstr.h"
/*
local result = ;
@@ -26,7 +27,7 @@ LIST *set_difference( PARSE *parse, FRAME *frame )
for(; b; b = b->next)
{
if (!list_in(a, b->string))
result = list_new(result, b->string);
result = list_new(result, copystr(b->string));
}
return result;
}

View File

@@ -4,6 +4,7 @@
#include "native.h"
#include "hash.h"
#include "newstr.h"
# define P0 (PARSE *)0
# define C0 (char *)0
@@ -19,7 +20,7 @@ void declare_native_rule(char* module, char* rule, char** args,
{
native_rule_t n, *np = &n;
n.name = rule;
n.name = newstr( rule );
if (args)
{
n.arguments = args_new();

View File

@@ -107,6 +107,14 @@ static char * allocate( size_t const n )
char * newstr( char * string )
{
#ifdef BJAM_NO_MEM_CACHE
int l = strlen( string );
char * m = (char *)BJAM_MALLOC( l + 1 );
strtotal += l + 1;
memcpy( m, string, l + 1 );
return m;
#else
STRING str;
STRING * s = &str;
@@ -127,6 +135,7 @@ char * newstr( char * string )
strcount_in += 1;
return *s;
#endif
}
@@ -136,8 +145,12 @@ char * newstr( char * string )
char * copystr( char * s )
{
#ifdef BJAM_NO_MEM_CACHE
return newstr( s );
#else
strcount_in += 1;
return s;
#endif
}
@@ -147,16 +160,36 @@ char * copystr( char * s )
void freestr( char * s )
{
strcount_out += 1;
#ifdef BJAM_NO_MEM_CACHE
BJAM_FREE( s );
#endif
if( s )
strcount_out += 1;
}
#ifdef BJAM_NEWSTR_NO_ALLOCATE
static void freestring( void * xstring, void * data )
{
BJAM_FREE( *(STRING *)xstring );
}
#endif
/*
* str_done() - free string tables.
*/
void str_done()
{
#ifdef BJAM_NEWSTR_NO_ALLOCATE
hashenumerate( strhash, freestring, (void *)0 );
#else
/* Reclaim string blocks. */
while ( strblock_chain != 0 )
{
@@ -165,6 +198,8 @@ void str_done()
strblock_chain = n;
}
#endif
hashdone( strhash );
if ( DEBUG_MEM )

View File

@@ -50,7 +50,7 @@ void parse_file( char * f, FRAME * frame )
break;
/* Run the parse tree. */
parse_evaluate( p, frame );
list_free( parse_evaluate( p, frame ) );
parse_free( p );
}
}
@@ -85,12 +85,13 @@ PARSE * parse_make(
if ( left )
{
p->file = left->file;
p->file = copystr( left->file );
p->line = left->line;
}
else
{
yyinput_stream( &p->file, &p->line );
p->file = copystr( p->file );
}
return p;
@@ -120,6 +121,8 @@ void parse_free( PARSE * p )
parse_free( p->third );
if ( p->rulename )
freestr( p->rulename );
if ( p->file )
freestr( p->file );
BJAM_FREE( (char *)p );
}

View File

@@ -62,5 +62,5 @@ pwd(void)
return L0;
}
}
return list_new(L0, pwd_result);
return list_new(L0, copystr( pwd_result ) );
}

View File

@@ -135,7 +135,8 @@ void rule_free( RULE * r )
{
freestr( r->name );
r->name = "";
parse_free( r->procedure );
if ( r->procedure )
parse_free( r->procedure );
r->procedure = 0;
if ( r->arguments )
args_free( r->arguments );
@@ -168,8 +169,11 @@ TARGET * bindtarget( char const * target_name )
{
memset( (char *)t, '\0', sizeof( *t ) );
t->name = newstr( (char *)target_name ); /* never freed */
t->boundname = t->name; /* default for T_FLAG_NOTFILE */
t->boundname = copystr( t->name ); /* default for T_FLAG_NOTFILE */
}
#ifdef NT
freestr( (char *)target_name );
#endif
return t;
}
@@ -190,6 +194,7 @@ static void bind_explicitly_located_target( void * xtarget, void * data )
/* We are binding a target with explicit LOCATE. So third
* argument is of no use: nothing will be returned through it.
*/
freestr( t->boundname );
t->boundname = search( t->name, &t->time, 0, 0 );
popsettings( t->settings );
break;
@@ -292,7 +297,7 @@ TARGET * copytarget( const TARGET * ot )
TARGET * t = (TARGET *)BJAM_MALLOC( sizeof( *t ) );
memset( (char *)t, '\0', sizeof( *t ) );
t->name = copystr( ot->name );
t->boundname = t->name;
t->boundname = copystr( t->name );
t->flags |= T_FLAG_NOTFILE | T_FLAG_INTERNAL;
@@ -367,6 +372,21 @@ TARGETS * targetchain( TARGETS * chain, TARGETS * targets )
return chain;
}
/*
* action_free - decrement the ACTIONs refrence count
* and (maybe) free it.
*/
void action_free ( ACTION * action )
{
if ( --action->refs == 0 )
{
freetargets( action->targets );
freetargets( action->sources );
BJAM_FREE( action );
}
}
/*
* actionlist() - append to an ACTION chain.
*/
@@ -377,6 +397,7 @@ ACTIONS * actionlist( ACTIONS * chain, ACTION * action )
actions->action = action;
++action->refs;
if ( !chain ) chain = actions;
else chain->tail->next = actions;
chain->tail = actions;
@@ -500,6 +521,7 @@ void freeactions( ACTIONS * chain )
while ( chain )
{
ACTIONS * n = chain->next;
action_free( chain->action );
BJAM_FREE( chain );
chain = n;
}
@@ -527,10 +549,19 @@ void freesettings( SETTINGS * v )
static void freetarget( void * xt, void * data )
{
TARGET * t = (TARGET *)xt;
if ( t->settings ) freesettings( t->settings );
if ( t->depends ) freetargets ( t->depends );
if ( t->includes ) freetarget ( t->includes, (void *)0 );
if ( t->actions ) freeactions ( t->actions );
if ( t->name ) freestr ( t->name );
if ( t->boundname ) freestr ( t->boundname );
if ( t->settings ) freesettings( t->settings );
if ( t->depends ) freetargets ( t->depends );
if ( t->dependants ) freetargets ( t->dependants );
if ( t->parents ) freetargets ( t->parents );
if ( t->actions ) freeactions ( t->actions );
if ( t->includes )
{
freetarget( t->includes, (void *)0 );
BJAM_FREE( t->includes );
}
}
@@ -641,7 +672,7 @@ static void set_rule_body( RULE * rule, argument_list * args, PARSE * procedure
static char * global_rule_name( RULE * r )
{
if ( r->module == root_module() )
return r->name;
return copystr( r->name );
{
char name[4096] = "";

View File

@@ -111,6 +111,7 @@ struct _action
TARGETS * sources; /* aka $(>) */
char running; /* has been started */
char status; /* see TARGET status */
int refs;
};
/* SETTINGS - variables to set when executing a TARGET's ACTIONS. */
@@ -240,6 +241,7 @@ struct _target
/* Action related functions. */
void action_free ( ACTION * );
ACTIONS * actionlist ( ACTIONS *, ACTION * );
void freeactions ( ACTIONS * );
SETTINGS * addsettings ( SETTINGS *, int flag, char * symbol, LIST * value );
@@ -273,6 +275,7 @@ TARGETS * targetentry ( TARGETS * chain, TARGET * );
void target_include ( TARGET * including, TARGET * included );
TARGETS * targetlist ( TARGETS * chain, LIST * target_names );
void touch_target ( char * t );
void clear_includes ( TARGET * );
/* Final module cleanup. */
void rules_done();

View File

@@ -62,7 +62,7 @@ void call_bind_rule
lol_add( frame->args, list_new( L0, boundname ) );
if ( lol_get( frame->args, 1 ) )
evaluate_rule( bind_rule->string, frame );
list_free( evaluate_rule( bind_rule->string, frame ) );
/* Clean up */
frame_free( frame );
@@ -213,7 +213,10 @@ search(
/* CONSIDER: we probably should issue a warning is another file
is explicitly bound to the same location. This might break
compatibility, though. */
hashenter( explicit_bindings, (HASHDATA * *)&ba );
if ( hashenter( explicit_bindings, (HASHDATA * *)&ba ) )
{
ba->binding = copystr( boundname );
}
}
/* prepare a call to BINDRULE if the variable is set */
@@ -221,3 +224,16 @@ search(
return boundname;
}
static void free_binding( void * xbinding, void * data )
{
BINDING * binding = (BINDING *)xbinding;
freestr( binding->binding );
}
void search_done( void )
{
hashenumerate( explicit_bindings, free_binding, (void *)0 );
hashdone( explicit_bindings );
}

View File

@@ -9,3 +9,4 @@
*/
char *search( char *target, time_t *time, char **another_target, int file );
void search_done( void );

View File

@@ -27,7 +27,10 @@ regexp* regex_compile( const char* pattern )
regex_hash = hashinit(sizeof(regex_entry), "regex");
if ( hashenter( regex_hash, (HASHDATA **)&e ) )
{
e->pattern = newstr( (char*)pattern );
e->regex = regcomp( (char*)pattern );
}
return e->regex;
}
@@ -92,3 +95,17 @@ builtin_subst(
return result;
}
static void free_regex( void * xregex, void * data )
{
regex_entry * regex = (regex_entry *)xregex;
freestr( (char *)regex->pattern );
BJAM_FREE( regex->regex );
}
void regex_done()
{
hashenumerate( regex_hash, free_regex, (void *)0 );
hashdone( regex_hash );
}

View File

@@ -215,6 +215,10 @@ static void time_enter( void * closure, char * target, int found, time_t time )
printf( "time ( %s ) : %s\n", target, time_progress[ b->progress ] );
}
static void free_timestamps ( void * xbinding, void * data )
{
freestr( ((BINDING *)xbinding)->name );
}
/*
* stamps_done() - free timestamp tables.
@@ -222,5 +226,6 @@ static void time_enter( void * closure, char * target, int found, time_t time )
void stamps_done()
{
hashenumerate( bindhash, free_timestamps, (void *)0 );
hashdone( bindhash );
}

View File

@@ -323,6 +323,7 @@ int var_string( char * in, char * out, int outsize, LOL * lol )
if ( dollar )
{
LIST * l = var_expand( L0, lastword, out, lol, 0 );
LIST * saved = l;
out = lastword;
@@ -339,7 +340,7 @@ int var_string( char * in, char * out, int outsize, LOL * lol )
if ( l ) *out++ = ' ';
}
list_free( l );
list_free( saved );
}
}
@@ -424,6 +425,7 @@ void var_string_to_file( const char * in, int insize, const char * out, LOL * lo
if ( dollar )
{
LIST * l = var_expand( L0, (char *)output_0, (char *)output_1, lol, 0 );
LIST * saved = l;
while ( l )
{
@@ -437,7 +439,7 @@ void var_string_to_file( const char * in, int insize, const char * out, LOL * lo
}
}
list_free( l );
list_free( saved );
}
else if ( output_0 < output_1 )
{
@@ -472,6 +474,9 @@ void var_string_to_file( const char * in, int insize, const char * out, LOL * lo
}
static LIST * saved_var = 0;
/*
* var_get() - get value of a user defined symbol.
*
@@ -485,23 +490,28 @@ LIST * var_get( char * symbol )
/* Some "fixed" variables... */
if ( strcmp( "TMPDIR", symbol ) == 0 )
{
result = list_new( L0, newstr( (char *)path_tmpdir() ) );
list_free( saved_var );
result = saved_var = list_new( L0, newstr( (char *)path_tmpdir() ) );
}
else if ( strcmp( "TMPNAME", symbol ) == 0 )
{
result = list_new( L0, newstr( (char *)path_tmpnam() ) );
list_free( saved_var );
result = saved_var = list_new( L0, (char *)path_tmpnam() );
}
else if ( strcmp( "TMPFILE", symbol ) == 0 )
{
result = list_new( L0, newstr( (char *)path_tmpfile() ) );
list_free( saved_var );
result = saved_var = list_new( L0, (char *)path_tmpfile() );
}
else if ( strcmp( "STDOUT", symbol ) == 0 )
{
result = list_new( L0, newstr( "STDOUT" ) );
list_free( saved_var );
result = saved_var = list_new( L0, newstr( "STDOUT" ) );
}
else if ( strcmp( "STDERR", symbol ) == 0 )
{
result = list_new( L0, newstr( "STDERR" ) );
list_free( saved_var );
result = saved_var = list_new( L0, newstr( "STDERR" ) );
}
else
#endif
@@ -626,6 +636,8 @@ static void delete_var_( void * xvar, void * data )
void var_done()
{
list_free( saved_var );
saved_var = 0;
hashenumerate( varhash, delete_var_, (void *)0 );
hashdone( varhash );
}