From 46ca4347374ab1d846340cda3f2725c9196366b5 Mon Sep 17 00:00:00 2001 From: Hartmut Brandt Date: Mon, 7 Feb 2005 11:27:47 +0000 Subject: [PATCH] Introduce Buf_StripNewLines() and use it where appropriate. Submitted by: Max Okumoto --- usr.bin/make/buf.c | 30 +++++++++++++++++ usr.bin/make/buf.h | 1 + usr.bin/make/main.c | 74 ++++++++++++++---------------------------- usr.bin/make/nonints.h | 6 ++-- usr.bin/make/parse.c | 8 ++--- usr.bin/make/var.c | 7 +++- 6 files changed, 69 insertions(+), 57 deletions(-) diff --git a/usr.bin/make/buf.c b/usr.bin/make/buf.c index b3748f0fd1b2..dc192827d93e 100644 --- a/usr.bin/make/buf.c +++ b/usr.bin/make/buf.c @@ -212,6 +212,36 @@ Buf_AppendRange(Buffer *bp, const char str[], const char *end) Buf_AddBytes(bp, end - str, str); } +/** + * Convert newlines in buffer to spaces. The trailing newline is + * removed. + */ +void +Buf_StripNewlines(Buffer *bp) +{ + char *ptr = bp->end; + + /* + * If there is anything in the buffer, remove the last + * newline character. + */ + if (ptr != bp->buf) { + if (*(ptr - 1) == '\n') { + /* shorten buffer */ + *(ptr - 1) = '\0'; + --bp->end; + } + --ptr; + } + + /* Convert newline characters to a space characters. */ + while (ptr != bp->buf) { + if (*ptr == '\n') { + *ptr = ' '; + } + --ptr; + } +} /** * Clear the contents of the buffer. */ diff --git a/usr.bin/make/buf.h b/usr.bin/make/buf.h index bc669ed7edc8..6b7ea493ab6c 100644 --- a/usr.bin/make/buf.h +++ b/usr.bin/make/buf.h @@ -85,5 +85,6 @@ void Buf_ReplaceLastByte(Buffer *, Byte); void Buf_Append(Buffer *, const char []); void Buf_AppendRange(Buffer *, const char [], const char *); +void Buf_StripNewlines(Buffer *); #endif /* buf_h_a61a6812 */ diff --git a/usr.bin/make/main.c b/usr.bin/make/main.c index 690c26763f6b..f53e1f2ff70f 100644 --- a/usr.bin/make/main.c +++ b/usr.bin/make/main.c @@ -1017,38 +1017,27 @@ found: * Side Effects: * The string must be freed by the caller. */ -char * +Buffer * Cmd_Exec(char *cmd, const char **error) { - 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; - size_t blen; - ssize_t rcnt; + ssize_t rcnt; *error = NULL; + buf = Buf_Init(0); if (shellPath == NULL) Shell_Init(); - /* - * Set up arguments for shell - */ - args[0] = shellName; - args[1] = "-c"; - args[2] = cmd; - args[3] = NULL; - /* * Open a pipe for fetching its output */ if (pipe(fds) == -1) { *error = "Couldn't create pipe for \"%s\""; - goto bad; + return (buf); } /* @@ -1069,13 +1058,23 @@ Cmd_Exec(char *cmd, const char **error) dup2(fds[1], 1); close(fds[1]); - execv(shellPath, args); - _exit(1); - /*NOTREACHED*/ + { + char *args[4]; + + /* Set up arguments for shell */ + args[0] = shellName; + args[1] = "-c"; + args[2] = cmd; + args[3] = NULL; + + execv(shellPath, args); + _exit(1); + /*NOTREACHED*/ + } case -1: *error = "Couldn't exec \"%s\""; - goto bad; + return (buf); default: /* @@ -1083,14 +1082,16 @@ Cmd_Exec(char *cmd, const char **error) */ close(fds[1]); - buf = Buf_Init(MAKE_BSIZE); - do { char result[BUFSIZ]; rcnt = read(fds[0], result, sizeof(result)); if (rcnt != -1) Buf_AddBytes(buf, (size_t)rcnt, (Byte *)result); } while (rcnt > 0 || (rcnt == -1 && errno == EINTR)); + + if (rcnt == -1) + *error = "Error reading shell's output for \"%s\""; + /* * Close the input side of the pipe. */ @@ -1102,41 +1103,14 @@ Cmd_Exec(char *cmd, const char **error) while (((pid = wait(&status)) != cpid) && (pid >= 0)) continue; - if (rcnt == -1) - *error = "Error reading shell's output for \"%s\""; - - res = (char *)Buf_GetAll(buf, &blen); - Buf_Destroy(buf, FALSE); - if (status) *error = "\"%s\" returned non-zero status"; - /* - * Null-terminate the result, convert newlines to spaces and - * install it in the variable. - */ - res[blen] = '\0'; - cp = &res[blen] - 1; + Buf_StripNewlines(buf); - 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); + return (buf); } /* diff --git a/usr.bin/make/nonints.h b/usr.bin/make/nonints.h index 5fe6d89556b5..3bef7cea3977 100644 --- a/usr.bin/make/nonints.h +++ b/usr.bin/make/nonints.h @@ -42,8 +42,10 @@ #ifndef nonints_h_33c5dafb #define nonints_h_33c5dafb -/* main.c */ +struct Buffer; + void Main_ParseArgLine(char *, int); -char *Cmd_Exec(char *, const char **); +Buffer *Cmd_Exec(char *, const char **); + #endif /* nonints_h_33c5dafb */ diff --git a/usr.bin/make/parse.c b/usr.bin/make/parse.c index 2db0d8afce5a..64150b32db04 100644 --- a/usr.bin/make/parse.c +++ b/usr.bin/make/parse.c @@ -1433,7 +1433,7 @@ Parse_DoVar(char *line, GNode *ctxt) } else if (type == VAR_SHELL) { Boolean freeCmd = FALSE; /* TRUE if the command needs to be freed, i.e. * if any variable expansion was performed */ - char *res; + Buffer *buf; const char *error; if (strchr(cp, '$') != NULL) { @@ -1446,9 +1446,9 @@ Parse_DoVar(char *line, GNode *ctxt) freeCmd = TRUE; } - res = Cmd_Exec(cp, &error); - Var_Set(line, res, ctxt); - free(res); + buf = Cmd_Exec(cp, &error); + Var_Set(line, Buf_GetAll(buf, NULL), ctxt); + Buf_Destroy(buf, TRUE); if (error) Parse_Error(PARSE_WARNING, error, cp); diff --git a/usr.bin/make/var.c b/usr.bin/make/var.c index c9b1d7a6004b..a7ccd59df238 100644 --- a/usr.bin/make/var.c +++ b/usr.bin/make/var.c @@ -1543,7 +1543,12 @@ Var_Parse(char *str, GNode *ctxt, Boolean err, size_t *lengthPtr, case 's': if (tstr[1] == 'h' && (tstr[2] == endc || tstr[2] == ':')) { const char *error; - newStr = Cmd_Exec(str, &error); + Buffer *buf; + + buf = Cmd_Exec(str, &error); + newStr = Buf_GetAll(buf, NULL); + Buf_Destroy(buf, FALSE); + if (error) Error(error, str); cp = tstr + 2;