Further halloc:ification if fish

darcs-hash:20060206181101-ac50b-db0aac307a81e7f0677acd15a9f38ff8c7ff36d2.gz
This commit is contained in:
axel 2006-02-07 04:11:01 +10:00
parent 4e77ee4516
commit 57d53c70e3
10 changed files with 113 additions and 172 deletions

View file

@ -82,7 +82,7 @@ FISH_OBJS := $(COMMON_OBJS) $(COMMON_OBJS_WITH_CODE) \
# All objects that the system needs to build fish_pager # All objects that the system needs to build fish_pager
FISH_PAGER_OBJS := fish_pager.o common.o output.o util.o wutil.o \ FISH_PAGER_OBJS := fish_pager.o common.o output.o util.o wutil.o \
tokenizer.o input_common.o env_universal.o env_universal_common.o \ tokenizer.o input_common.o env_universal.o env_universal_common.o \
translate.o translate.o halloc.o
# All objects that the system needs to build fish_tests # All objects that the system needs to build fish_tests
FISH_TESTS_OBJS := $(COMMON_OBJS) $(COMMON_OBJS_WITH_CODE) \ FISH_TESTS_OBJS := $(COMMON_OBJS) $(COMMON_OBJS_WITH_CODE) \
@ -90,11 +90,11 @@ FISH_TESTS_OBJS := $(COMMON_OBJS) $(COMMON_OBJS_WITH_CODE) \
# All objects that the system needs to build fishd # All objects that the system needs to build fishd
FISHD_OBJS := fishd.o env_universal_common.o common.o util.o wutil.o \ FISHD_OBJS := fishd.o env_universal_common.o common.o util.o wutil.o \
doc_src/fishd.o doc_src/fishd.o halloc.o
# All objects needed to build mimedb # All objects needed to build mimedb
MIME_OBJS := mimedb.o xdgmimealias.o xdgmime.o xdgmimeglob.o \ MIME_OBJS := mimedb.o xdgmimealias.o xdgmime.o xdgmimeglob.o \
xdgmimeint.o xdgmimemagic.o xdgmimeparent.o wutil.o xdgmimeint.o xdgmimemagic.o xdgmimeparent.o wutil.o halloc.o
# #
# Files containing documentation for builtins. Should be listed # Files containing documentation for builtins. Should be listed

View file

