#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "pcre.h"
#include "pcre_internal.h"
#include "pcreposix.h"
static const int eint[] = {
0,
PCRE_REG_EESCAPE,
PCRE_REG_EESCAPE,
PCRE_REG_EESCAPE,
PCRE_REG_BADBR,
PCRE_REG_BADBR,
PCRE_REG_EBRACK,
PCRE_REG_ECTYPE,
PCRE_REG_ERANGE,
PCRE_REG_BADRPT,
PCRE_REG_BADRPT,
PCRE_REG_ASSERT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_EPAREN,
PCRE_REG_ESUBREG,
PCRE_REG_INVARG,
PCRE_REG_INVARG,
PCRE_REG_EPAREN,
PCRE_REG_ESIZE,
PCRE_REG_ESIZE,
PCRE_REG_ESPACE,
PCRE_REG_EPAREN,
PCRE_REG_ASSERT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_ECTYPE,
PCRE_REG_BADPAT,
PCRE_REG_INVARG,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_EESCAPE,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_INVARG,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_INVARG,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT,
PCRE_REG_BADPAT
};
static const char *const pstring[] = {
"",
"internal error",
"invalid repeat counts in {}",
"pattern error",
"? * + invalid",
"unbalanced {}",
"unbalanced []",
"collation error - not relevant",
"bad class",
"bad escape sequence",
"empty expression",
"unbalanced ()",
"bad range inside []",
"expression too big",
"failed to get memory",
"bad back reference",
"bad argument",
"match failed"
};
PCREPOSIX_EXP_DEFN size_t PCRE_CALL_CONVENTION
pcre_regerror(int errcode, const pcre_regex_t *preg, char *errbuf, size_t errbuf_size)
{
const char *message, *addmessage;
size_t length, addlength;
message = (errcode >= (int)(sizeof(pstring)/sizeof(char *)))?
"unknown error code" : pstring[errcode];
length = strlen(message) + 1;
addmessage = " at offset ";
addlength = (preg != NULL && (int)preg->re_erroffset != -1)?
strlen(addmessage) + 6 : 0;
if (errbuf_size > 0)
{
if (addlength > 0 && errbuf_size >= length + addlength)
sprintf(errbuf, "%s%s%-6d", message, addmessage, (int)preg->re_erroffset);
else
{
strncpy(errbuf, message, errbuf_size - 1);
errbuf[errbuf_size-1] = 0;
}
}
return length + addlength;
}
PCREPOSIX_EXP_DEFN void PCRE_CALL_CONVENTION
pcre_regfree(pcre_regex_t *preg)
{
(PUBL(free))(preg->re_pcre);
}
PCREPOSIX_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_regcomp(pcre_regex_t *preg, const char *pattern, int cflags)
{
const char *errorptr;
int erroffset;
int errorcode;
int options = 0;
int re_nsub = 0;
if ((cflags & PCRE_REG_ICASE) != 0) options |= PCRE_CASELESS;
if ((cflags & PCRE_REG_NEWLINE) != 0) options |= PCRE_MULTILINE;
if ((cflags & PCRE_REG_DOTALL) != 0) options |= PCRE_DOTALL;
if ((cflags & PCRE_REG_NOSUB) != 0) options |= PCRE_NO_AUTO_CAPTURE;
if ((cflags & PCRE_REG_UTF8) != 0) options |= PCRE_UTF8;
if ((cflags & PCRE_REG_UCP) != 0) options |= PCRE_UCP;
if ((cflags & PCRE_REG_UNGREEDY) != 0) options |= PCRE_UNGREEDY;
preg->re_pcre = pcre_compile2(pattern, options, &errorcode, &errorptr,
&erroffset, NULL);
preg->re_erroffset = erroffset;
if (preg->re_pcre == NULL)
{
return (errorcode < (int)(sizeof(eint)/sizeof(const int)))?
eint[errorcode] : PCRE_REG_BADPAT;
}
(void)pcre_fullinfo((const pcre *)preg->re_pcre, NULL, PCRE_INFO_CAPTURECOUNT,
&re_nsub);
preg->re_nsub = (size_t)re_nsub;
preg->re_erroffset = (size_t)(-1);
return 0;
}
PCREPOSIX_EXP_DEFN int PCRE_CALL_CONVENTION
pcre_regexec(const pcre_regex_t *preg, const char *string, size_t nmatch,
pcre_regmatch_t pmatch[], int eflags)
{
int rc, so, eo;
int options = 0;
int *ovector = NULL;
int small_ovector[POSIX_MALLOC_THRESHOLD * 3];
BOOL allocated_ovector = FALSE;
BOOL nosub =
(REAL_PCRE_OPTIONS((const pcre *)preg->re_pcre) & PCRE_NO_AUTO_CAPTURE) != 0;
if ((eflags & PCRE_REG_NOTBOL) != 0) options |= PCRE_NOTBOL;
if ((eflags & PCRE_REG_NOTEOL) != 0) options |= PCRE_NOTEOL;
if ((eflags & PCRE_REG_NOTEMPTY) != 0) options |= PCRE_NOTEMPTY;
if (nosub || pmatch == NULL) nmatch = 0;
else if (nmatch > 0)
{
if (nmatch <= POSIX_MALLOC_THRESHOLD)
{
ovector = &(small_ovector[0]);
}
else
{
if (nmatch > INT_MAX/(sizeof(int) * 3)) return PCRE_REG_ESPACE;
ovector = (int *)malloc(sizeof(int) * nmatch * 3);
if (ovector == NULL) return PCRE_REG_ESPACE;
allocated_ovector = TRUE;
}
}
if ((eflags & PCRE_REG_STARTEND) != 0)
{
if (pmatch == NULL) return PCRE_REG_INVARG;
so = pmatch[0].rm_so;
eo = pmatch[0].rm_eo;
}
else
{
so = 0;
eo = (int)strlen(string);
}
rc = pcre_exec((const pcre *)preg->re_pcre, NULL, string + so, (eo - so),
0, options, ovector, (int)(nmatch * 3));
if (rc == 0) rc = (int)nmatch;
if (rc >= 0)
{
size_t i;
if (!nosub)
{
for (i = 0; i < (size_t)rc; i++)
{
pmatch[i].rm_so = (ovector[i*2] < 0)? -1 : ovector[i*2] + so;
pmatch[i].rm_eo = (ovector[i*2+1] < 0)? -1: ovector[i*2+1] + so;
}
if (allocated_ovector) free(ovector);
for (; i < nmatch; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1;
}
return 0;
}
if (allocated_ovector) free(ovector);
switch(rc)
{
case 0:
case (sizeof(eint)/sizeof(int) == ERRCOUNT):
return PCRE_REG_ASSERT;
case PCRE_ERROR_NOMATCH: return PCRE_REG_NOMATCH;
case PCRE_ERROR_NULL: return PCRE_REG_INVARG;
case PCRE_ERROR_BADOPTION: return PCRE_REG_INVARG;
case PCRE_ERROR_BADMAGIC: return PCRE_REG_INVARG;
case PCRE_ERROR_UNKNOWN_NODE: return PCRE_REG_ASSERT;
case PCRE_ERROR_NOMEMORY: return PCRE_REG_ESPACE;
case PCRE_ERROR_MATCHLIMIT: return PCRE_REG_ESPACE;
case PCRE_ERROR_BADUTF8: return PCRE_REG_INVARG;
case PCRE_ERROR_BADUTF8_OFFSET: return PCRE_REG_INVARG;
case PCRE_ERROR_BADMODE: return PCRE_REG_INVARG;
default: return PCRE_REG_ASSERT;
}
}