Commit Diff


commit - 13f9a4bd63892b264e45949e05f7c47ca74c0bc0
commit + 8a2def82135dc493741663856310c5c662106aff
blob - c48be0ead8bf4c0eefb746bba331fa166ccd8dd0
blob + 3e12922d9e871dd9a4847dcd109fc4599ea02fd8
--- script.c
+++ script.c
@@ -388,9 +388,61 @@ newop(int type)
 }
 
 void
+free_op_rec(struct op *op)
+{
+	struct op *n;
+
+	while (op != NULL) {
+		n = op->next;
+		free_op(op);
+		op = n;
+	}
+}
+
+void
 free_op(struct op *op)
 {
-	/* TODO: probably more... */
+	if (op == NULL)
+		return;
+
+	switch (op->type) {
+	case OP_REST:
+	case OP_LITERAL:
+	case OP_VARGS:
+		break;
+	case OP_ASSIGN:
+		free(op->v.assign.name);
+		free_op_rec(op->v.assign.expr);
+		break;
+	case OP_ASSERT:
+		free_op_rec(op->v.assert);
+		break;
+	case OP_FUNCALL:
+		free_op_rec(op->v.funcall.argv);
+		break;
+	case OP_VAR:
+		free(op->v.var);
+		break;
+	case OP_CAST:
+		free_op_rec(op->v.cast.expr);
+		break;
+	case OP_CMP_EQ:
+		free_op_rec(op->v.cmp_eq.a);
+		free_op_rec(op->v.cmp_eq.b);
+		break;
+	case OP_FACCESS:
+		free_op_rec(op->v.faccess.expr);
+		free(op->v.faccess.field);
+		break;
+	case OP_SFAIL:
+		free(op->v.sfail.msg);
+		free_op_rec(op->v.sfail.expr);
+		break;
+	default:
+		/* unreachable */
+		abort();
+	}
+
 	free(op);
 }