aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Mikhirev2014-11-18 15:56:35 +0300
committerDmitry Mikhirev2014-11-18 15:56:35 +0300
commit878c75eb60a06d12e283c6e84b9cc214db2cbad3 (patch)
tree911228f396d04a26a89d753de849582ea1f908b2
parent210a0a1c5c186fdafaa0847ae259698c557cb2bb (diff)
downloadmake_pcre-878c75eb60a06d12e283c6e84b9cc214db2cbad3.tar.gz
make_pcre-878c75eb60a06d12e283c6e84b9cc214db2cbad3.tar.bz2
make_pcre-878c75eb60a06d12e283c6e84b9cc214db2cbad3.tar.xz
make_pcre-878c75eb60a06d12e283c6e84b9cc214db2cbad3.zip
capture named substrings
-rw-r--r--GNUmakefile5
-rw-r--r--pcre.c39
2 files changed, 41 insertions, 3 deletions
diff --git a/GNUmakefile b/GNUmakefile
index 3557b15..1452ca8 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -1,7 +1,7 @@
MAKE_INCLUDE := -I$(HOME)/src/make-4.1
CFLAGS = -Wall
-tests = test001 test002 test003
+tests = test001 test002 test003 test004
-load pcre.so
@@ -28,6 +28,9 @@ test002 = '$(m ^t$(var)t$$,test,E)' = test
# test for string capturing by number
test003 = '$(m ^t(es)t$,test)$0$1' = testtestes -a -z '$(m a,b)$0$1'
+# test named string capturing
+test004 = '$(m ^t(?<var>es)t$,test)' = test -a '$(var)' = es
+
### END OF TEST EXPRESSIONS ###
diff --git a/pcre.c b/pcre.c
index 3a4366e..5900c96 100644
--- a/pcre.c
+++ b/pcre.c
@@ -27,6 +27,36 @@ int plugin_is_GPL_compatible;
const int MAX_CAP = 256; /* maximum number of substrings to capture */
const int MAX_CAP_LEN = 3; /* number of decimal digits in MAX_CAP */
+/* set_named_vars() - set make variables to substrings captured by name */
+int set_named_vars(const pcre *re, const char *subj, int *ovec, const int ncap)
+{
+ int ncount; /* name count */
+ int nentrysize; /* size of name entry */
+ char *ntable; /* name table */
+ int i; /* loop iterator */
+ char *n; /* name pointer */
+ const char *cap; /* captured substring */
+ int caplen; /* length of captured substring */
+
+ pcre_fullinfo(re, NULL, PCRE_INFO_NAMECOUNT, &ncount);
+ if (ncount <= 0) { /* no names defined, nothing to do */
+ return ncount;
+ }
+ pcre_fullinfo(re, NULL, PCRE_INFO_NAMEENTRYSIZE, &nentrysize);
+ pcre_fullinfo(re, NULL, PCRE_INFO_NAMETABLE, &ntable);
+ for (i = 0; i < ncount; i++) {
+ n = ntable + (i * nentrysize) + 2;
+ caplen = pcre_get_named_substring(re, subj, ovec, ncap, n, &cap);
+ if (caplen < 0) { /* unable to get substring */
+ continue;
+ }
+ char mk_set[strlen(n) + caplen + 16];
+ sprintf(mk_set, "define %s\n%s\nendef\n", n, cap);
+ gmk_eval(mk_set, NULL);
+ }
+ return i;
+}
+
/* match() - function to be attached to make pattern matching function */
char *match(const char *name, int argc, char **argv)
{
@@ -116,18 +146,23 @@ char *match(const char *name, int argc, char **argv)
/* expand subject string and execute regexp */
str = gmk_expand(argv[1]);
ncap = pcre_exec(re, NULL, str, strlen(str), 0, 0, ovec, MAX_CAP*3);
- pcre_free(re);
if ((ncap < 0) && (ncap != PCRE_ERROR_NOMATCH)) { /* error occured */
fprintf(stderr, "%s: pattern matching error: %d\n", name, ncap);
}
-end_match:
if (ncap > 0) { /* set retstr to matched substring */
int len = ovec[1] - ovec[0];
retstr = gmk_alloc(len + 1);
strncpy(retstr, str + ovec[0], len);
retstr[len] = '\0';
+
+ /* set named make vars to captured substrings */
+ set_named_vars(re, str, ovec, ncap);
}
+
+ pcre_free(re);
+
+end_match:
for (i = 0; (i < ncap) && (i < MAX_CAP); i++) { /* set make vars to captured substrings */
char c = *(str + ovec[i*2 + 1]);
*(str + ovec[i*2 + 1]) = '\0';