11 Commits

6 changed files with 184 additions and 127 deletions

View File

@@ -19,7 +19,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - name: Checkout Repository
uses: actions/checkout@v2
with:
submodules: recursive
- name: Install system dependencies - name: Install system dependencies
if: runner.os == 'Linux' if: runner.os == 'Linux'

View File

@@ -61,18 +61,18 @@ struct analysis_format_cmdarg {
static const struct analysis_format_cmdarg analysis_format_lookup[] = { static const struct analysis_format_cmdarg analysis_format_lookup[] = {
{ {
.format = ANA_FORMAT_SIMPLE, .format = ANA_FORMAT_SIMPLE,
.argument = "simple", .argument = "simple",
}, },
{ {
.format = ANA_FORMAT_PRETTY, .format = ANA_FORMAT_PRETTY,
.argument = "pretty", .argument = "pretty",
}, },
{ {
.format = ANA_FORMAT_CELLS_ONLY, .format = ANA_FORMAT_CELLS_ONLY,
.argument = "cellsonly" .argument = "cellsonly"
} }
}; };
static int string_array_count(char **string_array) 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) static void print_simple_stat(GList *lib_stat_list)
{ {
#if 0
int indentation_level = 0; int indentation_level = 0;
GList *lib_iter; GList *lib_iter;
GList *cell_iter; GList *cell_iter;
const struct gds_lib_statistics *lib_stats; const struct gds_library *lib;
const struct gds_cell_statistics *cell_stats; 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)) { 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; lib = (const struct gds_library *)lib_iter->data;
printf_indented(indentation_level, "Library %s\n", lib_stats->library->name); lib_stat = &lib->stats;
printf_indented(indentation_level, "Library %s\n", lib->name);
indentation_level++; indentation_level++;
for (cell_iter = lib_stats->cell_statistics; cell_iter; cell_iter = g_list_next(cell_iter)) { for (cell_iter = lib->cells; cell_iter; cell_iter = g_list_next(cell_iter)) {
cell_stats = (const struct gds_cell_statistics *)cell_iter->data; cell = (const struct gds_cell *)cell_iter->data;
printf_indented(indentation_level, "Cell %s\n", cell_stats->cell->name); cell_stat = &cell->stats;
printf_indented(indentation_level, "Cell %s\n", cell->name);
indentation_level++; indentation_level++;
printf_indented(indentation_level, "Reference count: %zu\n", cell_stats->reference_count); printf_indented(indentation_level, "Reference count: %zu\n", cell_stat->reference_count);
printf_indented(indentation_level, "Graphics count: %zu\n", cell_stats->gfx_count); printf_indented(indentation_level, "Graphics count: %zu\n", cell_stat->gfx_count);
printf_indented(indentation_level, "Vertex count: %zu\n", cell_stats->vertex_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", 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", 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--; indentation_level--;
} }
printf_indented(indentation_level, "Cell count: %zu\n", lib_stats->cell_count); printf_indented(indentation_level, "Cell count: %zu\n", lib_stat->cell_count);
printf_indented(indentation_level, "Reference count: %zu\n", lib_stats->reference_count); printf_indented(indentation_level, "Reference count: %zu\n", lib_stat->reference_count);
printf_indented(indentation_level, "Graphics count: %zu\n", lib_stats->gfx_count); printf_indented(indentation_level, "Graphics count: %zu\n", lib_stat->gfx_count);
printf_indented(indentation_level, "Vertex count: %zu\n", lib_stats->vertex_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_printf_ln(tab, "%s|%s|%zu|%zu|%zu|%zu|%zu|%d|%s",
ft_table_t *table; cell->parent_library->name,
GList *lib_stat_iter; cell->name,
GList *cell_stat_iter; cell->stats.gfx_count,
const struct gds_lib_statistics *lib_stats; cell->stats.total_gfx_count,
const struct gds_cell_statistics *cell_stats; 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(); table = ft_create_table();
ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER); 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); g_list_foreach(lib_list, (GFunc)table_stat_table_for_lib, table);
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);
}
}
printf("%s\n", ft_to_string(table)); printf("%s\n", ft_to_string(table));
ft_destroy_table(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) { switch (format) {
case ANA_FORMAT_PRETTY: case ANA_FORMAT_PRETTY:
print_table_stat(lib_stat_list); print_table_stat(lib_list);
break; break;
default: default:
print_simple_stat(lib_stat_list); print_simple_stat(lib_list);
break; break;
} }
} }
@@ -448,6 +456,7 @@ int command_line_analyze_lib(const char *format, const char *gds_name)
goto return_clear_libs; goto return_clear_libs;
} }
print_statistics(fmt, lib_list);
return_clear_libs: return_clear_libs:
clear_lib_list(&lib_list); clear_lib_list(&lib_list);

