aboutsummaryrefslogtreecommitdiffhomepage
path: root/env.c
diff options
context:
space:
mode:
authorGravatar axel <axel@liljencrantz.se>2006-06-05 06:14:51 +1000
committerGravatar axel <axel@liljencrantz.se>2006-06-05 06:14:51 +1000
commit04b142208d6a62a24cc067df437e0af4b8a1f4ca (patch)
treeb7af8ff58df2acc3587dc4fb665ca082373108fe /env.c
parentcf35a8e3a5ee724f12f13175d81d89b8d74c997c (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.c138
1 files changed, 93 insertions, 45 deletions
diff --git a/env.c b/env.c
index 39cd5a4b..d501576c 100644
--- a/env.c
+++ b/env.c
@@ -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;
+
}
/**