Module Name:    src
Committed By:   rillig
Date:           Sun Apr 11 17:48:01 UTC 2021

Modified Files:
        src/usr.bin/make: var.c

Log Message:
make: migrate handling of the modifier ':S,from,to,' to Substring

Right now this does not gain any performance, it only makes the code in
ModifyWord_Subst a little simpler since it only uses
Buf_AddBytesBetween, not a mixture with Buf_AddBytes.

When the word passed to the ModifyWord functions is converted to
Substring as well, the call to strlen will become redundant.

No functional change.


To generate a diff of this commit:
cvs rdiff -u -r1.917 -r1.918 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.917 src/usr.bin/make/var.c:1.918
--- src/usr.bin/make/var.c:1.917	Sun Apr 11 13:35:56 2021
+++ src/usr.bin/make/var.c	Sun Apr 11 17:48:01 2021
@@ -1,4 +1,4 @@
-/*	$NetBSD: var.c,v 1.917 2021/04/11 13:35:56 rillig Exp $	*/
+/*	$NetBSD: var.c,v 1.918 2021/04/11 17:48:01 rillig Exp $	*/
 
 /*
  * Copyright (c) 1988, 1989, 1990, 1993
@@ -140,7 +140,7 @@
 #include "metachar.h"
 
 /*	"@(#)var.c	8.3 (Berkeley) 3/19/94" */
-MAKE_RCSID("$NetBSD: var.c,v 1.917 2021/04/11 13:35:56 rillig Exp $");
+MAKE_RCSID("$NetBSD: var.c,v 1.918 2021/04/11 17:48:01 rillig Exp $");
 
 /*
  * Variables are defined using one of the VAR=value assignments.  Their
@@ -1541,14 +1541,25 @@ ModifyWord_SYSVSubst(const char *word, S
 
 
 struct ModifyWord_SubstArgs {
-	const char *lhs;
-	size_t lhsLen;
-	const char *rhs;
-	size_t rhsLen;
+	Substring lhs;
+	Substring rhs;
 	VarPatternFlags pflags;
 	bool matched;
 };
 
+static const char *
+Substring_Find(Substring haystack, Substring needle)
+{
+	size_t len, needleLen, i;
+
+	len = Substring_Length(haystack);
+	needleLen = Substring_Length(needle);
+	for (i = 0; i + needleLen <= len; i++)
+		if (memcmp(haystack.start + i, needle.start, needleLen) == 0)
+			return haystack.start + i;
+	return NULL;
+}
+
 /*
  * Callback for ModifyWords to implement the :S,from,to, modifier.
  * Perform a string substitution on the given word.
@@ -1556,61 +1567,59 @@ struct ModifyWord_SubstArgs {
 static void
 ModifyWord_Subst(const char *word, SepBuf *buf, void *data)
 {
-	size_t wordLen = strlen(word);
 	struct ModifyWord_SubstArgs *args = data;
-	const char *match;
+	size_t wordLen, lhsLen;
+	const char *wordEnd, *match;
 
+	wordLen = strlen(word);
+	wordEnd = word + wordLen;
 	if (args->pflags.subOnce && args->matched)
 		goto nosub;
 
+	lhsLen = Substring_Length(args->lhs);
 	if (args->pflags.anchorStart) {
-		if (wordLen < args->lhsLen ||
-		    memcmp(word, args->lhs, args->lhsLen) != 0)
+		if (wordLen < lhsLen ||
+		    memcmp(word, args->lhs.start, lhsLen) != 0)
 			goto nosub;
 
-		if (args->pflags.anchorEnd && wordLen != args->lhsLen)
+		if (args->pflags.anchorEnd && wordLen != lhsLen)
 			goto nosub;
 
 		/* :S,^prefix,replacement, or :S,^whole$,replacement, */