View File

@@ -274,25 +274,13 @@ const struct gds_cell_statistics cc = {
*/ */
static void on_load_gds(gpointer button, gpointer user) static void on_load_gds(gpointer button, gpointer user)
{ {
GList *cell; (void)button;
GtkTreeIter libiter;
GtkTreeIter celliter;
GList *lib;
struct gds_library *gds_lib;
struct gds_cell *gds_c;
GdsRenderGui *self; GdsRenderGui *self;
GtkWidget *open_dialog; GtkWidget *open_dialog;
GtkFileChooser *file_chooser; GtkFileChooser *file_chooser;
GtkFileFilter *filter; GtkFileFilter *filter;
GtkStyleContext *button_style;
gint dialog_result; gint dialog_result;
int gds_result;
char *filename; char *filename;
unsigned int cell_error_level;
const struct gds_library_parsing_opts gds_parsing_options = {
.simplified_polygons = 1,
};
self = RENDERER_GUI(user); self = RENDERER_GUI(user);
if (!self) if (!self)
@@ -319,59 +307,9 @@ static void on_load_gds(gpointer button, gpointer user)
/* Get File name */ /* Get File name */
filename = gtk_file_chooser_get_filename(file_chooser); filename = gtk_file_chooser_get_filename(file_chooser);
gtk_tree_store_clear(self->cell_tree_store); gds_render_gui_open_gds(self, filename);
clear_lib_list(&self->gds_libraries);
/* Parse new GDSII file */
gds_result = parse_gds_from_file(filename, &self->gds_libraries, &gds_parsing_options);
/* Delete file name afterwards */
g_free(filename); g_free(filename);
if (gds_result)
goto end_destroy;
/* remove suggested action from Open button */
button_style = gtk_widget_get_style_context(GTK_WIDGET(button));
gtk_style_context_remove_class(button_style, "suggested-action");
for (lib = self->gds_libraries; lib != NULL; lib = lib->next) {
gds_lib = (struct gds_library *)lib->data;
/* Create top level iter */
gtk_tree_store_append(self->cell_tree_store, &libiter, NULL);
gtk_tree_store_set(self->cell_tree_store, &libiter,
CELL_SEL_LIBRARY, gds_lib,
-1);
/* Check this library. This might take a while */
(void)gds_tree_check_cell_references(gds_lib);
(void)gds_tree_check_reference_loops(gds_lib);
for (cell = gds_lib->cells; cell != NULL; cell = cell->next) {
gds_c = (struct gds_cell *)cell->data;
gtk_tree_store_append(self->cell_tree_store, &celliter, &libiter);
/* Get the checking results for this cell */
cell_error_level = 0;
if (gds_c->checks.unresolved_child_count)
cell_error_level |= LIB_CELL_RENDERER_ERROR_WARN;
/* Check if it is completely b0rken */
if (gds_c->checks.affected_by_reference_loop)
cell_error_level |= LIB_CELL_RENDERER_ERROR_ERR;
/* Add cell to tree store model */
gtk_tree_store_set(self->cell_tree_store, &celliter,
CELL_SEL_CELL, gds_c,
CELL_SEL_CELL_ERROR_STATE, cell_error_level,
CELL_SEL_LIBRARY, gds_c->parent_library,
CELL_SEL_STAT, &gds_c->stats,
-1);
} /* for cells */
} /* for libraries */
/* Create Layers in Layer Box */
layer_selector_generate_layer_widgets(self->layer_selector, self->gds_libraries);
end_destroy: end_destroy:
/* Destroy dialog and filter */ /* Destroy dialog and filter */
@@ -758,6 +696,76 @@ GtkWindow *gds_render_gui_get_main_window(GdsRenderGui *gui)
return gui->main_window; return gui->main_window;
} }
void gds_render_gui_open_gds(GdsRenderGui *self, const char *path)
{
GList *cell;
GtkTreeIter libiter;
GtkTreeIter celliter;
GList *lib;
struct gds_library *gds_lib;
struct gds_cell *gds_c;
GtkStyleContext *button_style;
int gds_result;
unsigned int cell_error_level;
const struct gds_library_parsing_opts gds_parsing_options = {
.simplified_polygons = 1,
};
gtk_tree_store_clear(self->cell_tree_store);
clear_lib_list(&self->gds_libraries);
/* Parse new GDSII file */
gds_result = parse_gds_from_file(path, &self->gds_libraries, &gds_parsing_options);
/* Delete file name afterwards */
if (gds_result)
return;
/* remove suggested action from Open button */
button_style = gtk_widget_get_style_context(self->open_button);
gtk_style_context_remove_class(button_style, "suggested-action");
for (lib = self->gds_libraries; lib != NULL; lib = lib->next) {
gds_lib = (struct gds_library *)lib->data;
/* Create top level iter */
gtk_tree_store_append(self->cell_tree_store, &libiter, NULL);
gtk_tree_store_set(self->cell_tree_store, &libiter,
CELL_SEL_LIBRARY, gds_lib,
-1);
/* Check this library. This might take a while */
(void)gds_tree_check_cell_references(gds_lib);
(void)gds_tree_check_reference_loops(gds_lib);
for (cell = gds_lib->cells; cell != NULL; cell = cell->next) {
gds_c = (struct gds_cell *)cell->data;
gtk_tree_store_append(self->cell_tree_store, &celliter, &libiter);
/* Get the checking results for this cell */
cell_error_level = 0;
if (gds_c->checks.unresolved_child_count)
cell_error_level |= LIB_CELL_RENDERER_ERROR_WARN;
/* Check if it is completely b0rken */
if (gds_c->checks.affected_by_reference_loop)
cell_error_level |= LIB_CELL_RENDERER_ERROR_ERR;
/* Add cell to tree store model */
gtk_tree_store_set(self->cell_tree_store, &celliter,
CELL_SEL_CELL, gds_c,
CELL_SEL_CELL_ERROR_STATE, cell_error_level,
CELL_SEL_LIBRARY, gds_c->parent_library,
CELL_SEL_STAT, &gds_c->stats,
-1);
} /* for cells */
} /* for libraries */
/* Create Layers in Layer Box */
layer_selector_generate_layer_widgets(self->layer_selector, self->gds_libraries);
}
static void gds_render_gui_init(GdsRenderGui *self) static void gds_render_gui_init(GdsRenderGui *self)
{ {
GtkBuilder *main_builder; GtkBuilder *main_builder;

View File

@@ -284,8 +284,9 @@ static GList *append_library(GList *curr_list, const struct gds_library_parsing_
lib->stats.gfx_count = 0; lib->stats.gfx_count = 0;
lib->stats.reference_count = 0; lib->stats.reference_count = 0;
lib->stats.vertex_count = 0; lib->stats.vertex_count = 0;
} else } else {
return NULL; return NULL;
}
if (library_ptr) if (library_ptr)
*library_ptr = lib; *library_ptr = lib;
@@ -363,6 +364,7 @@ static GList *append_cell(GList *curr_list, struct gds_cell **cell_ptr)
cell->checks.affected_by_reference_loop = GDS_CELL_CHECK_NOT_RUN; cell->checks.affected_by_reference_loop = GDS_CELL_CHECK_NOT_RUN;
cell->stats.reference_count = 0; cell->stats.reference_count = 0;
cell->stats.total_vertex_count = 0; cell->stats.total_vertex_count = 0;
cell->stats.total_gfx_count = 0;
cell->stats.gfx_count = 0; cell->stats.gfx_count = 0;
cell->stats.vertex_count = 0; cell->stats.vertex_count = 0;
} else } else

