Module Name: src Committed By: rillig Date: Mon Jul 20 15:10:35 UTC 2020
Modified Files: src/usr.bin/make: var.c Log Message: make(1): make implementation of the :S modifier simpler To generate a diff of this commit: cvs rdiff -u -r1.278 -r1.279 src/usr.bin/make/var.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/make/var.c diff -u src/usr.bin/make/var.c:1.278 src/usr.bin/make/var.c:1.279 --- src/usr.bin/make/var.c:1.278 Mon Jul 20 14:50:41 2020 +++ src/usr.bin/make/var.c Mon Jul 20 15:10:35 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: var.c,v 1.278 2020/07/20 14:50:41 rillig Exp $ */ +/* $NetBSD: var.c,v 1.279 2020/07/20 15:10:35 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -69,14 +69,14 @@ */ #ifndef MAKE_NATIVE -static char rcsid[] = "$NetBSD: var.c,v 1.278 2020/07/20 14:50:41 rillig Exp $"; +static char rcsid[] = "$NetBSD: var.c,v 1.279 2020/07/20 15:10:35 rillig Exp $"; #else #include <sys/cdefs.h> #ifndef lint #if 0 static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 3/19/94"; #else -__RCSID("$NetBSD: var.c,v 1.278 2020/07/20 14:50:41 rillig Exp $"); +__RCSID("$NetBSD: var.c,v 1.279 2020/07/20 15:10:35 rillig Exp $"); #endif #endif /* not lint */ #endif @@ -1351,96 +1351,55 @@ static void VarSubstitute(GNode *ctx MAKE_ATTR_UNUSED, const char *word, SepBuf *buf, void *data) { - int wordLen = strlen(word); - const char *cp; /* General pointer */ + size_t wordLen = strlen(word); VarPattern *pattern = data; + const VarPatternFlags pflags = pattern->pflags; - if ((pattern->pflags & (VARP_SUB_ONE | VARP_SUB_MATCHED)) != - (VARP_SUB_ONE | VARP_SUB_MATCHED)) { - /* - * Still substituting -- break it down into simple anchored cases - * and if none of them fits, perform the general substitution case. - */ - if ((pattern->pflags & VARP_MATCH_START) && - (strncmp(word, pattern->lhs, pattern->leftLen) == 0)) { - /* - * Anchored at start and beginning of word matches pattern - */ - if ((pattern->pflags & VARP_MATCH_END) && - (wordLen == pattern->leftLen)) { - /* - * Also anchored at end and matches to the end (word - * is same length as pattern). - */ - SepBuf_AddBytes(buf, pattern->rhs, pattern->rightLen); - pattern->pflags |= VARP_SUB_MATCHED; - } else if (pattern->pflags & VARP_MATCH_END) { - /* - * Doesn't match to end -- copy word wholesale - */ - goto nosub; - } else { - /* - * Matches at start but need to copy in trailing characters - */ - SepBuf_AddBytes(buf, pattern->rhs, pattern->rightLen); - SepBuf_AddBytes(buf, word + pattern->leftLen, - wordLen - pattern->leftLen); - pattern->pflags |= VARP_SUB_MATCHED; - } - } else if (pattern->pflags & VARP_MATCH_START) { - /* - * Had to match at start of word and didn't -- copy whole word. - */ + if ((pflags & (VARP_SUB_ONE | VARP_SUB_MATCHED)) == + (VARP_SUB_ONE | VARP_SUB_MATCHED)) + goto nosub; + + if (pattern->pflags & VARP_MATCH_START) { + if (strncmp(word, pattern->lhs, pattern->leftLen) != 0) goto nosub; - } else if (pattern->pflags & VARP_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 - pattern->leftLen); - if (cp >= word && - strncmp(cp, pattern->lhs, pattern->leftLen) == 0) { - /* - * Match found. Stuff in the initial, unmatched part of the - * word followed by the right-hand-side. - */ - SepBuf_AddBytes(buf, word, cp - word); - SepBuf_AddBytes(buf, pattern->rhs, pattern->rightLen); - pattern->pflags |= VARP_SUB_MATCHED; - } else { - /* - * Had to match at end and didn't. Copy entire word. - */ + + if (pattern->pflags & VARP_MATCH_END) { + if (wordLen != (size_t)pattern->leftLen) goto nosub; - } + + SepBuf_AddBytes(buf, pattern->rhs, pattern->rightLen); + pattern->pflags |= VARP_SUB_MATCHED; } else { - /* - * Pattern is unanchored: search for the pattern in the word using - * String_FindSubstring, 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. - */ - while ((cp = Str_FindSubstring(word, pattern->lhs)) != NULL) { - SepBuf_AddBytes(buf, word, cp - word); - SepBuf_AddBytes(buf, pattern->rhs, pattern->rightLen); - wordLen -= (cp - word) + pattern->leftLen; - word = cp + pattern->leftLen; - if (wordLen == 0) - break; - if ((pattern->pflags & VARP_SUB_GLOBAL) == 0) - break; - pattern->pflags |= VARP_SUB_MATCHED; - } - SepBuf_AddBytes(buf, word, wordLen); + SepBuf_AddBytes(buf, pattern->rhs, pattern->rightLen); + SepBuf_AddBytes(buf, word + pattern->leftLen, + wordLen - pattern->leftLen); + pattern->pflags |= VARP_SUB_MATCHED; } return; } + + if (pattern->pflags & VARP_MATCH_END) { + const char *cp = word + (wordLen - pattern->leftLen); + if (cp < word || strncmp(cp, pattern->lhs, pattern->leftLen) != 0) + goto nosub; + + SepBuf_AddBytes(buf, word, cp - word); + SepBuf_AddBytes(buf, pattern->rhs, pattern->rightLen); + pattern->pflags |= VARP_SUB_MATCHED; + return; + } + + /* unanchored */ + const char *cp; + while ((cp = Str_FindSubstring(word, pattern->lhs)) != NULL) { + SepBuf_AddBytes(buf, word, cp - word); + SepBuf_AddBytes(buf, pattern->rhs, pattern->rightLen); + wordLen -= (cp - word) + pattern->leftLen; + word = cp + pattern->leftLen; + if (wordLen == 0 || !(pattern->pflags & VARP_SUB_GLOBAL)) + break; + pattern->pflags |= VARP_SUB_MATCHED; + } nosub: SepBuf_AddBytes(buf, word, wordLen); }