r5506 - trunk/eda/fped

werner at docs.openmoko.org werner at docs.openmoko.org
Fri Aug 21 10:34:17 CEST 2009


Author: werner
Date: 2009-08-21 10:34:17 +0200 (Fri, 21 Aug 2009)
New Revision: 5506

Added:
   trunk/eda/fped/leakcheck
Modified:
   trunk/eda/fped/delete.c
   trunk/eda/fped/delete.h
   trunk/eda/fped/expr.c
   trunk/eda/fped/fped.c
   trunk/eda/fped/inst.c
   trunk/eda/fped/inst.h
   trunk/eda/fped/obj.c
   trunk/eda/fped/obj.h
   trunk/eda/fped/util.c
   trunk/eda/fped/util.h
Log:
- delete.c: added more destructor functions
- deallocate all our data structures on exit (to help find memory leaks, bad
  pointers, and general logic errors)
- fixed memory leak when allocating pad names in instantiation
- added "magic" environment variable FPED_NO_GUI to run fped without 
  initializing Gtk+
- added valgrind wrapper "leakcheck"
- delete.c: destroy() now requires a deletion to exist
- vacate_op: free string expressions
- destroy_obj: free measurement labels
- delete_references: use do_delete_obj so the we don't bump the group number
- delete_frame: delete references after deleting the frame itself, so they end
  up on the stack above the frame and get destroyed first
- do_delete_vec: like above, even though it doesn't matter here



Modified: trunk/eda/fped/delete.c
===================================================================
--- trunk/eda/fped/delete.c	2009-08-21 06:45:58 UTC (rev 5505)
+++ trunk/eda/fped/delete.c	2009-08-21 08:34:17 UTC (rev 5506)
@@ -146,9 +146,6 @@
 	struct vec *walk, *prev;
 	struct deletion *del;
 
-	delete_vecs_by_ref(vec->frame->vecs, vec);
-	delete_objs_by_ref(&vec->frame->objs, vec);
-
 	prev = NULL;
 	for (walk = vec->frame->vecs; walk != vec; walk = walk->next)
 		prev = walk;
@@ -159,6 +156,9 @@
 	del = new_deletion(dt_vec);
 	del->u.vec.ref = vec;
 	del->u.vec.prev = prev;
+
+	delete_vecs_by_ref(vec->frame->vecs, vec);
+	delete_objs_by_ref(&vec->frame->objs, vec);
 }
 
 
@@ -204,6 +204,8 @@
 		free_expr(obj->u.arc.width);
 		break;
 	case ot_meas:
+		if (obj->u.meas.label)
+			free(obj->u.meas.label);
 		if (obj->u.meas.offset)
 			free_expr(obj->u.meas.offset);
 		break;
@@ -257,6 +259,20 @@
 /* ----- rows -------------------------------------------------------------- */
 
 
