mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-25 04:13:08 +00:00
Lots of modernization changed
Removed wcsdupcat
This commit is contained in:
parent
4bd63020ca
commit
9bcc7df96f
15 changed files with 177 additions and 348 deletions
|
@ -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 = (
|
||||
);
|
||||
|
|
|
@ -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 )
|
||||
{
|
||||
|
|
83
common.cpp
83
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<count; i++ )
|
||||
{
|
||||
res[i]=str2wcs(in[i]);
|
||||
}
|
||||
res[count]=0;
|
||||
return res;
|
||||
|
||||
}
|
||||
wcstring format_string(const wchar_t *format, ...)
|
||||
{
|
||||
va_list va;
|
||||
|
@ -1723,6 +1668,13 @@ void tokenize_variable_array( const wcstring &val, std::vector<wcstring> &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<char> 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);
|
||||
}
|
||||
}
|
||||
|
|
22
common.h
22
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.
|
||||
|
||||
|
|
95
complete.cpp
95
complete.cpp
|
@ -828,7 +828,7 @@ int complete_is_valid_argument( const wchar_t *str,
|
|||
*/
|
||||
|
||||
static void complete_strings( std::vector<completion_t> &comp_out,
|
||||
const wchar_t *wc_escaped,
|
||||
const wcstring &wc_escaped,
|
||||
const wchar_t *desc,
|
||||
const wchar_t *(*desc_func)(const wcstring &),
|
||||
std::vector<completion_t> &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++;
|
||||
}
|
||||
|
|
6
expand.h
6
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.
|
||||
|
|
78
fishd.cpp
78
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 )
|
||||
{
|
||||
|
|
|
@ -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<int> &color, int pos, wc
|
|||
|
||||
//our subcolors start at color + (begin-subbuff)+1
|
||||
size_t start = begin - subbuff + 1, len = wcslen(begin + 1);
|
||||
std::vector<int> subcolors;
|
||||
subcolors.resize(len, -1);
|
||||
std::vector<int> subcolors(len, -1);
|
||||
|
||||
highlight_shell( begin+1, subcolors, -1, error, vars );
|
||||
|
||||
|
|
17
kill.cpp
17
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;
|
||||
}
|
||||
|
|
10
parser.cpp
10
parser.cpp
|
@ -798,14 +798,8 @@ int parser_t::eval_args( const wchar_t *line, std::vector<completion_t> &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;
|
||||
|
|
40
path.cpp
40
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;
|
||||
|
|
2
path.h
2
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);
|
||||
|
||||
|
|
65
reader.cpp
65
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<completion_t> &comp )
|
||||
static void run_pager( const wcstring &prefix, int is_quoted, const std::vector<completion_t> &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<completion_t> &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<completion_t> &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<completion_t> &comp )
|
|||
|
||||
run_pager( prefix, is_quoted, comp );
|
||||
}
|
||||
|
||||
free( prefix );
|
||||
s_reset( &data->screen, true);
|
||||
reader_repaint();
|
||||
|
||||
|
|
89
wildcard.cpp
89
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<completion_t> &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<completion_t> &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<completion_t> &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<completion_t> &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<completion_t> &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<completion_t> &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 )
|
||||
|
|
|
@ -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 &),
|
||||
|
|
Loading…
Reference in a new issue