diff --git a/builtin.c b/builtin.c index b57068c..0e2849c 100644 --- a/builtin.c +++ b/builtin.c @@ -1965,7 +1965,8 @@ static int builtin_cd( wchar_t **argv ) wchar_t *dir_in; wchar_t *dir; int res=0; - + void *context = halloc( 0, 0 ); + if( argv[1] == 0 ) { dir_in = env_get( L"HOME" ); @@ -1979,7 +1980,7 @@ static int builtin_cd( wchar_t **argv ) else dir_in = argv[1]; - dir = parser_cdpath_get( dir_in ); + dir = parser_cdpath_get( context, dir_in ); if( !dir ) { @@ -1994,10 +1995,9 @@ static int builtin_cd( wchar_t **argv ) (void *)0 ); } - return 1; + res = 1; } - - if( wchdir( dir ) != 0 ) + else if( wchdir( dir ) != 0 ) { sb_printf( sb_err, _( L"%ls: '%ls' is not a directory\n" ), @@ -2010,18 +2010,15 @@ static int builtin_cd( wchar_t **argv ) (void *)0 ); } - free( dir ); - - return 1; + res = 1; } - - if( !set_pwd(L"PWD") ) + else if( !set_pwd(L"PWD") ) { res=1; sb_printf( sb_err, _( L"%ls: Could not set PWD variable\n" ), argv[0] ); } - free( dir ); + halloc_free( context ); return res; } diff --git a/complete.c b/complete.c index 8f81301..d21df12 100644 --- a/complete.c +++ b/complete.c @@ -41,6 +41,7 @@ #include "intern.h" #include "translate.h" #include "parse_util.h" +#include "halloc.h" #include "halloc_util.h" #include "wutil.h" @@ -557,18 +558,19 @@ void complete_remove( const wchar_t *cmd, } /** - Find the full path and commandname from a command string. the - result of \c pathp must be freed by the caller, the result of \c - cmdp must not be freed by the caller. + Find the full path and commandname from a command string. Both + pointers are allocated using halloc and will be free'd when\c + context is halloc_free'd. */ -static void parse_cmd_string( const wchar_t *str, +static void parse_cmd_string( void *context, + const wchar_t *str, wchar_t **pathp, wchar_t **cmdp ) { wchar_t *cmd, *path; /* Get the path of the command */ - path = get_filename( str ); + path = parser_get_filename( context, str ); if( path == 0 ) { /** @@ -611,6 +613,8 @@ int complete_is_valid_option( const wchar_t *str, int gnu_opt_len=0; char *short_validated; + void *context; + if( !str || !opt ) { debug( 0, L"%s called with null input", __func__ ); @@ -652,11 +656,15 @@ int complete_is_valid_option( const wchar_t *str, return 0; } - if( !(short_validated = malloc( wcslen( opt ) ))) + context = halloc( 0, 0 ); + + if( !(short_validated = halloc( context, wcslen( opt ) ))) { die_mem(); } + + memset( short_validated, 0, wcslen( opt ) ); hash_init( &gnu_match_hash, @@ -677,7 +685,7 @@ int complete_is_valid_option( const wchar_t *str, } } - parse_cmd_string( str, &path, &cmd ); + parse_cmd_string( context, str, &path, &cmd ); /* Make sure completions are loaded for the specified command @@ -776,7 +784,6 @@ int complete_is_valid_option( const wchar_t *str, } } } - free( path ); if( authorative ) { @@ -830,8 +837,9 @@ int complete_is_valid_option( const wchar_t *str, } hash_destroy( &gnu_match_hash ); - free( short_validated ); + halloc_free( context ); + return (authorative && found_match)?opt_found:1; } @@ -1567,13 +1575,14 @@ static int complete_param( wchar_t *cmd_orig, wchar_t *cmd, *path; int use_common=1, use_files=1; - parse_cmd_string( cmd_orig, &path, &cmd ); + void *context = halloc( 0, 0 ); + + parse_cmd_string( context, cmd_orig, &path, &cmd ); complete_load( cmd, 1 ); al_init( &matches ); - for( i=first_entry; i; i=i->next ) { wchar_t *match = i->cmd_type?path:cmd; @@ -1696,11 +1705,10 @@ static int complete_param( wchar_t *cmd_orig, */ if( o->long_opt[0] != L'\0' ) { - string_buffer_t whole_opt; - sb_init( &whole_opt ); - sb_append2( &whole_opt, o->old_mode?L"-":L"--", o->long_opt, (void *)0 ); + string_buffer_t *whole_opt = sb_halloc( context ); + sb_append2( whole_opt, o->old_mode?L"-":L"--", o->long_opt, (void *)0 ); - if( wcsncmp( str, (wchar_t *)whole_opt.buff, wcslen(str) )==0) + if( wcsncmp( str, (wchar_t *)whole_opt->buff, wcslen(str) )==0) { /* If the option requires arguments, add @@ -1713,7 +1721,7 @@ static int complete_param( wchar_t *cmd_orig, if( o->old_mode || !(o->result_mode & NO_COMMON ) ) { al_push( comp_out, - wcsdupcat2( &((wchar_t *)whole_opt.buff)[wcslen(str)], + wcsdupcat2( &((wchar_t *)whole_opt->buff)[wcslen(str)], COMPLETE_SEP_STR, C_(o->desc), (void *)0) ); @@ -1722,20 +1730,21 @@ static int complete_param( wchar_t *cmd_orig, if( !o->old_mode && ( wcslen(o->comp) || (o->result_mode & NO_COMMON ) ) ) { al_push( comp_out, - wcsdupcat2( &((wchar_t *)whole_opt.buff)[wcslen(str)], + wcsdupcat2( &((wchar_t *)whole_opt->buff)[wcslen(str)], L"=", COMPLETE_SEP_STR, C_(o->desc), (void *)0) ); } } - sb_destroy( &whole_opt ); } } } } } - free( path ); + + halloc_free( context ); + return use_files; } diff --git a/halloc_util.c b/halloc_util.c index a5d8ae8..766ce17 100644 --- a/halloc_util.c +++ b/halloc_util.c @@ -71,7 +71,7 @@ void *halloc_register( void *context, void *data ) return data; } -wchar_t *halloc_wcsdup( void *context, wchar_t *in ) +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)); diff --git a/halloc_util.h b/halloc_util.h index ea78583..680cffe 100644 --- a/halloc_util.h +++ b/halloc_util.h @@ -55,7 +55,7 @@ void *halloc_register( void *context, void *data ); Make a copy of the specified string using memory allocated using halloc and the specified context */ -wchar_t *halloc_wcsdup( void *context, wchar_t *str ); +wchar_t *halloc_wcsdup( void *context, const wchar_t *str ); /** Make a copy of the specified substring using memory allocated using diff --git a/highlight.c b/highlight.c index 2966bc2..84115ea 100644 --- a/highlight.c +++ b/highlight.c @@ -30,6 +30,8 @@ #include "common.h" #include "complete.h" #include "output.h" +#include "halloc.h" +#include "halloc_util.h" static void highlight_universal_internal( wchar_t * buff, int *color, @@ -381,11 +383,25 @@ void highlight_shell( wchar_t * buff, int i; int last_val; wchar_t *last_cmd=0; - int len = wcslen(buff); + int len; + + void *context; + + if( !buff || !color ) + { + debug( 0, L"%s called with null input", __func__ ); + return; + } + + + + len = wcslen(buff); if( !len ) return; + context = halloc( 0, 0 ); + for( i=0; buff[i] != 0; i++ ) color[i] = -1; @@ -430,7 +446,7 @@ void highlight_shell( wchar_t * buff, /* Command. First check that the command actually exists. */ - wchar_t *cmd = expand_one( 0, + wchar_t *cmd = expand_one( context, wcsdup(tok_last( &tok )), EXPAND_SKIP_SUBSHELL | EXPAND_SKIP_VARIABLES); @@ -491,15 +507,13 @@ void highlight_shell( wchar_t * buff, /* Check if this is a regular command */ - is_cmd |= !!(tmp=get_filename( cmd )); - free(tmp); + is_cmd |= !!(tmp=parser_get_filename( context, cmd )); /* Could not find the command. Maybe it is a path for a implicit cd command. */ - is_cmd |= !!(tmp=parser_cdpath_get( cmd )); - free( tmp ); + is_cmd |= !!(tmp=parser_cdpath_get( context, cmd )); if( is_cmd ) { @@ -513,13 +527,10 @@ void highlight_shell( wchar_t * buff, } had_cmd = 1; } - free(cmd); if( had_cmd ) { - if( last_cmd ) - free( last_cmd ); - last_cmd = wcsdup( tok_last( &tok ) ); + last_cmd = halloc_wcsdup( context, tok_last( &tok ) ); } } @@ -553,7 +564,7 @@ void highlight_shell( wchar_t * buff, { case TOK_STRING: { - target = expand_one( 0, wcsdup( tok_last( &tok ) ), EXPAND_SKIP_SUBSHELL); + target = expand_one( context, wcsdup( tok_last( &tok ) ), EXPAND_SKIP_SUBSHELL); /* Redirect filename may contain a subshell. If so, it will be ignored/not flagged. @@ -571,7 +582,7 @@ void highlight_shell( wchar_t * buff, if( target != 0 ) { - wchar_t *dir = wcsdup( target ); + wchar_t *dir = halloc_wcsdup( context, target ); wchar_t *dir_end = wcsrchr( dir, L'/' ); struct stat buff; /* @@ -587,9 +598,8 @@ void highlight_shell( wchar_t * buff, if( error ) al_push( error, wcsdupcat2( L"Directory \'", dir, L"\' does not exist", 0 ) ); - } + } } - free( dir ); /* If the file is read from or appended to, check @@ -605,7 +615,6 @@ void highlight_shell( wchar_t * buff, al_push( error, wcsdupcat2( L"File \'", target, L"\' does not exist", 0 ) ); } } - free( target ); } break; } @@ -655,16 +664,13 @@ void highlight_shell( wchar_t * buff, } } - if( last_cmd ) - free( last_cmd ); - tok_destroy( &tok ); /* Locate and syntax highlight subshells recursively */ - wchar_t *buffcpy = wcsdup( buff ); + wchar_t *buffcpy = halloc_wcsdup( context, buff ); wchar_t *subpos=buffcpy; int done=0; @@ -694,8 +700,6 @@ void highlight_shell( wchar_t * buff, subpos = end+1; } - free( buffcpy); - last_val=0; for( i=0; buff[i] != 0; i++ ) @@ -719,6 +723,9 @@ void highlight_shell( wchar_t * buff, color[i]=0; } } + + halloc_free( context ); + } /** diff --git a/kill.c b/kill.c index 32ed1dc..00d48fb 100644 --- a/kill.c +++ b/kill.c @@ -30,6 +30,7 @@ #include "env.h" #include "exec.h" #include "parser.h" +#include "halloc.h" /** Maximum entries in killring @@ -48,14 +49,11 @@ static wchar_t *cut_buffer=0; */ static int has_xsel() { - wchar_t *path = get_filename( L"xsel" ); - if( path) - { - free(path); - return 1; - } - else - return 0; + void *context = halloc(0, 0); + wchar_t *path = parser_get_filename( context, L"xsel" ); + int res = !!path; + halloc_free( context ); + return res; } diff --git a/parser.c b/parser.c index 6eebc2e..969c5d7 100644 --- a/parser.c +++ b/parser.c @@ -594,7 +594,7 @@ static const wchar_t *parser_find_end( const wchar_t * buff ) } -wchar_t *parser_cdpath_get( wchar_t *dir ) +wchar_t *parser_cdpath_get( void *context, wchar_t *dir ) { wchar_t *res = 0; @@ -609,7 +609,7 @@ wchar_t *parser_cdpath_get( wchar_t *dir ) { if( S_ISDIR(buf.st_mode) ) { - res = wcsdup( dir ); + res = halloc_wcsdup( context, dir ); } } } @@ -664,11 +664,11 @@ wchar_t *parser_cdpath_get( wchar_t *dir ) if( S_ISDIR(buf.st_mode) ) { res = whole_path; + halloc_register( context, whole_path ); break; } } free( whole_path ); - } free( path_cpy ); } @@ -707,7 +707,7 @@ void error( int ec, int p, const wchar_t *str, ... ) } -wchar_t *get_filename( const wchar_t *cmd ) +wchar_t *parser_get_filename( void *context, const wchar_t *cmd ) { wchar_t *path; @@ -717,7 +717,7 @@ wchar_t *get_filename( const wchar_t *cmd ) return 0; } - debug( 3, L"get_filename( '%ls' )", cmd ); + debug( 3, L"parser_get_filename( '%ls' )", cmd ); if(wcschr( cmd, L'/' ) != 0 ) { @@ -726,7 +726,7 @@ wchar_t *get_filename( const wchar_t *cmd ) struct stat buff; wstat( cmd, &buff ); if( S_ISREG(buff.st_mode) ) - return wcsdup( cmd ); + return halloc_wcsdup( context, cmd ); else return 0; } @@ -788,6 +788,7 @@ wchar_t *get_filename( const wchar_t *cmd ) if( S_ISREG(buff.st_mode) ) { free( path_cpy ); + halloc_register( context, new_cmd ); return new_cmd; } } @@ -2035,7 +2036,7 @@ static int parse_job( process_t *p, } else { - p->actual_cmd = halloc_register(j, get_filename( (wchar_t *)al_get( args, 0 ) )); + p->actual_cmd = parser_get_filename( j, (wchar_t *)al_get( args, 0 ) ); /* Check if the specified command exists @@ -2049,11 +2050,10 @@ static int parse_job( process_t *p, implicit command. */ wchar_t *pp = - parser_cdpath_get( (wchar_t *)al_get( args, 0 ) ); + parser_cdpath_get( j, (wchar_t *)al_get( args, 0 ) ); if( pp ) { wchar_t *tmp; - free( pp ); tmp = (wchar_t *)al_get( args, 0 ); al_truncate( args, 0 ); diff --git a/parser.h b/parser.h index ff14817..6042893 100644 --- a/parser.h +++ b/parser.h @@ -204,9 +204,10 @@ extern io_data_t *block_io; Finds the full path of an executable in a newly allocated string. \param cmd The name of the executable. + \param context the halloc context to use for memory allocations \return 0 if the command can not be found, the path of the command otherwise. */ -wchar_t *get_filename( const wchar_t *cmd ); +wchar_t *parser_get_filename( void *context, const wchar_t *cmd ); /** Evaluate the expressions contained in cmd. @@ -337,7 +338,7 @@ int parser_test_args( const wchar_t * buff, string_buffer_t *out, const wchar_t directories i the CDPATH, the full path is returned. If no directory can be found, 0 is returned. */ -wchar_t *parser_cdpath_get( wchar_t *in ); +wchar_t *parser_cdpath_get( void *context, wchar_t *in ); /** Tell the parser that the specified function may not be run if not