+static void destroy_row(struct row *row)
+{
+	struct value *next_value;
+
+	while (row->values) {
+		next_value = row->values->next;
+		free_expr(row->values->expr);
+		free(row->values);
+		row->values = next_value;
+	}
+	free(row);
+}
+
+
 void delete_row(struct row *row)
 {
 	struct deletion *del;
@@ -355,6 +371,23 @@
 /* ----- tables ------------------------------------------------------------ */
 
 
+static void destroy_table(struct table *table)
+{
+	struct var *next_var;
+
+	while (table->vars) {
+		next_var = table->vars->next;
+		free(table->vars);
+		table->vars = next_var;
+	}
+	while (table->rows) {
+		delete_row(table->rows);
+		destroy();
+	}
+	free(table);
+}
+
+
 void delete_table(struct table *table)
 {
 	struct frame *frame = table->vars->frame;
@@ -392,6 +425,14 @@
 /* ----- loops ------------------------------------------------------------- */
 
 
+static void destroy_loop(struct loop *loop)
+{
+	free_expr(loop->from.expr);
+	free_expr(loop->to.expr);
+	free(loop);
+}
+
+
 void delete_loop(struct loop *loop)
 {
 	struct frame *frame = loop->var.frame;
@@ -429,6 +470,28 @@
 /* ----- frames ------------------------------------------------------------ */
 
 
+static void destroy_frame(struct frame *frame)
+{
+	while (frame->tables) {
+		delete_table(frame->tables);
+		destroy();
+	}
+	while (frame->loops) {
+		delete_loop(frame->loops);
+		destroy();
+	}
+	while (frame->vecs) {
+		delete_vec(frame->vecs);
+		destroy();
+	}
+	while (frame->objs) {
+		delete_obj(frame->objs);
+		destroy();
+	}
+	free(frame);
+}
+
+
 static void delete_references(const struct frame *ref)
 {
 	struct frame *frame;
@@ -438,7 +501,7 @@
 		for (obj = frame->objs; obj; obj = obj->next)
 			if (obj->type == ot_frame)
 				if (obj->u.frame.ref == ref)
-					delete_obj(obj);
+					do_delete_obj(obj);
 }
 
 
@@ -447,7 +510,6 @@
 	struct deletion *del;
 
 	groups++;
-	delete_references(frame);
 
 	del = new_deletion(dt_frame);
 	del->u.frame.ref = frame;
@@ -459,6 +521,8 @@
 		frame->prev->next = frame->next;
 	else
 		frames = frame->next;
+
+	delete_references(frame);
 }
 
 
@@ -478,12 +542,10 @@
 /* ----- destroy/undelete interface ---------------------------------------- */
 
 
-int destroy(void)
+static void destroy_one(void)
 {
 	struct deletion *del;
 
-	if (!deletions)
-		return 0;
 	del = deletions;
 	switch (del->type) {
 	case dt_vec:
@@ -493,18 +555,39 @@
 		destroy_obj(del->u.obj.ref);
 		break;
 	case dt_frame:
-		abort();
-		/* @@@ later */
+		destroy_frame(del->u.frame.ref);
 		break;
+	case dt_loop:
+		destroy_loop(del->u.loop.ref);
+		break;
+	case dt_table:
+		destroy_table(del->u.table.ref);
+		break;
+	case dt_row:
+		destroy_row(del->u.row.ref);
+		break;
+	case dt_column:
+		abort(); /* @@@ later */
+		break;
 	default:
 		abort();
 	}
 	deletions = del->next;
 	free(del);
-	return 1;
 }
 
 
+void destroy(void)
+{
+	int group;
+
+	assert(deletions);
+	group = deletions->group;
+	while (deletions && deletions->group == group)
+		destroy_one();
+}
+
+
 static int undelete_one(void)
 {
 	struct deletion *del;
@@ -554,3 +637,10 @@
 		undelete_one();
 	return 1;
 }
+
+
+void purge(void)
+{
+	while (deletions)
+		destroy();
+}

Modified: trunk/eda/fped/delete.h
===================================================================
--- trunk/eda/fped/delete.h	2009-08-21 06:45:58 UTC (rev 5505)
+++ trunk/eda/fped/delete.h	2009-08-21 08:34:17 UTC (rev 5506)
@@ -25,7 +25,8 @@
 void delete_table(struct table *table);
 void delete_loop(struct loop *loop);
 void delete_frame(struct frame *frame);
-int destroy(void);
+void destroy(void);
 int undelete(void);
+void purge(void);
 
 #endif /* !DELETE_H */

Modified: trunk/eda/fped/expr.c
===================================================================
--- trunk/eda/fped/expr.c	2009-08-21 06:45:58 UTC (rev 5505)
+++ trunk/eda/fped/expr.c	2009-08-21 08:34:17 UTC (rev 5506)
@@ -459,9 +459,12 @@
 
 static void vacate_op(struct expr *expr)
 {
-	if (expr->op == op_num || expr->op == op_string ||
-	    expr->op == op_var)
+	if (expr->op == op_num || expr->op == op_var)
 		return;
+	if (expr->op == op_string) {
+		free(expr->u.str);
+		return;
+	}
 	if (expr->op == op_minus) {
 		free_expr(expr->u.op.a);
 		return;

Modified: trunk/eda/fped/fped.c
===================================================================
--- trunk/eda/fped/fped.c	2009-08-21 06:45:58 UTC (rev 5505)
+++ trunk/eda/fped/fped.c	2009-08-21 08:34:17 UTC (rev 5506)
@@ -22,6 +22,7 @@
 #include "inst.h"
 #include "file.h"
 #include "gui.h"
+#include "delete.h"
 #include "fpd.h"
 
 
@@ -55,10 +56,13 @@
 	int error;
 	int batch_write_kicad = 0, batch_write_ps = 0;
 	int c;
+	int have_gui = !getenv("FPED_NO_GUI");
 
-	error = gui_init(&argc, &argv);
-	if (error)
-		return error;
+	if (have_gui) {
+		error = gui_init(&argc, &argv);
+		if (error)
+			return error;
+	}
 
 	while ((c = getopt(argc, argv, "kp")) != EOF)
 		switch (c) {
@@ -102,15 +106,16 @@
 		write_kicad();
 	if (batch_write_ps)
 		write_ps();
-	if (batch_write_kicad || batch_write_ps)
-		exit(0);
-		
-//	inst_debug();
-	error = gui_main();
-	if (error)
-		return error;
+	if (have_gui && !batch_write_kicad && !batch_write_ps) {
+		error = gui_main();
+		if (error)
+			return error;
+	}
 
-//	dump(stdout);
+	purge();
+	inst_revert();
+	obj_cleanup();
+	unique_cleanup();
 
 	return 0;
 }

Modified: trunk/eda/fped/inst.c
===================================================================
--- trunk/eda/fped/inst.c	2009-08-21 06:45:58 UTC (rev 5505)
+++ trunk/eda/fped/inst.c	2009-08-21 08:34:17 UTC (rev 5506)
@@ -956,6 +956,18 @@
 }
 
 
+static void cleanup_inst(enum inst_prio prio, const struct inst *inst)
+{
+	switch (prio) {
+	case ip_pad:
+		free(inst->u.pad.name);
+		break;
+	default:
+		break;
+	}
+}
+
+
 static void free_pkgs(struct pkg *pkg)
 {
 	enum inst_prio prio;
@@ -967,6 +979,7 @@
 		FOR_INST_PRIOS_UP(prio)
 			for (inst = pkg->insts[prio]; inst; inst = next) {
 				next = inst->next;
+				cleanup_inst(prio, inst);
 				free(inst);
 			}
 		reset_samples(pkg->samples, pkg->n_samples);

Modified: trunk/eda/fped/inst.h
===================================================================
--- trunk/eda/fped/inst.h	2009-08-21 06:45:58 UTC (rev 5505)
+++ trunk/eda/fped/inst.h	2009-08-21 08:34:17 UTC (rev 5506)
@@ -88,7 +88,7 @@
 			unit_type width;
 		} rect;
 		struct {
-			const char *name;
+			char *name;
 			struct coord other;
 		} pad;
 		struct {

Added: trunk/eda/fped/leakcheck
===================================================================
--- trunk/eda/fped/leakcheck	                        (rev 0)
+++ trunk/eda/fped/leakcheck	2009-08-21 08:34:17 UTC (rev 5506)
@@ -0,0 +1,13 @@
+#!/bin/sh
+#valgrind --leak-check=full --show-reachable=yes --suppressions=leak.supp \
+#  ./fped "$@"
+
+#
+# Seems that we can't suppress warnings from gtk_init, so we use FPED_NO_GUI
+# to avoid bringing up Gtk+ at all.
+#
+FPED_NO_GUI=y valgrind --leak-check=full --show-reachable=yes \
+  ./fped "$@"
+
+#valgrind --leak-check=full --show-reachable=no \
+#  ./fped "$@"


Property changes on: trunk/eda/fped/leakcheck
___________________________________________________________________
Name: svn:executable
   + *

Modified: trunk/eda/fped/obj.c
===================================================================
--- trunk/eda/fped/obj.c	2009-08-21 06:45:58 UTC (rev 5505)
+++ trunk/eda/fped/obj.c	2009-08-21 08:34:17 UTC (rev 5506)
@@ -20,6 +20,7 @@
 #include "expr.h"
 #include "meas.h"
 #include "inst.h"
+#include "delete.h"
 #include "obj.h"
 
 
@@ -288,3 +289,16 @@
 		inst_revert();
 	return ok;
 }
+
+
+/* ----- deallocation ------------------------------------------------------ */
+
+
+void obj_cleanup(void)
+{
+	free(pkg_name);
+	while (frames) {
+		delete_frame(frames);
+		destroy();
+	}
+}

Modified: trunk/eda/fped/obj.h
===================================================================
--- trunk/eda/fped/obj.h	2009-08-21 06:45:58 UTC (rev 5505)
+++ trunk/eda/fped/obj.h	2009-08-21 08:34:17 UTC (rev 5506)
@@ -191,5 +191,6 @@
 
 
 int instantiate(void);
+void obj_cleanup(void);
 
 #endif /* !OBJ_H */

Modified: trunk/eda/fped/util.c
===================================================================
--- trunk/eda/fped/util.c	2009-08-21 06:45:58 UTC (rev 5505)
+++ trunk/eda/fped/util.c	2009-08-21 08:34:17 UTC (rev 5506)
@@ -79,7 +79,7 @@
 
 
 static struct unique {
-	const char *s;
+	char *s;
 	struct unique *next;
 } *uniques = NULL;
 
@@ -98,3 +98,17 @@
 	(*walk)->next = NULL;
 	return (*walk)->s;
 }
+
+
+void unique_cleanup(void)
+{
+	struct unique *next;
+
+	while (uniques) {
+		next = uniques->next;
+		free(uniques->s);
+		free(uniques);
+		uniques = next;
+	}
+}
+

Modified: trunk/eda/fped/util.h
===================================================================
--- trunk/eda/fped/util.h	2009-08-21 06:45:58 UTC (rev 5505)
+++ trunk/eda/fped/util.h	2009-08-21 08:34:17 UTC (rev 5506)
@@ -60,5 +60,6 @@
 int is_id(const char *s);
 
 const char *unique(const char *s);
+void unique_cleanup(void);
 
 #endif /* !UTIL_H */




More information about the commitlog mailing list