- 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



git-svn-id: http://svn.openmoko.org/trunk/eda/fped@5506 99fdad57-331a-0410-800a-d7fa5415bdb3
This commit is contained in:
werner 2009-08-21 08:34:17 +00:00
parent 2737f8a3fa
commit 9e7e804d1a
11 changed files with 182 additions and 27 deletions

112
delete.c
View File

@ -146,9 +146,6 @@ static void do_delete_vec(struct vec *vec)
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 @@ static void do_delete_vec(struct vec *vec)
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 @@ static void destroy_obj(struct obj *obj)
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 @@ static void undelete_obj(struct obj *obj, struct obj *prev)
/* ----- 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 @@ static void undelete_column(const struct column *col)
/* ----- 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 @@ static void undelete_table(struct table *table, struct table *prev)
/* ----- 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 @@ static void undelete_loop(struct loop *loop, struct loop *prev)
/* ----- 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 @@ static void delete_references(const struct frame *ref)
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 @@ void delete_frame(struct frame *frame)
struct deletion *del;
groups++;
delete_references(frame);
del = new_deletion(dt_frame);
del->u.frame.ref = frame;
@ -459,6 +521,8 @@ void delete_frame(struct frame *frame)
frame->prev->next = frame->next;
else
frames = frame->next;
delete_references(frame);
}
@ -478,12 +542,10 @@ static void undelete_frame(struct frame *frame, struct frame *prev)
/* ----- 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,15 +555,36 @@ int destroy(void)
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();
}
@ -554,3 +637,10 @@ int undelete(void)
undelete_one();
return 1;
}
void purge(void)
{
while (deletions)
destroy();
}

View File

@ -25,7 +25,8 @@ void delete_column(struct table *table, int n);
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 */

7
expr.c
View File

@ -459,9 +459,12 @@ struct expr *parse_expr(const char *s)
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;

27
fped.c
View File

@ -22,6 +22,7 @@
#include "inst.h"
#include "file.h"
#include "gui.h"
#include "delete.h"
#include "fpd.h"
@ -55,10 +56,13 @@ int main(int argc, char **argv)
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 @@ int main(int argc, char **argv)
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;
}

13
inst.c
View File

@ -956,6 +956,18 @@ struct bbox inst_get_bbox(void)
}
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 @@ static void free_pkgs(struct pkg *pkg)
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);

2
inst.h
View File

@ -88,7 +88,7 @@ struct inst {
unit_type width;
} rect;
struct {
const char *name;
char *name;
struct coord other;
} pad;
struct {

13
leakcheck Executable file
View File

@ -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 "$@"

14
obj.c
View File

@ -20,6 +20,7 @@
#include "expr.h"
#include "meas.h"
#include "inst.h"
#include "delete.h"
#include "obj.h"
@ -288,3 +289,16 @@ int instantiate(void)
inst_revert();
return ok;
}
/* ----- deallocation ------------------------------------------------------ */
void obj_cleanup(void)
{
free(pkg_name);
while (frames) {
delete_frame(frames);
destroy();
}
}

1
obj.h
View File

@ -191,5 +191,6 @@ extern void *instantiation_error;
int instantiate(void);
void obj_cleanup(void);
#endif /* !OBJ_H */

16
util.c
View File

@ -79,7 +79,7 @@ int is_id(const char *s)
static struct unique {
const char *s;
char *s;
struct unique *next;
} *uniques = NULL;
@ -98,3 +98,17 @@ const char *unique(const char *s)
(*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;
}
}

1
util.h
View File

@ -60,5 +60,6 @@ int is_id_char(char c, int first);
int is_id(const char *s);
const char *unique(const char *s);
void unique_cleanup(void);
#endif /* !UTIL_H */