@ -406,6 +406,7 @@ static int builtin_block( wchar_t **argv )
{ {
eb->next = block->first_event_block; eb->next = block->first_event_block;
block->first_event_block = eb; block->first_event_block = eb;
halloc_register( block, eb );
} }
else else
{ {
@ -917,10 +918,15 @@ static int builtin_function( wchar_t **argv )
int res=0; int res=0;
wchar_t *desc=0; wchar_t *desc=0;
int is_binding=0; int is_binding=0;
array_list_t *events = al_new(); array_list_t *events;
int i;
woptind=0; woptind=0;
parser_push_block( FUNCTION_DEF );
events=halloc( current_block, sizeof(array_list_t ) );
al_init( events );
const static struct woption const static struct woption
long_options[] = long_options[] =
{ {
@ -1003,7 +1009,7 @@ static int builtin_function( wchar_t **argv )
break; break;
} }
e = calloc( 1, sizeof(event_t)); e = halloc( current_block, sizeof(event_t));
if( !e ) if( !e )
die_mem(); die_mem();
e->type = EVENT_SIGNAL; e->type = EVENT_SIGNAL;
@ -1027,11 +1033,11 @@ static int builtin_function( wchar_t **argv )
break; break;
} }
e = calloc( 1, sizeof(event_t)); e = halloc( current_block, sizeof(event_t));
if( !e ) if( !e )
die_mem(); die_mem();
e->type = EVENT_VARIABLE; e->type = EVENT_VARIABLE;
e->param1.variable = wcsdup( woptarg ); e->param1.variable = halloc_register( current_block, wcsdup( woptarg ));
e->function_name=0; e->function_name=0;
al_push( events, e ); al_push( events, e );
break; break;
@ -1044,7 +1050,7 @@ static int builtin_function( wchar_t **argv )
wchar_t *end; wchar_t *end;
event_t *e; event_t *e;
e = calloc( 1, sizeof(event_t)); e = halloc( current_block, sizeof(event_t));
if( !e ) if( !e )
die_mem(); die_mem();
@ -1154,6 +1160,8 @@ static int builtin_function( wchar_t **argv )
} }
} }
halloc_register( current_block, events->arr );
if( res ) if( res )
{ {
int i; int i;
@ -1186,31 +1194,25 @@ static int builtin_function( wchar_t **argv )
sb_append2( sb_err, sb_append2( sb_err,
nxt, L" ", (void *)0 ); nxt, L" ", (void *)0 );
} }
free( names_arr ); halloc_free( names_arr );
al_destroy( &names ); al_destroy( &names );
sb_append( sb_err, L"\n" ); sb_append( sb_err, L"\n" );
parser_pop_block();
parser_push_block( FAKE ); parser_push_block( FAKE );
al_foreach( events, (void (*)(const void *))&event_free );
al_destroy( events );
halloc_free( events );
} }
else else
{ {
int i; current_block->param1.function_name=halloc_register( current_block, wcsdup(argv[woptind]));
current_block->param2.function_description=desc?halloc_register( current_block, wcsdup(desc)):0;
parser_push_block( FUNCTION_DEF );
current_block->param1.function_name=wcsdup(argv[woptind]);
current_block->param2.function_description=desc?wcsdup(desc):0;
current_block->param3.function_is_binding = is_binding; current_block->param3.function_is_binding = is_binding;
current_block->param4.function_events = events; current_block->param4.function_events = events;
for( i=0; i<al_get_count( events ); i++ ) for( i=0; i<al_get_count( events ); i++ )
{ {
event_t *e = (event_t *)al_get( events, i ); event_t *e = (event_t *)al_get( events, i );
e->function_name = wcsdup( current_block->param1.function_name ); e->function_name = current_block->param1.function_name;
} }
} }
current_block->tok_pos = parser_get_pos(); current_block->tok_pos = parser_get_pos();
@ -2579,12 +2581,14 @@ static int builtin_for( wchar_t **argv )
int i; int i;
current_block->tok_pos = parser_get_pos(); current_block->tok_pos = parser_get_pos();
current_block->param1.for_variable = wcsdup( argv[1] ); current_block->param1.for_variable = halloc_register( current_block, wcsdup( argv[1] ));
for( i=argc-1; i>3; i-- ) for( i=argc-1; i>3; i-- )
{ {
al_push( &current_block->param2.for_vars, wcsdup(argv[ i ] )); al_push( &current_block->param2.for_vars, halloc_register( current_block, wcsdup(argv[ i ] ) ) );
} }
halloc_register( current_block, current_block->param2.for_vars.arr );
if( argc > 3 ) if( argc > 3 )
{ {
env_set( current_block->param1.for_variable, argv[3], ENV_LOCAL ); env_set( current_block->param1.for_variable, argv[3], ENV_LOCAL );
@ -2669,10 +2673,7 @@ static int builtin_end( wchar_t **argv )
*/ */
if( current_block->loop_status == LOOP_BREAK ) if( current_block->loop_status == LOOP_BREAK )
{ {
while( al_get_count( &current_block->param2.for_vars ) ) al_truncate( &current_block->param2.for_vars, 0 );
{
free( (void *)al_pop( &current_block->param2.for_vars ) );
}
} }
if( al_get_count( &current_block->param2.for_vars ) ) if( al_get_count( &current_block->param2.for_vars ) )
@ -2681,7 +2682,6 @@ static int builtin_end( wchar_t **argv )
env_set( current_block->param1.for_variable, val, ENV_LOCAL); env_set( current_block->param1.for_variable, val, ENV_LOCAL);
current_block->loop_status = LOOP_NORMAL; current_block->loop_status = LOOP_NORMAL;
current_block->skip = 0; current_block->skip = 0;
free(val);
kill_block = 0; kill_block = 0;
parser_set_pos( current_block->tok_pos ); parser_set_pos( current_block->tok_pos );
@ -2901,7 +2901,7 @@ static int builtin_switch( wchar_t **argv )
else else
{ {
parser_push_block( SWITCH ); parser_push_block( SWITCH );
current_block->param1.switch_value = wcsdup( argv[1]); current_block->param1.switch_value = halloc_register( current_block, wcsdup( argv[1]));
current_block->skip=1; current_block->skip=1;
current_block->param2.switch_taken=0; current_block->param2.switch_taken=0;
} }

View file

@ -125,7 +125,11 @@ wchar_t **list_to_char_arr( void *context, array_list_t *l )
die_mem(); die_mem();
} }
for( i=0; i<al_get_count( l ); i++ ) for( i=0; i<al_get_count( l ); i++ )
{
res[i] = (wchar_t *)al_get(l,i); res[i] = (wchar_t *)al_get(l,i);
if( context )
halloc_register( context, res[i] );
}
res[i]='\0'; res[i]='\0';
return res; return res;
} }

