From 2552a55b8082ebf502cc4dd3b406258ee0977fea Mon Sep 17 00:00:00 2001 From: Dmitry Mikhirev Date: Thu, 18 Dec 2014 14:55:55 +0300 Subject: expand replacement string just before substitution, after vars set --- README.md | 14 ++++++++------ pcre.c | 31 ++++++++++++++++++++----------- tests.mk | 6 +++++- 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 8b2bcae..77359e2 100644 --- a/README.md +++ b/README.md @@ -51,9 +51,9 @@ pattern instead substring as first argument: $(pcre_find PATTERN,IN) $(m PATTERN,IN) -It searches IN for matching PATTERN. If it occurs, the matched substring is -returned; otherwise returned string is empty. Note that normally PATTERN is -not expanded, but IN is expanded before search. +It searches *IN* for matching *PATTERN*. If it occurs, the matched substring is +returned; otherwise returned string is empty. Note that normally *PATTERN* is +not expanded, but *IN* is expanded before search. ### `pcre_subst` function ### @@ -63,9 +63,11 @@ instead substring as first argument: $(pcre_subst PATTERN,REPLACEMENT,TEXT) $(s PATTERN,REPLACEMENT,TEXT) -It searches TEXT for matching PATTERN. If it occurs, the matched substring is -replaced with REPLACEMENT, and the resulting string is returned. If pattern -does not match, TEXT is returned unchanged. +It searches *TEXT* for matching *PATTERN*. If it occurs, the matched substring +is replaced with *REPLACEMENT*, and the resulting string is returned. If pattern +does not match, *TEXT* is returned unchanged. *PATTERN* is not expanded by default, +*TEXT* is expanded before search, and *REPLACEMENT* string is expanded just before +substitution. Capturing strings ----------------- diff --git a/pcre.c b/pcre.c index ffb9aee..5e932df 100644 --- a/pcre.c +++ b/pcre.c @@ -424,6 +424,7 @@ char *subst(const char *name, int argc, char **argv) int erroffset; /* offset in pattern where error occured */ pcre_extra *sd = NULL; /* pattern study data */ char *str = NULL; /* expanded subject string */ + char *rep = NULL; /* expanded replacement string */ int subjlen; /* length of subject string */ int replen; /* length of replacement string */ int offset = 0; /* subject string offset */ @@ -471,9 +472,7 @@ char *subst(const char *name, int argc, char **argv) /* expand subject string */ str = gmk_expand(argv[2]); - subjlen = strlen(str); - replen = strlen(argv[1]); do { /* execute regexp */ @@ -484,7 +483,16 @@ char *subst(const char *name, int argc, char **argv) goto end_subst; } - if (ncap > 0) { + if (ncap > 0) { /* match found */ + /* set make vars to captured substrings */ + set_vars(str, ovec, ncap); + /* set named make vars to captured substrings */ + set_named_vars(re, str, ovec, ncap); + + /* expand replacement string */ + rep = gmk_expand(argv[1]); + replen = strlen(rep); + newlen = retlen + (ovec[0] - offset) + replen; s = str_extend(retstr, newlen + 1); if (s == NULL) { @@ -493,14 +501,15 @@ char *subst(const char *name, int argc, char **argv) retstr = s; strncpy(retstr + retlen, str + offset, ovec[0] - offset); - strncpy(retstr + retlen + ovec[0] - offset, argv[1], replen + 1); + strncpy(retstr + retlen + ovec[0] - offset, rep, replen + 1); retlen += ovec[0] - offset + replen; + /* free expanded replacement string */ + gmk_free(rep); + rep = NULL; + /* where to start next search */ offset = ovec[1]; - - /* set named make vars to captured substrings */ - set_named_vars(re, str, ovec, ncap); } } while (global && (ncap != PCRE_ERROR_NOMATCH)); @@ -524,14 +533,14 @@ end_subst: #endif } - /* set make vars to captured substrings */ - set_vars(str, ovec, ncap); - if (str != NULL) { gmk_free(str); } - return retstr; + if (rep != NULL) { + gmk_free(rep); + } + return retstr; } int pcre_gmk_setup() diff --git a/tests.mk b/tests.mk index 10e34c8..3f40808 100644 --- a/tests.mk +++ b/tests.mk @@ -2,7 +2,7 @@ ifneq ($(findstring 4.,$(MAKE_VERSION)),4.) $(error you need GNU make 4.x to run tests) endif -NUMTESTS = 23 +NUMTESTS = 25 tests := $(foreach num,$(shell seq -f%03g $(NUMTESTS)),test$(num)) load pcre.so @@ -74,6 +74,10 @@ test021 = "$(s aaa,x,dcbaaa)" = "dcbx" test022 = "$(s aaa,x,aaabbaaa,g)" = "xbbx" test023 = "$(s a,x,aaa,g)" = "xxx" +# test expansion of substituted string +test024 = "$(s a(.),$(1),aaabac,g)" = "abc" +test025 = "$(s (?.)a,$(var),aabaca,g)" = "abc" + ### END OF TEST EXPRESSIONS ### test%: -- cgit v1.2.1