Amended the all pull request. (#51)
* [from NetBSD] - dynamic state allocation - centralize vector growth - centralize int array allocation - no casts for void * functions * - add missing allocation - revert change loop in pmatch
This commit is contained in:
parent
0ba1d0391d
commit
c16e8696d7
8
awk.h
8
awk.h
@ -226,16 +226,16 @@ typedef struct rrow {
|
|||||||
} rrow;
|
} rrow;
|
||||||
|
|
||||||
typedef struct fa {
|
typedef struct fa {
|
||||||
uschar gototab[NSTATES][HAT + 1];
|
unsigned int **gototab;
|
||||||
uschar out[NSTATES];
|
uschar *out;
|
||||||
uschar *restr;
|
uschar *restr;
|
||||||
int *posns[NSTATES];
|
int **posns;
|
||||||
|
int state_count;
|
||||||
int anchor;
|
int anchor;
|
||||||
int use;
|
int use;
|
||||||
int initstat;
|
int initstat;
|
||||||
int curstat;
|
int curstat;
|
||||||
int accept;
|
int accept;
|
||||||
int reset;
|
|
||||||
struct rrow re[1]; /* variable: actual size set by calling malloc */
|
struct rrow re[1]; /* variable: actual size set by calling malloc */
|
||||||
} fa;
|
} fa;
|
||||||
|
|
||||||
|
196
b.c
196
b.c
@ -76,10 +76,71 @@ static int poscnt;
|
|||||||
char *patbeg;
|
char *patbeg;
|
||||||
int patlen;
|
int patlen;
|
||||||
|
|
||||||
#define NFA 20 /* cache this many dynamic fa's */
|
#define NFA 128 /* cache this many dynamic fa's */
|
||||||
fa *fatab[NFA];
|
fa *fatab[NFA];
|
||||||
int nfatab = 0; /* entries in fatab */
|
int nfatab = 0; /* entries in fatab */
|
||||||
|
|
||||||
|
static int *
|
||||||
|
intalloc(size_t n, const char *f)
|
||||||
|
{
|
||||||
|
void *p = calloc(n, sizeof(int));
|
||||||
|
if (p == NULL)
|
||||||
|
overflo(f);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
resizesetvec(const char *f)
|
||||||
|
{
|
||||||
|
if (maxsetvec == 0)
|
||||||
|
maxsetvec = MAXLIN;
|
||||||
|
else
|
||||||
|
maxsetvec *= 4;
|
||||||
|
setvec = realloc(setvec, maxsetvec * sizeof(*setvec));
|
||||||
|
tmpset = realloc(tmpset, maxsetvec * sizeof(*tmpset));
|
||||||
|
if (setvec == NULL || tmpset == NULL)
|
||||||
|
overflo(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
resize_state(fa *f, int state)
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
int i, new_count;
|
||||||
|
|
||||||
|
if (++state < f->state_count)
|
||||||
|
return;
|
||||||
|
|
||||||
|
new_count = state + 10; /* needs to be tuned */
|
||||||
|
|
||||||
|
p = realloc(f->gototab, new_count * sizeof(f->gototab[0]));
|
||||||
|
if (p == NULL)
|
||||||
|
goto out;
|
||||||
|
f->gototab = p;
|
||||||
|
|
||||||
|
p = realloc(f->out, new_count * sizeof(f->out[0]));
|
||||||
|
if (p == NULL)
|
||||||
|
goto out;
|
||||||
|
f->out = p;
|
||||||
|
|
||||||
|
p = realloc(f->posns, new_count * sizeof(f->posns[0]));
|
||||||
|
if (p == NULL)
|
||||||
|
goto out;
|
||||||
|
f->posns = p;
|
||||||
|
|
||||||
|
for (i = f->state_count; i < new_count; ++i) {
|
||||||
|
f->gototab[i] = calloc(NCHARS, sizeof(**f->gototab));
|
||||||
|
if (f->gototab[i] == NULL)
|
||||||
|
goto out;
|
||||||
|
f->out[i] = 0;
|
||||||
|
f->posns[i] = NULL;
|
||||||
|
}
|
||||||
|
f->state_count = new_count;
|
||||||
|
return;
|
||||||
|
out:
|
||||||
|
overflo(__func__);
|
||||||
|
}
|
||||||
|
|
||||||
fa *makedfa(const char *s, int anchor) /* returns dfa for reg expr s */
|
fa *makedfa(const char *s, int anchor) /* returns dfa for reg expr s */
|
||||||
{
|
{
|
||||||
int i, use, nuse;
|
int i, use, nuse;
|
||||||
@ -87,11 +148,7 @@ fa *makedfa(const char *s, int anchor) /* returns dfa for reg expr s */
|
|||||||
static int now = 1;
|
static int now = 1;
|
||||||
|
|
||||||
if (setvec == NULL) { /* first time through any RE */
|
if (setvec == NULL) { /* first time through any RE */
|
||||||
maxsetvec = MAXLIN;
|
resizesetvec(__func__);
|
||||||
setvec = (int *) malloc(maxsetvec * sizeof(int));
|
|
||||||
tmpset = (int *) malloc(maxsetvec * sizeof(int));
|
|
||||||
if (setvec == NULL || tmpset == NULL)
|
|
||||||
overflo("out of space initializing makedfa");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compile_time) /* a constant for sure */
|
if (compile_time) /* a constant for sure */
|
||||||
@ -139,14 +196,13 @@ fa *mkdfa(const char *s, int anchor) /* does the real work of making a dfa */
|
|||||||
poscnt = 0;
|
poscnt = 0;
|
||||||
penter(p1); /* enter parent pointers and leaf indices */
|
penter(p1); /* enter parent pointers and leaf indices */
|
||||||
if ((f = (fa *) calloc(1, sizeof(fa) + poscnt*sizeof(rrow))) == NULL)
|
if ((f = (fa *) calloc(1, sizeof(fa) + poscnt*sizeof(rrow))) == NULL)
|
||||||
overflo("out of space for fa");
|
overflo(__func__);
|
||||||
f->accept = poscnt-1; /* penter has computed number of positions in re */
|
f->accept = poscnt-1; /* penter has computed number of positions in re */
|
||||||
cfoll(f, p1); /* set up follow sets */
|
cfoll(f, p1); /* set up follow sets */
|
||||||
freetr(p1);
|
freetr(p1);
|
||||||
if ((f->posns[0] = (int *) calloc(*(f->re[0].lfollow), sizeof(int))) == NULL)
|
resize_state(f, 1);
|
||||||
overflo("out of space in makedfa");
|
f->posns[0] = intalloc(*(f->re[0].lfollow), __func__);
|
||||||
if ((f->posns[1] = (int *) calloc(1, sizeof(int))) == NULL)
|
f->posns[1] = intalloc(1, __func__);
|
||||||
overflo("out of space in makedfa");
|
|
||||||
*f->posns[1] = 0;
|
*f->posns[1] = 0;
|
||||||
f->initstat = makeinit(f, anchor);
|
f->initstat = makeinit(f, anchor);
|
||||||
f->anchor = anchor;
|
f->anchor = anchor;
|
||||||
@ -164,11 +220,9 @@ int makeinit(fa *f, int anchor)
|
|||||||
|
|
||||||
f->curstat = 2;
|
f->curstat = 2;
|
||||||
f->out[2] = 0;
|
f->out[2] = 0;
|
||||||
f->reset = 0;
|
|
||||||
k = *(f->re[0].lfollow);
|
k = *(f->re[0].lfollow);
|
||||||
xfree(f->posns[2]);
|
xfree(f->posns[2]);
|
||||||
if ((f->posns[2] = (int *) calloc(k+1, sizeof(int))) == NULL)
|
f->posns[2] = intalloc(k + 1, __func__);
|
||||||
overflo("out of space in makeinit");
|
|
||||||
for (i=0; i <= k; i++) {
|
for (i=0; i <= k; i++) {
|
||||||
(f->posns[2])[i] = (f->re[0].lfollow)[i];
|
(f->posns[2])[i] = (f->re[0].lfollow)[i];
|
||||||
}
|
}
|
||||||
@ -308,7 +362,7 @@ char *cclenter(const char *argp) /* add a character class */
|
|||||||
static int bufsz = 100;
|
static int bufsz = 100;
|
||||||
|
|
||||||
op = p;
|
op = p;
|
||||||
if (buf == NULL && (buf = (uschar *) malloc(bufsz)) == NULL)
|
if (buf == NULL && (buf = malloc(bufsz)) == NULL)
|
||||||
FATAL("out of space for character class [%.10s...] 1", p);
|
FATAL("out of space for character class [%.10s...] 1", p);
|
||||||
bp = buf;
|
bp = buf;
|
||||||
for (i = 0; (c = *p++) != 0; ) {
|
for (i = 0; (c = *p++) != 0; ) {
|
||||||
@ -347,7 +401,7 @@ char *cclenter(const char *argp) /* add a character class */
|
|||||||
|
|
||||||
void overflo(const char *s)
|
void overflo(const char *s)
|
||||||
{
|
{
|
||||||
FATAL("regular expression too big: %.30s...", s);
|
FATAL("regular expression too big: out of space in %.30s...", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cfoll(fa *f, Node *v) /* enter follow set of each leaf of vertex v into lfollow[leaf] */
|
void cfoll(fa *f, Node *v) /* enter follow set of each leaf of vertex v into lfollow[leaf] */
|
||||||
@ -361,18 +415,13 @@ void cfoll(fa *f, Node *v) /* enter follow set of each leaf of vertex v into lfo
|
|||||||
f->re[info(v)].ltype = type(v);
|
f->re[info(v)].ltype = type(v);
|
||||||
f->re[info(v)].lval.np = right(v);
|
f->re[info(v)].lval.np = right(v);
|
||||||
while (f->accept >= maxsetvec) { /* guessing here! */
|
while (f->accept >= maxsetvec) { /* guessing here! */
|
||||||
maxsetvec *= 4;
|
resizesetvec(__func__);
|
||||||
setvec = (int *) realloc(setvec, maxsetvec * sizeof(int));
|
|
||||||
tmpset = (int *) realloc(tmpset, maxsetvec * sizeof(int));
|
|
||||||
if (setvec == NULL || tmpset == NULL)
|
|
||||||
overflo("out of space in cfoll()");
|
|
||||||
}
|
}
|
||||||
for (i = 0; i <= f->accept; i++)
|
for (i = 0; i <= f->accept; i++)
|
||||||
setvec[i] = 0;
|
setvec[i] = 0;
|
||||||
setcnt = 0;
|
setcnt = 0;
|
||||||
follow(v); /* computes setvec and setcnt */
|
follow(v); /* computes setvec and setcnt */
|
||||||
if ((p = (int *) calloc(setcnt+1, sizeof(int))) == NULL)
|
p = intalloc(setcnt + 1, __func__);
|
||||||
overflo("out of space building follow set");
|
|
||||||
f->re[info(v)].lfollow = p;
|
f->re[info(v)].lfollow = p;
|
||||||
*p = setcnt;
|
*p = setcnt;
|
||||||
for (i = f->accept; i >= 0; i--)
|
for (i = f->accept; i >= 0; i--)
|
||||||
@ -402,11 +451,7 @@ int first(Node *p) /* collects initially active leaves of p into setvec */
|
|||||||
LEAF
|
LEAF
|
||||||
lp = info(p); /* look for high-water mark of subscripts */
|
lp = info(p); /* look for high-water mark of subscripts */
|
||||||
while (setcnt >= maxsetvec || lp >= maxsetvec) { /* guessing here! */
|
while (setcnt >= maxsetvec || lp >= maxsetvec) { /* guessing here! */
|
||||||
maxsetvec *= 4;
|
resizesetvec(__func__);
|
||||||
setvec = (int *) realloc(setvec, maxsetvec * sizeof(int));
|
|
||||||
tmpset = (int *) realloc(tmpset, maxsetvec * sizeof(int));
|
|
||||||
if (setvec == NULL || tmpset == NULL)
|
|
||||||
overflo("out of space in first()");
|
|
||||||
}
|
}
|
||||||
if (type(p) == EMPTYRE) {
|
if (type(p) == EMPTYRE) {
|
||||||
setvec[lp] = 0;
|
setvec[lp] = 0;
|
||||||
@ -484,7 +529,9 @@ int match(fa *f, const char *p0) /* shortest match ? */
|
|||||||
int s, ns;
|
int s, ns;
|
||||||
uschar *p = (uschar *) p0;
|
uschar *p = (uschar *) p0;
|
||||||
|
|
||||||
s = f->reset ? makeinit(f,0) : f->initstat;
|
s = f->initstat;
|
||||||
|
assert (s < f->state_count);
|
||||||
|
|
||||||
if (f->out[s])
|
if (f->out[s])
|
||||||
return(1);
|
return(1);
|
||||||
do {
|
do {
|
||||||
@ -504,15 +551,11 @@ int pmatch(fa *f, const char *p0) /* longest match, for sub */
|
|||||||
int s, ns;
|
int s, ns;
|
||||||
uschar *p = (uschar *) p0;
|
uschar *p = (uschar *) p0;
|
||||||
uschar *q;
|
uschar *q;
|
||||||
int i, k;
|
|
||||||
|
|
||||||
/* s = f->reset ? makeinit(f,1) : f->initstat; */
|
s = f->initstat;
|
||||||
if (f->reset) {
|
assert(s < f->state_count);
|
||||||
f->initstat = s = makeinit(f,1);
|
|
||||||
} else {
|
patbeg = (char *)p;
|
||||||
s = f->initstat;
|
|
||||||
}
|
|
||||||
patbeg = (char *) p;
|
|
||||||
patlen = -1;
|
patlen = -1;
|
||||||
do {
|
do {
|
||||||
q = p;
|
q = p;
|
||||||
@ -524,6 +567,9 @@ int pmatch(fa *f, const char *p0) /* longest match, for sub */
|
|||||||
s = ns;
|
s = ns;
|
||||||
else
|
else
|
||||||
s = cgoto(f, s, *q);
|
s = cgoto(f, s, *q);
|
||||||
|
|
||||||
|
assert(s < f->state_count);
|
||||||
|
|
||||||
if (s == 1) { /* no transition */
|
if (s == 1) { /* no transition */
|
||||||
if (patlen >= 0) {
|
if (patlen >= 0) {
|
||||||
patbeg = (char *) p;
|
patbeg = (char *) p;
|
||||||
@ -541,20 +587,7 @@ int pmatch(fa *f, const char *p0) /* longest match, for sub */
|
|||||||
}
|
}
|
||||||
nextin:
|
nextin:
|
||||||
s = 2;
|
s = 2;
|
||||||
if (f->reset) {
|
} while (*p++);
|
||||||
for (i = 2; i <= f->curstat; i++)
|
|
||||||
xfree(f->posns[i]);
|
|
||||||
k = *f->posns[0];
|
|
||||||
if ((f->posns[2] = (int *) calloc(k+1, sizeof(int))) == NULL)
|
|
||||||
overflo("out of space in pmatch");
|
|
||||||
for (i = 0; i <= k; i++)
|
|
||||||
(f->posns[2])[i] = (f->posns[0])[i];
|
|
||||||
f->initstat = f->curstat = 2;
|
|
||||||
f->out[2] = f->out[0];
|
|
||||||
for (i = 0; i < NCHARS; i++)
|
|
||||||
f->gototab[2][i] = 0;
|
|
||||||
}
|
|
||||||
} while (*p++ != 0);
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -563,14 +596,11 @@ int nematch(fa *f, const char *p0) /* non-empty match, for sub */
|
|||||||
int s, ns;
|
int s, ns;
|
||||||
uschar *p = (uschar *) p0;
|
uschar *p = (uschar *) p0;
|
||||||
uschar *q;
|
uschar *q;
|
||||||
int i, k;
|
|
||||||
|
|
||||||
/* s = f->reset ? makeinit(f,1) : f->initstat; */
|
s = f->initstat;
|
||||||
if (f->reset) {
|
assert(s < f->state_count);
|
||||||
f->initstat = s = makeinit(f,1);
|
|
||||||
} else {
|
patbeg = (char *)p;
|
||||||
s = f->initstat;
|
|
||||||
}
|
|
||||||
patlen = -1;
|
patlen = -1;
|
||||||
while (*p) {
|
while (*p) {
|
||||||
q = p;
|
q = p;
|
||||||
@ -598,19 +628,6 @@ int nematch(fa *f, const char *p0) /* non-empty match, for sub */
|
|||||||
}
|
}
|
||||||
nnextin:
|
nnextin:
|
||||||
s = 2;
|
s = 2;
|
||||||
if (f->reset) {
|
|
||||||
for (i = 2; i <= f->curstat; i++)
|
|
||||||
xfree(f->posns[i]);
|
|
||||||
k = *f->posns[0];
|
|
||||||
if ((f->posns[2] = (int *) calloc(k+1, sizeof(int))) == NULL)
|
|
||||||
overflo("out of state space");
|
|
||||||
for (i = 0; i <= k; i++)
|
|
||||||
(f->posns[2])[i] = (f->posns[0])[i];
|
|
||||||
f->initstat = f->curstat = 2;
|
|
||||||
f->out[2] = f->out[0];
|
|
||||||
for (i = 0; i < NCHARS; i++)
|
|
||||||
f->gototab[2][i] = 0;
|
|
||||||
}
|
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
@ -909,7 +926,7 @@ replace_repeat(const uschar *reptok, int reptoklen, const uschar *atom,
|
|||||||
} else if (special_case == REPEAT_ZERO) {
|
} else if (special_case == REPEAT_ZERO) {
|
||||||
size += 2; /* just a null ERE: () */
|
size += 2; /* just a null ERE: () */
|
||||||
}
|
}
|
||||||
if ((buf = (uschar *) malloc(size+1)) == NULL)
|
if ((buf = malloc(size + 1)) == NULL)
|
||||||
FATAL("out of space in reg expr %.10s..", lastre);
|
FATAL("out of space in reg expr %.10s..", lastre);
|
||||||
memcpy(buf, basestr, prefix_length); /* copy prefix */
|
memcpy(buf, basestr, prefix_length); /* copy prefix */
|
||||||
j = prefix_length;
|
j = prefix_length;
|
||||||
@ -1035,7 +1052,7 @@ rescan:
|
|||||||
rlxval = c;
|
rlxval = c;
|
||||||
return CHAR;
|
return CHAR;
|
||||||
case '[':
|
case '[':
|
||||||
if (buf == NULL && (buf = (uschar *) malloc(bufsz)) == NULL)
|
if (buf == NULL && (buf = malloc(bufsz)) == NULL)
|
||||||
FATAL("out of space in reg expr %.10s..", lastre);
|
FATAL("out of space in reg expr %.10s..", lastre);
|
||||||
bp = buf;
|
bp = buf;
|
||||||
if (*prestr == '^') {
|
if (*prestr == '^') {
|
||||||
@ -1203,20 +1220,17 @@ rescan:
|
|||||||
|
|
||||||
int cgoto(fa *f, int s, int c)
|
int cgoto(fa *f, int s, int c)
|
||||||
{
|
{
|
||||||
int i, j, k;
|
|
||||||
int *p, *q;
|
int *p, *q;
|
||||||
|
int i, j, k;
|
||||||
|
|
||||||
assert(c == HAT || c < NCHARS);
|
assert(c == HAT || c < NCHARS);
|
||||||
while (f->accept >= maxsetvec) { /* guessing here! */
|
while (f->accept >= maxsetvec) { /* guessing here! */
|
||||||
maxsetvec *= 4;
|
resizesetvec(__func__);
|
||||||
setvec = (int *) realloc(setvec, maxsetvec * sizeof(int));
|
|
||||||
tmpset = (int *) realloc(tmpset, maxsetvec * sizeof(int));
|
|
||||||
if (setvec == NULL || tmpset == NULL)
|
|
||||||
overflo("out of space in cgoto()");
|
|
||||||
}
|
}
|
||||||
for (i = 0; i <= f->accept; i++)
|
for (i = 0; i <= f->accept; i++)
|
||||||
setvec[i] = 0;
|
setvec[i] = 0;
|
||||||
setcnt = 0;
|
setcnt = 0;
|
||||||
|
resize_state(f, s);
|
||||||
/* compute positions of gototab[s,c] into setvec */
|
/* compute positions of gototab[s,c] into setvec */
|
||||||
p = f->posns[s];
|
p = f->posns[s];
|
||||||
for (i = 1; i <= *p; i++) {
|
for (i = 1; i <= *p; i++) {
|
||||||
@ -1230,11 +1244,7 @@ int cgoto(fa *f, int s, int c)
|
|||||||
q = f->re[p[i]].lfollow;
|
q = f->re[p[i]].lfollow;
|
||||||
for (j = 1; j <= *q; j++) {
|
for (j = 1; j <= *q; j++) {
|
||||||
if (q[j] >= maxsetvec) {
|
if (q[j] >= maxsetvec) {
|
||||||
maxsetvec *= 4;
|
resizesetvec(__func__);
|
||||||
setvec = (int *) realloc(setvec, maxsetvec * sizeof(int));
|
|
||||||
tmpset = (int *) realloc(tmpset, maxsetvec * sizeof(int));
|
|
||||||
if (setvec == NULL || tmpset == NULL)
|
|
||||||
overflo("cgoto overflow");
|
|
||||||
}
|
}
|
||||||
if (setvec[q[j]] == 0) {
|
if (setvec[q[j]] == 0) {
|
||||||
setcnt++;
|
setcnt++;
|
||||||
@ -1251,6 +1261,7 @@ int cgoto(fa *f, int s, int c)
|
|||||||
if (setvec[i]) {
|
if (setvec[i]) {
|
||||||
tmpset[j++] = i;
|
tmpset[j++] = i;
|
||||||
}
|
}
|
||||||
|
resize_state(f, f->curstat > s ? f->curstat : s);
|
||||||
/* tmpset == previous state? */
|
/* tmpset == previous state? */
|
||||||
for (i = 1; i <= f->curstat; i++) {
|
for (i = 1; i <= f->curstat; i++) {
|
||||||
p = f->posns[i];
|
p = f->posns[i];
|
||||||
@ -1266,18 +1277,12 @@ int cgoto(fa *f, int s, int c)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* add tmpset to current set of states */
|
/* add tmpset to current set of states */
|
||||||
if (f->curstat >= NSTATES-1) {
|
++(f->curstat);
|
||||||
f->curstat = 2;
|
resize_state(f, f->curstat);
|
||||||
f->reset = 1;
|
|
||||||
for (i = 2; i < NSTATES; i++)
|
|
||||||
xfree(f->posns[i]);
|
|
||||||
} else
|
|
||||||
++(f->curstat);
|
|
||||||
for (i = 0; i < NCHARS; i++)
|
for (i = 0; i < NCHARS; i++)
|
||||||
f->gototab[f->curstat][i] = 0;
|
f->gototab[f->curstat][i] = 0;
|
||||||
xfree(f->posns[f->curstat]);
|
xfree(f->posns[f->curstat]);
|
||||||
if ((p = (int *) calloc(setcnt+1, sizeof(int))) == NULL)
|
p = intalloc(setcnt + 1, __func__);
|
||||||
overflo("out of space in cgoto");
|
|
||||||
|
|
||||||
f->posns[f->curstat] = p;
|
f->posns[f->curstat] = p;
|
||||||
f->gototab[s][c] = f->curstat;
|
f->gototab[s][c] = f->curstat;
|
||||||
@ -1297,6 +1302,8 @@ void freefa(fa *f) /* free a finite automaton */
|
|||||||
|
|
||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
return;
|
return;
|
||||||
|
for (i = 0; i < f->state_count; i++)
|
||||||
|
xfree(f->gototab[i])
|
||||||
for (i = 0; i <= f->curstat; i++)
|
for (i = 0; i <= f->curstat; i++)
|
||||||
xfree(f->posns[i]);
|
xfree(f->posns[i]);
|
||||||
for (i = 0; i <= f->accept; i++) {
|
for (i = 0; i <= f->accept; i++) {
|
||||||
@ -1305,5 +1312,8 @@ void freefa(fa *f) /* free a finite automaton */
|
|||||||
xfree((f->re[i].lval.np));
|
xfree((f->re[i].lval.np));
|
||||||
}
|
}
|
||||||
xfree(f->restr);
|
xfree(f->restr);
|
||||||
|
xfree(f->out);
|
||||||
|
xfree(f->posns);
|
||||||
|
xfree(f->gototab);
|
||||||
xfree(f);
|
xfree(f);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user