From d32751df13ba9707afb58eec6159835746bc18e4 Mon Sep 17 00:00:00 2001
From: axel <axel@liljencrantz.se>
Date: Tue, 13 Jun 2006 00:12:33 +1000
Subject: [PATCH] Use halloc in a few more places, including the highlight code

darcs-hash:20060612141233-ac50b-1c44411dd31cdc31d6ccb226f567c308c4fc0f55.gz
---
 builtin.c     | 19 ++++++++-----------
 complete.c    | 47 ++++++++++++++++++++++++++++-------------------
 halloc_util.c |  2 +-
 halloc_util.h |  2 +-
 highlight.c   | 49 ++++++++++++++++++++++++++++---------------------
 kill.c        | 14 ++++++--------
 parser.c      | 18 +++++++++---------
 parser.h      |  5 +++--
 8 files changed, 84 insertions(+), 72 deletions(-)

diff --git a/builtin.c b/builtin.c
index b57068c27..0e2849c7b 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 8f813012c..d21df1255 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 a5d8ae81f..766ce17da 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 ea7858371..680cffe76 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 2966bc2b6..84115ea85 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 32ed1dcf7..00d48fb97 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 6eebc2ee4..969c5d7af 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 ff1481713..604289360 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