Redesign new environment variables to use env_var_t instead of wcstring

Migrate uses of empty() to missing() to distinguish between empty variable and unset variable
This commit is contained in:
Peter Ammon 2012-01-14 02:42:17 -08:00
parent e8b6d48ad0
commit a359f45df2
17 changed files with 132 additions and 159 deletions

View file

@ -1999,7 +1999,6 @@ static int builtin_read( wchar_t **argv )
{
wchar_t *buff=0;
int i, argc = builtin_count_args( argv );
wcstring ifs;
int place = ENV_USER;
wchar_t *nxt;
const wchar_t *prompt = DEFAULT_READ_PROMPT;
@ -2284,8 +2283,8 @@ static int builtin_read( wchar_t **argv )
wchar_t *state;
ifs = env_get_string( L"IFS" );
if( ifs.empty() )
env_var_t ifs = env_get_string( L"IFS" );
if( ifs.missing() )
ifs = L"";
nxt = wcstok( buff, (i<argc-1)?ifs.c_str():L"", &state );
@ -2605,7 +2604,7 @@ static int builtin_exit( wchar_t **argv )
*/
static int builtin_cd( wchar_t **argv )
{
wcstring dir_in;
env_var_t dir_in;
wchar_t *dir;
int res=STATUS_BUILTIN_OK;
void *context = halloc( 0, 0 );
@ -2614,7 +2613,7 @@ static int builtin_cd( wchar_t **argv )
if( argv[1] == 0 )
{
dir_in = env_get_string( L"HOME" );
if( dir_in.empty() )
if( dir_in.missing_or_empty() )
{
sb_printf( sb_err,
_( L"%ls: Could not find home directory\n" ),
@ -2624,7 +2623,7 @@ static int builtin_cd( wchar_t **argv )
else
dir_in = argv[1];
dir = path_get_cdpath( context, dir_in.empty()?0:dir_in.c_str() );
dir = path_get_cdpath( context, dir_in.missing() ? NULL : dir_in.c_str() );
if( !dir )
{

View file

@ -620,31 +620,24 @@ static void print_variables(int include_values, int esc, int scope)
if( include_values )
{
wcstring value = env_get_string(key);
wchar_t *e_value;
if( !value.empty() )
env_var_t value = env_get_string(key);
if( !value.missing() )
{
int shorten = 0;
if( value.length() > 64 )
{
shorten = 1;
value = wcsndup( value.c_str(), 60 );
if( value.empty() )
{
DIE_MEM();
}
value.resize(60);
}
e_value = esc ? expand_escape_variable(value.c_str()) : wcsdup(value.c_str());
wcstring e_value = esc ? expand_escape_variable2(value) : value;
sb_append(sb_out, L" ", e_value, NULL);
free(e_value);
sb_append(sb_out, L" ", e_value.c_str(), NULL);
if( shorten )
{
sb_append(sb_out, L"\u2026");
// free( value );
}
}
@ -889,8 +882,9 @@ static int builtin_set( wchar_t **argv )
// al_init( &result );
// al_init( &indexes );
tokenize_variable_array2( env_get_string( dest ), result );
env_var_t dest_str = env_get_string(dest);
if (! dest_str.missing())
tokenize_variable_array2( dest_str, result );
if( !parse_index2( indexes, arg, dest, result.size() ) )
{
@ -1006,7 +1000,9 @@ static int builtin_set( wchar_t **argv )
// al_init(&indexes);
// al_init(&result);
tokenize_variable_array2( env_get_string(dest), result );
const env_var_t dest_str = env_get_string(dest);
if (! dest_str.missing())
tokenize_variable_array2( dest_str, result );
for( ; woptind<argc; woptind++ )
{

View file

@ -1080,16 +1080,15 @@ static void complete_cmd( const wchar_t *cmd,
int use_builtin,
int use_command )
{
wcstring path;
wchar_t *path_cpy;
wchar_t *nxt_path;
wchar_t *state;
array_list_t possible_comp;
wchar_t *nxt_completion;
const wcstring cdpath = env_get_string(L"CDPATH");
const env_var_t cdpath = env_get_string(L"CDPATH");
// wchar_t *cdpath_cpy = wcsdup( cdpath?cdpath:L"." );
wchar_t *cdpath_cpy = wcsdup( !cdpath.empty()?cdpath.c_str():L"." );
wchar_t *cdpath_cpy = wcsdup( !cdpath.missing()?cdpath.c_str():L"." );
if( (wcschr( cmd, L'/') != 0) || (cmd[0] == L'~' ) )
{
@ -1111,8 +1110,8 @@ static void complete_cmd( const wchar_t *cmd,
if( use_command )
{
path = env_get_string(L"PATH");
if( !path.empty() )
const env_var_t path = env_get_string(L"PATH");
if( !path.missing() )
{
path_cpy = wcsdup( path.c_str() );
@ -1656,11 +1655,8 @@ static int complete_variable( const wchar_t *whole_var,
if( match || match_no_case )
{
wcstring value_unescaped;
wchar_t *value;
value_unescaped = env_get_string( name );
if( !value_unescaped.empty() )
const env_var_t value_unescaped = env_get_string( name );
if( !value_unescaped.missing() )
{
string_buffer_t desc;
string_buffer_t comp;
@ -1680,10 +1676,10 @@ static int complete_variable( const wchar_t *whole_var,
flags = COMPLETE_NO_CASE | COMPLETE_DONT_ESCAPE;
}
value = expand_escape_variable( value_unescaped.c_str() );
wcstring value = expand_escape_variable2( value_unescaped );
sb_init( &desc );
sb_printf( &desc, COMPLETE_VAR_DESC_VAL, value );
sb_printf( &desc, COMPLETE_VAR_DESC_VAL, value.c_str() );
completion_allocate( comp_list,
(wchar_t *)comp.buff,
@ -1691,7 +1687,6 @@ static int complete_variable( const wchar_t *whole_var,
flags );
res =1;
free( value );
sb_destroy( &desc );
sb_destroy( &comp );
}

83
env.cpp
View file

@ -302,7 +302,6 @@ static int is_locale( const wchar_t *key )
static void handle_locale()
{
const env_var_t lc_all = env_get_string( L"LC_ALL" );
wcstring lang;
int i;
wchar_t *old = wcsdup(wsetlocale( LC_MESSAGES, NULL ));
@ -328,17 +327,17 @@ static void handle_locale()
}
else
{
lang = env_get_string( L"LANG" );
if( !lang.empty() )
const env_var_t lang = env_get_string( L"LANG" );
if( !lang.missing() )
{
wsetlocale( LC_ALL, lang.c_str() );
}
for( i=2; locale_variable[i]; i++ )
{
const wcstring val = env_get_string( locale_variable[i] );
const env_var_t val = env_get_string( locale_variable[i] );
if( !val.empty() )
if( !val.missing() )
{
wsetlocale( cat[i], val.c_str() );
}
@ -423,49 +422,47 @@ static void universal_callback( int type,
}
/**
Make sure the PATH variable contains the essaential directories
Make sure the PATH variable contains the essential directories
*/
static void setup_path()
{
wcstring path;
{
size_t i;
int j;
wcstring_list_t lst;
const wchar_t *path_el[] =
{
L"/bin",
L"/usr/bin",
PREFIX L"/bin",
0
}
{
L"/bin",
L"/usr/bin",
PREFIX L"/bin",
0
}
;
path = env_get_string( L"PATH" );
env_var_t path = env_get_string( L"PATH" );
if( !path.empty() )
if( !path.missing() )
{
tokenize_variable_array2( path, lst );
}
for( j=0; path_el[j]; j++ )
{
int has_el=0;
for( i=0; i<lst.size(); i++ )
{
wcstring el = lst.at(i);
size_t len = el.size();
while( (len > 0) && (el[len-1]==L'/') )
{
len--;
}
if( (wcslen( path_el[j] ) == len) &&
(wcsncmp( el.c_str(), path_el[j], len)==0) )
(wcsncmp( el.c_str(), path_el[j], len)==0) )
{
has_el = 1;
}
@ -474,21 +471,21 @@ static void setup_path()
if( !has_el )
{
wcstring buffer;
debug( 3, L"directory %ls was missing", path_el[j] );
if( !path.empty() )
if( !path.missing() )
{
buffer += path;
buffer += path;
}
buffer += ARRAY_SEP_STR;
buffer += path_el[j];
buffer += ARRAY_SEP_STR;
buffer += path_el[j];
env_set( L"PATH", buffer.empty()?NULL:buffer.c_str(), ENV_GLOBAL | ENV_EXPORT );
path = env_get_string( L"PATH" );
lst.resize(0);
lst.resize(0);
tokenize_variable_array2( path, lst );
}
}
@ -512,7 +509,7 @@ int env_set_pwd()
static void env_set_defaults()
{
if( env_get_string( L"USER" ).empty() )
if( env_get_string(L"USER").missing() )
{
struct passwd *pw = getpwuid( getuid());
wchar_t *unam = str2wcs( pw->pw_name );
@ -520,9 +517,9 @@ static void env_set_defaults()
free( unam );
}
if( env_get_string( L"HOME" ).empty() )
if( env_get_string(L"HOME").missing() )
{
const wcstring unam = env_get_string( L"USER" );
const env_var_t unam = env_get_string( L"USER" );
char *unam_narrow = wcs2str( unam.c_str() );
struct passwd *pw = getpwnam( unam_narrow );
wchar_t *dir = str2wcs( pw->pw_dir );
@ -657,11 +654,11 @@ void env_init()
env_set( L"version", version, ENV_GLOBAL );
free( version );
const wcstring fishd_dir_wstr = env_get_string( L"FISHD_SOCKET_DIR");
const wcstring user_dir_wstr = env_get_string( L"USER" );
const env_var_t fishd_dir_wstr = env_get_string( L"FISHD_SOCKET_DIR");
const env_var_t user_dir_wstr = env_get_string( L"USER" );
wchar_t * fishd_dir = fishd_dir_wstr.empty()?NULL:const_cast<wchar_t*>(fishd_dir_wstr.c_str());
wchar_t * user_dir = user_dir_wstr.empty()?NULL:const_cast<wchar_t*>(user_dir_wstr.c_str());
wchar_t * fishd_dir = fishd_dir_wstr.missing()?NULL:const_cast<wchar_t*>(fishd_dir_wstr.c_str());
wchar_t * user_dir = user_dir_wstr.missing()?NULL:const_cast<wchar_t*>(user_dir_wstr.c_str());
env_universal_init(fishd_dir , user_dir ,
&start_fishd,
@ -670,8 +667,8 @@ void env_init()
/*
Set up SHLVL variable
*/
const wcstring shlvl_str = env_get_string( L"SHLVL" );
const wchar_t *shlvl = shlvl_str.empty() ? NULL : shlvl_str.c_str();
const env_var_t shlvl_str = env_get_string( L"SHLVL" );
const wchar_t *shlvl = shlvl_str.missing() ? NULL : shlvl_str.c_str();
if ( shlvl )
{
@ -1831,9 +1828,9 @@ env_vars::env_vars(const wchar_t * const *keys)
{
ASSERT_IS_MAIN_THREAD();
for (size_t i=0; keys[i]; i++) {
const wcstring val = env_get_string(keys[i]);
if (!val.empty()) {
vars[keys[i]] = wcsdup(val.c_str());
const env_var_t val = env_get_string(keys[i]);
if (!val.missing()) {
vars[keys[i]] = val;
}
}
}

6
env.h
View file

@ -106,6 +106,12 @@ public:
bool missing(void) const { return is_missing; }
bool missing_or_empty(void) const { return missing() || empty(); }
const wchar_t *c_str(void) const;
env_var_t &operator=(const env_var_t &s) {
is_missing = s.is_missing;
wcstring::operator=(s);
return *this;
}
};
/**
Gets the variable with the specified name, or an empty string if it does not exist.

View file

@ -1740,16 +1740,15 @@ int exec_subshell( const wchar_t *cmd,
int prev_subshell = is_subshell;
int status, prev_status;
io_data_t *io_buffer;
const wchar_t *ifs;
char sep=0;
CHECK( cmd, -1 );
// ifs = env_get(L"IFS");
ifs = env_get_string(L"IFS").empty()?NULL:env_get_string(L"IFS").c_str();
const env_var_t ifs = env_get_string(L"IFS").empty()?NULL:env_get_string(L"IFS").c_str();
if( ifs && ifs[0] )
if( ! ifs.missing_or_empty() )
{
if( ifs[0] < 128 )
if( ifs.at(0) < 128 )
{
sep = '\n';//ifs[0];
}

View file

@ -278,7 +278,13 @@ wchar_t *expand_escape_variable( const wchar_t *in )
al_destroy( &l );
return (wchar_t *)buff.buff;
}
wcstring expand_escape_variable2( const wcstring &in ) {
wchar_t *tmp = expand_escape_variable(in.c_str());
wcstring result(tmp ? tmp : L"");
free(tmp);
return result;
}
/**

View file

@ -165,11 +165,12 @@ __warn_unused int expand_string2( const wcstring &input, std::list<wcstring> &ou
wchar_t *expand_one( void *context, wchar_t *in, int flag );
/**
Convert the variable value to a human readable form, i.e. escape things, handle arrays, etc. Suitable for pretty-printing.
Convert the variable value to a human readable form, i.e. escape things, handle arrays, etc. Suitable for pretty-printing. The result must be free'd!
\param in the value to escape
*/
wchar_t *expand_escape_variable( const wchar_t *in );
wcstring expand_escape_variable2( const wcstring &in );
/**
Perform tilde expansion and nothing else on the specified string, which is modified in place.

View file

@ -152,11 +152,10 @@ static void autoload_names( std::set<wcstring> &names, int get_hidden )
{
size_t i;
const wcstring path_var_wstr = env_get_string( L"fish_function_path" );
const wchar_t *path_var = path_var_wstr.empty()?NULL:path_var_wstr.c_str();
if( ! path_var )
return;
const env_var_t path_var_wstr = env_get_string( L"fish_function_path" );
if (path_var_wstr.missing())
return;
const wchar_t *path_var = path_var_wstr.c_str();
wcstring_list_t path_list;

View file

@ -190,23 +190,20 @@ int highlight_get_color( int highlight )
}
}
wcstring val_wstr = env_get_string( highlight_var[idx]);
const wchar_t *val = val_wstr.empty()?NULL:val_wstr.c_str();
env_var_t val_wstr = env_get_string( highlight_var[idx]);
// debug( 1, L"%d -> %d -> %ls", highlight, idx, val );
if( val == 0 ) {
if (val_wstr.missing())
val_wstr = env_get_string( highlight_var[0]);
val = val_wstr.empty()?NULL:val_wstr.c_str();
}
if( val )
result = output_color_code( val );
if( ! val_wstr.missing() )
result = output_color_code( val_wstr.c_str() );
if( highlight & HIGHLIGHT_VALID_PATH )
{
wcstring val2_wstr = env_get_string( L"fish_color_valid_path" );
const wchar_t *val2 = val2_wstr.empty()?NULL:val2_wstr.c_str();
env_var_t val2_wstr = env_get_string( L"fish_color_valid_path" );
const wchar_t *val2 = val2_wstr.missing() ? NULL : val2_wstr.c_str();
int result2 = output_color_code( val2 );
if( result == FISH_COLOR_NORMAL )

View file

@ -8,6 +8,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <errno.h>
#include <termios.h>
@ -324,7 +325,9 @@ int input_init()
debug( 0, _( L"Could not set up terminal" ) );
exit(1);
}
output_set_term( env_get_string( L"TERM" ).c_str() );
const env_var_t term = env_get_string( L"TERM" );
assert(! term.missing());
output_set_term( term.c_str() );
input_terminfo_init();

View file

@ -105,9 +105,8 @@ void kill_add( wchar_t *str )
command too, so, the command used must accept the input via stdin.
*/
const wcstring clipboard_wstr = env_get_string(L"FISH_CLIPBOARD_CMD");
// const wchar_t *clipboard = clipboard_wstr.empty()?NULL:clipboard.c_str();
if( !clipboard_wstr.empty() )
const env_var_t clipboard_wstr = env_get_string(L"FISH_CLIPBOARD_CMD");
if( !clipboard_wstr.missing() )
{
escaped_str = escape( str, 1 );
cmd = wcsdupcat(L"echo -n ", escaped_str, clipboard_wstr.c_str());
@ -119,9 +118,8 @@ void kill_add( wchar_t *str )
return;
}
const wcstring disp_wstr = env_get_string( L"DISPLAY" );
// wchar_t *disp = disp_wstr.empty()?NULL:disp_wstr.c_str();
if( !disp_wstr.empty() )
const env_var_t disp_wstr = env_get_string( L"DISPLAY" );
if( !disp_wstr.missing() )
{
escaped_str = escape( str, 1 );
cmd = wcsdupcat(L"echo ", escaped_str, L"|xsel -b" );
@ -217,14 +215,12 @@ wchar_t *kill_yank_rotate()
clipboard contents to the fish killring.
*/
static void kill_check_x_buffer()
{
wcstring disp;
{
if( !has_xsel() )
return;
if( (!(disp = env_get_string( L"DISPLAY" )).empty()) )
const env_var_t disp = env_get_string(L"DISPLAY");
if( ! disp.missing())
{
size_t i;
wcstring cmd = L"xsel -t 500 -b";

View file

@ -801,8 +801,6 @@ int parse_util_load( const wcstring &cmd,
void (*on_load)(const wchar_t *cmd),
int reload )
{
wcstring path_var;
int res;
int c, c2;
autoload_t *loaded;
@ -812,7 +810,7 @@ int parse_util_load( const wcstring &cmd,
// debug( 0, L"Autoload %ls in %ls", cmd, path_var_name );
parse_util_autounload( path_var_name.c_str(), cmd.c_str(), on_load );
path_var = env_get_string( path_var_name.c_str() );
const env_var_t path_var = env_get_string( path_var_name.c_str() );
/*
Do we know where to look?

View file

@ -2044,8 +2044,8 @@ static int parse_job( process_t *p,
else if(cmd[0]==L'$')
{
const wcstring val_wstr = env_get_string( cmd+1 );
const wchar_t *val = val_wstr.empty()?NULL:val_wstr.c_str();
const env_var_t val_wstr = env_get_string( cmd+1 );
const wchar_t *val = val_wstr.missing() ? NULL : val_wstr.c_str();
if( val )
{
debug( 0,

View file

@ -166,9 +166,8 @@ wchar_t *path_get_path( void *context, const wchar_t *cmd )
}
else
{
const wcstring path_wstr = env_get_string(L"PATH");
path = path_wstr.empty()?NULL:path_wstr.c_str();
if( path == 0 )
env_var_t path = env_get_string(L"PATH");
if( path.missing() )
{
if( contains( PREFIX L"/bin", L"/bin", L"/usr/bin" ) )
{
@ -183,14 +182,14 @@ wchar_t *path_get_path( void *context, const wchar_t *cmd )
/*
Allocate string long enough to hold the whole command
*/
wchar_t *new_cmd = (wchar_t *)halloc( context, sizeof(wchar_t)*(wcslen(cmd)+wcslen(path)+2) );
wchar_t *new_cmd = (wchar_t *)halloc( context, sizeof(wchar_t)*(wcslen(cmd)+path.size()+2) );
/*
We tokenize a copy of the path, since strtok modifies
its arguments
*/
wchar_t *path_cpy = wcsdup( path );
const wchar_t *nxt_path = path;
wchar_t *path_cpy = wcsdup( path.c_str() );
const wchar_t *nxt_path = path.c_str();
wchar_t *state;
if( (new_cmd==0) || (path_cpy==0) )
@ -357,22 +356,17 @@ wchar_t *path_get_cdpath( void *context, const wchar_t *dir )
}
else
{
const wchar_t *path;
wchar_t *path_cpy;
wchar_t *nxt_path;
const wchar_t *nxt_path;
wchar_t *state;
wchar_t *whole_path;
const wcstring path_wstr = env_get_string(L"CDPATH");
path = path_wstr.empty()?NULL:path_wstr.c_str();
if( !path || !wcslen(path) )
{
env_var_t path = env_get_string(L"CDPATH");
if( path.missing_or_empty() )
path = L".";
}
nxt_path = const_cast<wchar_t*>(path);
path_cpy = wcsdup( path );
nxt_path = path.c_str();
path_cpy = wcsdup( path.c_str() );
if( !path_cpy )
{
@ -439,47 +433,36 @@ wchar_t *path_get_cdpath( void *context, const wchar_t *dir )
wchar_t *path_get_config( void *context)
{
const wchar_t *xdg_dir, *home;
int done = 0;
wchar_t *res = 0;
wcstring res;
const wcstring xdg_dir_wstr = env_get_string( L"XDG_CONFIG_HOME" );
xdg_dir = xdg_dir_wstr.empty()?NULL:xdg_dir_wstr.c_str();
if( xdg_dir )
const env_var_t xdg_dir = env_get_string( L"XDG_CONFIG_HOME" );
if( ! xdg_dir.missing() )
{
res = wcsdupcat( xdg_dir, L"/fish" );
if( !create_directory( res ) )
res = xdg_dir + L"/fish";
if( !create_directory( res.c_str() ) )
{
done = 1;
}
else
{
free( res );
}
}
else
{
const wcstring home_wstr = env_get_string( L"HOME" );
home = home_wstr.empty()?NULL:home_wstr.c_str();
if( home )
const env_var_t home = env_get_string( L"HOME" );
if( ! home.missing() )
{
res = wcsdupcat( home, L"/.config/fish" );
if( !create_directory( res ) )
res = home + L"/.config/fish";
if( !create_directory( res.c_str() ) )
{
done = 1;
}
else
{
free( res );
}
}
}
if( done )
{
halloc_register_function( context, &free, res );
return res;
wchar_t *result = wcsdup(res.c_str());
halloc_register_function( context, &free, result );
return result;
}
else
{

View file

@ -606,8 +606,7 @@ int reader_interrupted()
void reader_write_title()
{
const wchar_t *title;
const wcstring term_str = env_get_string( L"TERM" );
const wchar_t *term = term_str.empty()?NULL:term_str.c_str();
const env_var_t term_str = env_get_string( L"TERM" );
/*
This is a pretty lame heuristic for detecting terminals that do
@ -623,11 +622,10 @@ void reader_write_title()
don't. Since we can't see the underlying terminal below screen
there is no way to fix this.
*/
if ( !term )
{
if ( term_str.missing() )
return;
}
const wchar_t *term = term_str.c_str();
bool recognized = false;
recognized = recognized || contains( term, L"xterm", L"screen", L"nxterm", L"rxvt" );
recognized = recognized || ! wcsncmp(term, L"xterm-", wcslen(L"xterm-"));

View file

@ -204,8 +204,8 @@ static int calc_prompt_width( const wchar_t *prompt )
{
if( prompt[j+1] == L'k' )
{
wcstring term_name = env_get_string( L"TERM" );
if( !term_name.empty() && wcsstr( term_name.c_str(), L"screen" ) == term_name )
const env_var_t term_name = env_get_string( L"TERM" );
if( !term_name.missing() && wcsstr( term_name.c_str(), L"screen" ) == term_name )
{
const wchar_t *end;
j+=2;