2 * Copyright (c) 1988, 1989, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1988, 1989 by Adam de Boor
5 * Copyright (c) 1989 by Berkeley Softworks
8 * This code is derived from software contributed to Berkeley by
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the University of
22 * California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39 * $DragonFly: src/usr.bin/make/shell.c,v 1.23 2005/07/29 22:48:41 okumoto Exp $
47 #include "pathnames.h"
52 struct Shell *commandShell = NULL;
55 * Helper function for sorting the builtin list alphabetically.
58 sort_builtins(const void *p1, const void *p2)
61 return (strcmp(*(const char* const*)p1, *(const char* const*)p2));
65 * Free a shell structure and all associated strings.
68 ShellFree(struct Shell *sh)
81 ArgArray_Done(&sh->builtins);
88 * Dump a shell specification to stderr.
91 Shell_Dump(const struct Shell *sh)
95 fprintf(stderr, "Shell %p:\n", sh);
96 fprintf(stderr, " name='%s' path='%s'\n", sh->name, sh->path);
97 fprintf(stderr, " hasEchoCtl=%d echoOff='%s' echoOn='%s'\n",
98 sh->hasEchoCtl, sh->echoOff, sh->echoOn);
99 fprintf(stderr, " noPrint='%s'\n", sh->noPrint);
100 fprintf(stderr, " hasErrCtl=%d errCheck='%s' ignErr='%s'\n",
101 sh->hasErrCtl, sh->errCheck, sh->ignErr);
102 fprintf(stderr, " echo='%s' exit='%s'\n", sh->echo, sh->exit);
103 fprintf(stderr, " builtins=%d\n", sh->builtins.argc - 1);
104 for (i = 1; i < sh->builtins.argc; i++)
105 fprintf(stderr, " '%s'", sh->builtins.argv[i]);
106 fprintf(stderr, "\n meta='%s'\n", sh->meta);
107 fprintf(stderr, " unsetenv=%d\n", sh->unsetenv);
111 * Parse a shell specification line and return the new Shell structure.
112 * In case of an error a message is printed and NULL is returned.
114 static struct Shell *
115 ShellParseSpec(const char *spec, bool *fullSpec)
125 sh = emalloc(sizeof(*sh));
126 memset(sh, 0, sizeof(*sh));
127 ArgArray_Init(&sh->builtins);
130 * Parse the specification by keyword but skip the first word
132 brk_string(&aa, spec, true);
134 for (arg = 1; arg < aa.argc; arg++) {
136 * Split keyword and value
139 if ((eq = strchr(keyw, '=')) == NULL) {
140 Parse_Error(PARSE_FATAL, "missing '=' in shell "
141 "specification keyword '%s'", keyw);
148 if (strcmp(keyw, "path") == 0) {
150 sh->path = estrdup(eq);
151 } else if (strcmp(keyw, "name") == 0) {
153 sh->name = estrdup(eq);
154 } else if (strcmp(keyw, "quiet") == 0) {
156 sh->echoOff = estrdup(eq);
158 } else if (strcmp(keyw, "echo") == 0) {
160 sh->echoOn = estrdup(eq);
162 } else if (strcmp(keyw, "filter") == 0) {
164 sh->noPrint = estrdup(eq);
166 } else if (strcmp(keyw, "echoFlag") == 0) {
168 sh->echo = estrdup(eq);
170 } else if (strcmp(keyw, "errFlag") == 0) {
172 sh->exit = estrdup(eq);
174 } else if (strcmp(keyw, "hasErrCtl") == 0) {
176 *eq == 'Y' || *eq == 'y' ||
177 *eq == 'T' || *eq == 't');
179 } else if (strcmp(keyw, "check") == 0) {
181 sh->errCheck = estrdup(eq);
183 } else if (strcmp(keyw, "ignore") == 0) {
185 sh->ignErr = estrdup(eq);
187 } else if (strcmp(keyw, "builtins") == 0) {
188 ArgArray_Done(&sh->builtins);
189 brk_string(&sh->builtins, eq, true);
190 qsort(sh->builtins.argv + 1, sh->builtins.argc - 1,
191 sizeof(char *), sort_builtins);
193 } else if (strcmp(keyw, "meta") == 0) {
195 sh->meta = estrdup(eq);
197 } else if (strcmp(keyw, "unsetenv") == 0) {
199 *eq == 'Y' || *eq == 'y' ||
200 *eq == 'T' || *eq == 't');
203 Parse_Error(PARSE_FATAL, "unknown keyword in shell "
204 "specification '%s'", keyw);
213 * Some checks (could be more)
216 if ((sh->echoOn != NULL) ^ (sh->echoOff != NULL)) {
217 Parse_Error(PARSE_FATAL, "Shell must have either both "
218 "echoOff and echoOn or none of them");
223 if (sh->echoOn != NULL && sh->echoOff != NULL)
224 sh->hasEchoCtl = true;
231 * Find a matching shell in 'shells' given its final component.
233 * Descriptions for various shells. What the list of builtins should contain
234 * is debatable: either all builtins or only those which may specified on
235 * a single line without use of meta-characters. For correct makefiles that
236 * contain only correct command lines there is no difference. But if a command
237 * line, for example, is: 'if -foo bar' and there is an executable named 'if'
238 * in the path, the first possibility would execute that 'if' while in the
239 * second case the shell would give an error. Histerically only a small
240 * subset of the builtins and no reserved words where given in the list which
241 * corresponds roughly to the first variant. So go with this but add missing
245 * A pointer to a Shell structure, or NULL if no shell with
246 * the given name is found.
248 static struct Shell *
249 ShellMatch(const char name[])
252 const char *shellDir = PATH_DEFSHELLDIR;
254 shell = emalloc(sizeof(struct Shell));
256 if (strcmp(name, "csh") == 0) {
258 * CSH description. The csh can do echo control by playing
259 * with the setting of the 'echo' shell variable. Sadly,
260 * however, it is unable to do error control nicely.
262 shell->name = strdup(name);
263 shell->path = str_concat(shellDir, '/', name);
264 shell->hasEchoCtl = true;
265 shell->echoOff = strdup("unset verbose");
266 shell->echoOn = strdup("set verbose");
267 shell->noPrint = strdup("unset verbose");
268 shell->hasErrCtl = false;
269 shell->errCheck = strdup("echo \"%s\"\n");
270 shell->ignErr = strdup("csh -c \"%s || exit 0\"");
271 shell->echo = strdup("v");
272 shell->exit = strdup("e");
273 shell->meta = strdup("#=|^(){};&<>*?[]:$`\\@\n");
274 brk_string(&shell->builtins,
275 "alias cd eval exec exit read set ulimit unalias "
276 "umask unset wait", true);
277 shell->unsetenv = false;
279 } else if (strcmp(name, "sh") == 0) {
281 * SH description. Echo control is also possible and, under
282 * sun UNIX anyway, one can even control error checking.
285 shell->name = strdup(name);
286 shell->path = str_concat(shellDir, '/', name);
287 shell->hasEchoCtl = true;
288 shell->echoOff = strdup("set -");
289 shell->echoOn = strdup("set -v");
290 shell->noPrint = strdup("set -");
291 #ifdef OLDBOURNESHELL
292 shell->hasErrCtl = false;
293 shell->errCheck = strdup("echo \"%s\"\n");
294 shell->ignErr = strdup("sh -c '%s || exit 0'\n");
296 shell->hasErrCtl = true;
297 shell->errCheck = strdup("set -e");
298 shell->ignErr = strdup("set +e");
300 shell->echo = strdup("v");
301 shell->exit = strdup("e");
302 shell->meta = strdup("#=|^(){};&<>*?[]:$`\\\n");
303 brk_string(&shell->builtins,
304 "alias cd eval exec exit read set ulimit unalias "
305 "umask unset wait", true);
306 shell->unsetenv = false;
308 } else if (strcmp(name, "ksh") == 0) {
310 * KSH description. The Korn shell has a superset of
311 * the Bourne shell's functionality. There are probably
312 * builtins missing here.
314 shell->name = strdup(name);
315 shell->path = str_concat(shellDir, '/', name);
316 shell->hasEchoCtl = true;
317 shell->echoOff = strdup("set -");
318 shell->echoOn = strdup("set -v");
319 shell->noPrint = strdup("set -");
320 shell->hasErrCtl = true;
321 shell->errCheck = strdup("set -e");
322 shell->ignErr = strdup("set +e");
323 shell->echo = strdup("v");
324 shell->exit = strdup("e");
325 shell->meta = strdup("#=|^(){};&<>*?[]:$`\\\n");
326 brk_string(&shell->builtins,
327 "alias cd eval exec exit read set ulimit unalias "
328 "umask unset wait", true);
329 shell->unsetenv = true;
340 Shell_Init(const char shellname[])
342 commandShell = ShellMatch(shellname);
346 * Given the line following a .SHELL target, parse the
347 * line as a shell specification. Returns false if the
348 * spec was incorrect.
350 * Parse a shell specification and set up commandShell.
353 * true if the specification was correct. false otherwise.
356 * commandShell points to a Shell structure (either predefined or
357 * created from the shell spec)
360 * A shell specification consists of a .SHELL target, with dependency
361 * operator, followed by a series of blank-separated words. Double
362 * quotes can be used to use blanks in words. A backslash escapes
363 * anything (most notably a double-quote and a space) and
364 * provides the functionality it does in C. Each word consists of
365 * keyword and value separated by an equal sign. There should be no
366 * unnecessary spaces in the word. The keywords are as follows:
367 * name Name of shell.
368 * path Location of shell. Overrides "name" if given
369 * quiet Command to turn off echoing.
370 * echo Command to turn echoing on
371 * filter Result of turning off echoing that shouldn't be
373 * echoFlag Flag to turn echoing on at the start
374 * errFlag Flag to turn error checking on at the start
375 * hasErrCtl True if shell has error checking control
376 * check Command to turn on error checking if hasErrCtl
377 * is true or template of command to echo a command
378 * for which error checking is off if hasErrCtl is
380 * ignore Command to turn off error checking if hasErrCtl
381 * is true or template of command to execute a
382 * command so as to ignore any errors it returns if
383 * hasErrCtl is false.
384 * builtins A space separated list of builtins. If one
385 * of these builtins is detected when make wants
386 * to execute a command line, the command line is
387 * handed to the shell. Otherwise make may try to
388 * execute the command directly. If this list is empty
389 * it is assumed, that the command must always be
390 * handed over to the shell.
391 * meta The shell meta characters. If this is not specified
392 * or empty, commands are alway passed to the shell.
393 * Otherwise they are not passed when they contain
394 * neither a meta character nor a builtin command.
397 Shell_Parse(const char line[])
402 /* parse the specification */
403 if ((sh = ShellParseSpec(line, &fullSpec)) == NULL)
406 if (sh->path == NULL) {
409 * If no path was given, the user wants one of the pre-defined
410 * shells, yes? So we find the one s/he wants with the help of
411 * ShellMatch and set things up the right way.
413 if (sh->name == NULL) {
414 Parse_Error(PARSE_FATAL,
415 "Neither path nor name specified");
420 Parse_Error(PARSE_FATAL, "No path specified");
424 if ((match = ShellMatch(sh->name)) == NULL) {
425 Parse_Error(PARSE_FATAL, "%s: no matching shell",
435 * The user provided a path. If s/he gave nothing else
436 * (fullSpec is false), try and find a matching shell in the
437 * ones we know of. Else we just take the specification at its
438 * word and copy it to a new location. In either case, we need
439 * to record the path the user gave for the shell.
441 if (sh->name == NULL) {
442 /* get the base name as the name */
443 if ((sh->name = strrchr(sh->path, '/')) == NULL) {
444 sh->name = estrdup(sh->path);
446 sh->name = estrdup(sh->name + 1);
453 if ((match = ShellMatch(sh->name)) == NULL) {
454 Parse_Error(PARSE_FATAL,
455 "%s: no matching shell", sh->name);
460 match->path = sh->path;
467 /* Release the old shell and set the new shell */
468 ShellFree(commandShell);