View file

@ -84,7 +84,9 @@ extern wchar_t *program_name;
/** /**
Take an array_list_t containing wide strings and converts them to a Take an array_list_t containing wide strings and converts them to a
single null-terminated wchar_t **. The array is allocated using single null-terminated wchar_t **. The array is allocated using
halloc, and uses the \c context parameter as context. halloc, and uses the \c context parameter as context. If \c context
is not noll, all elements of the \c array_list_t are also
registered to \c context using \c halloc_register().
*/ */
wchar_t **list_to_char_arr( void *context, array_list_t *l ); wchar_t **list_to_char_arr( void *context, array_list_t *l );

4
exec.c
View file

@ -792,7 +792,7 @@ void exec( job_t *j )
int i; int i;
string_buffer_t sb; string_buffer_t sb;
wchar_t * def = halloc_wcsdup( j, function_get_definition( p->argv[0] )); wchar_t * def = halloc_register( j, wcsdup( function_get_definition( p->argv[0] )));
//fwprintf( stderr, L"run function %ls\n", argv[0] ); //fwprintf( stderr, L"run function %ls\n", argv[0] );
if( def == 0 ) if( def == 0 )
{ {
@ -803,7 +803,7 @@ void exec( job_t *j )
parser_push_block( FUNCTION_CALL ); parser_push_block( FUNCTION_CALL );
current_block->param2.function_call_process = p; current_block->param2.function_call_process = p;
current_block->param1.function_name = wcsdup( p->argv[0] ); current_block->param1.function_name = halloc_register( current_block, wcsdup( p->argv[0] ) );
if( builtin_count_args(p->argv)>1 ) if( builtin_count_args(p->argv)>1 )
{ {

View file

@ -171,13 +171,11 @@ void expand_variable_array( const wchar_t *val, array_list_t *out )
if( *pos == ARRAY_SEP ) if( *pos == ARRAY_SEP )
{ {
*pos=0; *pos=0;
al_push( out, wcsdup(start) ); al_push( out, start==cpy?cpy:wcsdup(start) );
start=pos+1; start=pos+1;
} }
} }
al_push( out, wcsdup(start) ); al_push( out, start==cpy?cpy:wcsdup(start) );
free(cpy);
} }
} }

View file

