1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-06 13:09:50 +00:00

Fix the :S modifier to substitute in each word of the variable, according

to the description in the manpage. g flag means "replace every occurence
in each word", and its absence means "replace first occurence in each word".
Previously, absence of the g flag was implemented to mean "replace first
occurence found in all words, and then stop replacing", which was incorrect.
This commit is contained in:
Adam David 1995-11-01 12:18:32 +00:00
parent 74e1c9782c
commit 56c78cb71a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=11997

View File

@ -147,7 +147,6 @@ typedef struct {
#define VAR_SUB_GLOBAL 1 /* Apply substitution globally */ #define VAR_SUB_GLOBAL 1 /* Apply substitution globally */
#define VAR_MATCH_START 2 /* Match at start of word */ #define VAR_MATCH_START 2 /* Match at start of word */
#define VAR_MATCH_END 4 /* Match at end of word */ #define VAR_MATCH_END 4 /* Match at end of word */
#define VAR_NO_SUB 8 /* Substitution is non-global and already done */
} VarPattern; } VarPattern;
static int VarCmp __P((ClientData, ClientData)); static int VarCmp __P((ClientData, ClientData));
@ -883,9 +882,9 @@ VarSubstitute (word, addSpace, buf, patternp)
VarPattern *pattern = (VarPattern *) patternp; VarPattern *pattern = (VarPattern *) patternp;
wordLen = strlen(word); wordLen = strlen(word);
if ((pattern->flags & VAR_NO_SUB) == 0) { if (1) { /* substitute in each word of the variable */
/* /*
* Still substituting -- break it down into simple anchored cases * Break substitution down into simple anchored cases
* and if none of them fits, perform the general substitution case. * and if none of them fits, perform the general substitution case.
*/ */
if ((pattern->flags & VAR_MATCH_START) && if ((pattern->flags & VAR_MATCH_START) &&
@ -967,7 +966,7 @@ VarSubstitute (word, addSpace, buf, patternp)
* Pattern is unanchored: search for the pattern in the word using * Pattern is unanchored: search for the pattern in the word using
* String_FindSubstring, copying unmatched portions and the * String_FindSubstring, copying unmatched portions and the
* right-hand-side for each match found, handling non-global * right-hand-side for each match found, handling non-global
* subsititutions correctly, etc. When the loop is done, any * substitutions correctly, etc. When the loop is done, any
* remaining part of the word (word and wordLen are adjusted * remaining part of the word (word and wordLen are adjusted
* accordingly through the loop) is copied straight into the * accordingly through the loop) is copied straight into the
* buffer. * buffer.
@ -990,13 +989,9 @@ VarSubstitute (word, addSpace, buf, patternp)
Buf_AddBytes(buf, pattern->rightLen, (Byte *)pattern->rhs); Buf_AddBytes(buf, pattern->rightLen, (Byte *)pattern->rhs);
wordLen -= (cp - word) + pattern->leftLen; wordLen -= (cp - word) + pattern->leftLen;
word = cp + pattern->leftLen; word = cp + pattern->leftLen;
if (wordLen == 0) { if (wordLen == 0 || (pattern->flags & VAR_SUB_GLOBAL) == 0){
done = TRUE; done = TRUE;
} }
if ((pattern->flags & VAR_SUB_GLOBAL) == 0) {
done = TRUE;
pattern->flags |= VAR_NO_SUB;
}
} else { } else {
done = TRUE; done = TRUE;
} }
@ -1015,14 +1010,9 @@ VarSubstitute (word, addSpace, buf, patternp)
return ((Buf_Size(buf) != origSize) || addSpace); return ((Buf_Size(buf) != origSize) || addSpace);
} }
/* /*
* Common code for anchored substitutions: if performed a substitution * Common code for anchored substitutions:
* and it's not supposed to be global, mark the pattern as requiring * addSpace was set TRUE if characters were added to the buffer.
* no more substitutions. addSpace was set TRUE if characters were
* added to the buffer.
*/ */
if ((pattern->flags & VAR_SUB_GLOBAL) == 0) {
pattern->flags |= VAR_NO_SUB;
}
return (addSpace); return (addSpace);
} }
nosub: nosub: