- Move -D flags from Makefile to config.h and explain what they do. Add
-Wall -Wno-unused to CFLAGS. Add new define SYSVVARSUB to enable SysV style variable substitutions and enable them. - Add SunOS style command substitutions via SUNSHCMD - Fix core dump with '{variable = value'
This commit is contained in:
parent
ecbb3b2eb2
commit
5c1983c016
@ -1,8 +1,8 @@
|
||||
# $NetBSD: Makefile,v 1.10 1996/03/11 13:45:31 christos Exp $
|
||||
# $NetBSD: Makefile,v 1.11 1996/05/28 23:34:35 christos Exp $
|
||||
# @(#)Makefile 5.2 (Berkeley) 12/28/90
|
||||
|
||||
PROG= make
|
||||
CFLAGS+= -I${.CURDIR} -DPOSIX -DSYSVINCLUDE
|
||||
CFLAGS+= -I${.CURDIR} -Wall -Wno-unused
|
||||
SRCS= arch.c buf.c compat.c cond.c dir.c for.c hash.c job.c main.c \
|
||||
make.c parse.c str.c suff.c targ.c var.c util.c
|
||||
SRCS+= lstAppend.c lstAtEnd.c lstAtFront.c lstClose.c lstConcat.c \
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: config.h,v 1.5 1996/02/04 20:34:43 christos Exp $ */
|
||||
/* $NetBSD: config.h,v 1.6 1996/05/28 23:34:39 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -80,14 +80,37 @@
|
||||
* re-made, causing later targets to appear up-to-date. On systems
|
||||
* that don't have this problem, you should defined this. Under
|
||||
* NFS you probably should not, unless you aren't exporting jobs.
|
||||
*
|
||||
* POSIX
|
||||
* If the POSIX standard for Make is to be followed. There are
|
||||
* several areas that I dislike, hence this constant.
|
||||
*/
|
||||
#define LIBSUFF ".a"
|
||||
#define RECHECK
|
||||
|
||||
/*
|
||||
* POSIX
|
||||
* Adhere to the POSIX 1003.2 draft for the make(1) program.
|
||||
* - Use MAKEFLAGS instead of MAKE to pick arguments from the
|
||||
* environment.
|
||||
* - Allow empty command lines if starting with tab.
|
||||
*/
|
||||
#define POSIX
|
||||
|
||||
/*
|
||||
* SYSVINCLUDES
|
||||
* Recognize system V like include directives [include "filename"]
|
||||
* SYSVVARSUB
|
||||
* Recognize system V like ${VAR:x=y} variable substitutions
|
||||
*/
|
||||
#define SYSVINCLUDES
|
||||
#define SYSVVARSUB
|
||||
|
||||
/*
|
||||
* SUNSHCMD
|
||||
* Recognize SunOS and Solaris:
|
||||
* VAR :sh= CMD # Assign VAR to the command substitution of CMD
|
||||
* ${VAR:sh} # Return the command substitution of the value
|
||||
* # of ${VAR}
|
||||
*/
|
||||
#define SUNSHCMD
|
||||
|
||||
#if !defined(__svr4__) && !defined(__SVR4)
|
||||
# ifndef RANLIBMAG
|
||||
# define RANLIBMAG "__.SYMDEF"
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: main.c,v 1.28 1996/03/31 21:30:05 christos Exp $ */
|
||||
/* $NetBSD: main.c,v 1.29 1996/05/28 23:34:41 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -48,7 +48,7 @@ char copyright[] =
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)main.c 5.25 (Berkeley) 4/1/91";
|
||||
#else
|
||||
static char rcsid[] = "$NetBSD: main.c,v 1.28 1996/03/31 21:30:05 christos Exp $";
|
||||
static char rcsid[] = "$NetBSD: main.c,v 1.29 1996/05/28 23:34:41 christos Exp $";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -86,6 +86,7 @@ static char rcsid[] = "$NetBSD: main.c,v 1.28 1996/03/31 21:30:05 christos Exp $
|
||||
#include <sys/signal.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/wait.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
@ -819,6 +820,142 @@ found: Var_Set("MAKEFILE", fname, VAR_GLOBAL);
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*-
|
||||
* Cmd_Exec --
|
||||
* Execute the command in cmd, and return the output of that command
|
||||
* in a string.
|
||||
*
|
||||
* Results:
|
||||
* A string containing the output of the command, or the empty string
|
||||
* If err is not NULL, it contains the reason for the command failure
|
||||
*
|
||||
* Side Effects:
|
||||
* The string must be freed by the caller.
|
||||
*/
|
||||
char *
|
||||
Cmd_Exec(cmd, err)
|
||||
char *cmd;
|
||||
char **err;
|
||||
{
|
||||
char *args[4]; /* Args for invoking the shell */
|
||||
int fds[2]; /* Pipe streams */
|
||||
int cpid; /* Child PID */
|
||||
int pid; /* PID from wait() */
|
||||
char *res; /* result */
|
||||
int status; /* command exit status */
|
||||
Buffer buf; /* buffer to store the result */
|
||||
char *cp;
|
||||
int cc;
|
||||
|
||||
|
||||
*err = NULL;
|
||||
|
||||
/*
|
||||
* Set up arguments for shell
|
||||
*/
|
||||
args[0] = "sh";
|
||||
args[1] = "-c";
|
||||
args[2] = cmd;
|
||||
args[3] = NULL;
|
||||
|
||||
/*
|
||||
* Open a pipe for fetching its output
|
||||
*/
|
||||
if (pipe(fds) == -1) {
|
||||
*err = "Couldn't create pipe for \"%s\"";
|
||||
goto bad;
|
||||
}
|
||||
|
||||
/*
|
||||
* Fork
|
||||
*/
|
||||
switch (cpid = vfork()) {
|
||||
case 0:
|
||||
/*
|
||||
* Close input side of pipe
|
||||
*/
|
||||
(void) close(fds[0]);
|
||||
|
||||
/*
|
||||
* Duplicate the output stream to the shell's output, then
|
||||
* shut the extra thing down. Note we don't fetch the error
|
||||
* stream...why not? Why?
|
||||
*/
|
||||
(void) dup2(fds[1], 1);
|
||||
(void) close(fds[1]);
|
||||
|
||||
(void) execv("/bin/sh", args);
|
||||
_exit(1);
|
||||
/*NOTREACHED*/
|
||||
|
||||
case -1:
|
||||
*err = "Couldn't exec \"%s\"";
|
||||
goto bad;
|
||||
|
||||
default:
|
||||
/*
|
||||
* No need for the writing half
|
||||
*/
|
||||
(void) close(fds[1]);
|
||||
|
||||
buf = Buf_Init (MAKE_BSIZE);
|
||||
|
||||
do {
|
||||
char result[BUFSIZ];
|
||||
cc = read(fds[0], result, sizeof(result));
|
||||
if (cc > 0)
|
||||
Buf_AddBytes(buf, cc, (Byte *) result);
|
||||
}
|
||||
while (cc > 0 || (cc == -1 && errno == EINTR));
|
||||
|
||||
/*
|
||||
* Close the input side of the pipe.
|
||||
*/
|
||||
(void) close(fds[0]);
|
||||
|
||||
/*
|
||||
* Wait for the process to exit.
|
||||
*/
|
||||
while(((pid = wait(&status)) != cpid) && (pid >= 0))
|
||||
continue;
|
||||
|
||||
res = (char *)Buf_GetAll (buf, &cc);
|
||||
Buf_Destroy (buf, FALSE);
|
||||
|
||||
if (cc == 0)
|
||||
*err = "Couldn't read shell's output for \"%s\"";
|
||||
|
||||
if (status)
|
||||
*err = "\"%s\" returned non-zero status";
|
||||
|
||||
/*
|
||||
* Null-terminate the result, convert newlines to spaces and
|
||||
* install it in the variable.
|
||||
*/
|
||||
res[cc] = '\0';
|
||||
cp = &res[cc] - 1;
|
||||
|
||||
if (*cp == '\n') {
|
||||
/*
|
||||
* A final newline is just stripped
|
||||
*/
|
||||
*cp-- = '\0';
|
||||
}
|
||||
while (cp >= res) {
|
||||
if (*cp == '\n') {
|
||||
*cp = ' ';
|
||||
}
|
||||
cp--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
bad:
|
||||
res = emalloc(1);
|
||||
*res = '\0';
|
||||
return res;
|
||||
}
|
||||
|
||||
/*-
|
||||
* Error --
|
||||
* Print an error message given its format.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nonints.h,v 1.9 1996/03/31 21:30:07 christos Exp $ */
|
||||
/* $NetBSD: nonints.h,v 1.10 1996/05/28 23:34:44 christos Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -65,6 +65,7 @@ void For_Run __P((void));
|
||||
/* main.c */
|
||||
void Main_ParseArgLine __P((char *));
|
||||
int main __P((int, char **));
|
||||
char *Cmd_Exec __P((char *, char **));
|
||||
void Error __P((char *, ...));
|
||||
void Fatal __P((char *, ...));
|
||||
void Punt __P((char *, ...));
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: parse.c,v 1.22 1996/03/15 21:52:41 christos Exp $ */
|
||||
/* $NetBSD: parse.c,v 1.23 1996/05/28 23:34:46 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -42,7 +42,7 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)parse.c 5.18 (Berkeley) 2/19/91";
|
||||
#else
|
||||
static char rcsid[] = "$NetBSD: parse.c,v 1.22 1996/03/15 21:52:41 christos Exp $";
|
||||
static char rcsid[] = "$NetBSD: parse.c,v 1.23 1996/05/28 23:34:46 christos Exp $";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -96,7 +96,6 @@ static char rcsid[] = "$NetBSD: parse.c,v 1.22 1996/03/15 21:52:41 christos Exp
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <sys/wait.h>
|
||||
#include "make.h"
|
||||
#include "hash.h"
|
||||
#include "dir.h"
|
||||
@ -1275,22 +1274,31 @@ Parse_IsVar (line)
|
||||
default:
|
||||
if (wasSpace && haveName) {
|
||||
if (ISEQOPERATOR(*line)) {
|
||||
/*
|
||||
* We must have a finished word
|
||||
*/
|
||||
if (level != 0)
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* When an = operator [+?!:] is found, the next
|
||||
* character * must be an = or it ain't a valid
|
||||
* character must be an = or it ain't a valid
|
||||
* assignment.
|
||||
*/
|
||||
if (line[1] != '=' && level == 0)
|
||||
return FALSE;
|
||||
else
|
||||
if (line[1] == '=')
|
||||
return haveName;
|
||||
}
|
||||
else {
|
||||
#ifdef SUNSHCMD
|
||||
/*
|
||||
* This is the start of another word, so not assignment.
|
||||
* This is a shell command
|
||||
*/
|
||||
return FALSE;
|
||||
if (strncmp(line, ":sh", 3) == 0)
|
||||
return haveName;
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
* This is the start of another word, so not assignment.
|
||||
*/
|
||||
return FALSE;
|
||||
}
|
||||
else {
|
||||
haveName = TRUE;
|
||||
@ -1393,6 +1401,17 @@ Parse_DoVar (line, ctxt)
|
||||
break;
|
||||
|
||||
default:
|
||||
#ifdef SUNSHCMD
|
||||
while (*opc != ':')
|
||||
if (--opc < line)
|
||||
break;
|
||||
|
||||
if (strncmp(opc, ":sh", 3) == 0) {
|
||||
type = VAR_SHELL;
|
||||
*opc = '\0';
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
type = VAR_NORMAL;
|
||||
break;
|
||||
}
|
||||
@ -1424,156 +1443,38 @@ Parse_DoVar (line, ctxt)
|
||||
Var_Set(line, cp, ctxt);
|
||||
free(cp);
|
||||
} else if (type == VAR_SHELL) {
|
||||
char *args[4]; /* Args for invoking the shell */
|
||||
int fds[2]; /* Pipe streams */
|
||||
int cpid; /* Child PID */
|
||||
int pid; /* PID from wait() */
|
||||
Boolean freeCmd; /* TRUE if the command needs to be freed, i.e.
|
||||
* if any variable expansion was performed */
|
||||
Boolean freeCmd = FALSE; /* TRUE if the command needs to be freed, i.e.
|
||||
* if any variable expansion was performed */
|
||||
char *res, *err;
|
||||
|
||||
/*
|
||||
* Avoid clobbered variable warnings by forcing the compiler
|
||||
* to ``unregister'' variables
|
||||
*/
|
||||
#if __GNUC__
|
||||
(void) &freeCmd;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set up arguments for shell
|
||||
*/
|
||||
args[0] = "sh";
|
||||
args[1] = "-c";
|
||||
if (strchr(cp, '$') != (char *)NULL) {
|
||||
if (strchr(cp, '$') != NULL) {
|
||||
/*
|
||||
* There's a dollar sign in the command, so perform variable
|
||||
* expansion on the whole thing. The resulting string will need
|
||||
* freeing when we're done, so set freeCmd to TRUE.
|
||||
*/
|
||||
args[2] = Var_Subst(NULL, cp, VAR_CMD, TRUE);
|
||||
cp = Var_Subst(NULL, cp, VAR_CMD, TRUE);
|
||||
freeCmd = TRUE;
|
||||
} else {
|
||||
args[2] = cp;
|
||||
freeCmd = FALSE;
|
||||
}
|
||||
args[3] = (char *)NULL;
|
||||
|
||||
/*
|
||||
* Open a pipe for fetching its output
|
||||
*/
|
||||
pipe(fds);
|
||||
res = Cmd_Exec(cp, &err);
|
||||
Var_Set(line, res, ctxt);
|
||||
free(res);
|
||||
|
||||
/*
|
||||
* Fork
|
||||
*/
|
||||
cpid = vfork();
|
||||
if (cpid == 0) {
|
||||
/*
|
||||
* Close input side of pipe
|
||||
*/
|
||||
close(fds[0]);
|
||||
if (err)
|
||||
Parse_Error(PARSE_WARNING, err, cp);
|
||||
|
||||
/*
|
||||
* Duplicate the output stream to the shell's output, then
|
||||
* shut the extra thing down. Note we don't fetch the error
|
||||
* stream...why not? Why?
|
||||
*/
|
||||
dup2(fds[1], 1);
|
||||
close(fds[1]);
|
||||
|
||||
execv("/bin/sh", args);
|
||||
_exit(1);
|
||||
} else if (cpid < 0) {
|
||||
/*
|
||||
* Couldn't fork -- tell the user and make the variable null
|
||||
*/
|
||||
Parse_Error(PARSE_WARNING, "Couldn't exec \"%s\"", cp);
|
||||
Var_Set(line, "", ctxt);
|
||||
} else {
|
||||
int status;
|
||||
int cc;
|
||||
Buffer buf;
|
||||
char *res;
|
||||
|
||||
/*
|
||||
* No need for the writing half
|
||||
*/
|
||||
close(fds[1]);
|
||||
|
||||
buf = Buf_Init (MAKE_BSIZE);
|
||||
|
||||
do {
|
||||
char result[BUFSIZ];
|
||||
cc = read(fds[0], result, sizeof(result));
|
||||
if (cc > 0)
|
||||
Buf_AddBytes(buf, cc, (Byte *) result);
|
||||
}
|
||||
while (cc > 0 || (cc == -1 && errno == EINTR));
|
||||
|
||||
/*
|
||||
* Close the input side of the pipe.
|
||||
*/
|
||||
close(fds[0]);
|
||||
|
||||
/*
|
||||
* Wait for the process to exit.
|
||||
*/
|
||||
while(((pid = wait(&status)) != cpid) && (pid >= 0))
|
||||
continue;
|
||||
|
||||
res = (char *)Buf_GetAll (buf, &cc);
|
||||
Buf_Destroy (buf, FALSE);
|
||||
|
||||
if (cc == 0) {
|
||||
/*
|
||||
* Couldn't read the child's output -- tell the user and
|
||||
* set the variable to null
|
||||
*/
|
||||
Parse_Error(PARSE_WARNING, "Couldn't read shell's output");
|
||||
}
|
||||
|
||||
if (status) {
|
||||
/*
|
||||
* Child returned an error -- tell the user but still use
|
||||
* the result.
|
||||
*/
|
||||
Parse_Error(PARSE_WARNING, "\"%s\" returned non-zero", cp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Null-terminate the result, convert newlines to spaces and
|
||||
* install it in the variable.
|
||||
*/
|
||||
res[cc] = '\0';
|
||||
cp = &res[cc] - 1;
|
||||
|
||||
if (*cp == '\n') {
|
||||
/*
|
||||
* A final newline is just stripped
|
||||
*/
|
||||
*cp-- = '\0';
|
||||
}
|
||||
while (cp >= res) {
|
||||
if (*cp == '\n') {
|
||||
*cp = ' ';
|
||||
}
|
||||
cp--;
|
||||
}
|
||||
Var_Set(line, res, ctxt);
|
||||
free(res);
|
||||
|
||||
}
|
||||
if (freeCmd) {
|
||||
free(args[2]);
|
||||
}
|
||||
if (freeCmd)
|
||||
free(cp);
|
||||
} else {
|
||||
/*
|
||||
* Normal assignment -- just do it.
|
||||
*/
|
||||
Var_Set (line, cp, ctxt);
|
||||
Var_Set(line, cp, ctxt);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-
|
||||
* ParseAddCmd --
|
||||
* Lst_ForEach function to add a command line to all targets
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: var.c,v 1.12 1995/11/02 23:55:12 christos Exp $ */
|
||||
/* $NetBSD: var.c,v 1.13 1996/05/28 23:34:49 christos Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990 The Regents of the University of California.
|
||||
@ -42,7 +42,7 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)var.c 5.7 (Berkeley) 6/1/90";
|
||||
#else
|
||||
static char rcsid[] = "$NetBSD: var.c,v 1.12 1995/11/02 23:55:12 christos Exp $";
|
||||
static char rcsid[] = "$NetBSD: var.c,v 1.13 1996/05/28 23:34:49 christos Exp $";
|
||||
#endif
|
||||
#endif /* not lint */
|
||||
|
||||
@ -165,7 +165,9 @@ static Boolean VarTail __P((char *, Boolean, Buffer, ClientData));
|
||||
static Boolean VarSuffix __P((char *, Boolean, Buffer, ClientData));
|
||||
static Boolean VarRoot __P((char *, Boolean, Buffer, ClientData));
|
||||
static Boolean VarMatch __P((char *, Boolean, Buffer, ClientData));
|
||||
#ifdef SYSVVARSUB
|
||||
static Boolean VarSYSVMatch __P((char *, Boolean, Buffer, ClientData));
|
||||
#endif
|
||||
static Boolean VarNoMatch __P((char *, Boolean, Buffer, ClientData));
|
||||
static Boolean VarSubstitute __P((char *, Boolean, Buffer, ClientData));
|
||||
static char *VarModify __P((char *, Boolean (*)(char *, Boolean, Buffer,
|
||||
@ -782,8 +784,7 @@ VarMatch (word, addSpace, buf, pattern)
|
||||
return(addSpace);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef SYSVVARSUB
|
||||
/*-
|
||||
*-----------------------------------------------------------------------
|
||||
* VarSYSVMatch --
|
||||
@ -825,6 +826,7 @@ VarSYSVMatch (word, addSpace, buf, patp)
|
||||
|
||||
return(addSpace);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*-
|
||||
@ -1633,7 +1635,22 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
|
||||
break;
|
||||
}
|
||||
/*FALLTHRU*/
|
||||
default: {
|
||||
#ifdef SUNSHCMD
|
||||
case 's':
|
||||
if (tstr[1] == 'h' && (tstr[2] == endc || tstr[2] == ':')) {
|
||||
char *err;
|
||||
newStr = Cmd_Exec (str, &err);
|
||||
if (err)
|
||||
Error (err, str);
|
||||
cp = tstr + 2;
|
||||
termc = *cp;
|
||||
break;
|
||||
}
|
||||
/*FALLTHRU*/
|
||||
#endif
|
||||
default:
|
||||
{
|
||||
#ifdef SYSVVARSUB
|
||||
/*
|
||||
* This can either be a bogus modifier or a System-V
|
||||
* substitution command.
|
||||
@ -1700,7 +1717,9 @@ Var_Parse (str, ctxt, err, lengthPtr, freePtr)
|
||||
pattern.lhs[pattern.leftLen] = '=';
|
||||
pattern.rhs[pattern.rightLen] = endc;
|
||||
termc = endc;
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
Error ("Unknown modifier '%c'\n", *tstr);
|
||||
for (cp = tstr+1;
|
||||
*cp != ':' && *cp != endc && *cp != '\0';
|
||||
|
Loading…
Reference in New Issue
Block a user