@ -1,5 +1,9 @@
/** \file halloc.c /** \file halloc.c
A hierarchical memory allocation system
A hierarchical memory allocation system. Works just like talloc
used in Samba, except that an arbitrary block allocated with
malloc() can be registered to be freed by halloc_free.
*/ */
#include "config.h" #include "config.h"
@ -14,6 +18,7 @@
typedef struct halloc typedef struct halloc
{ {
array_list_t children; array_list_t children;
array_list_t hchildren;
long long data[0]; long long data[0];
} }
halloc_t; halloc_t;
@ -26,20 +31,37 @@ static halloc_t *halloc_from_data( void *data )
void *halloc( void *context, size_t size ) void *halloc( void *context, size_t size )
{ {
halloc_t *res = (halloc_t *)calloc( 1, sizeof(halloc_t) + size );
if( !res ) halloc_t *me, *parent;
me = (halloc_t *)calloc( 1, sizeof(halloc_t) + size );
if( !me )
return 0; return 0;
al_init( &res->children ); al_init( &me->children );
if( context ) if( context )
{ {
halloc_t *parent = halloc_from_data( context ); parent = halloc_from_data( context );
al_push( &parent->children, &res->data ); al_push( &parent->hchildren, &me->data );
} }
return &res->data;
return &me->data;
} }
void *halloc_register( void *context, void *data )
{
halloc_t *me;
if( !context )
return data;
me = halloc_from_data( context );
al_push( &me->children, data );
return data;
}
void halloc_free( void *context ) void halloc_free( void *context )
{ {
halloc_t *me; halloc_t *me;
@ -47,32 +69,10 @@ void halloc_free( void *context )
return; return;
me = halloc_from_data( context ); me = halloc_from_data( context );
al_foreach( &me->children, (void (*)(const void *))&halloc_free ); al_foreach( &me->hchildren, (void (*)(const void *))&halloc_free );
al_foreach( &me->children, (void (*)(const void *))&free );
al_destroy( &me->children ); al_destroy( &me->children );
al_destroy( &me->hchildren );
free(me); free(me);
} }
wchar_t *halloc_wcsdup( void *context, const wchar_t *in )
{
size_t len=wcslen(in);
wchar_t *out = halloc( context, sizeof( wchar_t)*(len+1));
if( out == 0 )
{
die_mem();
}
memcpy( out, in, sizeof( wchar_t)*(len+1));
return out;
}
wchar_t *halloc_wcsndup( void *context, const wchar_t *in, int c )
{
wchar_t *res = halloc( context, sizeof(wchar_t)*(c+1) );
if( res == 0 )
{
die_mem();
}
wcsncpy( res, in, c );
res[c] = L'\0';
return res;
}

View file

@ -1,18 +1,35 @@
/** \file halloc.h /** \file halloc.h
A hierarchical memory allocation system
A hierarchical memory allocation system. Works just like talloc
used in Samba, except that an arbitrary block allocated with
malloc() can be registered to be freed by halloc_free.
*/ */
/** /**
Allocate new memory using specified parent memory context. If \c Allocate new memory using specified parent memory context. If \c
context is null, a new root context is created. context is null, a new root context is created. Context _must_ be
either 0 or the result of a previous call to halloc.
If \c context is null, the resulting block must be freed with a
call to halloc_free().
If \c context is not null, the resulting memory block must never be
explicitly freed, it will be automatically freed whenever the
parent context is freed.
*/ */
void *halloc( void *context, size_t size ); void *halloc( void *context, size_t size );
/** /**
Free memory context and all children. Only root contexts may be Free memory context and all children contexts. Only root contexts
freed explicitly. may be freed explicitly.
*/ */
void halloc_free( void *context ); void halloc_free( void *context );
wchar_t *halloc_wcsdup( void *context, const wchar_t *str ); /**
wchar_t *halloc_wcsndup( void *context, const wchar_t *in, int c ); Free the memory pointed to by \c data when the memory pointed to by
\c context is free:d. Note that this will _not_ turn the specified
memory area into a valid halloc context. Only memory areas created
using a call to halloc() can be used as a context.
*/
void *halloc_register( void *context, void *data );

View file

