19
19
***********************************************************************/
20
20
#include "config_ast.h" // IWYU pragma: keep
21
21
22
- #include <setjmp.h>
23
22
#include <stdbool.h>
24
23
#include <string.h>
25
24
26
25
#include "builtins.h"
27
26
#include "cdt.h"
28
27
#include "defs.h"
29
28
#include "error.h"
30
- #include "fault.h"
31
29
#include "name.h"
32
30
#include "option.h"
33
- #include "sfio.h"
34
31
#include "shcmd.h"
35
32
36
- static_fn int unall (int , char * * , Dt_t * , Shell_t * );
37
-
38
- // The `unalias` builtin.
39
- int b_unalias (int argc , char * argv [], Shbltin_t * context ) {
40
- Shell_t * shp = context -> shp ;
41
- return unall (argc , argv , shp -> alias_tree , shp );
42
- }
43
-
44
33
// The `unset` builtin.
45
34
int b_unset (int argc , char * argv [], Shbltin_t * context ) {
35
+ UNUSED (argc );
46
36
Shell_t * shp = context -> shp ;
47
- return unall (argc , argv , shp -> var_tree , shp );
48
- }
49
-
50
- //
51
- // The removing of Shell variable names, aliases, and functions is performed here. Unset functions
52
- // with unset -f. Non-existent items being deleted give non-zero exit status.
53
- //
54
- static_fn int unall (int argc , char * * argv , Dt_t * troot , Shell_t * shp ) {
55
- Namval_t * np ;
56
- const char * name ;
57
- volatile int r ;
58
- Dt_t * dp ;
37
+ Dt_t * troot = shp -> var_tree ;
59
38
nvflag_t nvflags = 0 ;
60
- int all = 0 , isfun , jmpval ;
61
- checkpt_t buff ;
62
- enum { ALIAS , VARIABLE } type ;
63
- UNUSED (argc );
39
+ int n ;
64
40
65
- if (troot == shp -> alias_tree ) {
66
- type = ALIAS ;
67
- name = sh_optunalias ;
68
- if (shp -> subshell ) troot = sh_subaliastree (shp , 0 );
69
- } else {
70
- type = VARIABLE ;
71
- name = sh_optunset ;
72
- }
73
- while ((r = optget (argv , name ))) {
74
- switch (r ) { //!OCLINT(MissingDefaultStatement)
41
+ while ((n = optget (argv , sh_optunset ))) {
42
+ switch (n ) { //!OCLINT(MissingDefaultStatement)
75
43
case 'f' : {
76
44
troot = sh_subfuntree (shp , true);
77
- break ;
78
- }
79
- case 'a' : {
80
- all = 1 ;
45
+ nvflags |= NV_NOSCOPE ;
81
46
break ;
82
47
}
83
48
case 'n' : {
84
- nvflags = NV_NOREF ;
49
+ nvflags |= NV_NOREF ;
50
+ troot = shp -> var_tree ;
51
+ break ;
85
52
}
86
- // FALLTHRU
87
53
case 'v' : {
88
54
troot = shp -> var_tree ;
89
55
break ;
@@ -99,82 +65,12 @@ static_fn int unall(int argc, char **argv, Dt_t *troot, Shell_t *shp) {
99
65
}
100
66
}
101
67
argv += opt_info .index ;
102
- if (error_info .errors || ( * argv == 0 && ! all ) ) {
68
+ if (error_info .errors || ! * argv ) {
103
69
errormsg (SH_DICT , ERROR_usage (2 ), "%s" , optusage (NULL ));
104
70
__builtin_unreachable ();
105
71
}
106
- if (!troot ) return 1 ;
107
- r = 0 ;
108
- if (troot == shp -> var_tree ) {
109
- nvflags |= NV_VARNAME ;
110
- } else {
111
- nvflags = NV_NOSCOPE ;
112
- }
113
- if (all ) {
114
- dtclear (troot );
115
- return r ;
116
- }
117
- sh_pushcontext (shp , & buff , 1 );
118
- while (* argv ) {
119
- name = * argv ++ ;
120
- jmpval = sigsetjmp (buff .buff , 0 );
121
- np = NULL ;
122
- if (jmpval == 0 ) {
123
- if (shp -> namespace && troot != shp -> var_tree ) {
124
- np = sh_fsearch (shp , name , nvflags ? NV_NOSCOPE : 0 );
125
- }
126
- if (!np ) np = nv_open (name , troot , NV_NOADD | nvflags );
127
- } else {
128
- r = 1 ;
129
- continue ;
130
- }
131
- if (np ) {
132
- if (is_abuiltin (np ) || nv_isattr (np , NV_RDONLY )) {
133
- if (nv_isattr (np , NV_RDONLY )) {
134
- errormsg (SH_DICT , ERROR_warn (0 ), e_readonly , nv_name (np ));
135
- }
136
- r = 1 ;
137
- continue ;
138
- }
139
- isfun = is_afunction (np );
140
- if (troot == shp -> var_tree ) {
141
- if (nv_isarray (np ) && name [strlen (name ) - 1 ] == ']' && !nv_getsub (np )) {
142
- r = 1 ;
143
- continue ;
144
- }
145
-
146
- if (shp -> subshell ) np = sh_assignok (np , 0 );
147
- }
148
- if (!nv_isnull (np ) || nv_size (np ) || nv_isattr (np , ~(NV_MINIMAL | NV_NOFREE ))) {
149
- _nv_unset (np , 0 );
150
- }
151
- if (troot == shp -> var_tree && shp -> st .real_fun && (dp = shp -> var_tree -> walk ) &&
152
- dp == shp -> st .real_fun -> sdict ) {
153
- nv_delete (np , dp , NV_NOFREE );
154
- } else if (isfun ) {
155
- struct Ufunction * rp = FETCH_VT (np -> nvalue , rp );
156
- if (!rp || !rp -> running ) nv_delete (np , troot , 0 );
157
- } else if (type == ALIAS ) {
158
- // Alias has been unset by call to _nv_unset, remove it from the tree.
159
- nv_delete (np , troot , 0 );
160
- }
161
- #if 0
162
- // Causes unsetting local variable to expose global.
163
- else if (shp -> var_tree == troot && shp -> var_tree != shp -> var_base &&
164
- nv_search_namval (np , shp -> var_tree , NV_NOSCOPE )) {
165
- nv_delete (np ,shp -> var_tree ,0 );
166
- }
167
- #endif
168
- else {
169
- nv_close (np );
170
- }
171
72
172
- } else if (type == ALIAS ) {
173
- // Alias not found
174
- sfprintf (sfstderr , sh_translate (e_noalias ), name );
175
- r = 1 ;
176
- }
177
- }
178
- sh_popcontext (shp , & buff );
179
- return r ;
73
+ if (!troot ) return 1 ;
74
+ if (troot == shp -> var_tree ) nvflags |= NV_VARNAME ;
75
+ return nv_unall (argv , false, nvflags , troot , shp );
180
76
}
0 commit comments