summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorharti <harti@FreeBSD.org>2005-05-10 11:53:20 +0000
committerharti <harti@FreeBSD.org>2005-05-10 11:53:20 +0000
commitaa675175227258b0c762e4fa7bfb2aa863711abd (patch)
tree25c388f7927c6f98627341a7c6d0abfbfe779d48
parentc9931f2fee92f91f140c5048a0f524d269d0f04e (diff)
downloadFreeBSD-src-aa675175227258b0c762e4fa7bfb2aa863711abd.zip
FreeBSD-src-aa675175227258b0c762e4fa7bfb2aa863711abd.tar.gz
Merge var_modify.c into var.c and move types and function declarations
that are now used only in var.c from var.h to var.c Patches: 7.193,7.194 Submitted by: Max Okumoto <okumoto@ucsd.edu>
-rw-r--r--usr.bin/make/Makefile3
-rw-r--r--usr.bin/make/var.c657
-rw-r--r--usr.bin/make/var.h61
-rw-r--r--usr.bin/make/var_modify.c572
4 files changed, 602 insertions, 691 deletions
diff --git a/usr.bin/make/Makefile b/usr.bin/make/Makefile
index bf33e71..4a44543 100644
--- a/usr.bin/make/Makefile
+++ b/usr.bin/make/Makefile
@@ -5,8 +5,7 @@
PROG= make
CFLAGS+=-I${.CURDIR}
SRCS= arch.c buf.c compat.c cond.c dir.c for.c hash.c hash_tables.c \
- job.c lst.c main.c make.c parse.c str.c suff.c targ.c util.c \
- var.c var_modify.c
+ job.c lst.c main.c make.c parse.c str.c suff.c targ.c util.c var.c
NO_WERROR=
WARNS?= 3
diff --git a/usr.bin/make/var.c b/usr.bin/make/var.c
index 9848d58..9784ceb 100644
--- a/usr.bin/make/var.c
+++ b/usr.bin/make/var.c
@@ -1,4 +1,5 @@
/*-
+ * Copyright (c) 2002 Juli Mallett.
* Copyright (c) 1988, 1989, 1990, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 1989 by Berkeley Softworks
@@ -87,6 +88,8 @@ __FBSDID("$FreeBSD$");
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/types.h>
+#include <regex.h>
#include "buf.h"
#include "config.h"
@@ -110,6 +113,41 @@ typedef struct VarParser {
Boolean err;
Boolean execute;
} VarParser;
+
+typedef struct Var {
+ char *name; /* the variable's name */
+ struct Buffer *val; /* its value */
+ int flags; /* miscellaneous status flags */
+
+#define VAR_IN_USE 1 /* Variable's value currently being used.
+ * Used to avoid recursion */
+
+#define VAR_JUNK 4 /* Variable is a junk variable that
+ * should be destroyed when done with
+ * it. Used by Var_Parse for undefined,
+ * modified variables */
+
+#define VAR_TO_ENV 8 /* Place variable in environment */
+} Var;
+
+typedef struct {
+ struct Buffer *lhs; /* String to match */
+ struct Buffer *rhs; /* Replacement string (w/ &'s removed) */
+
+ regex_t re;
+ int nsub;
+ regmatch_t *matches;
+
+ int flags;
+#define VAR_SUB_GLOBAL 0x01 /* Apply substitution globally */
+#define VAR_SUB_ONE 0x02 /* Apply substitution to one word */
+#define VAR_SUB_MATCHED 0x04 /* There was a match */
+#define VAR_MATCH_START 0x08 /* Match at start of word */
+#define VAR_MATCH_END 0x10 /* Match at end of word */
+} VarPattern;
+
+typedef Boolean VarModifyProc(const char *, Boolean, struct Buffer *, void *);
+
static char *VarParse(VarParser *, Boolean *);
/*
@@ -194,6 +232,545 @@ VarDestroy(Var *v, Boolean f)
free(v);
}
+/**
+ * VarHead
+ * Remove the tail of the given word and place the result in the given
+ * buffer.
+ *
+ * Results:
+ * TRUE if characters were added to the buffer (a space needs to be
+ * added to the buffer before the next word).
+ *
+ * Side Effects:
+ * The trimmed word is added to the buffer.
+ */
+static Boolean
+VarHead(const char *word, Boolean addSpace, Buffer *buf, void *dummy __unused)
+{
+ char *slash;
+
+ slash = strrchr(word, '/');
+ if (slash != NULL) {
+ if (addSpace) {
+ Buf_AddByte(buf, (Byte)' ');
+ }
+ Buf_AppendRange(buf, word, slash);
+ } else {
+ /*
+ * If no directory part, give . (q.v. the POSIX standard)
+ */
+ if (addSpace) {
+ Buf_Append(buf, " .");
+ } else {
+ Buf_AddByte(buf, (Byte)'.');
+ }
+ }
+ return (TRUE);
+}
+
+/**
+ * VarTail
+ * Remove the head of the given word and place the result in the given
+ * buffer.
+ *
+ * Results:
+ * TRUE if characters were added to the buffer (a space needs to be
+ * added to the buffer before the next word).
+ *
+ * Side Effects:
+ * The trimmed word is added to the buffer.
+ */
+static Boolean
+VarTail(const char *word, Boolean addSpace, Buffer *buf, void *dummy __unused)
+{
+ const char *slash;
+
+ if (addSpace) {
+ Buf_AddByte (buf, (Byte)' ');
+ }
+
+ slash = strrchr(word, '/');
+ if (slash != NULL) {
+ slash++;
+ Buf_Append(buf, slash);
+ } else {
+ Buf_Append(buf, word);
+ }
+ return (TRUE);
+}
+
+/**
+ * VarSuffix
+ * Place the suffix of the given word in the given buffer.
+ *
+ * Results:
+ * TRUE if characters were added to the buffer (a space needs to be
+ * added to the buffer before the next word).
+ *
+ * Side Effects:
+ * The suffix from the word is placed in the buffer.
+ */
+static Boolean
+VarSuffix(const char *word, Boolean addSpace, Buffer *buf, void *dummy __unused)
+{
+ const char *dot;
+
+ dot = strrchr(word, '.');
+ if (dot != NULL) {
+ if (addSpace) {
+ Buf_AddByte(buf, (Byte)' ');
+ }
+ dot++;
+ Buf_Append(buf, dot);
+ addSpace = TRUE;
+ }
+ return (addSpace);
+}
+
+/**
+ * VarRoot
+ * Remove the suffix of the given word and place the result in the
+ * buffer.
+ *
+ * Results:
+ * TRUE if characters were added to the buffer (a space needs to be
+ * added to the buffer before the next word).
+ *
+ * Side Effects:
+ * The trimmed word is added to the buffer.
+ */
+static Boolean
+VarRoot(const char *word, Boolean addSpace, Buffer *buf, void *dummy __unused)
+{
+ char *dot;
+
+ if (addSpace) {
+ Buf_AddByte(buf, (Byte)' ');
+ }
+
+ dot = strrchr(word, '.');
+ if (dot != NULL) {
+ Buf_AppendRange(buf, word, dot);
+ } else {
+ Buf_Append(buf, word);
+ }
+ return (TRUE);
+}
+
+/**
+ * VarMatch
+ * Place the word in the buffer if it matches the given pattern.
+ * Callback function for VarModify to implement the :M modifier.
+ * A space will be added if requested. A pattern is supplied
+ * which the word must match.
+ *
+ * Results:
+ * TRUE if a space should be placed in the buffer before the next
+ * word.
+ *
+ * Side Effects:
+ * The word may be copied to the buffer.
+ */
+static Boolean
+VarMatch(const char *word, Boolean addSpace, Buffer *buf, void *pattern)
+{
+
+ if (Str_Match(word, pattern)) {
+ if (addSpace) {
+ Buf_AddByte(buf, (Byte)' ');
+ }
+ addSpace = TRUE;
+ Buf_Append(buf, word);
+ }
+ return (addSpace);
+}
+
+#ifdef SYSVVARSUB
+/**
+ * VarSYSVMatch
+ * Place the word in the buffer if it matches the given pattern.
+ * Callback function for VarModify to implement the System V %
+ * modifiers. A space is added if requested.
+ *
+ * Results:
+ * TRUE if a space should be placed in the buffer before the next
+ * word.
+ *
+ * Side Effects:
+ * The word may be copied to the buffer.
+ */
+static Boolean
+VarSYSVMatch(const char *word, Boolean addSpace, Buffer *buf, void *patp)
+{
+ int len;
+ const char *ptr;
+ VarPattern *pat = (VarPattern *)patp;
+
+ if (addSpace)
+ Buf_AddByte(buf, (Byte)' ');
+
+ addSpace = TRUE;
+
+ if ((ptr = Str_SYSVMatch(word, Buf_Data(pat->lhs), &len)) != NULL)
+ Str_SYSVSubst(buf, Buf_Data(pat->rhs), ptr, len);
+ else
+ Buf_Append(buf, word);
+
+ return (addSpace);
+}
+#endif
+
+/**
+ * VarNoMatch
+ * Place the word in the buffer if it doesn't match the given pattern.
+ * Callback function for VarModify to implement the :N modifier. A
+ * space is added if requested.
+ *
+ * Results:
+ * TRUE if a space should be placed in the buffer before the next
+ * word.
+ *
+ * Side Effects:
+ * The word may be copied to the buffer.
+ */
+static Boolean
+VarNoMatch(const char *word, Boolean addSpace, Buffer *buf, void *pattern)
+{
+
+ if (!Str_Match(word, pattern)) {
+ if (addSpace) {
+ Buf_AddByte(buf, (Byte)' ');
+ }
+ addSpace = TRUE;
+ Buf_Append(buf, word);
+ }
+ return (addSpace);
+}
+
+/**
+ * VarSubstitute
+ * Perform a string-substitution on the given word, placing the
+ * result in the passed buffer. A space is added if requested.
+ *
+ * Results:
+ * TRUE if a space is needed before more characters are added.
+ */
+static Boolean
+VarSubstitute(const char *word, Boolean addSpace, Buffer *buf, void *patternp)
+{
+ size_t wordLen; /* Length of word */
+ const char *cp; /* General pointer */
+ VarPattern *pattern = patternp;
+
+ wordLen = strlen(word);
+ if (1) { /* substitute in each word of the variable */
+ /*
+ * Break substitution down into simple anchored cases
+ * and if none of them fits, perform the general substitution
+ * case.
+ */
+ if ((pattern->flags & VAR_MATCH_START) &&
+ (strncmp(word, Buf_Data(pattern->lhs),
+ Buf_Size(pattern->lhs)) == 0)) {
+ /*
+ * Anchored at start and beginning of word matches
+ * pattern.
+ */
+ if ((pattern->flags & VAR_MATCH_END) &&
+ (wordLen == Buf_Size(pattern->lhs))) {
+ /*
+ * Also anchored at end and matches to the end
+ * (word is same length as pattern) add space
+ * and rhs only if rhs is non-null.
+ */
+ if (Buf_Size(pattern->rhs) != 0) {
+ if (addSpace) {
+ Buf_AddByte(buf, (Byte)' ');
+ }
+ addSpace = TRUE;
+ Buf_AppendBuf(buf, pattern->rhs);
+ }
+
+ } else if (pattern->flags & VAR_MATCH_END) {
+ /*
+ * Doesn't match to end -- copy word wholesale
+ */
+ goto nosub;
+
+ } else {
+ /*
+ * Matches at start but need to copy in
+ * trailing characters.
+ */
+ if ((Buf_Size(pattern->rhs) + wordLen -
+ Buf_Size(pattern->lhs)) != 0) {
+ if (addSpace) {
+ Buf_AddByte(buf, (Byte)' ');
+ }
+ addSpace = TRUE;
+ }
+ Buf_AppendBuf(buf, pattern->rhs);
+ Buf_AddBytes(buf, wordLen -
+ Buf_Size(pattern->lhs),
+ (word + Buf_Size(pattern->lhs)));
+ }
+
+ } else if (pattern->flags & VAR_MATCH_START) {
+ /*
+ * Had to match at start of word and didn't -- copy
+ * whole word.
+ */
+ goto nosub;
+
+ } else if (pattern->flags & VAR_MATCH_END) {
+ /*
+ * Anchored at end, Find only place match could occur
+ * (leftLen characters from the end of the word) and
+ * see if it does. Note that because the $ will be
+ * left at the end of the lhs, we have to use strncmp.
+ */
+ cp = word + (wordLen - Buf_Size(pattern->lhs));
+ if ((cp >= word) && (strncmp(cp, Buf_Data(pattern->lhs),
+ Buf_Size(pattern->lhs)) == 0)) {
+ /*
+ * Match found. If we will place characters in
+ * the buffer, add a space before hand as
+ * indicated by addSpace, then stuff in the
+ * initial, unmatched part of the word followed
+ * by the right-hand-side.
+ */
+ if ((cp - word) + Buf_Size(pattern->rhs) != 0) {
+ if (addSpace) {
+ Buf_AddByte(buf, (Byte)' ');
+ }
+ addSpace = TRUE;
+ }
+ Buf_AppendRange(buf, word, cp);
+ Buf_AppendBuf(buf, pattern->rhs);
+
+ } else {
+ /*
+ * Had to match at end and didn't. Copy entire
+ * word.
+ */
+ goto nosub;
+ }
+ } else {
+ /*
+ * Pattern is unanchored: search for the pattern in the
+ * word using strstr(3), copying unmatched portions and
+ * the right-hand-side for each match found, handling
+ * non-global substitutions correctly, etc. When the
+ * loop is done, any remaining part of the word (word
+ * and wordLen are adjusted accordingly through the
+ * loop) is copied straight into the buffer.
+ * addSpace is set FALSE as soon as a space is added
+ * to the buffer.
+ */
+ Boolean done;
+ size_t origSize;
+
+ done = FALSE;
+ origSize = Buf_Size(buf);
+ while (!done) {
+ cp = strstr(word, Buf_Data(pattern->lhs));
+ if (cp != NULL) {
+ if (addSpace && (((cp - word) +
+ Buf_Size(pattern->rhs)) != 0)) {
+ Buf_AddByte(buf, (Byte)' ');
+ addSpace = FALSE;
+ }
+ Buf_AppendRange(buf, word, cp);
+ Buf_AppendBuf(buf, pattern->rhs);
+ wordLen -= (cp - word) +
+ Buf_Size(pattern->lhs);
+ word = cp + Buf_Size(pattern->lhs);
+ if (wordLen == 0 || (pattern->flags &
+ VAR_SUB_GLOBAL) == 0) {
+ done = TRUE;
+ }
+ } else {
+ done = TRUE;
+ }
+ }
+ if (wordLen != 0) {
+ if (addSpace) {
+ Buf_AddByte(buf, (Byte)' ');
+ }
+ Buf_AddBytes(buf, wordLen, (const Byte *)word);
+ }
+
+ /*
+ * If added characters to the buffer, need to add a
+ * space before we add any more. If we didn't add any,
+ * just return the previous value of addSpace.
+ */
+ return ((Buf_Size(buf) != origSize) || addSpace);
+ }
+ /*
+ * Common code for anchored substitutions:
+ * addSpace was set TRUE if characters were added to the buffer.
+ */
+ return (addSpace);
+ }
+ nosub:
+ if (addSpace) {
+ Buf_AddByte(buf, (Byte)' ');
+ }
+ Buf_AddBytes(buf, wordLen, (const Byte *)word);
+ return (TRUE);
+}
+
+/**
+ * Print the error caused by a regcomp or regexec call.
+ *
+ * Side Effects:
+ * An error gets printed.
+ */
+static void
+VarREError(int err, regex_t *pat, const char *str)
+{
+ char *errbuf;
+ int errlen;
+
+ errlen = regerror(err, pat, 0, 0);
+ errbuf = emalloc(errlen);
+ regerror(err, pat, errbuf, errlen);
+ Error("%s: %s", str, errbuf);
+ free(errbuf);
+}
+
+
+/**
+ * VarRESubstitute
+ * Perform a regex substitution on the given word, placing the
+ * result in the passed buffer. A space is added if requested.
+ *
+ * Results:
+ * TRUE if a space is needed before more characters are added.
+ */
+static Boolean
+VarRESubstitute(const char *word, Boolean addSpace, Buffer *buf, void *patternp)
+{
+ VarPattern *pat;
+ int xrv;
+ const char *wp;
+ char *rp;
+ int added;
+ int flags = 0;
+
+#define MAYBE_ADD_SPACE() \
+ if (addSpace && !added) \
+ Buf_AddByte(buf, (Byte)' '); \
+ added = 1
+
+ added = 0;
+ wp = word;
+ pat = patternp;
+
+ if ((pat->flags & (VAR_SUB_ONE | VAR_SUB_MATCHED)) ==
+ (VAR_SUB_ONE | VAR_SUB_MATCHED)) {
+ xrv = REG_NOMATCH;
+ } else {
+ tryagain:
+ xrv = regexec(&pat->re, wp, pat->nsub, pat->matches, flags);
+ }
+
+ switch (xrv) {
+ case 0:
+ pat->flags |= VAR_SUB_MATCHED;
+ if (pat->matches[0].rm_so > 0) {
+ MAYBE_ADD_SPACE();
+ Buf_AddBytes(buf, pat->matches[0].rm_so,
+ (const Byte *)wp);
+ }
+
+ for (rp = Buf_Data(pat->rhs); *rp; rp++) {
+ if ((*rp == '\\') && ((rp[1] == '&') || (rp[1] == '\\'))) {
+ MAYBE_ADD_SPACE();
+ Buf_AddByte(buf, (Byte)rp[1]);
+ rp++;
+
+ } else if ((*rp == '&') ||
+ ((*rp == '\\') && isdigit((unsigned char)rp[1]))) {
+ int n;
+ const char *subbuf;
+ int sublen;
+ char errstr[3];
+
+ if (*rp == '&') {
+ n = 0;
+ errstr[0] = '&';
+ errstr[1] = '\0';
+ } else {
+ n = rp[1] - '0';
+ errstr[0] = '\\';
+ errstr[1] = rp[1];
+ errstr[2] = '\0';
+ rp++;
+ }
+
+ if (n > pat->nsub) {
+ Error("No subexpression %s",
+ &errstr[0]);
+ subbuf = "";
+ sublen = 0;
+
+ } else if ((pat->matches[n].rm_so == -1) &&
+ (pat->matches[n].rm_eo == -1)) {
+ Error("No match for subexpression %s",
+ &errstr[0]);
+ subbuf = "";
+ sublen = 0;
+
+ } else {
+ subbuf = wp + pat->matches[n].rm_so;
+ sublen = pat->matches[n].rm_eo -
+ pat->matches[n].rm_so;
+ }
+
+ if (sublen > 0) {
+ MAYBE_ADD_SPACE();
+ Buf_AddBytes(buf, sublen,
+ (const Byte *)subbuf);
+ }
+ } else {
+ MAYBE_ADD_SPACE();
+ Buf_AddByte(buf, (Byte)*rp);
+ }
+ }
+ wp += pat->matches[0].rm_eo;
+ if (pat->flags & VAR_SUB_GLOBAL) {
+ flags |= REG_NOTBOL;
+ if (pat->matches[0].rm_so == 0 &&
+ pat->matches[0].rm_eo == 0) {
+ MAYBE_ADD_SPACE();
+ Buf_AddByte(buf, (Byte)*wp);
+ wp++;
+ }
+ if (*wp)
+ goto tryagain;
+ }
+ if (*wp) {
+ MAYBE_ADD_SPACE();
+ Buf_Append(buf, wp);
+ }
+ break;
+
+ default:
+ VarREError(xrv, &pat->re, "Unexpected regex error");
+ /* fall through */
+
+ case REG_NOMATCH:
+ if (*wp) {
+ MAYBE_ADD_SPACE();
+ Buf_Append(buf, wp);
+ }
+ break;
+ }
+ return (addSpace || added);
+}
+
/*
* Find a variable in a variable list.
*/
@@ -796,62 +1373,6 @@ VarGetPattern(VarParser *vp, int delim, int *flags, VarPattern *patt)
return (NULL);
}
-/*-
- *-----------------------------------------------------------------------
- * Var_Quote --
- * Quote shell meta-characters in the string
- *
- * Results:
- * The quoted string
- *
- * Side Effects:
- * None.
- *
- *-----------------------------------------------------------------------
- */
-char *
-Var_Quote(const char *str)
-{
- Buffer *buf;
- /* This should cover most shells :-( */
- static char meta[] = "\n \t'`\";&<>()|*?{}[]\\$!#^~";
-
- buf = Buf_Init(MAKE_BSIZE);
- for (; *str; str++) {
- if (strchr(meta, *str) != NULL)
- Buf_AddByte(buf, (Byte)'\\');
- Buf_AddByte(buf, (Byte)*str);
- }
-
- return (Buf_Peel(buf));
-}
-
-/*-
- *-----------------------------------------------------------------------
- * VarREError --
- * Print the error caused by a regcomp or regexec call.
- *
- * Results:
- * None.
- *
- * Side Effects:
- * An error gets printed.
- *
- *-----------------------------------------------------------------------
- */
-void
-VarREError(int err, regex_t *pat, const char *str)
-{
- char *errbuf;
- int errlen;
-
- errlen = regerror(err, pat, 0, 0);
- errbuf = emalloc(errlen);
- regerror(err, pat, errbuf, errlen);
- Error("%s: %s", str, errbuf);
- free(errbuf);
-}
-
/**
* Make sure this variable is fully expanded.
*/
@@ -1167,6 +1688,30 @@ sysVvarsub(VarParser *vp, char startc, Var *v, const char value[])
return (newStr);
}
+/**
+ * Quote shell meta-characters in the string
+ *
+ * Results:
+ * The quoted string
+ */
+static char *
+Var_Quote(const char *str)
+{
+ Buffer *buf;
+ /* This should cover most shells :-( */
+ static char meta[] = "\n \t'`\";&<>()|*?{}[]\\$!#^~";
+
+ buf = Buf_Init(MAKE_BSIZE);
+ for (; *str; str++) {
+ if (strchr(meta, *str) != NULL)
+ Buf_AddByte(buf, (Byte)'\\');
+ Buf_AddByte(buf, (Byte)*str);
+ }
+
+ return (Buf_Peel(buf));
+}
+
+
/*
* Now we need to apply any modifiers the user wants applied.
* These are:
diff --git a/usr.bin/make/var.h b/usr.bin/make/var.h
index 986efe0..6de80d3 100644
--- a/usr.bin/make/var.h
+++ b/usr.bin/make/var.h
@@ -42,53 +42,9 @@
#ifndef var_h_9cccafce
#define var_h_9cccafce
-#include <regex.h>
-
-#include "config.h"
-
struct GNode;
struct Buffer;
-typedef struct Var {
- char *name; /* the variable's name */
- struct Buffer *val; /* its value */
- int flags; /* miscellaneous status flags */
-
-#define VAR_IN_USE 1 /* Variable's value currently being used.
- * Used to avoid recursion */
-
-#define VAR_JUNK 4 /* Variable is a junk variable that
- * should be destroyed when done with
- * it. Used by Var_Parse for undefined,
- * modified variables */
-
-#define VAR_TO_ENV 8 /* Place variable in environment */
-} Var;
-
-/* Var*Pattern flags */
-#define VAR_SUB_GLOBAL 0x01 /* Apply substitution globally */
-#define VAR_SUB_ONE 0x02 /* Apply substitution to one word */
-#define VAR_SUB_MATCHED 0x04 /* There was a match */
-#define VAR_MATCH_START 0x08 /* Match at start of word */
-#define VAR_MATCH_END 0x10 /* Match at end of word */
-
-typedef struct {
- struct Buffer *lhs; /* String to match */
- struct Buffer *rhs; /* Replacement string (w/ &'s removed) */
-
- regex_t re;
- int nsub;
- regmatch_t *matches;
-
- int flags;
-} VarPattern;
-
-typedef Boolean VarModifyProc(const char *, Boolean, struct Buffer *, void *);
-
-/*
- * var.c
- */
-void VarREError(int, regex_t *, const char *);
void Var_Append(const char *, const char *, struct GNode *);
void Var_Delete(const char *, struct GNode *);
void Var_Dump(void);
@@ -96,27 +52,10 @@ Boolean Var_Exists(const char *, struct GNode *);
void Var_Init(char **);
size_t Var_Match(const char [], struct GNode *);
char *Var_Parse(const char *, struct GNode *, Boolean, size_t *, Boolean *);
-char *Var_Quote(const char *);
void Var_Set(const char *, const char *, struct GNode *);
void Var_SetEnv(const char *, struct GNode *);
struct Buffer *Var_Subst(const char *, struct GNode *, Boolean);
struct Buffer *Var_SubstOnly(const char *, const char *, struct GNode *, Boolean);
char *Var_Value(const char *, struct GNode *, char **);
-/*
- * var_modify.c
- */
-VarModifyProc VarHead;
-VarModifyProc VarMatch;
-VarModifyProc VarNoMatch;
-VarModifyProc VarRESubstitute;
-VarModifyProc VarRoot;
-VarModifyProc VarSubstitute;
-VarModifyProc VarSuffix;
-VarModifyProc VarTail;
-
-#ifdef SYSVVARSUB
-VarModifyProc VarSYSVMatch;
-#endif
-
#endif /* var_h_9cccafce */
diff --git a/usr.bin/make/var_modify.c b/usr.bin/make/var_modify.c
deleted file mode 100644
index 5e30892..0000000
--- a/usr.bin/make/var_modify.c
+++ /dev/null
@@ -1,572 +0,0 @@
-/*-
- * Copyright (c) 2002 Juli Mallett.
- * Copyright (c) 1988, 1989, 1990, 1993
- * The Regents of the University of California. All rights reserved.
- * Copyright (c) 1989 by Berkeley Softworks
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Adam de Boor.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)var.c 8.3 (Berkeley) 3/19/94
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "buf.h"
-#include "config.h"
-#include "str.h"
-#include "util.h"
-#include "var.h"
-
-/**
- * VarHead
- * Remove the tail of the given word and place the result in the given
- * buffer.
- *
- * Results:
- * TRUE if characters were added to the buffer (a space needs to be
- * added to the buffer before the next word).
- *
- * Side Effects:
- * The trimmed word is added to the buffer.
- */
-Boolean
-VarHead(const char *word, Boolean addSpace, Buffer *buf, void *dummy __unused)
-{
- char *slash;
-
- slash = strrchr(word, '/');
- if (slash != NULL) {
- if (addSpace) {
- Buf_AddByte(buf, (Byte)' ');
- }
- Buf_AppendRange(buf, word, slash);
- } else {
- /*
- * If no directory part, give . (q.v. the POSIX standard)
- */
- if (addSpace) {
- Buf_Append(buf, " .");
- } else {
- Buf_AddByte(buf, (Byte)'.');
- }
- }
- return (TRUE);
-}
-
-/**
- * VarTail
- * Remove the head of the given word and place the result in the given
- * buffer.
- *
- * Results:
- * TRUE if characters were added to the buffer (a space needs to be
- * added to the buffer before the next word).
- *
- * Side Effects:
- * The trimmed word is added to the buffer.
- */
-Boolean
-VarTail(const char *word, Boolean addSpace, Buffer *buf, void *dummy __unused)
-{
- const char *slash;
-
- if (addSpace) {
- Buf_AddByte (buf, (Byte)' ');
- }
-
- slash = strrchr(word, '/');
- if (slash != NULL) {
- slash++;
- Buf_Append(buf, slash);
- } else {
- Buf_Append(buf, word);
- }
- return (TRUE);
-}
-
-/**
- * VarSuffix
- * Place the suffix of the given word in the given buffer.
- *
- * Results:
- * TRUE if characters were added to the buffer (a space needs to be
- * added to the buffer before the next word).
- *
- * Side Effects:
- * The suffix from the word is placed in the buffer.
- */
-Boolean
-VarSuffix(const char *word, Boolean addSpace, Buffer *buf, void *dummy __unused)
-{
- const char *dot;
-
- dot = strrchr(word, '.');
- if (dot != NULL) {
- if (addSpace) {
- Buf_AddByte(buf, (Byte)' ');
- }
- dot++;
- Buf_Append(buf, dot);
- addSpace = TRUE;
- }
- return (addSpace);
-}
-
-/**
- * VarRoot
- * Remove the suffix of the given word and place the result in the
- * buffer.
- *
- * Results:
- * TRUE if characters were added to the buffer (a space needs to be
- * added to the buffer before the next word).
- *
- * Side Effects:
- * The trimmed word is added to the buffer.
- */
-Boolean
-VarRoot(const char *word, Boolean addSpace, Buffer *buf, void *dummy __unused)
-{
- char *dot;
-
- if (addSpace) {
- Buf_AddByte(buf, (Byte)' ');
- }
-
- dot = strrchr(word, '.');
- if (dot != NULL) {
- Buf_AppendRange(buf, word, dot);
- } else {
- Buf_Append(buf, word);
- }
- return (TRUE);
-}
-
-/**
- * VarMatch
- * Place the word in the buffer if it matches the given pattern.
- * Callback function for VarModify to implement the :M modifier.
- * A space will be added if requested. A pattern is supplied
- * which the word must match.
- *
- * Results:
- * TRUE if a space should be placed in the buffer before the next
- * word.
- *
- * Side Effects:
- * The word may be copied to the buffer.
- */
-Boolean
-VarMatch(const char *word, Boolean addSpace, Buffer *buf, void *pattern)
-{
-
- if (Str_Match(word, pattern)) {
- if (addSpace) {
- Buf_AddByte(buf, (Byte)' ');
- }
- addSpace = TRUE;
- Buf_Append(buf, word);
- }
- return (addSpace);
-}
-
-#ifdef SYSVVARSUB
-/**
- * VarSYSVMatch
- * Place the word in the buffer if it matches the given pattern.
- * Callback function for VarModify to implement the System V %
- * modifiers. A space is added if requested.
- *
- * Results:
- * TRUE if a space should be placed in the buffer before the next
- * word.
- *
- * Side Effects:
- * The word may be copied to the buffer.
- */
-Boolean
-VarSYSVMatch(const char *word, Boolean addSpace, Buffer *buf, void *patp)
-{
- int len;
- const char *ptr;
- VarPattern *pat = (VarPattern *)patp;
-
- if (addSpace)
- Buf_AddByte(buf, (Byte)' ');
-
- addSpace = TRUE;
-
- if ((ptr = Str_SYSVMatch(word, Buf_Data(pat->lhs), &len)) != NULL)
- Str_SYSVSubst(buf, Buf_Data(pat->rhs), ptr, len);
- else
- Buf_Append(buf, word);
-
- return (addSpace);
-}
-#endif
-
-/**
- * VarNoMatch
- * Place the word in the buffer if it doesn't match the given pattern.
- * Callback function for VarModify to implement the :N modifier. A
- * space is added if requested.
- *
- * Results:
- * TRUE if a space should be placed in the buffer before the next
- * word.
- *
- * Side Effects:
- * The word may be copied to the buffer.
- */
-Boolean
-VarNoMatch(const char *word, Boolean addSpace, Buffer *buf, void *pattern)
-{
-
- if (!Str_Match(word, pattern)) {
- if (addSpace) {
- Buf_AddByte(buf, (Byte)' ');
- }
- addSpace = TRUE;
- Buf_Append(buf, word);
- }
- return (addSpace);
-}
-
-/**
- * VarSubstitute
- * Perform a string-substitution on the given word, placing the
- * result in the passed buffer. A space is added if requested.
- *
- * Results:
- * TRUE if a space is needed before more characters are added.
- */
-Boolean
-VarSubstitute(const char *word, Boolean addSpace, Buffer *buf, void *patternp)
-{
- size_t wordLen; /* Length of word */
- const char *cp; /* General pointer */
- VarPattern *pattern = patternp;
-
- wordLen = strlen(word);
- if (1) { /* substitute in each word of the variable */
- /*
- * Break substitution down into simple anchored cases
- * and if none of them fits, perform the general substitution
- * case.
- */
- if ((pattern->flags & VAR_MATCH_START) &&
- (strncmp(word, Buf_Data(pattern->lhs),
- Buf_Size(pattern->lhs)) == 0)) {
- /*
- * Anchored at start and beginning of word matches
- * pattern.
- */
- if ((pattern->flags & VAR_MATCH_END) &&
- (wordLen == Buf_Size(pattern->lhs))) {
- /*
- * Also anchored at end and matches to the end
- * (word is same length as pattern) add space
- * and rhs only if rhs is non-null.
- */
- if (Buf_Size(pattern->rhs) != 0) {
- if (addSpace) {
- Buf_AddByte(buf, (Byte)' ');
- }
- addSpace = TRUE;
- Buf_AppendBuf(buf, pattern->rhs);
- }
-
- } else if (pattern->flags & VAR_MATCH_END) {
- /*
- * Doesn't match to end -- copy word wholesale
- */
- goto nosub;
-
- } else {
- /*
- * Matches at start but need to copy in
- * trailing characters.
- */
- if ((Buf_Size(pattern->rhs) + wordLen -
- Buf_Size(pattern->lhs)) != 0) {
- if (addSpace) {
- Buf_AddByte(buf, (Byte)' ');
- }
- addSpace = TRUE;
- }
- Buf_AppendBuf(buf, pattern->rhs);
- Buf_AddBytes(buf, wordLen -
- Buf_Size(pattern->lhs),
- (word + Buf_Size(pattern->lhs)));
- }
-
- } else if (pattern->flags & VAR_MATCH_START) {
- /*
- * Had to match at start of word and didn't -- copy
- * whole word.
- */
- goto nosub;
-
- } else if (pattern->flags & VAR_MATCH_END) {
- /*
- * Anchored at end, Find only place match could occur
- * (leftLen characters from the end of the word) and
- * see if it does. Note that because the $ will be
- * left at the end of the lhs, we have to use strncmp.
- */
- cp = word + (wordLen - Buf_Size(pattern->lhs));
- if ((cp >= word) && (strncmp(cp, Buf_Data(pattern->lhs),
- Buf_Size(pattern->lhs)) == 0)) {
- /*
- * Match found. If we will place characters in
- * the buffer, add a space before hand as
- * indicated by addSpace, then stuff in the
- * initial, unmatched part of the word followed
- * by the right-hand-side.
- */
- if ((cp - word) + Buf_Size(pattern->rhs) != 0) {
- if (addSpace) {
- Buf_AddByte(buf, (Byte)' ');
- }
- addSpace = TRUE;
- }
- Buf_AppendRange(buf, word, cp);
- Buf_AppendBuf(buf, pattern->rhs);
-
- } else {
- /*
- * Had to match at end and didn't. Copy entire
- * word.
- */
- goto nosub;
- }
- } else {
- /*
- * Pattern is unanchored: search for the pattern in the
- * word using strstr(3), copying unmatched portions and
- * the right-hand-side for each match found, handling
- * non-global substitutions correctly, etc. When the
- * loop is done, any remaining part of the word (word
- * and wordLen are adjusted accordingly through the
- * loop) is copied straight into the buffer.
- * addSpace is set FALSE as soon as a space is added
- * to the buffer.
- */
- Boolean done;
- size_t origSize;
-
- done = FALSE;
- origSize = Buf_Size(buf);
- while (!done) {
- cp = strstr(word, Buf_Data(pattern->lhs));
- if (cp != NULL) {
- if (addSpace && (((cp - word) +
- Buf_Size(pattern->rhs)) != 0)) {
- Buf_AddByte(buf, (Byte)' ');
- addSpace = FALSE;
- }
- Buf_AppendRange(buf, word, cp);
- Buf_AppendBuf(buf, pattern->rhs);
- wordLen -= (cp - word) +
- Buf_Size(pattern->lhs);
- word = cp + Buf_Size(pattern->lhs);
- if (wordLen == 0 || (pattern->flags &
- VAR_SUB_GLOBAL) == 0) {
- done = TRUE;
- }
- } else {
- done = TRUE;
- }
- }
- if (wordLen != 0) {
- if (addSpace) {
- Buf_AddByte(buf, (Byte)' ');
- }
- Buf_AddBytes(buf, wordLen, (const Byte *)word);
- }
-
- /*
- * If added characters to the buffer, need to add a
- * space before we add any more. If we didn't add any,
- * just return the previous value of addSpace.
- */
- return ((Buf_Size(buf) != origSize) || addSpace);
- }
- /*
- * Common code for anchored substitutions:
- * addSpace was set TRUE if characters were added to the buffer.
- */
- return (addSpace);
- }
- nosub:
- if (addSpace) {
- Buf_AddByte(buf, (Byte)' ');
- }
- Buf_AddBytes(buf, wordLen, (const Byte *)word);
- return (TRUE);
-}
-
-/**
- * VarRESubstitute
- * Perform a regex substitution on the given word, placing the
- * result in the passed buffer. A space is added if requested.
- *
- * Results:
- * TRUE if a space is needed before more characters are added.
- */
-Boolean
-VarRESubstitute(const char *word, Boolean addSpace, Buffer *buf, void *patternp)
-{
- VarPattern *pat;
- int xrv;
- const char *wp;
- char *rp;
- int added;
- int flags = 0;
-
-#define MAYBE_ADD_SPACE() \
- if (addSpace && !added) \
- Buf_AddByte(buf, (Byte)' '); \
- added = 1
-
- added = 0;
- wp = word;
- pat = patternp;
-
- if ((pat->flags & (VAR_SUB_ONE | VAR_SUB_MATCHED)) ==
- (VAR_SUB_ONE | VAR_SUB_MATCHED)) {
- xrv = REG_NOMATCH;
- } else {
- tryagain:
- xrv = regexec(&pat->re, wp, pat->nsub, pat->matches, flags);
- }
-
- switch (xrv) {
- case 0:
- pat->flags |= VAR_SUB_MATCHED;
- if (pat->matches[0].rm_so > 0) {
- MAYBE_ADD_SPACE();
- Buf_AddBytes(buf, pat->matches[0].rm_so,
- (const Byte *)wp);
- }
-
- for (rp = Buf_Data(pat->rhs); *rp; rp++) {
- if ((*rp == '\\') && ((rp[1] == '&') || (rp[1] == '\\'))) {
- MAYBE_ADD_SPACE();
- Buf_AddByte(buf, (Byte)rp[1]);
- rp++;
-
- } else if ((*rp == '&') ||
- ((*rp == '\\') && isdigit((unsigned char)rp[1]))) {
- int n;
- const char *subbuf;
- int sublen;
- char errstr[3];
-
- if (*rp == '&') {
- n = 0;
- errstr[0] = '&';
- errstr[1] = '\0';
- } else {
- n = rp[1] - '0';
- errstr[0] = '\\';
- errstr[1] = rp[1];
- errstr[2] = '\0';
- rp++;
- }
-
- if (n > pat->nsub) {
- Error("No subexpression %s",
- &errstr[0]);
- subbuf = "";
- sublen = 0;
-
- } else if ((pat->matches[n].rm_so == -1) &&
- (pat->matches[n].rm_eo == -1)) {
- Error("No match for subexpression %s",
- &errstr[0]);
- subbuf = "";
- sublen = 0;
-
- } else {
- subbuf = wp + pat->matches[n].rm_so;
- sublen = pat->matches[n].rm_eo -
- pat->matches[n].rm_so;
- }
-
- if (sublen > 0) {
- MAYBE_ADD_SPACE();
- Buf_AddBytes(buf, sublen,
- (const Byte *)subbuf);
- }
- } else {
- MAYBE_ADD_SPACE();
- Buf_AddByte(buf, (Byte)*rp);
- }
- }
- wp += pat->matches[0].rm_eo;
- if (pat->flags & VAR_SUB_GLOBAL) {
- flags |= REG_NOTBOL;
- if (pat->matches[0].rm_so == 0 &&
- pat->matches[0].rm_eo == 0) {
- MAYBE_ADD_SPACE();
- Buf_AddByte(buf, (Byte)*wp);
- wp++;
- }
- if (*wp)
- goto tryagain;
- }
- if (*wp) {
- MAYBE_ADD_SPACE();
- Buf_Append(buf, wp);
- }
- break;
-
- default:
- VarREError(xrv, &pat->re, "Unexpected regex error");
- /* fall through */
-
- case REG_NOMATCH:
- if (*wp) {
- MAYBE_ADD_SPACE();
- Buf_Append(buf, wp);
- }
- break;
- }
- return (addSpace || added);
-}
OpenPOWER on IntegriCloud