void FNSyntax_DeleteExpression(ExprNode *node) { ExprNode *temp = NULL; for(ExprNode *i = node; i != NULL; i = i->next) { if(temp != NULL) { POV_FREE(temp); } FNSyntax_DeleteExpression(i->child); if((i->op == OP_VARIABLE) || (i->op == OP_MEMBER)) { POV_FREE(i->variable); } else if(i->op == OP_CALL) { if((i->call.token == FUNCT_ID_TOKEN) || (i->call.token == VECTFUNCT_ID_TOKEN)) POVFPU_RemoveFunction(i->call.fn); POV_FREE(i->call.name); } temp = i; } if(temp != NULL) { POV_FREE(temp); } }
void POVFPU_RemoveFunction(FUNCTION fn) { if((POVFPU_Functions == NULL) || (fn >= POVFPU_FunctionCnt)) return; if(POVFPU_Functions[fn].reference_count > 0) // necessary to prevent any recursion { POVFPU_Functions[fn].reference_count--; if(POVFPU_Functions[fn].reference_count == 0) { // The copying is necessary because recursive POVFPU_RemoveFunction // calls may shrink the POVFPU_Functions array and remove the data // before we are done with it here! [trf] FunctionEntry f = POVFPU_Functions[fn]; unsigned int i = 0; SYS_DELETE_FUNCTION(&f); for(i = 0; i < f.fn.program_size; i++) { if(GET_OP(f.fn.program[i]) == OPCODE_CALL) POVFPU_RemoveFunction(GET_K(f.fn.program[i])); } FNCode_Delete(&(f.fn)); for(i = POVFPU_FunctionCnt - 1; i > 0; i--) { if(POVFPU_Functions[i].reference_count == 0) POVFPU_FunctionCnt--; else break; } if(POVFPU_FunctionCnt == 0) { POV_FREE(POVFPU_Functions); POVFPU_Functions = NULL; } else POVFPU_Functions = (FunctionEntry *)POV_REALLOC(POVFPU_Functions, sizeof(FunctionEntry) * POVFPU_FunctionCnt, "fn: FunctionEntry"); } } }