mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 04:43:10 +00:00
Further halloc:ification if fish
darcs-hash:20060206181101-ac50b-db0aac307a81e7f0677acd15a9f38ff8c7ff36d2.gz
This commit is contained in:
parent
4e77ee4516
commit
57d53c70e3
10 changed files with 113 additions and 172 deletions
|
@ -82,7 +82,7 @@ FISH_OBJS := $(COMMON_OBJS) $(COMMON_OBJS_WITH_CODE) \
|
|||
# All objects that the system needs to build fish_pager
|
||||
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 \
|
||||
translate.o
|
||||
translate.o halloc.o
|
||||
|
||||
# All objects that the system needs to build fish_tests
|
||||
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
|
||||
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
|
||||
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
|
||||
|
|
56
builtin.c
56
builtin.c
|
@ -406,6 +406,7 @@ static int builtin_block( wchar_t **argv )
|
|||
{
|
||||
eb->next = block->first_event_block;
|
||||
block->first_event_block = eb;
|
||||
halloc_register( block, eb );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -917,10 +918,15 @@ static int builtin_function( wchar_t **argv )
|
|||
int res=0;
|
||||
wchar_t *desc=0;
|
||||
int is_binding=0;
|
||||
array_list_t *events = al_new();
|
||||
array_list_t *events;
|
||||
int i;
|
||||
|
||||
woptind=0;
|
||||
|
||||
parser_push_block( FUNCTION_DEF );
|
||||
events=halloc( current_block, sizeof(array_list_t ) );
|
||||
al_init( events );
|
||||
|
||||
const static struct woption
|
||||
long_options[] =
|
||||
{
|
||||
|
@ -1003,7 +1009,7 @@ static int builtin_function( wchar_t **argv )
|
|||
break;
|
||||
}
|
||||
|
||||
e = calloc( 1, sizeof(event_t));
|
||||
e = halloc( current_block, sizeof(event_t));
|
||||
if( !e )
|
||||
die_mem();
|
||||
e->type = EVENT_SIGNAL;
|
||||
|
@ -1027,11 +1033,11 @@ static int builtin_function( wchar_t **argv )
|
|||
break;
|
||||
}
|
||||
|
||||
e = calloc( 1, sizeof(event_t));
|
||||
e = halloc( current_block, sizeof(event_t));
|
||||
if( !e )
|
||||
die_mem();
|
||||
e->type = EVENT_VARIABLE;
|
||||
e->param1.variable = wcsdup( woptarg );
|
||||
e->param1.variable = halloc_register( current_block, wcsdup( woptarg ));
|
||||
e->function_name=0;
|
||||
al_push( events, e );
|
||||
break;
|
||||
|
@ -1044,10 +1050,10 @@ static int builtin_function( wchar_t **argv )
|
|||
wchar_t *end;
|
||||
event_t *e;
|
||||
|
||||
e = calloc( 1, sizeof(event_t));
|
||||
e = halloc( current_block, sizeof(event_t));
|
||||
if( !e )
|
||||
die_mem();
|
||||
|
||||
|
||||
if( ( opt == 'j' ) &&
|
||||
( wcscasecmp( woptarg, L"caller" ) == 0 ) )
|
||||
{
|
||||
|
@ -1154,6 +1160,8 @@ static int builtin_function( wchar_t **argv )
|
|||
}
|
||||
}
|
||||
|
||||
halloc_register( current_block, events->arr );
|
||||
|
||||
if( res )
|
||||
{
|
||||
int i;
|
||||
|
@ -1186,33 +1194,27 @@ static int builtin_function( wchar_t **argv )
|
|||
sb_append2( sb_err,
|
||||
nxt, L" ", (void *)0 );
|
||||
}
|
||||
free( names_arr );
|
||||
halloc_free( names_arr );
|
||||
al_destroy( &names );
|
||||
sb_append( sb_err, L"\n" );
|
||||
|
||||
parser_pop_block();
|
||||
parser_push_block( FAKE );
|
||||
|
||||
al_foreach( events, (void (*)(const void *))&event_free );
|
||||
al_destroy( events );
|
||||
halloc_free( events );
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
parser_push_block( FUNCTION_DEF );
|
||||
current_block->param1.function_name=wcsdup(argv[woptind]);
|
||||
current_block->param2.function_description=desc?wcsdup(desc):0;
|
||||
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;
|
||||
current_block->param3.function_is_binding = is_binding;
|
||||
current_block->param4.function_events = events;
|
||||
|
||||
for( i=0; i<al_get_count( 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->skip = 1;
|
||||
|
||||
|
@ -2579,12 +2581,14 @@ static int builtin_for( wchar_t **argv )
|
|||
|
||||
int i;
|
||||
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-- )
|
||||
{
|
||||
al_push( ¤t_block->param2.for_vars, wcsdup(argv[ i ] ));
|
||||
al_push( ¤t_block->param2.for_vars, halloc_register( current_block, wcsdup(argv[ i ] ) ) );
|
||||
}
|
||||
halloc_register( current_block, current_block->param2.for_vars.arr );
|
||||
|
||||
if( argc > 3 )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
while( al_get_count( ¤t_block->param2.for_vars ) )
|
||||
{
|
||||
free( (void *)al_pop( ¤t_block->param2.for_vars ) );
|
||||
}
|
||||
al_truncate( ¤t_block->param2.for_vars, 0 );
|
||||
}
|
||||
|
||||
if( al_get_count( ¤t_block->param2.for_vars ) )
|
||||
|
@ -2681,8 +2682,7 @@ static int builtin_end( wchar_t **argv )
|
|||
env_set( current_block->param1.for_variable, val, ENV_LOCAL);
|
||||
current_block->loop_status = LOOP_NORMAL;
|
||||
current_block->skip = 0;
|
||||
free(val);
|
||||
|
||||
|
||||
kill_block = 0;
|
||||
parser_set_pos( current_block->tok_pos );
|
||||
/*
|
||||
|
@ -2901,7 +2901,7 @@ static int builtin_switch( wchar_t **argv )
|
|||
else
|
||||
{
|
||||
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->param2.switch_taken=0;
|
||||
}
|
||||
|
|
4
common.c
4
common.c
|
@ -125,7 +125,11 @@ wchar_t **list_to_char_arr( void *context, array_list_t *l )
|
|||
die_mem();
|
||||
}
|
||||
for( i=0; i<al_get_count( l ); i++ )
|
||||
{
|
||||
res[i] = (wchar_t *)al_get(l,i);
|
||||
if( context )
|
||||
halloc_register( context, res[i] );
|
||||
}
|
||||
res[i]='\0';
|
||||
return res;
|
||||
}
|
||||
|
|
4
common.h
4
common.h
|
@ -84,7 +84,9 @@ extern wchar_t *program_name;
|
|||
/**
|
||||
Take an array_list_t containing wide strings and converts them to a
|
||||
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 );
|
||||
|
||||
|
|
4
exec.c
4
exec.c
|
@ -792,7 +792,7 @@ void exec( job_t *j )
|
|||
int i;
|
||||
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] );
|
||||
if( def == 0 )
|
||||
{
|
||||
|
@ -803,7 +803,7 @@ void exec( job_t *j )
|
|||
parser_push_block( FUNCTION_CALL );
|
||||
|
||||
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 )
|
||||
{
|
||||
|
|
6
expand.c
6
expand.c
|
@ -171,13 +171,11 @@ void expand_variable_array( const wchar_t *val, array_list_t *out )
|
|||
if( *pos == ARRAY_SEP )
|
||||
{
|
||||
*pos=0;
|
||||
al_push( out, wcsdup(start) );
|
||||
al_push( out, start==cpy?cpy:wcsdup(start) );
|
||||
start=pos+1;
|
||||
}
|
||||
}
|
||||
al_push( out, wcsdup(start) );
|
||||
|
||||
free(cpy);
|
||||
al_push( out, start==cpy?cpy:wcsdup(start) );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
72
halloc.c
72
halloc.c
|
@ -1,5 +1,9 @@
|
|||
/** \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"
|
||||
|
@ -14,6 +18,7 @@
|
|||
typedef struct halloc
|
||||
{
|
||||
array_list_t children;
|
||||
array_list_t hchildren;
|
||||
long long data[0];
|
||||
}
|
||||
halloc_t;
|
||||
|
@ -26,53 +31,48 @@ static halloc_t *halloc_from_data( void *data )
|
|||
|
||||
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;
|
||||
|
||||
al_init( &res->children );
|
||||
|
||||
|
||||
al_init( &me->children );
|
||||
|
||||
if( context )
|
||||
{
|
||||
halloc_t *parent = halloc_from_data( context );
|
||||
al_push( &parent->children, &res->data );
|
||||
{
|
||||
parent = halloc_from_data( context );
|
||||
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 )
|
||||
{
|
||||
halloc_t *me;
|
||||
if( !context )
|
||||
return;
|
||||
|
||||
|
||||
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->hchildren );
|
||||
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;
|
||||
}
|
||||
|
|
31
halloc.h
31
halloc.h
|
@ -1,18 +1,35 @@
|
|||
/** \file halloc.h
|
||||
A hierarchical memory allocation system
|
||||
/** \file halloc.h
|
||||
|
||||
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
|
||||
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 );
|
||||
|
||||
/**
|
||||
Free memory context and all children. Only root contexts may be
|
||||
freed explicitly.
|
||||
Free memory context and all children contexts. Only root contexts
|
||||
may be freed explicitly.
|
||||
*/
|
||||
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 );
|
||||
|
|
72
parser.c
72
parser.c
|
@ -339,7 +339,7 @@ static int block_count( block_t *b )
|
|||
|
||||
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_filename = parser_current_filename()?intern(parser_current_filename()):0;
|
||||
|
@ -376,9 +376,6 @@ void parser_push_block( int type )
|
|||
|
||||
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 );
|
||||
|
||||
if( (current_block->type != FUNCTION_DEF ) &&
|
||||
|
@ -388,51 +385,9 @@ void parser_pop_block()
|
|||
env_pop();
|
||||
}
|
||||
|
||||
switch( current_block->type)
|
||||
{
|
||||
case FOR:
|
||||
{
|
||||
free( current_block->param1.for_variable );
|
||||
al_foreach( ¤t_block->param2.for_vars,
|
||||
(void (*)(const void *))&free );
|
||||
al_destroy( ¤t_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;
|
||||
current_block = current_block->outer;
|
||||
free( old );
|
||||
halloc_free( old );
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
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;
|
||||
if( !unmatched )
|
||||
{
|
||||
unmatched = halloc_wcsdup( j, tok_last( tok ));
|
||||
unmatched = halloc_register( j, wcsdup( tok_last( tok )));
|
||||
unmatched_pos = tok_get_pos( tok );
|
||||
}
|
||||
|
||||
|
@ -1532,9 +1487,7 @@ static void parse_job_main_loop( process_t *p,
|
|||
{
|
||||
case TOK_STRING:
|
||||
{
|
||||
wchar_t *tmp = expand_one( wcsdup( tok_last( tok ) ), 0);
|
||||
target = halloc_wcsdup( j, tmp );
|
||||
free( tmp );
|
||||
target = (wchar_t *)halloc_register( j, expand_one( wcsdup( tok_last( tok ) ), 0));
|
||||
|
||||
if( target == 0 && error_code == 0 )
|
||||
{
|
||||
|
@ -1955,13 +1908,12 @@ static int parse_job( process_t *p,
|
|||
*/
|
||||
if( current_block->skip )
|
||||
{
|
||||
p->actual_cmd = wcsdup(L"");
|
||||
p->actual_cmd = L"";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
p->actual_cmd = get_filename( (wchar_t *)al_get( &args, 0 ) );
|
||||
|
||||
p->actual_cmd = halloc_register(j, get_filename( (wchar_t *)al_get( &args, 0 ) ));
|
||||
|
||||
/*
|
||||
Check if the specified command exists
|
||||
*/
|
||||
|
@ -2236,13 +2188,11 @@ static void eval_job( tokenizer *tok )
|
|||
if( newline )
|
||||
stop_pos = mini( stop_pos, newline - tok_string(tok) );
|
||||
|
||||
j->command = halloc_wcsndup( j,
|
||||
tok_string(tok)+start_pos,
|
||||
stop_pos-start_pos );
|
||||
j->command = halloc_register( j, wcsndup( tok_string(tok)+start_pos,
|
||||
stop_pos-start_pos ));
|
||||
}
|
||||
else
|
||||
j->command = halloc_wcsdup( j,
|
||||
L"" );
|
||||
j->command = L"";
|
||||
|
||||
if( profile )
|
||||
{
|
||||
|
|
30
proc.c
30
proc.c
|
@ -109,28 +109,6 @@ void proc_init()
|
|||
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
|
||||
*/
|
||||
|
@ -164,15 +142,7 @@ static int job_remove( 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 );
|
||||
|
||||
/* Then free ourselves */
|
||||
free_process( j->first_process);
|
||||
|
||||
halloc_free( j );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue