Copy and free funcall tokens
Again, even though there is not as of yet any way to create them
This commit is contained in:
parent
d6b4adfc8c
commit
b0e989d848
@ -38,10 +38,21 @@ Token tcopy(Token n)
|
|||||||
Token result;
|
Token result;
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
|
|
||||||
result=n;
|
result = n;
|
||||||
if (result.type==STRING) result.u.string=strcpy(malloc(strlen(n.u.string)+1),n.u.string);
|
switch (n.type) {
|
||||||
else if (result.type==EEK) result.u.err=strcpy(malloc(strlen(n.u.err)+1),n.u.err);
|
case STRING: result.u.string = strdup(n.u.string); break;
|
||||||
else if (result.type==LIDENT) result.u.lident=strcpy(malloc(strlen(n.u.lident)+1),n.u.lident);
|
case LIDENT: result.u.lident = strdup(n.u.lident); break;
|
||||||
|
case FUNCALL:
|
||||||
|
if (n.u.funcall.argc > 0)
|
||||||
|
{
|
||||||
|
result.u.funcall.argv = malloc(n.u.funcall.argc*sizeof(Token));
|
||||||
|
for (size_t ai = 0; ai < n.u.funcall.argc; ++ai)
|
||||||
|
result.u.funcall.argv[ai] = tcopy(n.u.funcall.argv[ai]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EEK: result.u.err = strdup(n.u.err); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
@ -58,23 +69,42 @@ void tfree(Token *n)
|
|||||||
/* tfree_protected -- free dynamic data of token but not if same as protected */ /*{{{*/
|
/* tfree_protected -- free dynamic data of token but not if same as protected */ /*{{{*/
|
||||||
void tfree_protected(Token *n, const Token dontfree)
|
void tfree_protected(Token *n, const Token dontfree)
|
||||||
{
|
{
|
||||||
if (n->type == STRING &&
|
bool difftype = (dontfree.type != n->type);
|
||||||
(dontfree.type != STRING || n->u.string != dontfree.u.string))
|
switch (n->type) {
|
||||||
|
case STRING:
|
||||||
|
if (difftype || n->u.string != dontfree.u.string)
|
||||||
{
|
{
|
||||||
free(n->u.string);
|
free(n->u.string);
|
||||||
n->u.string=(char*)0;
|
n->u.string=(char*)0;
|
||||||
}
|
}
|
||||||
else if (n->type == EEK &&
|
break;
|
||||||
(dontfree.type != EEK || n->u.err != dontfree.u.err))
|
case LIDENT:
|
||||||
|
if (difftype || n->u.lident != dontfree.u.lident)
|
||||||
|
{
|
||||||
|
free(n->u.lident);
|
||||||
|
n->u.lident=(char*)0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FUNCALL:
|
||||||
|
if (difftype || n->u.funcall.argv != dontfree.u.funcall.argv)
|
||||||
|
{
|
||||||
|
for (int ai = 0; ai < n->u.funcall.argc; ++ai)
|
||||||
|
tfree_protected(n->u.funcall.argv + ai, dontfree);
|
||||||
|
if (n->u.funcall.argv != NULLTOKEN) {
|
||||||
|
free(n->u.funcall.argv);
|
||||||
|
n->u.funcall.argv = NULLTOKEN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EEK:
|
||||||
|
if (difftype || n->u.err != dontfree.u.err)
|
||||||
{
|
{
|
||||||
free(n->u.err);
|
free(n->u.err);
|
||||||
n->u.err=(char*)0;
|
n->u.err=(char*)0;
|
||||||
}
|
}
|
||||||
else if (n->type==LIDENT &&
|
break;
|
||||||
(dontfree.type != LIDENT || n->u.lident != dontfree.u.lident))
|
default:
|
||||||
{
|
break;
|
||||||
free(n->u.lident);
|
|
||||||
n->u.lident=(char*)0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*}}}*/
|
/*}}}*/
|
||||||
|
Loading…
Reference in New Issue
Block a user