/***********************************************************************
* *
* This software is part of the ast package *
* Copyright (c) 1985-2010 AT&T Intellectual Property *
* and is licensed under the *
* Common Public License, Version 1.0 *
* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
* *
* Information and Software Systems Research *
* AT&T Research *
* Florham Park NJ *
* *
* Glenn Fowler <gsf@research.att.com> *
* David Korn <dgk@research.att.com> *
* Phong Vo <kpv@research.att.com> *
* *
***********************************************************************/
#pragma prototyped
/*
* posix regex ed(1) style substitute compile
*/
#include "reglib.h"
{
'g', REG_SUB_ALL,
'l', REG_SUB_LOWER,
'n', REG_SUB_NUMBER,
'p', REG_SUB_PRINT,
's', REG_SUB_STOP,
'u', REG_SUB_UPPER,
0, 0
};
int
regsubflags(regex_t* p, register const char* s, char** e, int delim, register const regflags_t* map, int* pm, regflags_t* pf)
{
register int c;
register const regflags_t* m;
int minmatch;
if (!map)
while (!(flags & REG_SUB_LAST))
{
if (!(c = *s++) || c == delim)
{
s--;
break;
}
else if (c >= '0' && c <= '9')
{
if (minmatch)
{
regfree(p);
}
minmatch = c - '0';
while (*s >= '0' && *s <= '9')
}
else
{
for (m = map; *m; m++)
if (*m++ == c)
{
if (flags & *m)
{
regfree(p);
}
flags |= *m--;
break;
}
if (!*m)
{
s--;
break;
}
}
}
if (pf)
if (pm)
if (e)
*e = (char*)s;
return 0;
}
/*
* compile substitute rhs and optional flags
*/
int
regsubcomp(regex_t* p, register const char* s, const regflags_t* map, int minmatch, regflags_t flags)
{
register int c;
register int d;
register char* t;
char* e;
const char* r;
int sre;
int f;
int g;
int n;
int nops;
const char* o;
{
regfree(p);
}
if (!(sub = (regsub_t*)alloc(p->env->disc, 0, sizeof(regsub_t) + strlen(s))) || !(sub->re_ops = (regsubop_t*)alloc(p->env->disc, 0, (nops = 8) * sizeof(regsubop_t))))
{
if (sub)
regfree(p);
}
o = s;
d = 0;
else
switch (d = *(s - 1))
{
case '\\':
case '\n':
case '\r':
regfree(p);
}
if (d)
{
r = s;
for (;;)
{
if (!*s)
{
{
regfree(p);
}
break;
}
else if (*s == d)
{
flags |= REG_SUB_FULL;
s++;
break;
}
else if (*s++ == '\\' && !*s++)
{
regfree(p);
}
}
if (*s)
{
return n;
s = (const char*)e;
}
p->re_npat = s - o;
s = r;
}
else
p->re_npat = 0;
while ((c = *s++) != d)
{
if (!c)
{
p->re_npat = s - o - 1;
break;
}
else if (c == '\\')
{
if (*s == c)
{
*t++ = *s++;
continue;
}
if ((c = *s++) == d)
goto again;
if (!c)
{
regfree(p);
}
if (c == '&')
{
*t++ = c;
continue;
}
}
else if (c == '&')
{
if (sre)
{
*t++ = c;
continue;
}
}
else
{
{
case REG_SUB_UPPER:
if (islower(c))
c = toupper(c);
break;
case REG_SUB_LOWER:
if (isupper(c))
c = tolower(c);
break;
case REG_SUB_UPPER|REG_SUB_LOWER:
if (isupper(c))
c = tolower(c);
else if (islower(c))
c = toupper(c);
break;
}
*t++ = c;
continue;
}
switch (c)
{
case 0:
s--;
continue;
case '&':
c = 0;
break;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
c -= '0';
c = c * 10 + *s++ - '0';
break;
case 'l':
if (c = *s)
{
s++;
if (isupper(c))
c = tolower(c);
*t++ = c;
}
continue;
case 'u':
if (c = *s)
{
s++;
if (islower(c))
c = toupper(c);
*t++ = c;
}
continue;
case 'E':
f = g;
set:
{
if (!(sub->re_ops = (regsubop_t*)alloc(p->env->disc, sub->re_ops, (nops *= 2) * sizeof(regsubop_t))))
{
regfree(p);
}
}
continue;
case 'L':
g = f;
f = REG_SUB_LOWER;
goto set;
case 'U':
g = f;
f = REG_SUB_UPPER;
goto set;
default:
if (!sre)
{
*t++ = chresc(s - 2, &e);
s = (const char*)e;
continue;
}
s--;
c = -1;
break;
}
if (c > p->re_nsub)
{
regfree(p);
}
{
if (!(sub->re_ops = (regsubop_t*)alloc(p->env->disc, sub->re_ops, (nops *= 2) * sizeof(regsubop_t))))
{
regfree(p);
}
}
op++;
op++;
}
{
if (!(sub->re_ops = (regsubop_t*)alloc(p->env->disc, sub->re_ops, (nops *= 2) * sizeof(regsubop_t))))
{
regfree(p);
}
}
return 0;
}
void
{
{
p->re_sub = 0;
{
}
}
}