From dbc9fcdf344f4dc9e60e1d7aa76862f13ea9ae11 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Sun, 17 Apr 2022 16:54:57 +0200 Subject: [PATCH 1/4] Issue #47: AddVertex count column to tree view --- gds-render-gui.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/gds-render-gui.c b/gds-render-gui.c index 616ebc4..d29062f 100644 --- a/gds-render-gui.c +++ b/gds-render-gui.c @@ -48,6 +48,7 @@ enum cell_store_columns { CELL_SEL_LIBRARY = 0, CELL_SEL_CELL, CELL_SEL_CELL_ERROR_STATE, /**< Used for cell color and selectability */ + CELL_SEL_STAT, CELL_SEL_COLUMN_COUNT /**< @brief Not a column. Used to determine count of columns */ }; @@ -219,10 +220,11 @@ int gds_render_gui_setup_cell_selector(GdsRenderGui *self) { GtkCellRenderer *render_cell; GtkCellRenderer *render_lib; + GtkCellRenderer *render_vertex_count; GtkTreeViewColumn *column; self->cell_tree_store = gtk_tree_store_new(CELL_SEL_COLUMN_COUNT, G_TYPE_POINTER, - G_TYPE_POINTER, G_TYPE_UINT); + G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_STRING); /* Searching */ self->cell_filter = GTK_TREE_MODEL_FILTER( @@ -238,6 +240,7 @@ int gds_render_gui_setup_cell_selector(GdsRenderGui *self) render_cell = lib_cell_renderer_new(); render_lib = lib_cell_renderer_new(); + render_vertex_count = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Library"), render_lib, "gds-lib", CELL_SEL_LIBRARY, NULL); gtk_tree_view_append_column(self->cell_tree_view, column); @@ -246,6 +249,10 @@ int gds_render_gui_setup_cell_selector(GdsRenderGui *self) "error-level", CELL_SEL_CELL_ERROR_STATE, NULL); gtk_tree_view_append_column(self->cell_tree_view, column); + column = gtk_tree_view_column_new_with_attributes(_("Vertex Count"), render_vertex_count, "text", CELL_SEL_STAT, + NULL); + gtk_tree_view_append_column(self->cell_tree_view, column); + /* Callback for selection * This prevents selecting a library */ From 22bc3a18d7e86b7f77c809e05ba51858c3db1734 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Sun, 17 Apr 2022 17:40:18 +0200 Subject: [PATCH 2/4] Issue #47: Add renderer for cell statistics and render dummy value --- cell-selector/cell-statistics-renderer.c | 105 ++++++++++++++++++ gds-render-gui.c | 12 +- .../cell-selector/cell-statistics-renderer.h | 56 ++++++++++ 3 files changed, 170 insertions(+), 3 deletions(-) create mode 100644 cell-selector/cell-statistics-renderer.c create mode 100644 include/gds-render/cell-selector/cell-statistics-renderer.h diff --git a/cell-selector/cell-statistics-renderer.c b/cell-selector/cell-statistics-renderer.c new file mode 100644 index 0000000..42588fa --- /dev/null +++ b/cell-selector/cell-statistics-renderer.c @@ -0,0 +1,105 @@ +/* + * GDSII-Converter + * Copyright (C) 2022 Mario Hüttel + * + * This file is part of GDSII-Converter. + * + * GDSII-Converter is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * GDSII-Converter is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GDSII-Converter. If not, see . + */ + +/** + * @file cell-statistics-renderer.c + * @brief CellStatisticsRenderer GObject Class + * @author Mario Hüttel + */ + +/** + * @addtogroup CellStatisticsRenderer + * @{ + */ + +#include + +G_DEFINE_TYPE(CellStatisticsRenderer, cell_statistics_renderer, GTK_TYPE_CELL_RENDERER_TEXT) + +enum { + PROP_CELL_STAT = 1, + PROP_COUNT +}; + +static void cell_statistics_renderer_set_property(GObject *object, + guint param_id, + const GValue *value, + GParamSpec *pspec) +{ + GValue val = G_VALUE_INIT; + GString *string; + const struct gds_cell_statistics *cell_stat; + + switch (param_id) { + case PROP_CELL_STAT: + cell_stat = (const struct gds_cell_statistics *)g_value_get_pointer(value); + g_value_init(&val, G_TYPE_STRING); + string = g_string_new_len("", 5); + if (cell_stat) + g_string_printf(string, "%zu", cell_stat->vertex_count); + g_value_set_string(&val, string->str); + g_object_set_property(object, "text", &val); + g_value_unset(&val); + g_string_free(string, TRUE); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); + break; + } +} + +static void cell_statistics_renderer_get_property(GObject *object, + guint param_id, + GValue *value, + GParamSpec *pspec) +{ + (void)value; + + switch (param_id) { + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec); + break; + } +} + +static GParamSpec *properties[PROP_COUNT]; + +void cell_statistics_renderer_class_init(CellStatisticsRendererClass *klass) +{ + GObjectClass *oclass = G_OBJECT_CLASS(klass); + + oclass->set_property = cell_statistics_renderer_set_property; + oclass->get_property = cell_statistics_renderer_get_property; + + properties[PROP_CELL_STAT] = g_param_spec_pointer("cell-stat", "cell-stat", + "Cell statistics", G_PARAM_WRITABLE); + g_object_class_install_properties(oclass, PROP_COUNT, properties); +} + +void cell_statistics_renderer_init(CellStatisticsRenderer *self) +{ + (void)self; +} + +GtkCellRenderer *cell_statistics_renderer_new(void) +{ + return GTK_CELL_RENDERER(g_object_new(TYPE_GDS_RENDER_CELL_STAT_RENDERER, NULL)); +} + +/** @} */ diff --git a/gds-render-gui.c b/gds-render-gui.c index d29062f..adf02ac 100644 --- a/gds-render-gui.c +++ b/gds-render-gui.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -224,7 +225,7 @@ int gds_render_gui_setup_cell_selector(GdsRenderGui *self) GtkTreeViewColumn *column; self->cell_tree_store = gtk_tree_store_new(CELL_SEL_COLUMN_COUNT, G_TYPE_POINTER, - G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_STRING); + G_TYPE_POINTER, G_TYPE_UINT, G_TYPE_POINTER); /* Searching */ self->cell_filter = GTK_TREE_MODEL_FILTER( @@ -240,7 +241,7 @@ int gds_render_gui_setup_cell_selector(GdsRenderGui *self) render_cell = lib_cell_renderer_new(); render_lib = lib_cell_renderer_new(); - render_vertex_count = gtk_cell_renderer_text_new(); + render_vertex_count = cell_statistics_renderer_new(); column = gtk_tree_view_column_new_with_attributes(_("Library"), render_lib, "gds-lib", CELL_SEL_LIBRARY, NULL); gtk_tree_view_append_column(self->cell_tree_view, column); @@ -249,7 +250,7 @@ int gds_render_gui_setup_cell_selector(GdsRenderGui *self) "error-level", CELL_SEL_CELL_ERROR_STATE, NULL); gtk_tree_view_append_column(self->cell_tree_view, column); - column = gtk_tree_view_column_new_with_attributes(_("Vertex Count"), render_vertex_count, "text", CELL_SEL_STAT, + column = gtk_tree_view_column_new_with_attributes(_("Vertex Count"), render_vertex_count, "cell-stat", CELL_SEL_STAT, NULL); gtk_tree_view_append_column(self->cell_tree_view, column); @@ -262,6 +263,10 @@ int gds_render_gui_setup_cell_selector(GdsRenderGui *self) return 0; } +const struct gds_cell_statistics cc = { + .vertex_count = 12, +}; + /** * @brief Callback function of Load GDS button * @param button @@ -360,6 +365,7 @@ static void on_load_gds(gpointer button, gpointer user) CELL_SEL_CELL, gds_c, CELL_SEL_CELL_ERROR_STATE, cell_error_level, CELL_SEL_LIBRARY, gds_c->parent_library, + CELL_SEL_STAT, &cc, -1); } /* for cells */ } /* for libraries */ diff --git a/include/gds-render/cell-selector/cell-statistics-renderer.h b/include/gds-render/cell-selector/cell-statistics-renderer.h new file mode 100644 index 0000000..d45870a --- /dev/null +++ b/include/gds-render/cell-selector/cell-statistics-renderer.h @@ -0,0 +1,56 @@ +/* + * GDSII-Converter + * Copyright (C) 2022 Mario Hüttel + * + * This file is part of GDSII-Converter. + * + * GDSII-Converter is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * GDSII-Converter is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GDSII-Converter. If not, see . + */ + +/** + * @file cell-statistics-renderer.h + * @brief Header file for the CellStatisticsRenderer GObject Class + * @author Mario Hüttel + */ + +/** + * @addtogroup CellStatisticsRenderer + * @{ + */ + +#ifndef _CELL_STATISTICS_RENDERER_H_ +#define _CELL_STATISTICS_RENDERER_H_ + +#include +#include + +G_BEGIN_DECLS + +G_DECLARE_FINAL_TYPE(CellStatisticsRenderer, cell_statistics_renderer, GDS_RENDER, CELL_STAT_RENDERER, GtkCellRendererText) +#define TYPE_GDS_RENDER_CELL_STAT_RENDERER (cell_statistics_renderer_get_type()) + +typedef struct _CellStatisticsRenderer { + GtkCellRendererText super; +} CellStatisticsRenderer; + +/** + * @brief New Cell statistics renderer + * @return GObject + */ +GtkCellRenderer *cell_statistics_renderer_new(void); + +G_END_DECLS + +#endif /* _CELL_STATISTICS_RENDERER_H_ */ + +/** @} */ From c0ac6cc3c52f7d812c6b72f044f13af54f5ad225 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Sun, 17 Apr 2022 18:37:32 +0200 Subject: [PATCH 3/4] Move statistic calculation to parser. Show Vertex and GFX count in GUI. CLI -A param is now broken. Will implement in next commits. --- cell-selector/cell-statistics-renderer.c | 3 +- command-line.c | 13 +- gds-render-gui.c | 4 +- gds-utils/gds-parser.c | 32 ++++- gds-utils/gds-statistics.c | 118 ++++++------------ include/gds-render/gds-utils/gds-statistics.h | 38 +----- include/gds-render/gds-utils/gds-types.h | 19 +++ 7 files changed, 96 insertions(+), 131 deletions(-) diff --git a/cell-selector/cell-statistics-renderer.c b/cell-selector/cell-statistics-renderer.c index 42588fa..3f4737f 100644 --- a/cell-selector/cell-statistics-renderer.c +++ b/cell-selector/cell-statistics-renderer.c @@ -52,7 +52,8 @@ static void cell_statistics_renderer_set_property(GObject *object, g_value_init(&val, G_TYPE_STRING); string = g_string_new_len("", 5); if (cell_stat) - g_string_printf(string, "%zu", cell_stat->vertex_count); + g_string_printf(string, "%zu (%zu) | %zu (%zu)", cell_stat->total_vertex_count, + cell_stat->vertex_count, cell_stat->total_gfx_count, cell_stat->gfx_count); g_value_set_string(&val, string->str); g_object_set_property(object, "text", &val); g_value_unset(&val); diff --git a/command-line.c b/command-line.c index 7a40116..5ae18fa 100644 --- a/command-line.c +++ b/command-line.c @@ -297,6 +297,7 @@ static int printf_indented(int level, const char *format, ...) static void print_simple_stat(GList *lib_stat_list) { +#if 0 int indentation_level = 0; GList *lib_iter; GList *cell_iter; @@ -327,11 +328,13 @@ static void print_simple_stat(GList *lib_stat_list) printf_indented(indentation_level, "Graphics count: %zu\n", lib_stats->gfx_count); printf_indented(indentation_level, "Vertex count: %zu\n", lib_stats->vertex_count); } +#endif } static void print_table_stat(GList *lib_stat_list) { +#if 0 ft_table_t *table; GList *lib_stat_iter; GList *cell_stat_iter; @@ -361,7 +364,7 @@ static void print_table_stat(GList *lib_stat_list) printf("%s\n", ft_to_string(table)); ft_destroy_table(table); - +#endif } static void print_statistics(enum analysis_format format, GList *lib_stat_list) @@ -402,7 +405,6 @@ int command_line_analyze_lib(const char *format, const char *gds_name) int res; int ret = 0; GList *lib_iter; - GList *lib_stat_list = NULL; g_return_val_if_fail(gds_name, -1002); @@ -447,13 +449,6 @@ int command_line_analyze_lib(const char *format, const char *gds_name) } - gds_statistics_calc_library(lib_list, &lib_stat_list); - - print_statistics(fmt, lib_stat_list); - - /* Clean up the whole mess */ - - gds_statistics_free_lib_stat_list(&lib_stat_list); return_clear_libs: clear_lib_list(&lib_list); return_val: diff --git a/gds-render-gui.c b/gds-render-gui.c index adf02ac..33f756f 100644 --- a/gds-render-gui.c +++ b/gds-render-gui.c @@ -250,7 +250,7 @@ int gds_render_gui_setup_cell_selector(GdsRenderGui *self) "error-level", CELL_SEL_CELL_ERROR_STATE, NULL); gtk_tree_view_append_column(self->cell_tree_view, column); - column = gtk_tree_view_column_new_with_attributes(_("Vertex Count"), render_vertex_count, "cell-stat", CELL_SEL_STAT, + column = gtk_tree_view_column_new_with_attributes(_("Vertex | GFX Count"), render_vertex_count, "cell-stat", CELL_SEL_STAT, NULL); gtk_tree_view_append_column(self->cell_tree_view, column); @@ -365,7 +365,7 @@ static void on_load_gds(gpointer button, gpointer user) CELL_SEL_CELL, gds_c, CELL_SEL_CELL_ERROR_STATE, cell_error_level, CELL_SEL_LIBRARY, gds_c->parent_library, - CELL_SEL_STAT, &cc, + CELL_SEL_STAT, &gds_c->stats, -1); } /* for cells */ } /* for libraries */ diff --git a/gds-utils/gds-parser.c b/gds-utils/gds-parser.c index d09307e..8915e79 100644 --- a/gds-utils/gds-parser.c +++ b/gds-utils/gds-parser.c @@ -43,6 +43,7 @@ #include #include +#include /** * @brief Default units assumed for library. @@ -279,6 +280,10 @@ static GList *append_library(GList *curr_list, const struct gds_library_parsing_ lib->cell_names = NULL; /* Copy the settings into the library */ memcpy(&lib->parsing_opts, opts, sizeof(struct gds_library_parsing_opts)); + lib->stats.cell_count = 0; + lib->stats.gfx_count = 0; + lib->stats.reference_count = 0; + lib->stats.vertex_count = 0; } else return NULL; if (library_ptr) @@ -356,6 +361,10 @@ static GList *append_cell(GList *curr_list, struct gds_cell **cell_ptr) cell->parent_library = NULL; cell->checks.unresolved_child_count = GDS_CELL_CHECK_NOT_RUN; cell->checks.affected_by_reference_loop = GDS_CELL_CHECK_NOT_RUN; + cell->stats.reference_count = 0; + cell->stats.total_vertex_count = 0; + cell->stats.gfx_count = 0; + cell->stats.vertex_count = 0; } else return NULL; /* return cell */ @@ -605,6 +614,15 @@ static void scan_library_references(gpointer library_list_item, gpointer user) g_list_foreach(lib->cells, scan_cell_references_and_polygons, lib); } +static void calc_library_stats(gpointer library_list_item, gpointer user) +{ + struct gds_library *lib = (struct gds_library *)library_list_item; + (void)user; + + GDS_INF("Calculating stats for Library: %s\n", lib->name); + gds_statistics_calc_cummulative_counts_in_lib(lib); +} + /** * @brief gds_parse_date * @param buffer Buffer that contains the GDS Date field @@ -686,6 +704,7 @@ static void convert_aref_to_sref(struct gds_cell_array_instance *aref, struct gd for (row = 0; row < aref->rows; row++) { /* Create new instance for this row/column and configure data */ container_cell->child_cells = append_cell_ref(container_cell->child_cells, &sref_inst); + container_cell->stats.reference_count++; if (!sref_inst) { GDS_ERROR("Appending cell ref failed!"); continue; @@ -867,6 +886,7 @@ int parse_gds_from_file(const char *filename, GList **library_list, } current_cell->child_cells = append_cell_ref(current_cell->child_cells, ¤t_s_reference); + current_cell->stats.reference_count++; if (current_cell->child_cells == NULL) { GDS_ERROR("Memory allocation failed"); run = -4; @@ -896,6 +916,9 @@ int parse_gds_from_file(const char *filename, GList **library_list, : (current_graphics->gfx_type == GRAPHIC_PATH ? "path" : "box"))); current_graphics = NULL; + if (current_cell) { + current_cell->stats.gfx_count++; + } } if (current_s_reference != NULL) { GDS_INF("\tLeaving Reference\n"); @@ -1045,7 +1068,9 @@ int parse_gds_from_file(const char *filename, GList **library_list, current_graphics->vertices = append_vertex(current_graphics->vertices, x, y); GDS_INF("\t\tSet coordinate: %d/%d\n", x, y); - + if (current_cell) { + current_cell->stats.vertex_count++; + } } } else if (current_a_reference) { for (i = 0; i < 3; i++) { @@ -1161,8 +1186,13 @@ int parse_gds_from_file(const char *filename, GList **library_list, if (!run) { /* Iterate and find references to cells */ g_list_foreach(lib_list, scan_library_references, NULL); + + /* Calculate lib stats and cummulative total counts */ + g_list_foreach(lib_list, calc_library_stats, NULL); } + + *library_list = lib_list; free(workbuff); diff --git a/gds-utils/gds-statistics.c b/gds-utils/gds-statistics.c index c806cfc..2e37c7e 100644 --- a/gds-utils/gds-statistics.c +++ b/gds-utils/gds-statistics.c @@ -32,105 +32,61 @@ * @{ */ -void gds_statistics_calc_cell(const struct gds_cell *cell, struct gds_cell_statistics *stat) +#define MAX_RECURSION_DEPTH (1024) + +static void calculate_vertex_gfx_count_cell(struct gds_cell *cell, unsigned int recursion_depth) { - GList *iter; - GList *vertex_iter; - struct gds_graphics *gfx; + GList *cell_iter; + struct gds_cell_instance *cell_ref; + struct gds_cell *sub_cell; - if (!stat) { - fprintf(stderr, "Internal pointer error.\n"); + g_return_if_fail(cell); + + /* Check if cell has already been calculated */ + if (cell->stats.total_gfx_count && cell->stats.total_vertex_count) { + /* Return. This cell and all of its subcells have been calculated */ return; } - stat->cell = NULL; - stat->gfx_count = 0; - stat->reference_count = 0; - stat->vertex_count = 0; + /* Update with own vertex / GFX count */ + cell->stats.total_vertex_count = cell->stats.vertex_count; + cell->stats.total_gfx_count = cell->stats.gfx_count; - if (!cell) { - fprintf(stderr, "Internal pointer error.\n"); + /* Do not analyze further, if maximum recursion depth is reached */ + if (!recursion_depth) return; + for (cell_iter = cell->child_cells; cell_iter; cell_iter = g_list_next(cell_iter)) { + /* Scan all subcells recursively, if there are any */ + + cell_ref = (struct gds_cell_instance *)cell_iter->data; + sub_cell = (struct gds_cell *)cell_ref->cell_ref; + + calculate_vertex_gfx_count_cell(sub_cell, recursion_depth - 1); + + /* Increment count */ + cell->stats.total_vertex_count += sub_cell->stats.total_vertex_count; + cell->stats.total_gfx_count += sub_cell->stats.total_vertex_count; } - stat->cell = cell; - - /* Sum up references */ - for (iter = cell->child_cells; iter; iter = g_list_next(iter)) - stat->reference_count++; - - /* Sum up graphics objects and vertices */ - for (iter = cell->graphic_objs; iter; iter = g_list_next(iter)) { - gfx = (struct gds_graphics *)iter->data; - stat->gfx_count++; - for (vertex_iter = gfx->vertices; vertex_iter; vertex_iter = g_list_next(vertex_iter)) { - stat->vertex_count++; - } - } } -void gds_statistics_calc_library(GList *library_list, GList **lib_stat_list) -{ - GList *lib_iter; +void gds_statistics_calc_cummulative_counts_in_lib(struct gds_library *lib) +{ GList *cell_iter; - struct gds_lib_statistics *lib_stats; - struct gds_cell_statistics *cell_stats; - struct gds_library *gds_lib; struct gds_cell *cell; - /* Go through each library/cell and generate statistics */ - for (lib_iter = library_list; lib_iter; lib_iter = g_list_next(lib_iter)) { - gds_lib = (struct gds_library *)lib_iter->data; - lib_stats = (struct gds_lib_statistics *)malloc(sizeof(struct gds_lib_statistics)); - if (!lib_stats) { - g_error("Failed allocating memory"); - } + g_return_if_fail(lib); - lib_stats->library = gds_lib; - lib_stats->gfx_count = 0; - lib_stats->cell_count = 0; - lib_stats->reference_count = 0; - lib_stats->vertex_count = 0; - lib_stats->cell_statistics = NULL; - - for (cell_iter = gds_lib->cells; cell_iter; cell_iter = g_list_next(cell_iter)) { - cell = (struct gds_cell *)cell_iter->data; - cell_stats = (struct gds_cell_statistics *)malloc(sizeof(struct gds_cell_statistics)); - lib_stats->cell_count++; - gds_statistics_calc_cell(cell, cell_stats); - lib_stats->gfx_count += cell_stats->gfx_count; - lib_stats->reference_count += cell_stats->reference_count; - lib_stats->vertex_count += cell_stats->vertex_count; - lib_stats->cell_statistics = g_list_append(lib_stats->cell_statistics, cell_stats); - } - - *lib_stat_list = g_list_append(*lib_stat_list, lib_stats); - } /* for lib */ -} - -static void free_stat_object(gpointer stat_obj) -{ - if (stat_obj) - free(stat_obj); -} - -void gds_statistics_free_lib_stat_list(GList **lib_stat_list) -{ - GList *lib_iter; - struct gds_lib_statistics *lib_stats; - - g_return_if_fail(lib_stat_list); - g_return_if_fail(*lib_stat_list); - - for (lib_iter = *lib_stat_list; lib_iter; lib_iter = g_list_next(lib_iter)) { - lib_stats = (struct gds_lib_statistics *) lib_iter->data; - g_list_free_full(lib_stats->cell_statistics, - free_stat_object); + for (cell_iter = lib->cells; cell_iter; cell_iter = g_list_next(cell_iter)) { + cell = (struct gds_cell *)cell_iter->data; + calculate_vertex_gfx_count_cell(cell, MAX_RECURSION_DEPTH); + lib->stats.vertex_count += cell->stats.vertex_count; + lib->stats.cell_count++; + lib->stats.gfx_count += cell->stats.gfx_count; + lib->stats.reference_count += cell->stats.reference_count; } - g_list_free_full(*lib_stat_list, free_stat_object); - *lib_stat_list = NULL; } diff --git a/include/gds-render/gds-utils/gds-statistics.h b/include/gds-render/gds-utils/gds-statistics.h index 9378aa3..b67190f 100644 --- a/include/gds-render/gds-utils/gds-statistics.h +++ b/include/gds-render/gds-utils/gds-statistics.h @@ -35,43 +35,7 @@ #include -struct gds_cell_statistics { - size_t gfx_count; - size_t vertex_count; - size_t reference_count; - const struct gds_cell *cell; -}; - -struct gds_lib_statistics { - size_t gfx_count; - size_t vertex_count; - size_t reference_count; - size_t cell_count; - GList *cell_statistics; - const struct gds_library *library; -}; - -/** - * @brief Calculate statistics of a single cell - * @param[in] cell GDS cell - * @param[out] stat Statistics output - */ -void gds_statistics_calc_cell(const struct gds_cell *cell, - struct gds_cell_statistics *stat); - -/** - * @brief Calc statistic information for library - * @param[in] library_list List containing all libraries - * @param[in,out] lib_stat_list Statistic list - */ -void gds_statistics_calc_library(GList * library_list, - GList ** lib_stat_list); - -/** - * @brief Free library statistics GList - * @param[in,out] lib_stat_list List to free - */ -void gds_statistics_free_lib_stat_list(GList ** lib_stat_list); +void gds_statistics_calc_cummulative_counts_in_lib(struct gds_library *lib); /** @} */ diff --git a/include/gds-render/gds-utils/gds-types.h b/include/gds-render/gds-utils/gds-types.h index dc3f981..801ce34 100644 --- a/include/gds-render/gds-utils/gds-types.h +++ b/include/gds-render/gds-utils/gds-types.h @@ -65,6 +65,22 @@ struct gds_point { int y; }; +struct gds_cell_statistics { + size_t gfx_count; + size_t vertex_count; + size_t total_vertex_count; + size_t total_gfx_count; + size_t reference_count; +}; + +struct gds_lib_statistics { + size_t gfx_count; + size_t vertex_count; + size_t reference_count; + size_t cell_count; +}; + + /** * @brief Stores the result of the cell checks. */ @@ -127,6 +143,7 @@ struct gds_cell { GList *graphic_objs; /**< @brief List of #gds_graphics */ struct gds_library *parent_library; /**< @brief Pointer to parent library */ struct gds_cell_checks checks; /**< @brief Checking results */ + struct gds_cell_statistics stats; /**< @brief Optional statistic info */ }; /** @@ -147,8 +164,10 @@ struct gds_library { double unit_in_meters; /**< Length of a database unit in meters */ GList *cells; /**< List of #gds_cell that contains all cells in this library*/ GList *cell_names /**< List of strings that contains all cell names */; + struct gds_lib_statistics stats; }; + /** @} */ #endif /* __GDS_TYPES_H__ */ From c2ca2ff573168cbc2ca8d3f7be72385a34566dea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20H=C3=BCttel?= Date: Sun, 17 Apr 2022 20:07:57 +0200 Subject: [PATCH 4/4] Rework the analysis cmd option to work with new statistics functions --- command-line.c | 123 ++++++++++++++++++++++------------------- gds-utils/gds-parser.c | 3 +- 2 files changed, 68 insertions(+), 58 deletions(-) diff --git a/command-line.c b/command-line.c index 5ae18fa..ebe7352 100644 --- a/command-line.c +++ b/command-line.c @@ -61,18 +61,18 @@ struct analysis_format_cmdarg { static const struct analysis_format_cmdarg analysis_format_lookup[] = { - { - .format = ANA_FORMAT_SIMPLE, - .argument = "simple", - }, - { - .format = ANA_FORMAT_PRETTY, - .argument = "pretty", - }, - { - .format = ANA_FORMAT_CELLS_ONLY, - .argument = "cellsonly" - } +{ + .format = ANA_FORMAT_SIMPLE, + .argument = "simple", +}, +{ + .format = ANA_FORMAT_PRETTY, + .argument = "pretty", +}, +{ + .format = ANA_FORMAT_CELLS_ONLY, + .argument = "cellsonly" +} }; static int string_array_count(char **string_array) @@ -297,84 +297,92 @@ static int printf_indented(int level, const char *format, ...) static void print_simple_stat(GList *lib_stat_list) { -#if 0 int indentation_level = 0; GList *lib_iter; GList *cell_iter; - const struct gds_lib_statistics *lib_stats; - const struct gds_cell_statistics *cell_stats; + const struct gds_library *lib; + const struct gds_cell *cell; + const struct gds_lib_statistics *lib_stat; + const struct gds_cell_statistics *cell_stat; for (lib_iter = lib_stat_list; lib_iter; lib_iter = g_list_next(lib_iter)) { - lib_stats = (const struct gds_lib_statistics *)lib_iter->data; - printf_indented(indentation_level, "Library %s\n", lib_stats->library->name); + lib = (const struct gds_library *)lib_iter->data; + lib_stat = &lib->stats; + printf_indented(indentation_level, "Library %s\n", lib->name); indentation_level++; - for (cell_iter = lib_stats->cell_statistics; cell_iter; cell_iter = g_list_next(cell_iter)) { - cell_stats = (const struct gds_cell_statistics *)cell_iter->data; - printf_indented(indentation_level, "Cell %s\n", cell_stats->cell->name); + for (cell_iter = lib->cells; cell_iter; cell_iter = g_list_next(cell_iter)) { + cell = (const struct gds_cell *)cell_iter->data; + cell_stat = &cell->stats; + printf_indented(indentation_level, "Cell %s\n", cell->name); indentation_level++; - printf_indented(indentation_level, "Reference count: %zu\n", cell_stats->reference_count); - printf_indented(indentation_level, "Graphics count: %zu\n", cell_stats->gfx_count); - printf_indented(indentation_level, "Vertex count: %zu\n", cell_stats->vertex_count); + printf_indented(indentation_level, "Reference count: %zu\n", cell_stat->reference_count); + printf_indented(indentation_level, "Graphics count: %zu\n", cell_stat->gfx_count); + printf_indented(indentation_level, "Total Graphics count: %zu\n", cell_stat->total_gfx_count); + printf_indented(indentation_level, "Vertex count: %zu\n", cell_stat->vertex_count); + printf_indented(indentation_level, "Total Vertex count: %zu\n", cell_stat->total_vertex_count); printf_indented(indentation_level, "Unresolved children: %d\n", - cell_stats->cell->checks.unresolved_child_count); + cell->checks.unresolved_child_count); printf_indented(indentation_level, "Reference loop: %s\n", - cell_stats->cell->checks.affected_by_reference_loop ? "yes" : "no"); + cell->checks.affected_by_reference_loop ? "yes" : "no"); indentation_level--; } - printf_indented(indentation_level, "Cell count: %zu\n", lib_stats->cell_count); - printf_indented(indentation_level, "Reference count: %zu\n", lib_stats->reference_count); - printf_indented(indentation_level, "Graphics count: %zu\n", lib_stats->gfx_count); - printf_indented(indentation_level, "Vertex count: %zu\n", lib_stats->vertex_count); + printf_indented(indentation_level, "Cell count: %zu\n", lib_stat->cell_count); + printf_indented(indentation_level, "Reference count: %zu\n", lib_stat->reference_count); + printf_indented(indentation_level, "Graphics count: %zu\n", lib_stat->gfx_count); + printf_indented(indentation_level, "Vertex count: %zu\n", lib_stat->vertex_count); } -#endif - } -static void print_table_stat(GList *lib_stat_list) +static void table_stat_create_cell_row(struct gds_cell *cell, ft_table_t *tab) { -#if 0 - ft_table_t *table; - GList *lib_stat_iter; - GList *cell_stat_iter; - const struct gds_lib_statistics *lib_stats; - const struct gds_cell_statistics *cell_stats; + ft_printf_ln(tab, "%s|%s|%zu|%zu|%zu|%zu|%zu|%d|%s", + cell->parent_library->name, + cell->name, + cell->stats.gfx_count, + cell->stats.total_gfx_count, + cell->stats.vertex_count, + cell->stats.total_vertex_count, + cell->stats.reference_count, + cell->checks.unresolved_child_count, + cell->checks.affected_by_reference_loop ? "yes" : "no"); +} +static void table_stat_table_for_lib(struct gds_library *lib, ft_table_t *tab) +{ + ft_printf_ln(tab, "%s|%zu|%zu|-|%zu|-|%zu|-|-", + lib->name, + lib->stats.cell_count, + lib->stats.gfx_count, + lib->stats.vertex_count, + lib->stats.reference_count); + g_list_foreach(lib->cells, (GFunc)table_stat_create_cell_row, tab); +} + +static void print_table_stat(GList *lib_list) +{ + ft_table_t *table; table = ft_create_table(); ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER); + ft_write_ln(table, "Library", "Cell", "GFX", "GFX+", "Vertices", "Vertices+", "Refs", "Unresolved Refs", "Loops"); - ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER); - ft_write_ln(table, "Library", "Cell", "GFX", "Vertices", "Refs", "Unresolved Refs", "Loops"); - for (lib_stat_iter = lib_stat_list; lib_stat_iter; lib_stat_iter = g_list_next(lib_stat_iter)) { - lib_stats = (const struct gds_lib_statistics *)lib_stat_iter->data; - ft_printf_ln(table, "%s|%zu|%zu|%zu|%zu|-|-", lib_stats->library->name, lib_stats->cell_count, - lib_stats->gfx_count, lib_stats->vertex_count, lib_stats->reference_count); - for (cell_stat_iter = lib_stats->cell_statistics; cell_stat_iter; - cell_stat_iter = g_list_next(cell_stat_iter)) { - cell_stats = (const struct gds_cell_statistics *)cell_stat_iter->data; - ft_printf_ln(table, "%s|%s|%zu|%zu|%zu|%d|%d", lib_stats->library->name, cell_stats->cell->name, - cell_stats->gfx_count, cell_stats->vertex_count, cell_stats->reference_count, - cell_stats->cell->checks.unresolved_child_count, - cell_stats->cell->checks.affected_by_reference_loop); - } - } + g_list_foreach(lib_list, (GFunc)table_stat_table_for_lib, table); printf("%s\n", ft_to_string(table)); ft_destroy_table(table); -#endif } -static void print_statistics(enum analysis_format format, GList *lib_stat_list) +static void print_statistics(enum analysis_format format, GList *lib_list) { switch (format) { case ANA_FORMAT_PRETTY: - print_table_stat(lib_stat_list); + print_table_stat(lib_list); break; default: - print_simple_stat(lib_stat_list); + print_simple_stat(lib_list); break; } } @@ -448,6 +456,7 @@ int command_line_analyze_lib(const char *format, const char *gds_name) goto return_clear_libs; } + print_statistics(fmt, lib_list); return_clear_libs: clear_lib_list(&lib_list); diff --git a/gds-utils/gds-parser.c b/gds-utils/gds-parser.c index 8915e79..87ac3c2 100644 --- a/gds-utils/gds-parser.c +++ b/gds-utils/gds-parser.c @@ -284,8 +284,9 @@ static GList *append_library(GList *curr_list, const struct gds_library_parsing_ lib->stats.gfx_count = 0; lib->stats.reference_count = 0; lib->stats.vertex_count = 0; - } else + } else { return NULL; + } if (library_ptr) *library_ptr = lib;