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;
|
||||
/*}}}*/
|
||||
|
||||
result=n;
|
||||
if (result.type==STRING) result.u.string=strcpy(malloc(strlen(n.u.string)+1),n.u.string);
|
||||
else if (result.type==EEK) result.u.err=strcpy(malloc(strlen(n.u.err)+1),n.u.err);
|
||||
else if (result.type==LIDENT) result.u.lident=strcpy(malloc(strlen(n.u.lident)+1),n.u.lident);
|
||||
result = n;
|
||||
switch (n.type) {
|
||||
case STRING: result.u.string = strdup(n.u.string); break;
|
||||
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;
|
||||
}
|
||||
/*}}}*/
|
||||
@ -58,23 +69,42 @@ void tfree(Token *n)
|
||||
/* tfree_protected -- free dynamic data of token but not if same as protected */ /*{{{*/
|
||||
void tfree_protected(Token *n, const Token dontfree)
|
||||
{
|
||||
if (n->type == STRING &&
|
||||
(dontfree.type != STRING || n->u.string != dontfree.u.string))
|
||||
{
|
||||
free(n->u.string);
|
||||
n->u.string=(char*)0;
|
||||
}
|
||||
else if (n->type == EEK &&
|
||||
(dontfree.type != EEK || n->u.err != dontfree.u.err))
|
||||
{
|
||||
free(n->u.err);
|
||||
n->u.err=(char*)0;
|
||||
}
|
||||
else if (n->type==LIDENT &&
|
||||
(dontfree.type != LIDENT || n->u.lident != dontfree.u.lident))
|
||||
{
|
||||
free(n->u.lident);
|
||||
n->u.lident=(char*)0;
|
||||
bool difftype = (dontfree.type != n->type);
|
||||
switch (n->type) {
|
||||
case STRING:
|
||||
if (difftype || n->u.string != dontfree.u.string)
|
||||
{
|
||||
free(n->u.string);
|
||||
n->u.string=(char*)0;
|
||||
}
|
||||
break;
|
||||
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);
|
||||
n->u.err=(char*)0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*}}}*/
|
||||
|
Loading…
Reference in New Issue
Block a user