mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
Modified builtin_set.cpp to use env_get(), added functions like update_values2(), env_set2() etc. to support wcstring and vector instead of using array_list_t
This commit is contained in:
parent
feed900f3d
commit
7b3377e78c
1 changed files with 294 additions and 43 deletions
337
builtin_set.cpp
337
builtin_set.cpp
|
@ -12,7 +12,8 @@ Functions used for implementing the set builtin.
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
#include "fallback.h"
|
#include "fallback.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
@ -72,7 +73,7 @@ static int my_env_set( const wchar_t *key, array_list_t *val, int scope )
|
||||||
int show_hint = 0;
|
int show_hint = 0;
|
||||||
|
|
||||||
struct stat buff;
|
struct stat buff;
|
||||||
wchar_t *dir = (wchar_t *)al_get( val, i );
|
const wchar_t *dir = (wchar_t *)al_get( val, i );
|
||||||
|
|
||||||
if( wstat( dir, &buff ) )
|
if( wstat( dir, &buff ) )
|
||||||
{
|
{
|
||||||
|
@ -88,7 +89,7 @@ static int my_env_set( const wchar_t *key, array_list_t *val, int scope )
|
||||||
|
|
||||||
if( error )
|
if( error )
|
||||||
{
|
{
|
||||||
wchar_t *colon;
|
const wchar_t *colon;
|
||||||
|
|
||||||
sb_printf( sb_err,
|
sb_printf( sb_err,
|
||||||
_(BUILTIN_SET_PATH_ERROR),
|
_(BUILTIN_SET_PATH_ERROR),
|
||||||
|
@ -173,6 +174,126 @@ static int my_env_set( const wchar_t *key, array_list_t *val, int scope )
|
||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int my_env_set2( const wchar_t *key, wcstring_list_t &val, int scope )
|
||||||
|
{
|
||||||
|
string_buffer_t sb;
|
||||||
|
int i;
|
||||||
|
int retcode = 0;
|
||||||
|
wchar_t *val_str=0;
|
||||||
|
|
||||||
|
if( is_path_variable( key ) )
|
||||||
|
{
|
||||||
|
int error = 0;
|
||||||
|
|
||||||
|
for( i=0; i< val.size() ; i++ )
|
||||||
|
{
|
||||||
|
int show_perror = 0;
|
||||||
|
int show_hint = 0;
|
||||||
|
|
||||||
|
struct stat buff;
|
||||||
|
const wchar_t *dir = val[ i ].c_str();
|
||||||
|
|
||||||
|
if( wstat( dir, &buff ) )
|
||||||
|
{
|
||||||
|
error = 1;
|
||||||
|
show_perror = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( !( S_ISDIR(buff.st_mode) ) )
|
||||||
|
{
|
||||||
|
error = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if( error )
|
||||||
|
{
|
||||||
|
const wchar_t *colon;
|
||||||
|
|
||||||
|
sb_printf( sb_err,
|
||||||
|
_(BUILTIN_SET_PATH_ERROR),
|
||||||
|
L"set",
|
||||||
|
dir,
|
||||||
|
key );
|
||||||
|
|
||||||
|
colon = wcschr( dir, L':' );
|
||||||
|
|
||||||
|
if( colon && *(colon+1) )
|
||||||
|
{
|
||||||
|
show_hint = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if( show_perror )
|
||||||
|
{
|
||||||
|
builtin_wperror( L"set" );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( show_hint )
|
||||||
|
{
|
||||||
|
sb_printf( sb_err,
|
||||||
|
_(BUILTIN_SET_PATH_HINT),
|
||||||
|
L"set",
|
||||||
|
key,
|
||||||
|
key,
|
||||||
|
wcschr( dir, L':' )+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( error )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if( error )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sb_init( &sb );
|
||||||
|
|
||||||
|
if( val.size() )
|
||||||
|
{
|
||||||
|
for( i=0; i< val.size() ; i++ )
|
||||||
|
{
|
||||||
|
const wchar_t *next = val[ i ].c_str();
|
||||||
|
sb_append( &sb, next?next:L"" );
|
||||||
|
if( i<val.size() - 1 )
|
||||||
|
{
|
||||||
|
sb_append( &sb, ARRAY_SEP_STR );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val_str = (wchar_t *)sb.buff;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( env_set( key, val_str, scope | ENV_USER ) )
|
||||||
|
{
|
||||||
|
case ENV_PERM:
|
||||||
|
{
|
||||||
|
sb_printf( sb_err, _(L"%ls: Tried to change the read-only variable '%ls'\n"), L"set", key );
|
||||||
|
retcode=1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ENV_INVALID:
|
||||||
|
{
|
||||||
|
sb_printf( sb_err, _(L"%ls: Unknown error"), L"set" );
|
||||||
|
retcode=1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sb_destroy( &sb );
|
||||||
|
|
||||||
|
return retcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Extract indexes from a destination argument of the form name[index1 index2...]
|
Extract indexes from a destination argument of the form name[index1 index2...]
|
||||||
|
|
||||||
|
@ -260,6 +381,82 @@ static int parse_index( array_list_t *indexes,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int parse_index2( std::vector<long> &indexes,
|
||||||
|
const wchar_t *src,
|
||||||
|
const wchar_t *name,
|
||||||
|
int var_count )
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
const wchar_t *src_orig = src;
|
||||||
|
|
||||||
|
if (src == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*src != L'\0' && (iswalnum(*src) || *src == L'_'))
|
||||||
|
{
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*src != L'[')
|
||||||
|
{
|
||||||
|
sb_printf( sb_err, _(BUILTIN_SET_ARG_COUNT), L"set" );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = src-src_orig;
|
||||||
|
|
||||||
|
if( (wcsncmp( src_orig, name, len )!=0) || (wcslen(name) != (len)) )
|
||||||
|
{
|
||||||
|
sb_printf( sb_err,
|
||||||
|
_(L"%ls: Multiple variable names specified in single call (%ls and %.*ls)\n"),
|
||||||
|
L"set",
|
||||||
|
name,
|
||||||
|
len,
|
||||||
|
src_orig);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
src++;
|
||||||
|
|
||||||
|
while (iswspace(*src))
|
||||||
|
{
|
||||||
|
src++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*src != L']')
|
||||||
|
{
|
||||||
|
wchar_t *end;
|
||||||
|
|
||||||
|
long l_ind;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
|
||||||
|
l_ind = wcstol(src, &end, 10);
|
||||||
|
|
||||||
|
if( end==src || errno )
|
||||||
|
{
|
||||||
|
sb_printf(sb_err, _(L"%ls: Invalid index starting at '%ls'\n"), L"set", src);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( l_ind < 0 )
|
||||||
|
{
|
||||||
|
l_ind = var_count+l_ind+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
indexes.push_back( l_ind );
|
||||||
|
src = end;
|
||||||
|
count++;
|
||||||
|
while (iswspace(*src)) src++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Update a list \c list by writing copies (using wcsdup) of the
|
Update a list \c list by writing copies (using wcsdup) of the
|
||||||
values specified by \c values to the indexes specified by \c
|
values specified by \c values to the indexes specified by \c
|
||||||
|
@ -295,7 +492,32 @@ static int update_values( array_list_t *list,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int update_values2( wcstring_list_t &list,
|
||||||
|
std::vector<long> &indexes,
|
||||||
|
wcstring_list_t &values )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Replace values where needed */
|
||||||
|
for( i = 0; i < indexes.size(); i++ )
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
The '- 1' below is because the indices in fish are
|
||||||
|
one-based, but the array_list_t uses zero-based indices
|
||||||
|
*/
|
||||||
|
long ind = indexes[i] - 1;
|
||||||
|
const wcstring newv = values[ i ];
|
||||||
|
if( ind < 0 )
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// free((void *) al_get(list, ind));
|
||||||
|
list[ ind ] = newv;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
Return 1 if an array list of longs contains the specified
|
Return 1 if an array list of longs contains the specified
|
||||||
value, 0 otherwise
|
value, 0 otherwise
|
||||||
|
@ -345,6 +567,35 @@ static void erase_values(array_list_t *list, array_list_t *indexes)
|
||||||
al_destroy(&result);
|
al_destroy(&result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Erase from a list of wcstring values at specified indexes
|
||||||
|
*/
|
||||||
|
static void erase_values2 (wcstring_list_t &list, std::vector<long> &indexes)
|
||||||
|
{
|
||||||
|
long i;
|
||||||
|
wcstring_list_t result;
|
||||||
|
|
||||||
|
// al_init(&result);
|
||||||
|
|
||||||
|
for (i = 0; i < list.size(); i++)
|
||||||
|
{
|
||||||
|
if (std::find(indexes.begin(), indexes.end(), i + 1) != indexes.end())
|
||||||
|
{
|
||||||
|
result.push_back( list[ i ] );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// free( (void *)al_get(list, i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// al_truncate(list,0);
|
||||||
|
list.clear();
|
||||||
|
copy(result.begin(),result.end(),back_inserter( list ) );
|
||||||
|
|
||||||
|
// al_destroy(&result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Print the names of all environment variables in the scope, with or without values,
|
Print the names of all environment variables in the scope, with or without values,
|
||||||
|
@ -369,23 +620,23 @@ static void print_variables(int include_values, int esc, int scope)
|
||||||
|
|
||||||
if( include_values )
|
if( include_values )
|
||||||
{
|
{
|
||||||
wchar_t *value = env_get(key);
|
wcstring value = env_get_string(key);
|
||||||
wchar_t *e_value;
|
wchar_t *e_value;
|
||||||
if( value )
|
if( !value.empty() )
|
||||||
{
|
{
|
||||||
int shorten = 0;
|
int shorten = 0;
|
||||||
|
|
||||||
if( wcslen( value ) > 64 )
|
if( value.length() > 64 )
|
||||||
{
|
{
|
||||||
shorten = 1;
|
shorten = 1;
|
||||||
value = wcsndup( value, 60 );
|
value = wcsndup( value.c_str(), 60 );
|
||||||
if( !value )
|
if( value.empty() )
|
||||||
{
|
{
|
||||||
DIE_MEM();
|
DIE_MEM();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
e_value = esc ? expand_escape_variable(value) : wcsdup(value);
|
e_value = esc ? expand_escape_variable(value.c_str()) : wcsdup(value.c_str());
|
||||||
|
|
||||||
sb_append(sb_out, L" ", e_value, NULL);
|
sb_append(sb_out, L" ", e_value, NULL);
|
||||||
free(e_value);
|
free(e_value);
|
||||||
|
@ -393,7 +644,7 @@ static void print_variables(int include_values, int esc, int scope)
|
||||||
if( shorten )
|
if( shorten )
|
||||||
{
|
{
|
||||||
sb_append(sb_out, L"\u2026");
|
sb_append(sb_out, L"\u2026");
|
||||||
free( value );
|
// free( value );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -632,25 +883,25 @@ static int builtin_set( wchar_t **argv )
|
||||||
|
|
||||||
if( slice )
|
if( slice )
|
||||||
{
|
{
|
||||||
array_list_t indexes;
|
std::vector<long> indexes;
|
||||||
array_list_t result;
|
wcstring_list_t result;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
al_init( &result );
|
// al_init( &result );
|
||||||
al_init( &indexes );
|
// al_init( &indexes );
|
||||||
|
|
||||||
tokenize_variable_array( env_get( dest ), &result );
|
tokenize_variable_array2( env_get_string( dest ), result );
|
||||||
|
|
||||||
if( !parse_index( &indexes, arg, dest, al_get_count( &result ) ) )
|
if( !parse_index2( indexes, arg, dest, result.size() ) )
|
||||||
{
|
{
|
||||||
builtin_print_help( argv[0], sb_err );
|
builtin_print_help( argv[0], sb_err );
|
||||||
retcode = 1;
|
retcode = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for( j=0; j<al_get_count( &indexes ); j++ )
|
for( j=0; j < indexes.size() ; j++ )
|
||||||
{
|
{
|
||||||
long idx = al_get_long( &indexes, j );
|
long idx = indexes[j];
|
||||||
if( idx < 1 || idx > al_get_count( &result ) )
|
if( idx < 1 || idx > result.size() )
|
||||||
{
|
{
|
||||||
retcode++;
|
retcode++;
|
||||||
}
|
}
|
||||||
|
@ -747,19 +998,19 @@ static int builtin_set( wchar_t **argv )
|
||||||
Slice mode
|
Slice mode
|
||||||
*/
|
*/
|
||||||
int idx_count, val_count;
|
int idx_count, val_count;
|
||||||
array_list_t values;
|
wcstring_list_t values;
|
||||||
array_list_t indexes;
|
std::vector<long> indexes;
|
||||||
array_list_t result;
|
wcstring_list_t result;
|
||||||
|
|
||||||
al_init(&values);
|
// al_init(&values);
|
||||||
al_init(&indexes);
|
// al_init(&indexes);
|
||||||
al_init(&result);
|
// al_init(&result);
|
||||||
|
|
||||||
tokenize_variable_array( env_get(dest), &result );
|
tokenize_variable_array2( env_get_string(dest), result );
|
||||||
|
|
||||||
for( ; woptind<argc; woptind++ )
|
for( ; woptind<argc; woptind++ )
|
||||||
{
|
{
|
||||||
if( !parse_index( &indexes, argv[woptind], dest, al_get_count( &result ) ) )
|
if( !parse_index2( indexes, argv[woptind], dest, result.size() ) )
|
||||||
{
|
{
|
||||||
builtin_print_help( argv[0], sb_err );
|
builtin_print_help( argv[0], sb_err );
|
||||||
retcode = 1;
|
retcode = 1;
|
||||||
|
@ -767,7 +1018,7 @@ static int builtin_set( wchar_t **argv )
|
||||||
}
|
}
|
||||||
|
|
||||||
val_count = argc-woptind-1;
|
val_count = argc-woptind-1;
|
||||||
idx_count = al_get_count( &indexes );
|
idx_count = indexes.size();
|
||||||
|
|
||||||
if( !erase )
|
if( !erase )
|
||||||
{
|
{
|
||||||
|
@ -794,42 +1045,42 @@ static int builtin_set( wchar_t **argv )
|
||||||
|
|
||||||
if( erase )
|
if( erase )
|
||||||
{
|
{
|
||||||
erase_values(&result, &indexes);
|
erase_values2(result, indexes);
|
||||||
my_env_set( dest, &result, scope);
|
my_env_set2( dest, result, scope);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
array_list_t value;
|
wcstring_list_t value;
|
||||||
al_init(&value);
|
// al_init(&value);
|
||||||
|
|
||||||
while( woptind < argc )
|
while( woptind < argc )
|
||||||
{
|
{
|
||||||
al_push(&value, argv[woptind++]);
|
value.push_back( argv[woptind++] );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( update_values( &result,
|
if( update_values2( result,
|
||||||
&indexes,
|
indexes,
|
||||||
&value ) )
|
value ) )
|
||||||
{
|
{
|
||||||
sb_printf( sb_err, L"%ls: ", argv[0] );
|
sb_printf( sb_err, L"%ls: ", argv[0] );
|
||||||
sb_printf( sb_err, ARRAY_BOUNDS_ERR );
|
sb_printf( sb_err, ARRAY_BOUNDS_ERR );
|
||||||
sb_append( sb_err, L"\n" );
|
sb_append( sb_err, L"\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
my_env_set(dest,
|
my_env_set2(dest,
|
||||||
&result,
|
result,
|
||||||
scope);
|
scope);
|
||||||
|
|
||||||
al_destroy( &value );
|
// al_destroy( &value );
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
al_foreach( &result, &free );
|
// al_foreach( &result, &free );
|
||||||
al_destroy( &result );
|
// al_destroy( &result );
|
||||||
|
|
||||||
al_destroy(&indexes);
|
// al_destroy(&indexes);
|
||||||
al_destroy(&values);
|
// al_destroy(&values);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in a new issue