View File

@@ -54,6 +54,13 @@ GdsRenderGui *gds_render_gui_new();
*/ */
GtkWindow *gds_render_gui_get_main_window(GdsRenderGui *gui); GtkWindow *gds_render_gui_get_main_window(GdsRenderGui *gui);
/**
* @brief gds_render_gui_open_gds Open a GDS file. Emulates the manual load via GUI open button
* @param self GUI instance
* @param path file path
*/
void gds_render_gui_open_gds(GdsRenderGui *self, const char *path);
G_END_DECLS G_END_DECLS
/** @} */ /** @} */

36
main.c
View File

@@ -40,6 +40,8 @@
struct application_data { struct application_data {
GtkApplication *app; GtkApplication *app;
GList *gui_list; GList *gui_list;
gint num_files_to_open;
GFile **files;
}; };
/** /**
@@ -158,6 +160,7 @@ static void gapp_activate(GApplication *app, gpointer user_data)
{ {
GtkWindow *main_window; GtkWindow *main_window;
GdsRenderGui *gui; GdsRenderGui *gui;
char *open_file_path;
struct application_data * const appdata = (struct application_data *)user_data; struct application_data * const appdata = (struct application_data *)user_data;
gui = gds_render_gui_new(); gui = gds_render_gui_new();
@@ -166,11 +169,32 @@ static void gapp_activate(GApplication *app, gpointer user_data)
g_signal_connect(gui, "window-closed", G_CALLBACK(gui_window_closed_callback), &appdata->gui_list); g_signal_connect(gui, "window-closed", G_CALLBACK(gui_window_closed_callback), &appdata->gui_list);
main_window = gds_render_gui_get_main_window(gui); main_window = gds_render_gui_get_main_window(gui);
if (appdata->num_files_to_open >= 1) {
/* Open first file. Multiple files are not supported and ignored */
open_file_path = g_file_get_path(appdata->files[0]);
gds_render_gui_open_gds(gui, open_file_path);
g_free(open_file_path);
}
gtk_application_add_window(GTK_APPLICATION(app), main_window); gtk_application_add_window(GTK_APPLICATION(app), main_window);
gtk_widget_show(GTK_WIDGET(main_window)); gtk_widget_show(GTK_WIDGET(main_window));
} }
/**
* @brief Activation of GUI when opening a file from commandline
* @param app he GApplication reference
* @param user_data Used to store the individual GUI instances.
*/
static void gapp_activate_open(GApplication *app, GFile** files, gint n_files, const gchar* hint, gpointer user_data)
{
(void)hint;
struct application_data *appdata = (struct application_data *)user_data;
appdata->files = files;
appdata->num_files_to_open = n_files;
gapp_activate(app, user_data);
}
/** /**
* @brief Start the graphical interface. * @brief Start the graphical interface.
* *
@@ -188,7 +212,9 @@ static int start_gui(int argc, char **argv)
GString *application_domain; GString *application_domain;
int app_status; int app_status;
static struct application_data appdata = { static struct application_data appdata = {
.gui_list = NULL .gui_list = NULL,
.num_files_to_open = 0,
.files = NULL,
}; };
GMenu *menu; GMenu *menu;
GMenu *m_quit; GMenu *m_quit;
@@ -201,10 +227,11 @@ static int start_gui(int argc, char **argv)
application_domain = g_string_new(NULL); application_domain = g_string_new(NULL);
g_string_printf(application_domain, "de.shimatta.gds_render_%s", _app_git_commit); g_string_printf(application_domain, "de.shimatta.gds_render_%s", _app_git_commit);
gapp = gtk_application_new(application_domain->str, G_APPLICATION_FLAGS_NONE); gapp = gtk_application_new(application_domain->str, G_APPLICATION_HANDLES_OPEN);
g_string_free(application_domain, TRUE); g_string_free(application_domain, TRUE);
g_application_register(G_APPLICATION(gapp), NULL, NULL); g_application_register(G_APPLICATION(gapp), NULL, NULL);
g_signal_connect(gapp, "open", G_CALLBACK(gapp_activate_open), &appdata);
g_signal_connect(gapp, "activate", G_CALLBACK(gapp_activate), &appdata); g_signal_connect(gapp, "activate", G_CALLBACK(gapp_activate), &appdata);
if (g_application_get_is_remote(G_APPLICATION(gapp)) == TRUE) { if (g_application_get_is_remote(G_APPLICATION(gapp)) == TRUE) {
@@ -311,7 +338,8 @@ int main(int argc, char **argv)
goto ret_status; goto ret_status;
} }
if (argc >= 2) { /* A minimum of a file name and a cell or analyze command are needed to use CLI */
if (argc >= 2 && (analyze || cellname || output_paths)) {
if (scale < 1) { if (scale < 1) {
printf(_("Scale < 1 not allowed. Setting to 1\n")); printf(_("Scale < 1 not allowed. Setting to 1\n"));
scale = 1; scale = 1;