From 9bcc7df96f2e40e54fb1cebdb6df5de4139b0ed9 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Wed, 9 May 2012 02:33:42 -0700 Subject: [PATCH] Lots of modernization changed Removed wcsdupcat --- FishsFish.xcodeproj/project.pbxproj | 2 +- builtin.cpp | 9 ++- common.cpp | 83 ++++++------------------- common.h | 22 +------ complete.cpp | 95 +++++++++-------------------- expand.h | 6 +- fishd.cpp | 78 +++++++++-------------- highlight.cpp | 5 +- kill.cpp | 17 +++--- parser.cpp | 10 +-- path.cpp | 40 +++++------- path.h | 2 +- reader.cpp | 65 ++++++-------------- wildcard.cpp | 89 ++++++++++++--------------- wildcard.h | 2 +- 15 files changed, 177 insertions(+), 348 deletions(-) diff --git a/FishsFish.xcodeproj/project.pbxproj b/FishsFish.xcodeproj/project.pbxproj index 00cff2bc3..c74623f5e 100644 --- a/FishsFish.xcodeproj/project.pbxproj +++ b/FishsFish.xcodeproj/project.pbxproj @@ -231,7 +231,7 @@ /* Begin PBXLegacyTarget section */ D0A084F713B3AC130099B651 /* FishsFish */ = { isa = PBXLegacyTarget; - buildArgumentsString = "-k ${ACTION} -j 3"; + buildArgumentsString = "-k ${ACTION}"; buildConfigurationList = D0A084FA13B3AC130099B651 /* Build configuration list for PBXLegacyTarget "FishsFish" */; buildPhases = ( ); diff --git a/builtin.cpp b/builtin.cpp index a926f436e..c0372812c 100644 --- a/builtin.cpp +++ b/builtin.cpp @@ -2569,7 +2569,7 @@ static int builtin_exit( parser_t &parser, wchar_t **argv ) static int builtin_cd( parser_t &parser, wchar_t **argv ) { env_var_t dir_in; - wchar_t *dir; + wchar_t *dir = NULL; int res=STATUS_BUILTIN_OK; @@ -2583,10 +2583,13 @@ static int builtin_cd( parser_t &parser, wchar_t **argv ) argv[0] ); } } - else + else { dir_in = argv[1]; + } - dir = path_allocate_cdpath( dir_in.missing() ? NULL : dir_in.c_str() ); + if (! dir_in.missing()) { + dir = path_allocate_cdpath(dir_in); + } if( !dir ) { diff --git a/common.cpp b/common.cpp index 7ec061aa2..b86cca5d1 100644 --- a/common.cpp +++ b/common.cpp @@ -401,61 +401,6 @@ char **wcsv2strv( const wchar_t * const *in ) } -wchar_t *wcsdupcat_internal( const wchar_t *a, ... ) -{ - int len=wcslen(a); - int pos; - va_list va, va2; - wchar_t *arg; - - va_start( va, a ); - va_copy( va2, va ); - while( (arg=va_arg(va, wchar_t *) )!= 0 ) - { - len += wcslen( arg ); - } - va_end( va ); - - wchar_t *res = (wchar_t *)malloc( sizeof(wchar_t)*(len +1 )); - if( res == 0 ) - { - DIE_MEM(); - } - - wcscpy( res, a ); - pos = wcslen(a); - while( (arg=va_arg(va2, wchar_t *) )!= 0 ) - { - wcscpy( res+pos, arg ); - pos += wcslen(arg); - } - va_end( va2 ); - return res; - -} - - -wchar_t **strv2wcsv( const char **in ) -{ - int count =0; - int i; - - while( in[count] != 0 ) - count++; - wchar_t **res = (wchar_t **)malloc( sizeof( wchar_t *)*(count+1)); - if( res == 0 ) - { - DIE_MEM(); - } - - for( i=0; i &out) out.push_back(val.substr(pos, end - pos)); } +bool string_prefixes_string(const wchar_t *proposed_prefix, const wcstring &value) +{ + size_t prefix_size = wcslen(proposed_prefix); + return prefix_size <= value.size() && value.compare(0, prefix_size, proposed_prefix) == 0; +} + + bool string_prefixes_string(const wcstring &proposed_prefix, const wcstring &value) { size_t prefix_size = proposed_prefix.size(); @@ -1948,14 +1900,19 @@ null_terminated_array_t convert_wide_array_to_narrow(const null_terminated void append_path_component(wcstring &path, const wcstring &component) { - size_t len = path.size(); - if (len == 0) - { - path = component; - } - else - { - if (path[len-1] != L'/') path.push_back(L'/'); + if (path.empty() || component.empty()) { + path.append(component); + } else { + size_t path_len = path.size(); + bool path_slash = path.at(path_len-1) == L'/'; + bool comp_slash = component.at(0) == L'/'; + if (! path_slash && ! comp_slash) { + // Need a slash + path.push_back(L'/'); + } else if (path_slash && comp_slash) { + // Too many slashes + path.erase(path_len - 1, 1); + } path.append(component); } } diff --git a/common.h b/common.h index c98a8956b..ce8acb3dd 100644 --- a/common.h +++ b/common.h @@ -180,10 +180,6 @@ extern const wchar_t *program_name; Check if the specified stringelement is a part of the specified string list */ #define contains( str,... ) contains_internal( str, __VA_ARGS__, NULL ) -/** - Concatenate all the specified strings into a single newly allocated one - */ -#define wcsdupcat( str,... ) wcsdupcat_internal( str, __VA_ARGS__, NULL ) /** Print a stack trace to stderr @@ -251,6 +247,7 @@ std::string wcs2string(const wcstring &input); /** Test if a string prefixes another. Returns true if a is a prefix of b */ bool string_prefixes_string(const wcstring &proposed_prefix, const wcstring &value); +bool string_prefixes_string(const wchar_t *proposed_prefix, const wcstring &value); /** Test if a string prefixes another without regard to case. Returns true if a is a prefix of b */ bool string_prefixes_string_case_insensitive(const wcstring &proposed_prefix, const wcstring &value); @@ -520,23 +517,6 @@ void append_format(wcstring &str, const wchar_t *format, ...); */ char **wcsv2strv( const wchar_t * const *in ); -/** - Returns a newly allocated multibyte character string array equivalent of the specified wide character string array -*/ -wchar_t **strv2wcsv( const char **in ); - - -/** - Returns a newly allocated concatenation of the specified wide - character strings. The last argument must be a null pointer. -*/ -__sentinel wchar_t *wcsdupcat_internal( const wchar_t *a, ... ); - -/** - Test if the given string is a valid variable name -*/ - - /** Test if the given string is a valid variable name. diff --git a/complete.cpp b/complete.cpp index b3218a3e7..d248e1589 100644 --- a/complete.cpp +++ b/complete.cpp @@ -828,7 +828,7 @@ int complete_is_valid_argument( const wchar_t *str, */ static void complete_strings( std::vector &comp_out, - const wchar_t *wc_escaped, + const wcstring &wc_escaped, const wchar_t *desc, const wchar_t *(*desc_func)(const wcstring &), std::vector &possible_comp, @@ -1001,9 +1001,12 @@ static const wchar_t *complete_function_desc( const wcstring &fn ) \param comp the list to add all completions to */ -void completer_t::complete_cmd( const wcstring &str, bool use_function, bool use_builtin, bool use_command) +void completer_t::complete_cmd( const wcstring &str_cmd, bool use_function, bool use_builtin, bool use_command) { - const wchar_t * const cmd = str.c_str(); + /* Paranoia */ + if (str_cmd.empty()) + return; + wchar_t *path_cpy; wchar_t *nxt_path; wchar_t *state; @@ -1013,20 +1016,19 @@ void completer_t::complete_cmd( const wcstring &str, bool use_function, bool use env_var_t cdpath = env_get_string(L"CDPATH"); if (cdpath.missing_or_empty()) cdpath = L"."; - wchar_t *cdpath_cpy = wcsdup(cdpath.c_str()); const bool wants_description = (type == COMPLETE_DEFAULT); - if( (wcschr( cmd, L'/') != 0) || (cmd[0] == L'~' ) ) + if (str_cmd.find(L'/') != wcstring::npos || str_cmd.at(0) == L'~') { if( use_command ) { - if( expand_string(str, this->completions, ACCEPT_INCOMPLETE | EXECUTABLES_ONLY | this->expand_flags() ) != EXPAND_ERROR ) + if( expand_string(str_cmd, this->completions, ACCEPT_INCOMPLETE | EXECUTABLES_ONLY | this->expand_flags() ) != EXPAND_ERROR ) { if (wants_description) { - this->complete_cmd_desc( str ); + this->complete_cmd_desc( str_cmd ); } } } @@ -1046,43 +1048,37 @@ void completer_t::complete_cmd( const wcstring &str, bool use_function, bool use nxt_path != 0; nxt_path = wcstok( 0, ARRAY_SEP_STR, &state) ) { - size_t prev_count; - int path_len = wcslen(nxt_path); - int add_slash; - - if( !path_len ) - { - continue; - } + wcstring base_path = nxt_path; + if (base_path.empty()) + continue; + + /* Make sure the base path ends with a slash */ + if (base_path.at(base_path.size() - 1) != L'/') + base_path.push_back(L'/'); - add_slash = nxt_path[path_len-1]!=L'/'; - wchar_t *nxt_completion = wcsdupcat( nxt_path, - add_slash?L"/":L"", - cmd ); - if( ! nxt_completion ) - continue; - - prev_count = this->completions.size() ; - + wcstring nxt_completion = base_path; + nxt_completion.append(str_cmd); + + size_t prev_count = this->completions.size(); if( expand_string( nxt_completion, this->completions, ACCEPT_INCOMPLETE | EXECUTABLES_ONLY | this->expand_flags() ) != EXPAND_ERROR ) { + /* For all new completions, if COMPLETE_NO_CASE is set, then use only the last path component */ for( size_t i=prev_count; i< this->completions.size(); i++ ) { completion_t &c = this->completions.at( i ); if(c.flags & COMPLETE_NO_CASE ) { - c.completion += add_slash ; + + c.completion.erase(0, base_path.size()); } } } - - free(nxt_completion); } free( path_cpy ); if (wants_description) - this->complete_cmd_desc( str ); + this->complete_cmd_desc( str_cmd ); } } @@ -1093,12 +1089,12 @@ void completer_t::complete_cmd( const wcstring &str, bool use_function, bool use if( use_function ) { //function_get_names( &possible_comp, cmd[0] == L'_' ); - wcstring_list_t names = function_get_names(cmd[0] == L'_' ); + wcstring_list_t names = function_get_names(str_cmd.at(0) == L'_' ); for (size_t i=0; i < names.size(); i++) { possible_comp.push_back(completion_t(names.at(i))); } - complete_strings( this->completions, cmd, 0, &complete_function_desc, possible_comp, 0 ); + complete_strings( this->completions, str_cmd, 0, &complete_function_desc, possible_comp, 0 ); } possible_comp.clear(); @@ -1106,43 +1102,10 @@ void completer_t::complete_cmd( const wcstring &str, bool use_function, bool use if( use_builtin ) { builtin_get_names( possible_comp ); - complete_strings( this->completions, cmd, 0, &builtin_get_desc, possible_comp, 0 ); + complete_strings( this->completions, str_cmd, 0, &builtin_get_desc, possible_comp, 0 ); } -// al_destroy( &possible_comp ); } - - if( use_builtin || (use_function && function_exists( L"cd") ) ) - { - /* - Tab complete implicit cd for directories in CDPATH - */ - if( cmd[0] != L'/' && ( wcsncmp( cmd, L"./", 2 )!=0) ) - { - for( nxt_path = wcstok( cdpath_cpy, ARRAY_SEP_STR, &state ); - nxt_path != 0; - nxt_path = wcstok( 0, ARRAY_SEP_STR, &state) ) - { - wchar_t *nxt_completion= - wcsdupcat( nxt_path, - (nxt_path[wcslen(nxt_path)-1]==L'/'?L"":L"/"), - cmd ); - if( ! nxt_completion ) - { - continue; - } - - if( expand_string( nxt_completion, - this->completions, - ACCEPT_INCOMPLETE | DIRECTORIES_ONLY | this->expand_flags() ) != EXPAND_ERROR ) - { - } - free(nxt_completion); - } - } - } - - free( cdpath_cpy ); } @@ -1178,7 +1141,7 @@ void completer_t::complete_from_args( const wcstring &str, if (! is_autosuggest) proc_pop_interactive(); - complete_strings( this->completions, str.c_str(), desc.c_str(), 0, possible_comp, flags ); + complete_strings( this->completions, str, desc.c_str(), 0, possible_comp, flags ); } /** @@ -1507,7 +1470,7 @@ void completer_t::complete_param_expand( const wcstring &sstr, bool do_file) const wchar_t * const str = sstr.c_str(); const wchar_t *comp_str; - if( (wcsncmp( str, L"--", 2 )) == 0 && (comp_str = wcschr(str, L'=' ) ) ) + if (string_prefixes_string( L"--", sstr) && (comp_str = wcschr(str, L'=' ) ) ) { comp_str++; } diff --git a/expand.h b/expand.h index 414768c74..14a092304 100644 --- a/expand.h +++ b/expand.h @@ -105,8 +105,7 @@ enum EXPAND_WILDCARD_NO_MATCH, /* Ok, a wildcard in the string matched a file */ EXPAND_WILDCARD_MATCH -} - ; +}; /** Character for separating two array elements. We use 30, i.e. the ascii record separator since that seems logical. */ #define ARRAY_SEP 0x1e @@ -129,8 +128,7 @@ class parser_t; into the list out. If the parameter does not need expansion, it is copied into the list - out. If expansion is performed, the original parameter is freed and - newly allocated strings are inserted into the list out. + out. \param input The parameter to expand \param output The list to which the result will be appended. diff --git a/fishd.cpp b/fishd.cpp index 1dc9727d6..bf4cfcb56 100644 --- a/fishd.cpp +++ b/fishd.cpp @@ -670,54 +670,45 @@ static wchar_t *fishd_env_get( const wchar_t *key ) to be rewritten to avoid dragging in additional library dependencies. */ -static wchar_t *fishd_get_config() +static wcstring fishd_get_config() { wchar_t *xdg_dir, *home; - int done = 0; - wchar_t *res = 0; + bool done = false; + wcstring result; xdg_dir = fishd_env_get( L"XDG_CONFIG_HOME" ); - if( xdg_dir ) + if (xdg_dir) { - res = wcsdupcat( xdg_dir, L"/fish" ); - if( !create_directory( res ) ) + result = xdg_dir; + append_path_component(result, L"/fish"); + if (!create_directory(result)) { - done = 1; + done = true; } - else - { - free( res ); - } - free( xdg_dir ); + free(xdg_dir); } else { home = fishd_env_get( L"HOME" ); if( home ) { - res = wcsdupcat( home, L"/.config/fish" ); - if( !create_directory( res ) ) + result = home; + append_path_component(result, L"/.config/fish"); + if (!create_directory(result)) { done = 1; } - else - { - free( res ); - } free( home ); } } - - if( done ) - { - return res; - } - else - { + + if (! done) { + /* Bad juju */ debug( 0, _(L"Unable to create a configuration directory for fish. Your personal settings will not be saved. Please set the $XDG_CONFIG_HOME variable to a directory where the current user has write access." )); - return 0; - } - + result.clear(); + } + + return result; } /** @@ -725,41 +716,30 @@ static wchar_t *fishd_get_config() */ static void load_or_save( int save) { - char *name; - wchar_t *wdir = fishd_get_config(); - char *dir; + const wcstring wdir = fishd_get_config(); char hostname[HOSTNAME_LEN]; connection_t c; int fd; - if( !wdir ) - { + if (wdir.empty()) return; - } - dir = wcs2str( wdir ); - - free( wdir ); + std::string dir = wcs2string( wdir ); gethostname( hostname, HOSTNAME_LEN ); - name = (char *)malloc( strlen(dir)+ strlen(FILE)+ strlen(hostname) + 2 ); - strcpy( name, dir ); - strcat( name, "/" ); - strcat( name, FILE ); - strcat( name, hostname ); - - free( dir ); - + std::string name; + name.append(dir); + name.append("/"); + name.append(FILE); + name.append(hostname); debug( 4, L"Open file for %s: '%s'", save?"saving":"loading", - name ); + name.c_str() ); /* OK to not use CLO_EXEC here because fishd is single threaded */ - fd = open( name, save?(O_CREAT | O_TRUNC | O_WRONLY):O_RDONLY, 0600); - - free( name ); + fd = open(name.c_str(), save?(O_CREAT | O_TRUNC | O_WRONLY):O_RDONLY, 0600); if( fd == -1 ) { diff --git a/highlight.cpp b/highlight.cpp index fdcd6f38e..15fc07664 100644 --- a/highlight.cpp +++ b/highlight.cpp @@ -807,7 +807,7 @@ bool autosuggest_special_validate_from_history(const wcstring &str, const wcstri if (is_help) { suggestionOK = false; } else { - wchar_t *path = path_allocate_cdpath(dir.c_str(), working_directory.c_str()); + wchar_t *path = path_allocate_cdpath(dir, working_directory.c_str()); if (path == NULL) { suggestionOK = false; } else if (paths_are_same_file(working_directory, path)) { @@ -1237,8 +1237,7 @@ void highlight_shell( const wcstring &buff, std::vector &color, int pos, wc //our subcolors start at color + (begin-subbuff)+1 size_t start = begin - subbuff + 1, len = wcslen(begin + 1); - std::vector subcolors; - subcolors.resize(len, -1); + std::vector subcolors(len, -1); highlight_shell( begin+1, subcolors, -1, error, vars ); diff --git a/kill.cpp b/kill.cpp index 35730bf84..c5c0e2c38 100644 --- a/kill.cpp +++ b/kill.cpp @@ -76,8 +76,8 @@ void kill_add( const wcstring &str ) if (str.empty()) return; - wchar_t *cmd = NULL; - wchar_t *escaped_str; + wcstring cmd; + wchar_t *escaped_str = NULL; kill_list.push_front(str); /* @@ -92,7 +92,9 @@ void kill_add( const wcstring &str ) if( !clipboard_wstr.missing() ) { escaped_str = escape( str.c_str(), 1 ); - cmd = wcsdupcat(L"echo -n ", escaped_str, clipboard_wstr.c_str()); + cmd.assign(L"echo -n "); + cmd.append(escaped_str); + cmd.append(clipboard_wstr); } else { @@ -105,13 +107,15 @@ void kill_add( const wcstring &str ) if( !disp_wstr.missing() ) { escaped_str = escape( str.c_str(), 1 ); - cmd = wcsdupcat(L"echo ", escaped_str, L"|xsel -b" ); + cmd.assign(L"echo "); + cmd.append(escaped_str); + cmd.append(L"|xsel -b" ); } } - if (cmd != NULL) + if (! cmd.empty()) { - if( exec_subshell( cmd) == -1 ) + if( exec_subshell(cmd) == -1 ) { /* Do nothing on failiure @@ -119,7 +123,6 @@ void kill_add( const wcstring &str ) } free( cut_buffer ); - free( cmd ); cut_buffer = escaped_str; } diff --git a/parser.cpp b/parser.cpp index d08fc4800..b6e03d16e 100644 --- a/parser.cpp +++ b/parser.cpp @@ -798,14 +798,8 @@ int parser_t::eval_args( const wchar_t *line, std::vector &args ) { case TOK_STRING: { - wchar_t *tmp = wcsdup(tok_last( &tok )); - - if( !tmp ) - { - DIE_MEM(); - } - - if( expand_string( tmp, args, eflags ) == EXPAND_ERROR ) + const wcstring tmp = tok_last(&tok); + if( expand_string(tmp, args, eflags) == EXPAND_ERROR ) { err_pos=tok_get_pos( &tok ); do_loop=0; diff --git a/path.cpp b/path.cpp index 05b20c139..1ffd91918 100644 --- a/path.cpp +++ b/path.cpp @@ -343,12 +343,12 @@ bool path_get_cdpath_string(const wcstring &dir_str, wcstring &result, const env } -wchar_t *path_allocate_cdpath( const wchar_t *dir, const wchar_t *wd ) +wchar_t *path_allocate_cdpath( const wcstring &dir, const wchar_t *wd ) { wchar_t *res = NULL; int err = ENOENT; - if( !dir ) - return 0; + if (dir.empty()) + return NULL; if (wd) { size_t len = wcslen(wd); @@ -357,13 +357,12 @@ wchar_t *path_allocate_cdpath( const wchar_t *dir, const wchar_t *wd ) wcstring_list_t paths; - if (dir[0] == L'/') { + if (dir.at(0) == L'/') { /* Absolute path */ paths.push_back(dir); - } else if (wcsncmp(dir, L"./", 2) == 0 || - wcsncmp(dir, L"../", 3) == 0 || - wcscmp(dir, L".") == 0 || - wcscmp(dir, L"..") == 0) { + } else if (string_prefixes_string(L"./", dir) || + string_prefixes_string(L"../", dir) || + dir == L"." || dir == L"..") { /* Path is relative to the working directory */ wcstring path; if (wd) @@ -373,7 +372,6 @@ wchar_t *path_allocate_cdpath( const wchar_t *dir, const wchar_t *wd ) } else { wchar_t *path_cpy; wchar_t *state; - wchar_t *whole_path; // Respect CDPATH env_var_t path = env_get_string(L"CDPATH"); @@ -392,25 +390,17 @@ wchar_t *path_allocate_cdpath( const wchar_t *dir, const wchar_t *wd ) nxt_path = wd; } - wchar_t *expanded_path = expand_tilde_compat( wcsdup(nxt_path) ); + wcstring expanded_path = nxt_path; + expand_tilde(expanded_path); -// debug( 2, L"woot %ls\n", expanded_path ); +// debug( 2, L"woot %ls\n", expanded_path.c_str() ); - int path_len = wcslen( expanded_path ); - if( path_len == 0 ) - { - free(expanded_path ); + if (expanded_path.empty()) continue; - } - - whole_path = - wcsdupcat( expanded_path, - ( expanded_path[path_len-1] != L'/' )?L"/":L"", - dir ); - - free(expanded_path ); + + wcstring whole_path = expanded_path; + append_path_component(whole_path, dir); paths.push_back(whole_path); - free( whole_path ); } free( path_cpy ); } @@ -442,7 +432,7 @@ wchar_t *path_allocate_cdpath( const wchar_t *dir, const wchar_t *wd ) bool path_can_get_cdpath(const wcstring &in, const wchar_t *wd) { - wchar_t *tmp = path_allocate_cdpath(in.c_str(), wd); + wchar_t *tmp = path_allocate_cdpath(in, wd); bool result = (tmp != NULL); free(tmp); return result; diff --git a/path.h b/path.h index bd5b4e5e7..eff5ac80c 100644 --- a/path.h +++ b/path.h @@ -53,7 +53,7 @@ bool path_get_path_string(const wcstring &cmd, wcstring &output, const env_vars \return 0 if the command can not be found, the path of the command otherwise. The path should be free'd with free(). */ -wchar_t *path_allocate_cdpath( const wchar_t *in, const wchar_t *wd = NULL); +wchar_t *path_allocate_cdpath( const wcstring &in, const wchar_t *wd = NULL); bool path_can_get_cdpath(const wcstring &in, const wchar_t *wd = NULL); bool path_get_cdpath_string(const wcstring &in, wcstring &out, const env_vars &vars); diff --git a/reader.cpp b/reader.cpp index be56bc45e..2ec488043 100644 --- a/reader.cpp +++ b/reader.cpp @@ -938,7 +938,6 @@ static void get_param( const wchar_t *cmd, */ static wcstring completion_apply_to_command_line(const wcstring &val_str, int flags, const wcstring &command_line, size_t *inout_cursor_pos) { - wchar_t *replaced; const wchar_t *val = val_str.c_str(); bool add_space = !(flags & COMPLETE_NO_SPACE); bool do_replace = !!(flags & COMPLETE_NO_CASE); @@ -988,25 +987,20 @@ static wcstring completion_apply_to_command_line(const wcstring &val_str, int fl else { wchar_t quote = L'\0'; + wcstring replaced; if( do_escape ) { get_param(command_line.c_str(), cursor_pos, "e, 0, 0, 0); if( quote == L'\0' ) { - replaced = escape( val, ESCAPE_ALL | ESCAPE_NO_QUOTED ); + replaced = escape_string( val, ESCAPE_ALL | ESCAPE_NO_QUOTED ); } else { bool unescapable = false; - - const wchar_t *pin; - wchar_t *pout; - - replaced = pout = (wchar_t *)malloc( sizeof(wchar_t)*(wcslen(val) + 1) ); - - for( pin=val; *pin; pin++ ) + for (const wchar_t *pin = val; *pin; pin++) { - switch( *pin ) + switch (*pin ) { case L'\n': case L'\t': @@ -1015,31 +1009,26 @@ static wcstring completion_apply_to_command_line(const wcstring &val_str, int fl unescapable = true; break; default: - *pout++ = *pin; + replaced.push_back(*pin); break; } } if (unescapable) { - free( replaced ); - wchar_t *tmp = escape( val, ESCAPE_ALL | ESCAPE_NO_QUOTED ); - replaced = wcsdupcat( L" ", tmp ); - free( tmp); - replaced[0]=quote; + replaced = escape_string(val, ESCAPE_ALL | ESCAPE_NO_QUOTED); + replaced.insert(0, "e, 1); } - else - *pout = 0; } } else { - replaced = wcsdup(val); + replaced = val; } wcstring result = command_line; result.insert(cursor_pos, replaced); - size_t new_cursor_pos = cursor_pos + wcslen(replaced); + size_t new_cursor_pos = cursor_pos + replaced.size(); if (add_space) { if (quote && (command_line.c_str()[cursor_pos] != quote)) @@ -1049,7 +1038,6 @@ static wcstring completion_apply_to_command_line(const wcstring &val_str, int fl } result.insert(new_cursor_pos++, L" "); } - free(replaced); *inout_cursor_pos = new_cursor_pos; return result; } @@ -1084,31 +1072,29 @@ static void completion_insert( const wchar_t *val, int flags ) \param comp the list of completions to display */ -static void run_pager( wchar_t *prefix, int is_quoted, const std::vector &comp ) +static void run_pager( const wcstring &prefix, int is_quoted, const std::vector &comp ) { wcstring msg; - wchar_t * prefix_esc; + wcstring prefix_esc; char *foo; io_data_t *in; wchar_t *escaped_separator; int has_case_sensitive=0; - if( !prefix || (wcslen(prefix)==0)) + if (prefix.empty()) { - prefix_esc = wcsdup(L"\"\""); + prefix_esc = L"\"\""; } else { - prefix_esc = escape( prefix,1); + prefix_esc = escape_string(prefix, 1); } wcstring cmd = format_string(L"fish_pager -c 3 -r 4 %ls -p %ls", // L"valgrind --track-fds=yes --log-file=pager.txt --leak-check=full ./fish_pager %d %ls", is_quoted?L"-q":L"", - prefix_esc ); + prefix_esc.c_str() ); - free(prefix_esc); - in= io_buffer_create( 1 ); in->fd = 3; @@ -1611,7 +1597,7 @@ static int handle_completions( const std::vector &comp ) is true, so we print the list */ int len; - wchar_t * prefix; + wcstring prefix; const wchar_t * prefix_start; const wchar_t *buff = data->command_line.c_str(); get_param( buff, @@ -1625,23 +1611,12 @@ static int handle_completions( const std::vector &comp ) if( len <= PREFIX_MAX_LEN ) { - prefix = (wchar_t *)malloc( sizeof(wchar_t)*(len+1) ); - wcslcpy( prefix, prefix_start, len ); - prefix[len]=L'\0'; + prefix.append(prefix_start, len); } else { - wchar_t tmp[2]= - { - ellipsis_char, - 0 - } - ; - - prefix = wcsdupcat( tmp, - prefix_start + (len - PREFIX_MAX_LEN) ); - prefix[PREFIX_MAX_LEN] = 0; - + prefix = wcstring(&ellipsis_char, 1); + prefix.append(prefix_start + (len - PREFIX_MAX_LEN)); } { @@ -1656,8 +1631,6 @@ static int handle_completions( const std::vector &comp ) run_pager( prefix, is_quoted, comp ); } - - free( prefix ); s_reset( &data->screen, true); reader_repaint(); diff --git a/wildcard.cpp b/wildcard.cpp index 0918f9ce2..e9055f9be 100644 --- a/wildcard.cpp +++ b/wildcard.cpp @@ -199,54 +199,49 @@ static int wildcard_match2( const wcstring &str_str, possible completion of the string, the remainder of the string is inserted into the out vector. */ -static int wildcard_complete_internal( const wchar_t *orig, +static bool wildcard_complete_internal(const wcstring &orig, const wchar_t *str, const wchar_t *wc, - int is_first, + bool is_first, const wchar_t *desc, const wchar_t *(*desc_func)(const wcstring &), std::vector &out, int flags ) { - if( !wc || !str || !orig) + if( !wc || ! str || orig.empty()) { debug( 2, L"Got null string on line %d of file %s", __LINE__, __FILE__ ); return 0; } if( *wc == 0 && - ( ( *str != L'.') || (!is_first)) ) + ( (str[0] != L'.') || (!is_first)) ) { - wchar_t *out_completion = 0; - const wchar_t *out_desc = desc; + wcstring out_completion; + wcstring out_desc = (desc ? desc : L""); if( flags & COMPLETE_NO_CASE ) { - out_completion = wcsdup( orig ); + out_completion = orig; } else { - out_completion = wcsdup( str ); + out_completion = str; } - if( wcschr( str, PROG_COMPLETE_SEP ) ) + size_t complete_sep_loc = out_completion.find(PROG_COMPLETE_SEP); + if (complete_sep_loc != wcstring::npos) { - /* - This completion has an embedded description, du not use the generic description - */ - wchar_t *sep; - - sep = wcschr(out_completion, PROG_COMPLETE_SEP ); - *sep = 0; - out_desc = sep + 1; - + /* This completion has an embedded description, do not use the generic description */ + out_desc.assign(out_completion, complete_sep_loc + 1, out_completion.size() - complete_sep_loc - 1); + out_completion.resize(complete_sep_loc); } else { if( desc_func ) { /* - A descripton generating function is specified, call + A description generating function is specified, call it. If it returns something, use that as the description. */ @@ -257,36 +252,33 @@ static int wildcard_complete_internal( const wchar_t *orig, } - if(out_completion) + if (! out_completion.empty()) { completion_allocate( out, out_completion, - out_desc ? out_desc : L"", + out_desc, flags ); - } - - free ( out_completion ); - - return 1; + } + return true; } if( *wc == ANY_STRING ) { - int res=0; + bool res=false; /* Ignore hidden file */ if( is_first && str[0] == L'.' ) - return 0; + return false; /* Try all submatches */ do { - res |= wildcard_complete_internal( orig, str, wc+1, 0, desc, desc_func, out, flags ); - if( res ) + res = wildcard_complete_internal( orig, str, wc+1, 0, desc, desc_func, out, flags ); + if (res) break; } - while( *str++ != 0 ); + while (*str++ != 0); return res; } @@ -302,20 +294,18 @@ static int wildcard_complete_internal( const wchar_t *orig, { return wildcard_complete_internal( orig, str+1, wc+1, 0, desc, desc_func, out, flags | COMPLETE_NO_CASE ); } - return 0; + return false; } -int wildcard_complete( const wchar_t *str, +bool wildcard_complete(const wcstring &str, const wchar_t *wc, const wchar_t *desc, const wchar_t *(*desc_func)(const wcstring &), std::vector &out, int flags ) { - int res; - - res = wildcard_complete_internal( str, str, wc, 1, desc, desc_func, out, flags ); - + bool res; + res = wildcard_complete_internal( str, str.c_str(), wc, true, desc, desc_func, out, flags ); return res; } @@ -570,15 +560,14 @@ static wcstring file_get_desc( const wchar_t *filename, */ static void wildcard_completion_allocate( std::vector &list, const wcstring &fullname, - const wchar_t *completion, + const wcstring &completion, const wchar_t *wc, expand_flags_t expand_flags) { struct stat buf, lbuf; wcstring sb; - - int free_completion = 0; - + wcstring munged_completion; + int flags = 0; int stat_res, lstat_res; int stat_errno=0; @@ -593,12 +582,13 @@ static void wildcard_completion_allocate( std::vector &list, */ if( ( lstat_res = lwstat( fullname, &lbuf ) ) ) { + /* lstat failed! */ sz=-1; stat_res = lstat_res; } else { - if( S_ISLNK(lbuf.st_mode)) + if (S_ISLNK(lbuf.st_mode)) { if( ( stat_res = wstat( fullname, &buf ) ) ) @@ -630,9 +620,9 @@ static void wildcard_completion_allocate( std::vector &list, if( sz >= 0 && S_ISDIR(buf.st_mode) ) { - free_completion = 1; flags = flags | COMPLETE_NO_SPACE; - completion = wcsdupcat( completion, L"/" ); + munged_completion = completion; + munged_completion.push_back(L'/'); sb.append(desc); } else @@ -641,10 +631,9 @@ static void wildcard_completion_allocate( std::vector &list, sb.append(L", "); sb.append(format_size(sz)); } - - wildcard_complete( completion, wc, sb.c_str(), NULL, list, flags ); - if( free_completion ) - free( (void *)completion ); + + const wcstring &completion_to_use = munged_completion.empty() ? completion : munged_completion; + wildcard_complete(completion_to_use, wc, sb.c_str(), NULL, list, flags); } /** @@ -790,7 +779,7 @@ static int wildcard_expand_internal( const wchar_t *wc, { wildcard_completion_allocate( out, long_name, - next.c_str(), + next, L"", flags); } @@ -812,7 +801,7 @@ static int wildcard_expand_internal( const wchar_t *wc, This is the last wildcard segment, and it is not empty. Match files/directories. */ wcstring next; - while(wreaddir(dir, next)) + while (wreaddir(dir, next)) { const wchar_t * const name = next.c_str(); if( flags & ACCEPT_INCOMPLETE ) diff --git a/wildcard.h b/wildcard.h index b85ba241e..cf7aa10f0 100644 --- a/wildcard.h +++ b/wildcard.h @@ -86,7 +86,7 @@ int wildcard_has( const wchar_t *str, int internal ); /** Test wildcard completion */ -int wildcard_complete( const wchar_t *str, +bool wildcard_complete(const wcstring &str, const wchar_t *wc, const wchar_t *desc, const wchar_t *(*desc_func)(const wcstring &),