about summary refs log tree commit diff
path: root/mpick.c
diff options
context:
space:
mode:
Diffstat (limited to 'mpick.c')
-rw-r--r--mpick.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/mpick.c b/mpick.c
index f9da79d..e1f9478 100644
--- a/mpick.c
+++ b/mpick.c
@@ -220,6 +220,50 @@ mkexpr(enum op op)
 	return e;
 }
 
+static void
+freeexpr(struct expr *e)
+{
+	if (!e) return;
+	switch (e->op) {
+	case EXPR_OR:
+	case EXPR_AND:
+		freeexpr(e->a.expr);
+		freeexpr(e->b.expr);
+		break;
+	case EXPR_COND:
+		freeexpr(e->a.expr);
+		freeexpr(e->b.expr);
+		freeexpr(e->c.expr);
+		break;
+	case EXPR_NOT:
+		freeexpr(e->a.expr);
+		break;
+	case EXPR_REDIR_FILE:
+	case EXPR_REDIR_PIPE:
+		free(e->a.string);
+		free(e->b.string);
+		break;
+	case EXPR_STREQ:
+	case EXPR_STREQI:
+	case EXPR_GLOB:
+	case EXPR_GLOBI:
+	case EXPR_REGEX:
+	case EXPR_REGEXI:
+		switch (e->a.prop) {
+		case PROP_PATH:
+		case PROP_FROM:
+		case PROP_TO:
+			break;
+		default: free(e->a.string);
+		}
+		if (e->op == EXPR_REGEX || e->op == EXPR_REGEXI)
+			regfree(e->b.regex);
+		else
+			free(e->b.string);
+	}
+	free(e);
+}
+
 static struct expr *
 chain(struct expr *e1, enum op op, struct expr *e2)
 {
@@ -1299,6 +1343,8 @@ main(int argc, char *argv[])
 	if (Tflag && thr)
 		do_thr();
 
+	freeexpr(expr);
+
 	if (vflag)
 		fprintf(stderr, "%ld mails tested, %ld picked.\n", i, kept);