Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/ksh93/bltins/whence.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1982-2012 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* David Korn <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
/*
22
* command [-pvVx] name [arg...]
23
* whence [-afvp] name...
24
*
25
* David Korn
26
* AT&T Labs
27
*
28
*/
29
30
#include "defs.h"
31
#include <error.h>
32
#include "shtable.h"
33
#include "name.h"
34
#include "path.h"
35
#include "shlex.h"
36
#include "builtins.h"
37
38
#define P_FLAG 1
39
#define V_FLAG 2
40
#define A_FLAG 4
41
#define F_FLAG 010
42
#define X_FLAG 020
43
#define Q_FLAG 040
44
45
static int whence(Shell_t *,char**, int);
46
47
/*
48
* command is called with argc==0 when checking for -V or -v option
49
* In this case return 0 when -v or -V or unknown option, otherwise
50
* the shift count to the command is returned
51
*/
52
int b_command(register int argc,char *argv[],Shbltin_t *context)
53
{
54
register int n, flags=0;
55
register Shell_t *shp = context->shp;
56
opt_info.index = opt_info.offset = 0;
57
while((n = optget(argv,sh_optcommand))) switch(n)
58
{
59
case 'p':
60
if(sh_isoption(SH_RESTRICTED))
61
errormsg(SH_DICT,ERROR_exit(1),e_restricted,"-p");
62
sh_onstate(SH_DEFPATH);
63
break;
64
case 'v':
65
flags |= X_FLAG;
66
break;
67
case 'V':
68
flags |= V_FLAG;
69
break;
70
case 'x':
71
shp->xargexit = 1;
72
break;
73
case ':':
74
if(argc==0)
75
return(0);
76
errormsg(SH_DICT,2, "%s", opt_info.arg);
77
break;
78
case '?':
79
if(argc==0)
80
return(0);
81
errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
82
break;
83
}
84
if(argc==0)
85
return(flags?0:opt_info.index);
86
argv += opt_info.index;
87
if(error_info.errors || !*argv)
88
errormsg(SH_DICT,ERROR_usage(2),"%s", optusage((char*)0));
89
return(whence(shp,argv, flags));
90
}
91
92
/*
93
* for the whence command
94
*/
95
int b_whence(int argc,char *argv[],Shbltin_t *context)
96
{
97
register int flags=0, n;
98
register Shell_t *shp = context->shp;
99
NOT_USED(argc);
100
if(*argv[0]=='t')
101
flags = V_FLAG;
102
while((n = optget(argv,sh_optwhence))) switch(n)
103
{
104
case 'a':
105
flags |= A_FLAG;
106
/* FALL THRU */
107
case 'v':
108
flags |= V_FLAG;
109
break;
110
case 'f':
111
flags |= F_FLAG;
112
break;
113
case 'p':
114
flags |= P_FLAG;
115
flags &= ~V_FLAG;
116
break;
117
case 'q':
118
flags |= Q_FLAG;
119
break;
120
case ':':
121
errormsg(SH_DICT,2, "%s", opt_info.arg);
122
break;
123
case '?':
124
errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
125
break;
126
}
127
argv += opt_info.index;
128
if(error_info.errors || !*argv)
129
errormsg(SH_DICT,ERROR_usage(2),optusage((char*)0));
130
return(whence(shp, argv, flags));
131
}
132
133
static int whence(Shell_t *shp,char **argv, register int flags)
134
{
135
register const char *name;
136
register Namval_t *np;
137
register const char *cp;
138
register int aflag,r=0;
139
register const char *msg;
140
int tofree;
141
Dt_t *root;
142
Namval_t *nq;
143
char *notused;
144
Pathcomp_t *pp=0;
145
int notrack = 1;
146
if(flags&Q_FLAG)
147
flags &= ~A_FLAG;
148
while(name= *argv++)
149
{
150
tofree=0;
151
aflag = ((flags&A_FLAG)!=0);
152
cp = 0;
153
np = 0;
154
if(flags&P_FLAG)
155
goto search;
156
if(flags&Q_FLAG)
157
goto bltins;
158
/* reserved words first */
159
if(sh_lookup(name,shtab_reserved))
160
{
161
sfprintf(sfstdout,"%s%s\n",name,(flags&V_FLAG)?sh_translate(is_reserved):"");
162
if(!aflag)
163
continue;
164
aflag++;
165
}
166
/* non-tracked aliases */
167
if((np=nv_search(name,shp->alias_tree,0))
168
&& !nv_isnull(np) && !(notrack=nv_isattr(np,NV_TAGGED))
169
&& (cp=nv_getval(np)))
170
{
171
if(flags&V_FLAG)
172
{
173
if(nv_isattr(np,NV_EXPORT))
174
msg = sh_translate(is_xalias);
175
else
176
msg = sh_translate(is_alias);
177
sfprintf(sfstdout,msg,name);
178
}
179
sfputr(sfstdout,sh_fmtq(cp),'\n');
180
if(!aflag)
181
continue;
182
cp = 0;
183
aflag++;
184
}
185
/* built-ins and functions next */
186
bltins:
187
root = (flags&F_FLAG)?shp->bltin_tree:shp->fun_tree;
188
if(np= nv_bfsearch(name, root, &nq, &notused))
189
{
190
if(is_abuiltin(np) && nv_isnull(np))
191
goto search;
192
cp = "";
193
if(flags&V_FLAG)
194
{
195
if(nv_isnull(np))
196
cp = sh_translate(is_ufunction);
197
else if(is_abuiltin(np))
198
{
199
if(nv_isattr(np,BLT_SPC))
200
cp = sh_translate(is_spcbuiltin);
201
else
202
cp = sh_translate(is_builtin);
203
}
204
else
205
cp = sh_translate(is_function);
206
}
207
if(flags&Q_FLAG)
208
continue;
209
sfprintf(sfstdout,"%s%s\n",name,cp);
210
if(!aflag)
211
continue;
212
cp = 0;
213
aflag++;
214
}
215
search:
216
if(sh_isstate(SH_DEFPATH))
217
{
218
cp=0;
219
notrack=1;
220
}
221
do
222
{
223
if(path_search(shp,name,&pp,2+(aflag>1)))
224
{
225
cp = name;
226
if((flags&P_FLAG) && *cp!='/')
227
cp = 0;
228
}
229
else
230
{
231
cp = stakptr(PATH_OFFSET);
232
if(*cp==0)
233
cp = 0;
234
else if(*cp!='/')
235
{
236
cp = path_fullname(shp,cp);
237
tofree=1;
238
}
239
}
240
if(flags&Q_FLAG)
241
{
242
pp = 0;
243
r |= !cp;
244
}
245
else if(cp)
246
{
247
if(flags&V_FLAG)
248
{
249
if(*cp!= '/')
250
{
251
if(!np && (np=nv_search(name,shp->track_tree,0)))
252
sfprintf(sfstdout,"%s %s %s/%s\n",name,sh_translate(is_talias),path_pwd(shp,0),cp);
253
else if(!np || nv_isnull(np))
254
sfprintf(sfstdout,"%s%s\n",name,sh_translate(is_ufunction));
255
continue;
256
}
257
sfputr(sfstdout,sh_fmtq(name),' ');
258
/* built-in version of program */
259
if(*cp=='/' && (np=nv_search(cp,shp->bltin_tree,0)))
260
msg = sh_translate(is_builtver);
261
/* tracked aliases next */
262
else if(aflag>1 || !notrack || strchr(name,'/'))
263
msg = sh_translate("is");
264
else
265
msg = sh_translate(is_talias);
266
sfputr(sfstdout,msg,' ');
267
}
268
sfputr(sfstdout,sh_fmtq(cp),'\n');
269
if(aflag)
270
{
271
if(aflag<=1)
272
aflag++;
273
if (pp)
274
pp = pp->next;
275
}
276
else
277
pp = 0;
278
if(tofree)
279
{
280
free((char*)cp);
281
tofree = 0;
282
}
283
}
284
else if(aflag<=1)
285
{
286
r |= 1;
287
if(flags&V_FLAG)
288
errormsg(SH_DICT,ERROR_exit(0),e_found,sh_fmtq(name));
289
}
290
} while(pp);
291
}
292
return(r);
293
}
294
295
296