Imported from ../bash-1.14.7.tar.gz.
[platform/upstream/bash.git] / builtins / setattr.def
1 This file is setattr.def, from which is created setattr.c.
2 It implements the builtins "export" and "readonly", in Bash.
3
4 Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
5
6 This file is part of GNU Bash, the Bourne Again SHell.
7
8 Bash is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 1, or (at your option) any later
11 version.
12
13 Bash is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with Bash; see the file COPYING.  If not, write to the Free Software
20 Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
21
22 $PRODUCES setattr.c
23
24 #include "../shell.h"
25 #include "common.h"
26 #include "bashgetopt.h"
27
28 extern int array_needs_making;
29 extern char *this_command_name;
30
31 $BUILTIN export
32 $FUNCTION export_builtin
33 $SHORT_DOC export [-n] [-f] [name ...] or export -p
34 NAMEs are marked for automatic export to the environment of
35 subsequently executed commands.  If the -f option is given,
36 the NAMEs refer to functions.  If no NAMEs are given, or if `-p'
37 is given, a list of all names that are exported in this shell is
38 printed.  An argument of `-n' says to remove the export property
39 from subsequent NAMEs.  An argument of `--' disables further option
40 processing.
41 $END
42
43 /* For each variable name in LIST, make that variable appear in the
44    environment passed to simple commands.  If there is no LIST, then
45    print all such variables.  An argument of `-n' says to remove the
46    exported attribute from variables named in LIST.  An argument of
47   -f indicates that the names present in LIST refer to functions. */
48 export_builtin (list)
49      register WORD_LIST *list;
50 {
51   return (set_or_show_attributes (list, att_exported));
52 }
53
54 $BUILTIN readonly
55 $FUNCTION readonly_builtin
56 $SHORT_DOC readonly [-n] [-f] [name ...] or readonly -p
57 The given NAMEs are marked readonly and the values of these NAMEs may
58 not be changed by subsequent assignment.  If the -f option is given,
59 then functions corresponding to the NAMEs are so marked.  If no
60 arguments are given, or if `-p' is given, a list of all readonly names
61 is printed.  An argument of `-n' says to remove the readonly property
62 from subsequent NAMEs.  An argument of `--' disables further option
63 processing.
64 $END
65
66 /* For each variable name in LIST, make that variable readonly.  Given an
67    empty LIST, print out all existing readonly variables. */
68 readonly_builtin (list)
69      register WORD_LIST *list;
70 {
71   return (set_or_show_attributes (list, att_readonly));
72 }
73
74 /* For each variable name in LIST, make that variable have the specified
75    ATTRIBUTE.  An arg of `-n' says to remove the attribute from the the
76    remaining names in LIST. */
77 int
78 set_or_show_attributes (list, attribute)
79      register WORD_LIST *list;
80      int attribute;
81 {
82   register SHELL_VAR *var;
83   int assign, undo = 0, functions_only = 0, any_failed = 0, opt;
84
85   /* Read arguments from the front of the list. */
86   reset_internal_getopt ();
87   while ((opt = internal_getopt (list, "nfp")) != -1)
88     {
89       switch (opt)
90         {
91           case 'n':
92             undo = 1;
93             break;
94           case 'f':
95             functions_only = 1;
96             break;
97           case 'p':
98             break;
99           default:
100             builtin_error ("usage: %s [-nfp] [varname]", this_command_name);
101             return (EX_USAGE);
102         }
103     }
104   list = loptend;
105
106   if (list)
107     {
108       if (attribute & att_exported)
109         array_needs_making = 1;
110
111       /* Cannot undo readonly status. */
112       if (undo && (attribute & att_readonly))
113         attribute &= ~att_readonly;
114
115       while (list)
116         {
117           register char *name = list->word->word;
118
119           if (functions_only)
120             {
121               var = find_function (name);
122               if (!var)
123                 {
124                   builtin_error ("%s: not a function", name);
125                   any_failed++;
126                 }
127               else
128                 {
129                   if (undo)
130                     var->attributes &= ~attribute;
131                   else
132                     var->attributes |= attribute;
133                 }
134               list = list->next;
135               if (attribute == att_exported)
136                 array_needs_making++;
137               continue;
138             }
139
140           assign = assignment (name);
141
142           if (assign)
143             name[assign] = '\0';
144           if (legal_identifier (name) == 0)
145             {
146               builtin_error ("%s: not a legal variable name", name);
147               any_failed++;
148               list = list->next;
149               continue;
150             }
151
152           if (assign)
153             {
154               name[assign] = '=';
155               /* This word has already been expanded once with command
156                  and parameter expansion.  Call do_assignment_no_expand (),
157                  which does not do command or parameter substitution. */
158               do_assignment_no_expand (name);
159               name[assign] = '\0';
160             }
161
162           if (undo)
163             {
164               var = find_variable (name);
165               if (var)
166                 var->attributes &= ~attribute;
167             }
168           else
169             {
170               SHELL_VAR *find_tempenv_variable (), *tv;
171
172               if (tv = find_tempenv_variable (name))
173                 {
174                   var = bind_variable (tv->name, tv->value);
175                   dispose_variable (tv);
176                 }
177               else
178                 var = find_variable (name);
179
180               if (!var)
181                 {
182                   var = bind_variable (name, (char *)NULL);
183                   var->attributes |= att_invisible;
184                 }
185
186               var->attributes |= attribute;
187             }
188
189           array_needs_making++; /* XXX */
190           list = list->next;
191         }
192     }
193   else
194     {
195       SHELL_VAR **variable_list;
196       register int i;
197
198       if ((attribute & att_function) || functions_only)
199         {
200           variable_list = all_shell_functions ();
201           if (attribute != att_function)
202             attribute &= ~att_function; /* so declare -xf works, for example */
203         }
204       else
205         variable_list = all_shell_variables ();
206
207       if (variable_list)
208         {
209           for (i = 0; var = variable_list[i]; i++)
210             {
211               if ((var->attributes & attribute) && !invisible_p (var))
212                 {
213                   char flags[6];
214
215                   flags[0] = '\0';
216
217                   if (exported_p (var))
218                     strcat (flags, "x");
219
220                   if (readonly_p (var))
221                     strcat (flags, "r");
222
223                   if (function_p (var))
224                     strcat (flags, "f");
225
226                   if (integer_p (var))
227                     strcat (flags, "i");
228
229                   if (flags[0])
230                     {
231                       printf ("declare -%s ", flags);
232
233                       if (!function_p (var))
234                         {
235                           char *x = double_quote (value_cell (var));
236                           printf ("%s=%s\n", var->name, x);
237                           free (x);
238                         }
239                       else
240                         {
241                           char *named_function_string ();
242
243                           printf ("%s\n", named_function_string
244                                   (var->name, function_cell (var), 1));
245                         }
246                     }
247                 }
248             }
249           free (variable_list);
250         }
251     }
252   return (any_failed == 0 ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
253 }