diff options
author | axel <axel@liljencrantz.se> | 2006-06-05 06:14:51 +1000 |
---|---|---|
committer | axel <axel@liljencrantz.se> | 2006-06-05 06:14:51 +1000 |
commit | 04b142208d6a62a24cc067df437e0af4b8a1f4ca (patch) | |
tree | b7af8ff58df2acc3587dc4fb665ca082373108fe /env.c | |
parent | cf35a8e3a5ee724f12f13175d81d89b8d74c997c (diff) |
Make it possible to specify scope of a variable to be erased or tested. Also make sure set exits with a non-zero exit status when erasing fails.
darcs-hash:20060604201451-ac50b-4ea0212c513b33be40559dfe8d65c1446c53f682.gz
Diffstat (limited to 'env.c')
-rw-r--r-- | env.c | 138 |
1 files changed, 93 insertions, 45 deletions
@@ -822,10 +822,12 @@ int env_set( const wchar_t *key, \return zero if the variable was not found, non-zero otherwise */ static int try_remove( env_node_t *n, - const wchar_t *key ) + const wchar_t *key, + int var_mode ) { const void *old_key_void, *old_val_void; wchar_t *old_key, *old_val; + if( n == 0 ) return 0; @@ -850,44 +852,70 @@ static int try_remove( env_node_t *n, return 1; } + if( var_mode & ENV_LOCAL ) + return 0; + if( n->new_scope ) - return try_remove( global_env, key ); + return try_remove( global_env, key, var_mode ); else - return try_remove( n->next, key ); + return try_remove( n->next, key, var_mode ); } -void env_remove( const wchar_t *key, int var_mode ) +int env_remove( const wchar_t *key, int var_mode ) { + env_node_t *first_node; + int erased = 0; + if( (var_mode & ENV_USER ) && hash_get( &env_read_only, key ) ) { - return; + return 2; } - if( try_remove( top, key ) ) - { - event_t ev; - - ev.type=EVENT_VARIABLE; - ev.param1.variable=key; - ev.function_name=0; - - al_init( &ev.arguments ); - al_push( &ev.arguments, L"VARIABLE" ); - al_push( &ev.arguments, L"ERASE" ); - al_push( &ev.arguments, key ); - event_fire( &ev ); - al_destroy( &ev.arguments ); + first_node = top; + + if( ! (var_mode & ENV_UNIVERSAL ) ) + { + + if( var_mode & ENV_GLOBAL ) + { + first_node = global_env; + } + + if( try_remove( first_node, key, var_mode ) ) + { + event_t ev; + + ev.type=EVENT_VARIABLE; + ev.param1.variable=key; + ev.function_name=0; + + al_init( &ev.arguments ); + al_push( &ev.arguments, L"VARIABLE" ); + al_push( &ev.arguments, L"ERASE" ); + al_push( &ev.arguments, key ); + + event_fire( &ev ); + + al_destroy( &ev.arguments ); + erased = 1; + } } - else + + if( !erased && + !(var_mode & ENV_GLOBAL) && + !(var_mode & ENV_LOCAL) ) { - env_universal_remove( key ); + erased = !env_universal_remove( key ); } if( is_locale( key ) ) + { handle_locale(); - + } + + return !erased; } @@ -989,40 +1017,60 @@ wchar_t *env_get( const wchar_t *key ) return item; } -int env_exist( const wchar_t *key ) +int env_exist( const wchar_t *key, int mode ) { var_entry_t *res; - env_node_t *env = top; - wchar_t *item; - - if( hash_get( &env_read_only, key ) || hash_get( &env_electric, key ) ) - { - return 1; - } - - while( env != 0 ) + env_node_t *env; + wchar_t *item=0; + + /* + Read only variables all exist, and they are all global. A local + varion can not exist. + */ + if( ! (mode & ENV_LOCAL) && ! (mode & ENV_UNIVERSAL) ) { - res = (var_entry_t *) hash_get( &env->env, - key ); - if( res != 0 ) + if( hash_get( &env_read_only, key ) || hash_get( &env_electric, key ) ) { return 1; } - - if( env->new_scope ) - env = global_env; - else - env = env->next; - } - if( !proc_had_barrier) + } + + if( ! (mode & ENV_UNIVERSAL) ) { - proc_had_barrier=1; - env_universal_barrier(); + env = (mode & ENV_GLOBAL)?global_env:top; + + while( env != 0 ) + { + res = (var_entry_t *) hash_get( &env->env, + key ); + if( res != 0 ) + { + return 1; + } + + if( mode & ENV_LOCAL ) + break; + + if( env->new_scope ) + env = global_env; + else + env = env->next; + } } - item = env_universal_get( key ); + if( ! (mode & ENV_LOCAL) && ! (mode & ENV_GLOBAL) ) + { + if( !proc_had_barrier) + { + proc_had_barrier=1; + env_universal_barrier(); + } + + item = env_universal_get( key ); + } return item != 0; + } /** |