@ -339,7 +339,7 @@ static int block_count( block_t *b )
void parser_push_block( int type ) void parser_push_block( int type )
{ {
block_t *new = calloc( 1, sizeof( block_t )); block_t *new = halloc( 0, sizeof( block_t ));
new->src_lineno = parser_get_lineno(); new->src_lineno = parser_get_lineno();
new->src_filename = parser_current_filename()?intern(parser_current_filename()):0; new->src_filename = parser_current_filename()?intern(parser_current_filename()):0;
@ -376,9 +376,6 @@ void parser_push_block( int type )
void parser_pop_block() void parser_pop_block()
{ {
event_block_t *eb, *eb_next;
// debug( 3, L"Block pop %ls %d\n", parser_get_block_desc(current_block->type), block_count(current_block)-1 ); // debug( 3, L"Block pop %ls %d\n", parser_get_block_desc(current_block->type), block_count(current_block)-1 );
if( (current_block->type != FUNCTION_DEF ) && if( (current_block->type != FUNCTION_DEF ) &&
@ -388,51 +385,9 @@ void parser_pop_block()
env_pop(); env_pop();
} }
switch( current_block->type)
{
case FOR:
{
free( current_block->param1.for_variable );
al_foreach( &current_block->param2.for_vars,
(void (*)(const void *))&free );
al_destroy( &current_block->param2.for_vars );
break;
}
case SWITCH:
{
free( current_block->param1.switch_value );
break;
}
case FUNCTION_DEF:
{
free( current_block->param1.function_name );
free( current_block->param2.function_description );
al_foreach( current_block->param4.function_events,
(void (*)(const void *))&event_free );
al_destroy( current_block->param4.function_events );
free( current_block->param4.function_events );
break;
}
case FUNCTION_CALL:
{
free( current_block->param1.function_name );
break;
}
}
for( eb=current_block->first_event_block; eb; eb=eb_next )
{
eb_next = eb->next;
free(eb);
}
block_t *old = current_block; block_t *old = current_block;
current_block = current_block->outer; current_block = current_block->outer;
free( old ); halloc_free( old );
} }
const wchar_t *parser_get_block_desc( int block ) const wchar_t *parser_get_block_desc( int block )
@ -1440,7 +1395,7 @@ static void parse_job_main_loop( process_t *p,
Display help for count Display help for count
*/ */
p->type = INTERNAL_BUILTIN; p->type = INTERNAL_BUILTIN;
wcscpy( p->actual_cmd, L"count" ); p->actual_cmd = L"count";
} }
@ -1465,7 +1420,7 @@ static void parse_job_main_loop( process_t *p,
unmatched_wildcard = 1; unmatched_wildcard = 1;
if( !unmatched ) if( !unmatched )
{ {
unmatched = halloc_wcsdup( j, tok_last( tok )); unmatched = halloc_register( j, wcsdup( tok_last( tok )));
unmatched_pos = tok_get_pos( tok ); unmatched_pos = tok_get_pos( tok );
} }
@ -1532,9 +1487,7 @@ static void parse_job_main_loop( process_t *p,
{ {
case TOK_STRING: case TOK_STRING:
{ {
wchar_t *tmp = expand_one( wcsdup( tok_last( tok ) ), 0); target = (wchar_t *)halloc_register( j, expand_one( wcsdup( tok_last( tok ) ), 0));
target = halloc_wcsdup( j, tmp );
free( tmp );
if( target == 0 && error_code == 0 ) if( target == 0 && error_code == 0 )
{ {
@ -1955,12 +1908,11 @@ static int parse_job( process_t *p,
*/ */
if( current_block->skip ) if( current_block->skip )
{ {
p->actual_cmd = wcsdup(L""); p->actual_cmd = L"";
} }
else else
{ {
p->actual_cmd = halloc_register(j, get_filename( (wchar_t *)al_get( &args, 0 ) ));
p->actual_cmd = get_filename( (wchar_t *)al_get( &args, 0 ) );
/* /*
Check if the specified command exists Check if the specified command exists
@ -2236,13 +2188,11 @@ static void eval_job( tokenizer *tok )
if( newline ) if( newline )
stop_pos = mini( stop_pos, newline - tok_string(tok) ); stop_pos = mini( stop_pos, newline - tok_string(tok) );
j->command = halloc_wcsndup( j, j->command = halloc_register( j, wcsndup( tok_string(tok)+start_pos,
tok_string(tok)+start_pos, stop_pos-start_pos ));
stop_pos-start_pos );
} }
else else
j->command = halloc_wcsdup( j, j->command = L"";
L"" );
if( profile ) if( profile )
{ {

30
proc.c
View file

@ -109,28 +109,6 @@ void proc_init()
sb_init( &event_status ); sb_init( &event_status );
} }
/**
Recursively free a process and those following it
*/
static void free_process( process_t *p )
{
wchar_t **arg;
if( p==0 )
return;
free_process( p->next );
free( p->actual_cmd );
if( p->argv != 0 )
{
for( arg=p->argv; *arg; arg++ )
{
free( *arg );
}
}
}
/** /**
Remove job from list of jobs Remove job from list of jobs
*/ */
@ -164,15 +142,7 @@ static int job_remove( job_t *j )
*/ */
void job_free( job_t * j ) void job_free( job_t * j )
{ {
io_data_t *io, *ionext;
// fwprintf( stderr, L"Remove job %d (%ls)\n", j->job_id, j->command );
job_remove( j ); job_remove( j );
/* Then free ourselves */
free_process( j->first_process);
halloc_free( j ); halloc_free( j );
} }