Copy and free funcall tokens

Again, even though there is not as of yet any way to create them
This commit is contained in:
Glen Whitney 2019-08-04 10:39:20 -04:00
parent d6b4adfc8c
commit b0e989d848

View File

@ -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;
} }
} }
/*}}}*/ /*}}}*/