diff options
-rw-r--r-- | usr.bin/make/PSD.doc/tutorial.ms | 202 | ||||
-rw-r--r-- | usr.bin/make/job.c | 218 | ||||
-rw-r--r-- | usr.bin/make/parse.c | 10 |
3 files changed, 4 insertions, 426 deletions
diff --git a/usr.bin/make/PSD.doc/tutorial.ms b/usr.bin/make/PSD.doc/tutorial.ms index 6b6e28a0da4..1b446dce96c 100644 --- a/usr.bin/make/PSD.doc/tutorial.ms +++ b/usr.bin/make/PSD.doc/tutorial.ms @@ -1,4 +1,4 @@ -.\" $OpenBSD: tutorial.ms,v 1.10 2007/02/20 08:18:47 jmc Exp $ +.\" $OpenBSD: tutorial.ms,v 1.11 2007/09/16 10:57:03 espie Exp $ .\" $NetBSD: tutorial.ms,v 1.3 1996/03/06 00:15:31 christos Exp $ .\" Copyright (c) 1988, 1989 by Adam de Boor .\" Copyright (c) 1989 by Berkeley Softworks @@ -2306,15 +2306,6 @@ attribute is given to every target in the file. This target applies the .CW .MAKE attribute to all its sources. It does nothing if you don't give it any sources. -.IP .SHELL \n(pw -.Ix 0 def .SHELL -Make is not constrained to only using the Bourne shell to execute -the commands you put in the makefile. You can tell it some other shell -to use with this target. Check out -.B "A Shell is a Shell is a Shell" -(section 4.4) -.Rm 7 4.4 -for more information. .IP .SILENT \n(pw .Ix 0 def .SILENT target .Ix 0 ref .SILENT attribute @@ -2993,197 +2984,6 @@ would wreak havoc if you tried .CW "make draft print" '' `` since you would use the same formatter for each target. As I said, this all gets somewhat complicated. -.xH 2 A Shell is a Shell is a Shell -.Rd 7 -.LP -In normal operation, the Bourne Shell (better known as -.CW sh '') `` -is used to execute the commands to re-create targets. Make also allows you -to specify a different shell for it to use when executing these -commands. There are several things Make must know about the shell you -wish to use. These things are specified as the sources for the -.CW .SHELL -.Ix 0 ref .SHELL -.Ix 0 ref target .SHELL -target by keyword, as follows: -.IP "\fBpath=\fP\fIpath\fP" -Make needs to know where the shell actually resides, so it can -execute it. If you specify this and nothing else, Make will use the -last component of the path and look in its table of the shells it -knows and use the specification it finds, if any. Use this if you just -want to use a different version of the Bourne or C Shell (yes, Make knows -how to use the C Shell too). -.IP "\fBname=\fP\fIname\fP" -This is the name by which the shell is to be known. It is a single -word and, if no other keywords are specified (other than -.B path ), -it is the name by which Make attempts to find a specification for -it (as mentioned above). You can use this if you would just rather use -the C Shell than the Bourne Shell -.CW ".SHELL: name=csh" '' (`` -will do it). -.IP "\fBquiet=\fP\fIecho-off command\fP" -As mentioned before, Make actually controls whether commands are -printed by introducing commands into the shell's input stream. This -keyword, and the next two, control what those commands are. The -.B quiet -keyword is the command used to turn echoing off. Once it is turned -off, echoing is expected to remain off until the echo-on command is given. -.IP "\fBecho=\fP\fIecho-on command\fP" -The command Make should give to turn echoing back on again. -.IP "\fBfilter=\fP\fIprinted echo-off command\fP" -Many shells will echo the echo-off command when it is given. This -keyword tells Make in what format the shell actually prints the -echo-off command. Wherever Make sees this string in the shell's -output, it will delete it and any following whitespace, up to and -including the next newline. See the example at the end of this section -for more details. -.IP "\fBechoFlag=\fP\fIflag to turn echoing on\fP" -Unless a target has been marked -.CW .SILENT , -Make wants to start the shell running with echoing on. To do this, it -passes this flag to the shell as one of its arguments. If either this -or the next flag begins with a `\-', the flags will be passed to the -shell as separate arguments. Otherwise, the two will be concatenated -(if they are used at the same time, of course). -.IP "\fBerrFlag=\fP\fIflag to turn error checking on\fP" -Likewise, unless a target is marked -.CW .IGNORE , -Make wishes error-checking to be on from the very start. To this end, -it will pass this flag to the shell as an argument. The same rules for -an initial `\-' apply as for the -.B echoFlag . -.IP "\fBcheck=\fP\fIcommand to turn error checking on\fP" -Just as for echo-control, error-control is achieved by inserting -commands into the shell's input stream. This is the command to make -the shell check for errors. It also serves another purpose if the -shell doesn't have error-control as commands, but I'll get into that -in a minute. Again, once error checking has been turned on, it is -expected to remain on until it is turned off again. -.IP "\fBignore=\fP\fIcommand to turn error checking off\fP" -This is the command Make uses to turn error checking off. It has -another use if the shell doesn't do error-control, but I'll tell you -about that.\|.\|.\|now. -.IP "\fBhasErrCtl=\fP\fIyes or no\fP" -This takes a value that is either -.B yes -or -.B no . -Now you might think that the existence of the -.B check -and -.B ignore -keywords would be enough to tell Make if the shell can do -error-control, but you'd be wrong. If -.B hasErrCtl -is -.B yes , -Make uses the check and ignore commands in a straight-forward manner. -If this is -.B no , -however, their use is rather different. In this case, the check -command is used as a template, in which the string -.B %s -is replaced by the command that's about to be executed, to produce a -command for the shell that will echo the command to be executed. The -ignore command is also used as a template, again with -.B %s -replaced by the command to be executed, to produce a command that will -execute the command to be executed and ignore any error it returns. -When these strings are used as templates, you must provide newline(s) -.CW \en '') (`` -in the appropriate place(s). -.LP -The strings that follow these keywords may be enclosed in single or -double quotes (the quotes will be stripped off) and may contain the -usual C backslash-characters (\en is newline, \er is return, \eb is -backspace, \e' escapes a single-quote inside single-quotes, \e" -escapes a double-quote inside double-quotes). Now for an example. -.LP -This is actually the contents of the -.CW <shx.mk> -system makefile, and causes Make to use the Bourne Shell in such a -way that each command is printed as it is executed. That is, if more -than one command is given on a line, each will be printed separately. -Similarly, each time the body of a loop is executed, the commands -within that loop will be printed, etc. The specification runs like -this: -.DS -# -# This is a shell specification to have the bourne shell echo -# the commands just before executing them, rather than when it reads -# them. Useful if you want to see how variables are being expanded, etc. -# -\&.SHELL : path=/bin/sh \e - quiet="set -" \e - echo="set -x" \e - filter="+ set - " \e - echoFlag=x \e - errFlag=e \e - hasErrCtl=yes \e - check="set -e" \e - ignore="set +e" -.DE -.LP -It tells Make the following: -.Bp -The shell is located in the file -.CW /bin/sh . -It need not tell Make that the name of the shell is -.CW sh -as Make can figure that out for itself (it's the last component of -the path). -.Bp -The command to stop echoing is -.CW "set -" . -.Bp -The command to start echoing is -.CW "set -x" . -.Bp -When the echo off command is executed, the shell will print -.CW "+ set - " -(The `+' comes from using the -.CW \-x -flag (rather than the -.CW \-v -flag Make usually uses)). Make will remove all occurrences of this -string from the output, so you don't notice extra commands you didn't -put there. -.Bp -The flag the Bourne Shell will take to start echoing in this way is -the -.CW \-x -flag. The Bourne Shell will only take its flag arguments concatenated -as its first argument, so neither this nor the -.B errFlag -specification begins with a \-. -.Bp -The flag to use to turn error-checking on from the start is -.CW \-e . -.Bp -The shell can turn error-checking on and off, and the commands to do -so are -.CW "set +e" -and -.CW "set -e" , -respectively. -.LP -This will cause Make to execute the two commands -.DS -echo "+ \fIcmd\fP" -sh -c '\fIcmd\fP || true' -.DE -for each command for which errors are to be ignored. (In case you are -wondering, the thing for -.CW ignore -tells the shell to execute another shell without error checking on and -always exit 0, since the -.B || -causes the -.CW "exit 0" -to be executed only if the first command exited non-zero, and if the -first command exited zero, the shell will also exit zero, since that's -the last command it executed). .xH 2 Compatibility .Ix 0 ref compatibility .LP diff --git a/usr.bin/make/job.c b/usr.bin/make/job.c index 91a54dc553b..d2eff2d82ec 100644 --- a/usr.bin/make/job.c +++ b/usr.bin/make/job.c @@ -1,5 +1,5 @@ /* $OpenPackages$ */ -/* $OpenBSD: job.c,v 1.63 2007/09/16 10:39:07 espie Exp $ */ +/* $OpenBSD: job.c,v 1.64 2007/09/16 10:57:02 espie Exp $ */ /* $NetBSD: job.c,v 1.16 1996/11/06 17:59:08 christos Exp $ */ /* @@ -71,10 +71,6 @@ * Job_Empty Return true if the job table is completely * empty. * - * Job_ParseShell Given the line following a .SHELL target, parse - * the line as a shell specification. Returns - * false if the spec was incorrect. - * * Job_Finish Perform any final processing which needs doing. * This includes the execution of any commands * which have been/were attached to the .END @@ -86,11 +82,6 @@ * just kills them. It should only be called in * an emergency, as it were. * - * Job_CheckCommands Verify that the commands for a target are - * ok. Provide them if necessary and possible. - * - * Job_Touch Update a target without really updating it. - * * Job_Wait Wait for all currently-running jobs to finish. */ @@ -353,9 +344,7 @@ static Shell shells[] = { }; static Shell *commandShell = &shells[DEFSHELL];/* this is the shell to * which we pass all - * commands in the Makefile. - * It is set by the - * Job_ParseShell function */ + * commands in the Makefile*/ static char *shellPath = NULL, /* full pathname of * executable image */ *shellName = NULL, /* last component of shell */ @@ -2255,209 +2244,6 @@ Job_Empty(void) /*- *----------------------------------------------------------------------- - * JobMatchShell -- - * Find a matching shell in 'shells' given its final component. - * - * Results: - * A pointer to the Shell structure. - *----------------------------------------------------------------------- - */ -static Shell * -JobMatchShell(char *name) /* Final component of shell path */ -{ - Shell *sh; /* Pointer into shells table */ - Shell *match; /* Longest-matching shell */ - char *cp1, - *cp2; - char *eoname; - - eoname = name + strlen(name); - - match = NULL; - - for (sh = shells; sh->name != NULL; sh++) { - for (cp1 = eoname - strlen(sh->name), cp2 = sh->name; - *cp1 != '\0' && *cp1 == *cp2; - cp1++, cp2++) { - continue; - } - if (*cp1 != *cp2) { - continue; - } else if (match == NULL || strlen(match->name) < strlen(sh->name)) { - match = sh; - } - } - return match == NULL ? sh : match; -} - -/*- - *----------------------------------------------------------------------- - * Job_ParseShell -- - * Parse a shell specification and set up commandShell, shellPath - * and shellName appropriately. - * - * Results: - * false if the specification was incorrect. - * - * Side Effects: - * commandShell points to a Shell structure (either predefined or - * created from the shell spec), shellPath is the full path of the - * shell described by commandShell, while shellName is just the - * final component of shellPath. - * - * Notes: - * A shell specification consists of a .SHELL target, with dependency - * operator, followed by a series of blank-separated words. Double - * quotes can be used to use blanks in words. A backslash escapes - * anything (most notably a double-quote and a space) and - * provides the functionality it does in C. Each word consists of - * keyword and value separated by an equal sign. There should be no - * unnecessary spaces in the word. The keywords are as follows: - * name Name of shell. - * path Location of shell. Overrides "name" if given - * quiet Command to turn off echoing. - * echo Command to turn echoing on - * filter Result of turning off echoing that shouldn't be - * printed. - * echoFlag Flag to turn echoing on at the start - * errFlag Flag to turn error checking on at the start - * hasErrCtl True if shell has error checking control - * check Command to turn on error checking if hasErrCtl - * is true or template of command to echo a command - * for which error checking is off if hasErrCtl is - * false. - * ignore Command to turn off error checking if hasErrCtl - * is true or template of command to execute a - * command so as to ignore any errors it returns if - * hasErrCtl is false. - *----------------------------------------------------------------------- - */ -bool -Job_ParseShell(const char *line) /* The shell spec */ -{ - char **words; - int wordCount; - char **argv; - int argc; - char *path; - Shell newShell; - bool fullSpec = false; - - while (isspace(*line)) { - line++; - } - - efree(shellArgv); - - words = brk_string(line, &wordCount, &shellArgv); - - memset(&newShell, 0, sizeof(newShell)); - - /* - * Parse the specification by keyword - */ - for (path = NULL, argc = wordCount - 1, argv = words; - argc != 0; - argc--, argv++) { - if (strncmp(*argv, "path=", 5) == 0) { - path = &argv[0][5]; - } else if (strncmp(*argv, "name=", 5) == 0) { - newShell.name = &argv[0][5]; - } else { - if (strncmp(*argv, "quiet=", 6) == 0) { - newShell.echoOff = &argv[0][6]; - } else if (strncmp(*argv, "echo=", 5) == 0) { - newShell.echoOn = &argv[0][5]; - } else if (strncmp(*argv, "filter=", 7) == 0) { - newShell.noPrint = &argv[0][7]; - newShell.noPLen = strlen(newShell.noPrint); - } else if (strncmp(*argv, "echoFlag=", 9) == 0) { - newShell.echo = &argv[0][9]; - } else if (strncmp(*argv, "errFlag=", 8) == 0) { - newShell.exit = &argv[0][8]; - } else if (strncmp(*argv, "hasErrCtl=", 10) == 0) { - char c = argv[0][10]; - newShell.hasErrCtl = !(c != 'Y' && c != 'y' && - c != 'T' && c != 't'); - } else if (strncmp(*argv, "check=", 6) == 0) { - newShell.errCheck = &argv[0][6]; - } else if (strncmp(*argv, "ignore=", 7) == 0) { - newShell.ignErr = &argv[0][7]; - } else { - Parse_Error(PARSE_FATAL, "Unknown keyword \"%s\"", - *argv); - free(words); - return false; - } - fullSpec = true; - } - } - - if (path == NULL) { - /* - * If no path was given, the user wants one of the pre-defined shells, - * yes? So we find the one s/he wants with the help of JobMatchShell - * and set things up the right way. shellPath will be set up by - * Job_Init. - */ - if (newShell.name == NULL) { - Parse_Error(PARSE_FATAL, "Neither path nor name specified"); - return false; - } else { - commandShell = JobMatchShell(newShell.name); - shellName = newShell.name; - } - } else { - /* - * The user provided a path. If s/he gave nothing else (fullSpec is - * false), try and find a matching shell in the ones we know of. - * Else we just take the specification at its word and copy it - * to a new location. In either case, we need to record the - * path the user gave for the shell. - */ - shellPath = path; - path = strrchr(path, '/'); - if (path == NULL) { - path = shellPath; - } else { - path += 1; - } - if (newShell.name != NULL) { - shellName = newShell.name; - } else { - shellName = path; - } - if (!fullSpec) { - commandShell = JobMatchShell(shellName); - } else { - commandShell = emalloc(sizeof(Shell)); - *commandShell = newShell; - } - } - - if (commandShell->echoOn && commandShell->echoOff) { - commandShell->hasEchoCtl = true; - } - - if (!commandShell->hasErrCtl) { - if (commandShell->errCheck == NULL) { - commandShell->errCheck = ""; - } - if (commandShell->ignErr == NULL) { - commandShell->ignErr = "%s\n"; - } - } - - /* - * Do not free up the words themselves, since they might be in use by the - * shell specification... - */ - free(words); - return true; -} - -/*- - *----------------------------------------------------------------------- * JobInterrupt -- * Handle the receipt of an interrupt. * diff --git a/usr.bin/make/parse.c b/usr.bin/make/parse.c index 272712508c5..898e66d1644 100644 --- a/usr.bin/make/parse.c +++ b/usr.bin/make/parse.c @@ -1,5 +1,5 @@ /* $OpenPackages$ */ -/* $OpenBSD: parse.c,v 1.81 2007/09/16 10:14:26 espie Exp $ */ +/* $OpenBSD: parse.c,v 1.82 2007/09/16 10:57:02 espie Exp $ */ /* $NetBSD: parse.c,v 1.29 1997/03/10 21:20:04 christos Exp $ */ /* @@ -136,7 +136,6 @@ typedef enum { ExPath, /* .PATH */ Phony, /* .PHONY */ Precious, /* .PRECIOUS */ - ExShell, /* .SHELL */ Silent, /* .SILENT */ SingleShell, /* .SINGLESHELL */ Suffixes, /* .SUFFIXES */ @@ -194,7 +193,6 @@ static struct { { ".PHONY", Phony, OP_PHONY }, { ".PRECIOUS", Precious, OP_PRECIOUS }, { ".RECURSIVE", Attribute, OP_MAKE }, -{ ".SHELL", ExShell, 0 }, { ".SILENT", Silent, OP_SILENT }, { ".SINGLESHELL", SingleShell, 0 }, { ".SUFFIXES", Suffixes, 0 }, @@ -941,12 +939,6 @@ ParseDoDependency(char *line) /* the line to parse */ */ Main_ParseArgLine(line); *line = '\0'; - } else if (specType == ExShell) { - if (!Job_ParseShell(line)) { - Parse_Error(PARSE_FATAL, "improper shell specification"); - return; - } - *line = '\0'; } else if (specType == NotParallel || specType == SingleShell) { *line = '\0'; } |