From 7fd9fe181150f166a098eaf4e006f878c28cb770 Mon Sep 17 00:00:00 2001 From: Gluzskiy Alexandr Date: Mon, 15 Feb 2010 05:51:01 +0300 Subject: sort --- Utilities/PCRE/pcre_subst/pcre_subst.c | 191 +++++++++++++++++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 Utilities/PCRE/pcre_subst/pcre_subst.c (limited to 'Utilities/PCRE/pcre_subst/pcre_subst.c') diff --git a/Utilities/PCRE/pcre_subst/pcre_subst.c b/Utilities/PCRE/pcre_subst/pcre_subst.c new file mode 100644 index 0000000..3f34f97 --- /dev/null +++ b/Utilities/PCRE/pcre_subst/pcre_subst.c @@ -0,0 +1,191 @@ +/************************************************* +* PCRE string replacement * +*************************************************/ + +/* +PCRE is a library of functions to support regular expressions whose syntax +and semantics are as close as possible to those of the Perl 5 language. +pcre_subst is a wrapper around pcre_exec designed to make it easier to +perform PERL style replacements with PCRE. + +Written by: Bert Driehuis + + Copyright (c) 2000 Bert Driehuis + +----------------------------------------------------------------------------- +Permission is granted to anyone to use this software for any purpose on any +computer system, and to redistribute it freely, subject to the following +restrictions: + +1. This software is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +2. The origin of this software must not be misrepresented, either by + explicit claim or by omission. + +3. Altered versions must be plainly marked as such, and must not be + misrepresented as being the original software. + +4. If PCRE is embedded in any software that is released under the GNU + General Purpose Licence (GPL), then the terms of that licence shall + supersede any condition above with which it is incompatible. +*/ + +#include +#include +#include +#include +#include "pcre_subst.h" + +#define MAXCAPTURE 50 + +#ifdef DEBUG_PCRE_SUBST +static void +dumpstr(const char *str, int len, int start, int end) +{ + int i; + for (i = 0; i < strlen(str); i++) { + if (i >= start && i < end) + putchar(str[i]); + else + putchar('-'); + } + putchar('\n'); +} + +static void +dumpmatch(const char *str, int len, const char *rep, int nmat, const int *ovec) +{ + int i; + printf("%s Input\n", str); + printf("nmat=%d", nmat); + for (i = 0; i < nmat * 2; i++) + printf(" %d", ovec[i]); + printf("\n"); + for (i = 0; i < nmat * 2; i += 2) + dumpstr(str, len, ovec[i], ovec[i+1]); + printf("\n"); +} +#endif + +static int +findreplen(const char *rep, int nmat, const int *replen) +{ + int len = 0; + int val; + char *cp = (char *)rep; + while(*cp) { + if (*cp == '$' && isdigit(cp[1])) { + val = strtoul(&cp[1], &cp, 10); + if (val && val <= nmat + 1) + len += replen[val -1]; + else + fprintf(stderr, "repl %d out of range\n", val); + } else { + cp++; + len++; + } + } + return len; +} + +static void +doreplace(char *out, const char *rep, int nmat, int *replen, const char **repstr) +{ + int val; + char *cp = (char *)rep; + while(*cp) { + if (*cp == '$' && isdigit(cp[1])) { + val = strtoul(&cp[1], &cp, 10); + if (val && val <= nmat + 1) { + strncpy(out, repstr[val - 1], replen[val - 1]); + out += replen[val -1]; + } + } else { + *out++ = *cp++; + } + } +} + +static char * +edit(const char *str, int len, const char *rep, int nmat, const int *ovec) +{ + int i, slen, rlen; + const int *mvec = ovec; + char *res, *cp; + int replen[MAXCAPTURE]; + const char *repstr[MAXCAPTURE]; + nmat--; + ovec += 2; + for (i = 0; i < nmat; i++) { + replen[i] = ovec[i * 2 + 1] - ovec[i * 2]; + repstr[i] = &str[ovec[i * 2]]; +#ifdef DEBUG_PCRE_SUBST + printf(">>>%d %d %.*s\n", i, replen[i], replen[i], repstr[i]); +#endif + } + slen = len; + len -= mvec[1] - mvec[0]; + len += rlen = findreplen(rep, nmat, replen); +#ifdef DEBUG_PCRE_SUBST + printf("resulting length %d (srclen=%d)\n", len, slen); +#endif + cp = res = pcre_malloc(len + 1); + if (mvec[0] > 0) { + strncpy(cp, str, mvec[0]); + cp += mvec[0]; + } + doreplace(cp, rep, nmat, replen, repstr); + cp += rlen; + if (mvec[1] < slen) + strcpy(cp, &str[mvec[1]]); + res[len] = 0; + return res; +} + +char * +pcre_subst(const pcre *ppat, const pcre_extra *extra, const char *str, int len, + int offset, int options, const char *rep) +{ + int nmat; + int ovec[MAXCAPTURE * 3]; + nmat = pcre_exec(ppat, extra, str, len, offset, options, + ovec, sizeof(ovec)); +#ifdef DEBUG_PCRE_SUBST + dumpmatch(str, len, rep, nmat, ovec); +#endif + if (nmat <= 0) + return NULL; + return(edit(str, len, rep, nmat, ovec)); +} + +#ifdef DEBUG_BUILD +int +main() +{ + char *pat = "quick\\s(\\w+)\\s(fox)"; + char *rep = "$1ish $2"; + char *str = "The quick brown foxy"; + char *newstr; + const char *err; + int erroffset; + pcre_extra *extra; + pcre *ppat = pcre_compile(pat, 0, &err, &erroffset, NULL); + if (ppat == NULL) { + fprintf(stderr, "%s at %d\n", err, erroffset); + exit(1); + } + extra = pcre_study(ppat, 0, &err); + if (err != NULL) + fprintf(stderr, "Study %s failed: %s\n", pat, err); + newstr = pcre_subst(ppat, extra, str, strlen(str), 0, 0, rep); + if (newstr) { + printf("Newstr\t%s\n", newstr); + pcre_free(newstr); + } else { + printf("No match\n"); + } + return 0; +} +#endif -- cgit v1.2.3