-		SepBuf_AddBytes(buf, args->rhs, args->rhsLen);
-		SepBuf_AddBytesBetween(buf,
-		    word + args->lhsLen, word + wordLen);
+		SepBuf_AddBytesBetween(buf, args->rhs.start, args->rhs.end);
+		SepBuf_AddBytesBetween(buf, word + lhsLen, wordEnd);
 		args->matched = true;
 		return;
 	}
 
 	if (args->pflags.anchorEnd) {
-		const char *start;
-
-		if (wordLen < args->lhsLen)
+		if (wordLen < lhsLen)
 			goto nosub;
-
-		start = word + (wordLen - args->lhsLen);
-		if (memcmp(start, args->lhs, args->lhsLen) != 0)
+		if (memcmp(wordEnd - lhsLen, args->lhs.start, lhsLen) != 0)
 			goto nosub;
 
 		/* :S,suffix$,replacement, */
-		SepBuf_AddBytesBetween(buf, word, start);
-		SepBuf_AddBytes(buf, args->rhs, args->rhsLen);
+		SepBuf_AddBytesBetween(buf, word, wordEnd - lhsLen);
+		SepBuf_AddBytesBetween(buf, args->rhs.start, args->rhs.end);
 		args->matched = true;
 		return;
 	}
 
-	if (args->lhs[0] == '\0')
+	if (args->lhs.start[0] == '\0')
 		goto nosub;
 
 	/* unanchored case, may match more than once */
-	while ((match = strstr(word, args->lhs)) != NULL) {
+	while ((match = Substring_Find(Substring_Init(word, wordEnd),
+	    args->lhs)) != NULL) {
 		SepBuf_AddBytesBetween(buf, word, match);
-		SepBuf_AddBytes(buf, args->rhs, args->rhsLen);
+		SepBuf_AddBytesBetween(buf, args->rhs.start, args->rhs.end);
 		args->matched = true;
-		wordLen -= (size_t)(match - word) + args->lhsLen;
-		word += (size_t)(match - word) + args->lhsLen;
-		if (wordLen == 0 || !args->pflags.subGlobal)
+		word += (size_t)(match - word) + lhsLen;
+		if (word == wordEnd || !args->pflags.subGlobal)
 			break;
 	}
 nosub:
-	SepBuf_AddBytes(buf, word, wordLen);
+	SepBuf_AddBytesBetween(buf, word, wordEnd);
 }
 
 #ifndef NO_REGEX
@@ -2189,9 +2198,9 @@ ParseModifierPartSubst(
     VarEvalMode emode,
     ModChain *ch,
     char **out_part,
-    /* Optionally stores the length of the returned string, just to save
+    /* Optionally stores the end of the returned string, just to save
      * another strlen call. */
-    size_t *out_length,
+    const char **out_part_end,
     /* For the first part of the :S modifier, sets the VARP_ANCHOR_END flag
      * if the last character of the pattern is a $. */
     VarPatternFlags *out_pflags,
@@ -2221,7 +2230,8 @@ ParseModifierPartSubst(
 
 		if (*p != '$') {	/* Unescaped, simple text */
 			if (subst != NULL && *p == '&')
-				Buf_AddBytes(&buf, subst->lhs, subst->lhsLen);
+				Buf_AddBytesBetween(&buf,
+				    subst->lhs.start, subst->lhs.end);
 			else
 				Buf_AddByte(&buf, *p);
 			p++;
@@ -2299,8 +2309,8 @@ ParseModifierPartSubst(
 	}
 
 	*pp = p + 1;
-	if (out_length != NULL)
-		*out_length = buf.len;
+	if (out_part_end != NULL)
+		*out_part_end = buf.data + buf.len;
 
 	*out_part = Buf_DoneData(&buf);
 	DEBUG1(VAR, "Modifier part: \"%s\"\n", *out_part);
@@ -2931,16 +2941,16 @@ ApplyModifier_Subst(const char **pp, Mod
 	}
 
 	res = ParseModifierPartSubst(pp, delim, ch->expr->emode, ch, &lhs,
-	    &args.lhsLen, &args.pflags, NULL);
+	    &args.lhs.end, &args.pflags, NULL);
 	if (res != VPR_OK)
 		return AMR_CLEANUP;
-	args.lhs = lhs;
+	args.lhs.start = lhs;
 
 	res = ParseModifierPartSubst(pp, delim, ch->expr->emode, ch, &rhs,
-	    &args.rhsLen, NULL, &args);
+	    &args.rhs.end, NULL, &args);
 	if (res != VPR_OK)
 		return AMR_CLEANUP;
-	args.rhs = rhs;
+	args.rhs.start = rhs;
 
 	oneBigWord = ch->oneBigWord;
 	ParsePatternFlags(pp, &args.pflags, &oneBigWord);

Reply via email to