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:
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,5 +9,6 @@
|
||||
#include "frames.h"
|
||||
|
||||
char* make_class_module(LIST* xname, LIST* bases, FRAME* frame);
|
||||
void class_done( void );
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1293,4 +1293,10 @@ static void close_alert( HANDLE process )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void exec_done( void )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
#endif /* USE_EXECNT */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -158,4 +158,9 @@ int exec_wait()
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void exec_done( void )
|
||||
{
|
||||
}
|
||||
|
||||
# endif /* VMS */
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 ) );
|
||||
}
|
||||
|
||||
@@ -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. */
|
||||
|
||||
1733
src/engine/jamgram.c
1733
src/engine/jamgram.c
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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; }
|
||||
;
|
||||
|
||||
|
||||
|
||||
@@ -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 ); }
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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 ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -32,6 +32,7 @@ LIST* imported_modules(module_t* module);
|
||||
|
||||
struct hash* demand_rules( module_t* );
|
||||
|
||||
void modules_done();
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -62,5 +62,5 @@ pwd(void)
|
||||
return L0;
|
||||
}
|
||||
}
|
||||
return list_new(L0, pwd_result);
|
||||
return list_new(L0, copystr( pwd_result ) );
|
||||
}
|
||||
|
||||
@@ -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] = "";
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -9,3 +9,4 @@
|
||||
*/
|
||||
|
||||
char *search( char *target, time_t *time, char **another_target, int file );
|
||||
void search_done( void );
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user