diff --git a/TODO b/TODO index 3460d2f..bc8f02e 100644 --- a/TODO +++ b/TODO @@ -34,8 +34,6 @@ Bugs: - whenever we call parse_* for input parsing, we may leak lots of expressions - can't edit measurement labels through the GUI - r of rpads is misleading, particularly if we have a circle -- using variables in a measurement offset causes a crash because evaluation - takes place after all table entries have been visited Code cleanup: - merge edit_unique with edit_name diff --git a/fped.c b/fped.c index 48c27f9..ab753e3 100644 --- a/fped.c +++ b/fped.c @@ -56,13 +56,10 @@ 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"); - if (have_gui) { - error = gui_init(&argc, &argv); - if (error) - return error; - } + error = gui_init(&argc, &argv); + if (error) + return error; while ((c = getopt(argc, argv, "kp")) != EOF) switch (c) { @@ -106,7 +103,7 @@ int main(int argc, char **argv) write_kicad(); if (batch_write_ps) write_ps(); - if (have_gui && !batch_write_kicad && !batch_write_ps) { + if (!batch_write_kicad && !batch_write_ps) { error = gui_main(); if (error) return error; diff --git a/gui.c b/gui.c index 5049bd2..31ca821 100644 --- a/gui.c +++ b/gui.c @@ -139,6 +139,15 @@ static void make_tool_bar(GtkWidget *hbox, GdkDrawable *drawable) } +static void cleanup_tool_bar(void) +{ + g_object_unref(stuff_image[0]); + g_object_unref(stuff_image[1]); + g_object_unref(meas_image[0]); + g_object_unref(meas_image[1]); +} + + static void make_top_bar(GtkWidget *vbox) { GtkWidget *hbox; @@ -248,5 +257,9 @@ int gui_main(void) gtk_main(); + gui_cleanup_style(); + gui_cleanup_tools(); + cleanup_tool_bar(); + return 0; } diff --git a/gui_style.c b/gui_style.c index c355bb4..f55307c 100644 --- a/gui_style.c +++ b/gui_style.c @@ -74,3 +74,9 @@ void gui_setup_style(GdkDrawable *drawable) item_list_font = pango_font_description_from_string(ITEM_LIST_FONT); } + + +void gui_cleanup_style(void) +{ + pango_font_description_free(item_list_font); +} diff --git a/gui_style.h b/gui_style.h index 1fbdb0a..cf101d9 100644 --- a/gui_style.h +++ b/gui_style.h @@ -115,5 +115,6 @@ extern GdkGC *gc_frame[mode_n]; extern PangoFontDescription *item_list_font; void gui_setup_style(GdkDrawable *drawable); +void gui_cleanup_style(void); #endif /* !GUI_STYLE_H */ diff --git a/gui_tool.c b/gui_tool.c index de17af5..65bc0ea 100644 --- a/gui_tool.c +++ b/gui_tool.c @@ -1044,3 +1044,13 @@ GtkWidget *gui_setup_tools(GdkDrawable *drawable) return bar; } + + +void gui_cleanup_tools(void) +{ + g_object_unref(frame_image); + g_object_unref(frame_image_locked); + g_object_unref(frame_image_ready); + g_object_unref(delete_image[0]); + g_object_unref(delete_image[1]); +} diff --git a/gui_tool.h b/gui_tool.h index 78a2d64..05e1705 100644 --- a/gui_tool.h +++ b/gui_tool.h @@ -77,5 +77,6 @@ void tool_selected_inst(struct inst *inst); void tool_reset(void); GtkWidget *gui_setup_tools(GdkDrawable *drawable); +void gui_cleanup_tools(void); #endif /* !GUI_TOOL_H */ diff --git a/inst.c b/inst.c index 38e94e6..2b99090 100644 --- a/inst.c +++ b/inst.c @@ -803,18 +803,28 @@ static struct inst_ops meas_ops = { }; -int inst_meas(struct obj *obj, - struct coord from, struct coord to, unit_type offset) +static struct inst *find_meas_hint(const struct obj *obj) +{ + struct inst *inst; + + for (inst = curr_pkg->insts[ip_meas]; inst; inst = inst->next) + if (inst->obj == obj) + break; + return inst; +} + + +int inst_meas(struct obj *obj, struct coord from, struct coord to) { struct inst *inst; struct coord a1, b1; - inst = add_inst(&meas_ops, ip_meas, from); - inst->obj = obj; + inst = find_meas_hint(obj); + assert(inst); + inst->base = from; inst->u.meas.end = to; - inst->u.meas.offset = offset; - inst->active = 1; /* measurements are always active */ /* @@@ we still need to consider the text size as well */ + update_bbox(&inst->bbox, from); update_bbox(&inst->bbox, to); project_meas(inst, &a1, &b1); update_bbox(&inst->bbox, a1); @@ -824,6 +834,21 @@ int inst_meas(struct obj *obj, } +void inst_meas_hint(struct obj *obj, unit_type offset) +{ + static const struct coord zero = { 0, 0 }; + struct inst *inst; + + inst = find_meas_hint(obj); + if (inst) + return; + inst = add_inst(&meas_ops, ip_meas, zero); + inst->obj = obj; + inst->u.meas.offset = offset; + inst->active = 1; /* measurements are always active */ +} + + /* ----- direct editing of objects ----------------------------------------- */ diff --git a/inst.h b/inst.h index 8b1f9ab..0351d13 100644 --- a/inst.h +++ b/inst.h @@ -164,8 +164,8 @@ int inst_rect(struct obj *obj, struct coord a, struct coord b, unit_type width); int inst_pad(struct obj *obj, const char *name, struct coord a, struct coord b); int inst_arc(struct obj *obj, struct coord center, struct coord start, struct coord stop, unit_type width); -int inst_meas(struct obj *obj, struct coord from, struct coord to, - unit_type offset); +int inst_meas(struct obj *obj, struct coord from, struct coord to); +void inst_meas_hint(struct obj *obj, unit_type offset); void inst_begin_active(int active); void inst_end_active(void); diff --git a/leak.supp b/leak.supp new file mode 100644 index 0000000..cc6770d --- /dev/null +++ b/leak.supp @@ -0,0 +1,31 @@ +{ + gtk_internal + Memcheck:Leak + ... + fun:gtk_init +} + +{ + lex + Memcheck:Leak + fun:malloc + ... + fun:yyensure_buffer_stack + ... +} + +{ + pango_leaks_like_crazy + Memcheck:Leak + ... + fun:pango_* + ... +} + +{ + gdk_pixbuf_new_from_xpm_data_leaks_through_dlopen + Memcheck:Leak + ... + fun:dlopen + ... +} diff --git a/leakcheck b/leakcheck index 8c6920c..1d4c060 100755 --- a/leakcheck +++ b/leakcheck @@ -1,13 +1,4 @@ #!/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 \ +valgrind --leak-check=full --show-reachable=yes --num-callers=50 \ + --suppressions=leak.supp \ ./fped "$@" - -#valgrind --leak-check=full --show-reachable=no \ -# ./fped "$@" diff --git a/meas.c b/meas.c index 27e5aec..734e231 100644 --- a/meas.c +++ b/meas.c @@ -231,7 +231,6 @@ static int instantiate_meas_pkg(void) const struct meas *meas; struct coord a0, b0; lt_op_type lt; - struct num offset; for (obj = root_frame->objs; obj; obj = obj->next) { if (obj->type != ot_meas) @@ -250,18 +249,8 @@ static int instantiate_meas_pkg(void) b0 = meas_find_max(lt, curr_pkg->samples[meas->high->n]); - if (!meas->offset) - offset.n = 0; - else { - offset = eval_unit(meas->offset, root_frame); - if (is_undef(offset)) { - instantiation_error = obj; - return 0; - } - } inst_meas(obj, - meas->inverted ? b0 : a0, meas->inverted ? a0 : b0, - offset.n); + meas->inverted ? b0 : a0, meas->inverted ? a0 : b0); } return 1; } diff --git a/obj.c b/obj.c index 3b09ff7..54ba7e1 100644 --- a/obj.c +++ b/obj.c @@ -94,10 +94,15 @@ error: static int generate_objs(struct frame *frame, struct coord base, int active) { + static const struct num zero_offset = { + .type = nt_mm, + .exponent = 0, + .n = 0, + }; struct obj *obj; char *name; int ok; - struct num width; + struct num width, offset; for (obj = frame->objs; obj; obj = obj->next) switch (obj->type) { @@ -150,6 +155,12 @@ static int generate_objs(struct frame *frame, struct coord base, int active) goto error; break; case ot_meas: + assert(frame == root_frame); + offset = eval_unit_default(obj->u.meas.offset, frame, + zero_offset); + if (is_undef(offset)) + goto error; + inst_meas_hint(obj, offset.n); break; default: abort();