/*! \todo Finish function documentation!!! * \brief * \par Function Description * */ void s_hierarchy_down_symbol (TOPLEVEL *toplevel, const CLibSymbol *symbol, PAGE *parent) { PAGE *page; gchar *filename; filename = s_clib_symbol_get_filename (symbol); page = s_page_search (toplevel, filename); if (page) { /* change link to parent page since we * can come here from any parent and must * come back to the same page */ page->up = parent->pid; s_page_goto (toplevel, page); g_free (filename); return; } page = s_page_new (toplevel, filename); g_free(filename); s_page_goto (toplevel, page); f_open(toplevel, page, s_page_get_filename (page), NULL); page->up = parent->pid; page_control_counter++; page->page_control = page_control_counter; }
/*! \brief Completes initialitation of the widget after realization. * \par Function Description * This function terminates the initialization of preview's GSCHEM_TOPLEVEL * and TOPLEVEL environments after the widget has been realized. * * It creates a preview page in the TOPLEVEL environment. * * \param [in] widget The preview widget. * \param [in] user_data Unused user data. */ static void preview_callback_realize (GtkWidget *widget, gpointer user_data) { Preview *preview = PREVIEW (widget); GSCHEM_TOPLEVEL *preview_w_current = preview->preview_w_current; TOPLEVEL *preview_toplevel = preview_w_current->toplevel; PAGE *preview_page; preview_w_current->window = preview_w_current->drawing_area->window; gtk_widget_grab_focus (preview_w_current->drawing_area); preview_toplevel->width = preview_w_current->drawing_area->allocation.width; preview_toplevel->height = preview_w_current->drawing_area->allocation.height; preview_w_current->win_width = preview_toplevel->width; preview_w_current->win_height = preview_toplevel->height; preview_w_current->drawable = preview_w_current->window; x_window_setup_gc (preview_w_current); preview_page = s_page_new (preview_toplevel, "unknown"); s_page_goto (preview_toplevel, preview_page); a_zoom_extents(preview_w_current, s_page_objects (preview_page), A_PAN_DONT_REDRAW); o_invalidate_all (preview_w_current); }
/*! \todo Finish function documentation!!! * \brief * \par Function Description * */ void s_hierarchy_down_symbol (TOPLEVEL *toplevel, const CLibSymbol *symbol, PAGE *parent) { PAGE *page; gchar *filename; filename = s_clib_symbol_get_filename (symbol); page = s_page_search (toplevel, filename); if (page) { s_page_goto (toplevel, page); g_free (filename); return; } page = s_page_new (toplevel, filename); g_free(filename); s_page_goto (toplevel, page); f_open(toplevel, page, page->page_filename, NULL); page->up = parent->pid; page_control_counter++; page->page_control = page_control_counter; }
static void preview_init (GschemPreview *preview) { struct event_reg_t { gchar *detailed_signal; GCallback c_handler; } drawing_area_events[] = { { "realize", G_CALLBACK (preview_callback_realize) }, { "expose_event", G_CALLBACK (x_event_expose) }, { "button_press_event", G_CALLBACK (preview_callback_button_press) }, { "configure_event", G_CALLBACK (x_event_configure) }, { "scroll_event", G_CALLBACK (preview_event_scroll) }, { NULL, NULL } }, *tmp; GschemToplevel *preview_w_current; preview_w_current = gschem_toplevel_new (); gschem_toplevel_set_toplevel (preview_w_current, s_toplevel_new ()); preview_w_current->toplevel->load_newer_backup_func = x_fileselect_load_backup; preview_w_current->toplevel->load_newer_backup_data = preview_w_current; o_text_set_rendered_bounds_func (preview_w_current->toplevel, o_text_get_rendered_bounds, preview_w_current); i_vars_set (preview_w_current); /* be sure to turn off scrollbars */ preview_w_current->scrollbars_flag = FALSE; /* be sure to turn off the grid */ gschem_options_set_grid_mode (preview_w_current->options, GRID_MODE_NONE); /* preview_w_current windows don't have toolbars */ preview_w_current->handleboxes = FALSE; preview_w_current->toolbars = FALSE; preview_w_current->drawing_area = GTK_WIDGET (preview); preview->preview_w_current = preview_w_current; preview->active = FALSE; preview->filename = NULL; preview->buffer = NULL; GSCHEM_PAGE_VIEW (preview)->page = s_page_new (preview->preview_w_current->toplevel, "preview"); gtk_widget_set_events (GTK_WIDGET (preview), GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK | GDK_BUTTON_PRESS_MASK); for (tmp = drawing_area_events; tmp->detailed_signal != NULL; tmp++) { g_signal_connect (GTK_WIDGET (preview), tmp->detailed_signal, tmp->c_handler, preview_w_current); } }
/*! \brief Updates the preview widget. * \par Function Description * This function update the preview: if the preview is active and a * filename has been given, it opens the file and display * it. Otherwise it display a blank page. * * \param [in] preview The preview widget. */ static void preview_update (Preview *preview) { GSCHEM_TOPLEVEL *preview_w_current = preview->preview_w_current; TOPLEVEL *preview_toplevel = preview_w_current->toplevel; int left, top, right, bottom; int width, height; if (preview_toplevel->page_current == NULL) { return; } /* delete old preview, create new page */ /* it would be better to just resets current page - Fix me */ s_page_delete (preview_toplevel, preview_toplevel->page_current); s_page_goto (preview_toplevel, s_page_new (preview_toplevel, "preview")); if (preview->active) { g_assert ((preview->filename == NULL) || (preview->buffer == NULL)); if (preview->filename != NULL) { /* open up file in current page */ f_open_flags (preview_toplevel, preview_toplevel->page_current, preview->filename, F_OPEN_RC | F_OPEN_RESTORE_CWD, NULL); /* test value returned by f_open... - Fix me */ /* we should display something if there an error occured - Fix me */ } if (preview->buffer != NULL) { /* Load the data buffer */ s_page_append_list (preview_toplevel, preview_toplevel->page_current, o_read_buffer (preview_toplevel, NULL, preview->buffer, -1, _("Preview Buffer"))); } } if (world_get_object_glist_bounds (preview_toplevel, s_page_objects (preview_toplevel->page_current), &left, &top, &right, &bottom)) { /* Clamp the canvas size to the extents of the page being previewed */ width = right - left; height = bottom - top; preview_toplevel->init_left = left - ((double)width * OVER_ZOOM_FACTOR); preview_toplevel->init_right = right + ((double)width * OVER_ZOOM_FACTOR); preview_toplevel->init_top = top - ((double)height * OVER_ZOOM_FACTOR); preview_toplevel->init_bottom = bottom + ((double)height * OVER_ZOOM_FACTOR); } /* display current page (possibly empty) */ a_zoom_extents (preview_w_current, s_page_objects (preview_toplevel->page_current), A_PAN_DONT_REDRAW); o_invalidate_all (preview_w_current); }
/*! \brief Load a subpage * * \par Function Description * Implements s_hierarchy_down_schematic(), but without changing variables * related to the UI. * * - Ensures a duplicate page is not loaded * - Does not change the current page * - Does not modify the most recent "up" page * * \param [in] page * \param [in] filename * \param [out] error * \return A pointer to the subpage or NULL if an error occured. */ PAGE* s_hierarchy_load_subpage (PAGE *page, const char *filename, GError **error) { char *string; PAGE *subpage = NULL; g_return_val_if_fail (filename != NULL, NULL); g_return_val_if_fail (page != NULL, NULL); SCM string_s = scm_call_1 (scm_c_public_ref ("geda library", "get-source-library-file"), scm_from_utf8_string (filename)); if (scm_is_false (string_s)) { g_set_error (error, EDA_ERROR, EDA_ERROR_NOLIB, _("Schematic not found in source library.")); } else { string = scm_to_utf8_string (string_s); gchar *normalized = f_normalize_filename (string, error); subpage = s_page_search (page->toplevel, normalized); if (subpage == NULL) { int success; subpage = s_page_new (page->toplevel, string); success = f_open (page->toplevel, subpage, s_page_get_filename (subpage), error); if (success) { subpage->page_control = ++page_control_counter; } else { s_page_delete (page->toplevel, subpage); subpage = NULL; } } g_free (normalized); } return subpage; }
/*! \brief Load a subpage * * \par Function Description * Implements s_hierarchy_down_schematic(), but without changing variables * related to the UI. * * - Ensures a duplicate page is not loaded * - Does not change the current page * - Does not modify the most recent "up" page * * \param [in] page * \param [in] filename * \param [out] error * \return A pointer to the subpage or NULL if an error occured. */ PAGE* s_hierarchy_load_subpage (PAGE *page, const char *filename, GError **error) { char *string; PAGE *subpage = NULL; g_return_val_if_fail (filename != NULL, NULL); g_return_val_if_fail (page != NULL, NULL); string = s_slib_search_single (filename); if (string == NULL) { g_set_error (error, EDA_ERROR, EDA_ERROR_NOLIB, _("Schematic not found in source library.")); } else { gchar *normalized = f_normalize_filename (string, error); subpage = s_page_search (page->toplevel, normalized); if (subpage == NULL) { int success; subpage = s_page_new (page->toplevel, string); success = f_open (page->toplevel, subpage, subpage->page_filename, error); if (success) { subpage->page_control = ++page_control_counter; } else { s_page_delete (page->toplevel, subpage); subpage = NULL; } } g_free (normalized); } return subpage; }
/*! \brief Opens a new page from a file. * \par Function Description * This function opens the file whose name is <B>filename</B> in a * new PAGE of <B>toplevel</B>. * * If there is no page for <B>filename</B> in <B>toplevel</B>'s list * of pages, it creates a new PAGE, loads the file in it and returns * a pointer on the new page. Otherwise it returns a pointer on the * existing page. * * If the filename passed is NULL, this function creates an empty, * untitled page. The name of the untitled page is build from * configuration data ('untitled-name') and a counter for uniqueness. * * The opened page becomes the current page of <B>toplevel</B>. * * \param [in] w_current The toplevel environment. * \param [in] filename The name of the file to open or NULL for a blank page. * \returns A pointer on the new page. * * \bug This code should check to make sure any untitled filename * does not conflict with a file on disk. */ PAGE* x_window_open_page (GschemToplevel *w_current, const gchar *filename) { TOPLEVEL *toplevel = gschem_toplevel_get_toplevel (w_current); GschemPageView *page_view = gschem_toplevel_get_current_page_view (w_current); PAGE *page; gchar *fn; g_return_val_if_fail (toplevel != NULL, NULL); /* Generate untitled filename if none was specified */ if (filename == NULL) { gchar *cwd, *tmp, *untitled_name; EdaConfig *cfg; cwd = g_get_current_dir (); cfg = eda_config_get_context_for_path (cwd); untitled_name = eda_config_get_string (cfg, "gschem", "default-filename", NULL); tmp = g_strdup_printf ("%s_%d.sch", untitled_name, ++w_current->num_untitled); fn = g_build_filename (cwd, tmp, NULL); g_free (untitled_name); g_free(cwd); g_free(tmp); } else { fn = g_strdup (filename); } /* Return existing page if it is already loaded */ page = s_page_search (toplevel, fn); if ( page != NULL ) { g_free(fn); return page; } page = s_page_new (toplevel, fn); s_page_goto (toplevel, page); gschem_toplevel_page_changed (w_current); /* Load from file if necessary, otherwise just print a message */ if (filename != NULL) { GError *err = NULL; if (!quiet_mode) s_log_message (_("Loading schematic [%s]\n"), fn); if (!f_open (toplevel, page, (gchar *) fn, &err)) { GtkWidget *dialog; g_warning ("%s\n", err->message); dialog = gtk_message_dialog_new_with_markup (GTK_WINDOW (w_current->main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, _("<b>An error occurred while loading the requested file.</b>\n\nLoading from '%s' failed: %s. The gschem log may contain more information."), fn, err->message); gtk_window_set_title (GTK_WINDOW (dialog), _("Failed to load file")); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); g_error_free (err); } else { gtk_recent_manager_add_item (recent_manager, g_filename_to_uri(fn, NULL, NULL)); } } else { if (!quiet_mode) s_log_message (_("New file [%s]\n"), toplevel->page_current->page_filename); g_run_hook_page (w_current, "%new-page-hook", toplevel->page_current); } gschem_page_view_set_page (page_view, toplevel->page_current); o_undo_savestate (w_current, toplevel->page_current, UNDO_ALL); /* This line is generally un-needed, however if some code * wants to open a page, yet not bring it to the front, it is * needed needed to add it into the page manager. Otherwise, * it will get done in x_window_set_current_page(...) */ x_pagesel_update (w_current); /* ??? */ g_free (fn); return page; }
void main_prog(void *closure, int argc, char *argv[]) { int i; int argv_index; char *cwd; gchar *str; gchar *filename; TOPLEVEL *pr_current; /* set default output filename */ output_filename = g_strdup("output.net"); argv_index = parse_commandline(argc, argv); cwd = g_get_current_dir(); scm_set_program_arguments (argc, argv, NULL); /* this is a kludge to make sure that spice mode gets set */ /* Hacked by SDB to allow spice netlisters of arbitrary name * as long as they begin with "spice". For example, this spice * netlister is valid: "spice-sdb". */ if (guile_proc) { if (strncmp(guile_proc, "spice", 5) == 0) { netlist_mode = SPICE; } } libgeda_init(); /* create log file right away */ /* even if logging is enabled */ s_log_init ("gnetlist"); s_log_message("gEDA/gnetlist version %s%s.%s\n", PREPEND_VERSION_STRING, PACKAGE_DOTTED_VERSION, PACKAGE_DATE_VERSION); s_log_message ("gEDA/gnetlist comes with ABSOLUTELY NO WARRANTY; see COPYING for more details.\n"); s_log_message ("This is free software, and you are welcome to redistribute it under certain\n"); s_log_message ("conditions; please see the COPYING file for more details.\n\n"); #if defined(__MINGW32__) && defined(DEBUG) fprintf(stderr, "This is the MINGW32 port.\n\n"); #endif /* register guile (scheme) functions */ g_register_funcs(); pr_current = s_toplevel_new (); /* Evaluate Scheme expressions that need to be run before rc files * are loaded. */ scm_eval (pre_rc_list, scm_current_module ()); g_rc_parse (pr_current, argv[0], "gnetlistrc", rc_filename); /* immediately setup user params */ i_vars_set (pr_current); s_rename_init(); if(list_backends) { gnetlist_backends(pr_current); exit (0); } /* Evaluate the first set of Scheme expressions before we load any * schematic files */ scm_eval (pre_backend_list, scm_current_module ()); i = argv_index; while (argv[i] != NULL) { GError *err = NULL; if (g_path_is_absolute(argv[i])) { /* Path is already absolute so no need to do any concat of cwd */ filename = g_strdup (argv[i]); } else { filename = g_build_filename (cwd, argv[i], NULL); } if (!quiet_mode) { s_log_message ("Loading schematic [%s]\n", filename); printf ("Loading schematic [%s]\n", filename); } s_page_goto (pr_current, s_page_new (pr_current, filename)); if (!f_open (pr_current, pr_current->page_current, filename, &err)) { g_warning ("%s\n", err->message); fprintf (stderr, "%s\n", err->message); g_error_free (err); } /* collect input filenames for backend use */ input_files = g_slist_append(input_files, argv[i]); i++; g_free (filename); } /* Change back to the directory where we started. This is done */ /* since gnetlist is a command line utility and will deposit its output */ /* in the current directory. Having the output go to a different */ /* directory will confuse the user (confused me, at first). */ if (chdir (cwd)) { /* Error occured with chdir */ #warning FIME: What do we do? } /* free(cwd); - Defered; see below */ if (argv[argv_index] == NULL) { fprintf (stderr, "ERROR: No schematics files specified for processing.\n"); fprintf (stderr, "\nRun `%s --help' for more information.\n", argv[0]); exit (1); } g_set_project_current(pr_current); #if DEBUG s_page_print_all(pr_current); #endif /* Load basic gnetlist functions */ scm_primitive_load_path (scm_from_utf8_string ("gnetlist.scm")); if (guile_proc) { SCM s_backend_path; /* Search for backend scm file in load path */ str = g_strdup_printf("gnet-%s.scm", guile_proc); s_backend_path = scm_sys_search_load_path (scm_from_locale_string (str)); g_free (str); /* If it couldn't be found, fail. */ if (scm_is_false (s_backend_path)) { fprintf (stderr, "ERROR: Could not find backend `%s' in load path.\n", guile_proc); fprintf (stderr, "\nRun `%s --list-backends' for a full list of available backends.\n", argv[0]); exit (1); } /* Load backend code. */ scm_primitive_load (s_backend_path); /* Evaluate second set of Scheme expressions. */ scm_eval (post_backend_list, scm_current_module ()); } s_traverse_init(); s_traverse_start(pr_current); /* Change back to the directory where we started AGAIN. This is done */ /* because the s_traverse functions can change the Current Working Directory. */ if (chdir (cwd)) { /* Error occured with chdir */ #warning FIXME: What do we do? } g_free(cwd); /* Run post-traverse code. */ scm_primitive_load_path (scm_from_utf8_string ("gnetlist-post.scm")); if (guile_proc) { /* check size here hack */ str = g_strdup_printf ("(%s \"%s\")", guile_proc, output_filename); scm_c_eval_string (str); g_free (str); /* gh_eval_str_with_stack_saving_handler (input_str); */ } else if (interactive_mode) { scm_c_eval_string ("(set-repl-prompt! \"gnetlist> \")"); scm_shell (0, NULL); } else { fprintf(stderr, "You gave neither backend to execute nor interactive mode!\n"); } gnetlist_quit(); }
/*! * \brief Search for schematic associated source files and load them. * \par Function Description * This function searches the associated source file refered by the * <B>filename</B> and loads it. If the <B>flag</B> is set to * <B>HIERARCHY_NORMAL_LOAD</B> and the page is already in the list of * pages it will return the <B>pid</B> of that page. * If the <B>flag</B> is set to <B>HIERARCHY_FORCE_LOAD</B> then this * function will load the page again with a new page id. The second case * is mainly used by gnetlist where pushed down schematics MUST be unique. * * \param [in] toplevel The TOPLEVEL object. * \param [in] filename Schematic file name. * \param [in] parent The parent page of the schematic. * \param [in] page_control * \param [in] flag sets whether to force load * \param [out] err Location to return a GError on failure. * \return The page loaded, or NULL if failed. * * \note * This function finds the associated source files and * loads all up * It only works for schematic files though * this is basically push * flag can either be HIERARCHY_NORMAL_LOAD or HIERARCHY_FORCE_LOAD * flag is mainly used by gnetlist where pushed down schematics MUST be unique */ PAGE * s_hierarchy_down_schematic_single(TOPLEVEL *toplevel, const gchar *filename, PAGE *parent, int page_control, int flag, GError **err) { gchar *string; PAGE *found = NULL; PAGE *forbear; g_return_val_if_fail ((toplevel != NULL), NULL); g_return_val_if_fail ((filename != NULL), NULL); g_return_val_if_fail ((parent != NULL), NULL); SCM string_s = scm_call_1 (scm_c_public_ref ("geda library", "get-source-library-file"), scm_from_utf8_string (filename)); if (scm_is_false (string_s)) { g_set_error (err, EDA_ERROR, EDA_ERROR_NOLIB, _("Schematic not found in source library.")); return NULL; } string = scm_to_utf8_string (string_s); switch (flag) { case HIERARCHY_NORMAL_LOAD: { gchar *filename = f_normalize_filename (string, NULL); found = s_page_search (toplevel, filename); g_free (filename); if (found) { /* check whether this page is in the parents list */ for (forbear = parent; forbear != NULL && found->pid != forbear->pid && forbear->up >= 0; forbear = s_page_search_by_page_id (toplevel->pages, forbear->up)) ; /* void */ if (forbear != NULL && found->pid == forbear->pid) { g_set_error (err, EDA_ERROR, EDA_ERROR_LOOP, _("Hierarchy contains a circular dependency.")); return NULL; /* error signal */ } s_page_goto (toplevel, found); if (page_control != 0) { found->page_control = page_control; } found->up = parent->pid; g_free (string); return found; } found = s_page_new (toplevel, string); f_open (toplevel, found, s_page_get_filename (found), NULL); } break; case HIERARCHY_FORCE_LOAD: { found = s_page_new (toplevel, string); f_open (toplevel, found, s_page_get_filename (found), NULL); } break; default: g_return_val_if_reached (NULL); } if (page_control == 0) { page_control_counter++; found->page_control = page_control_counter; } else { found->page_control = page_control; } found->up = parent->pid; g_free (string); return found; }
static void cmd_export_impl (void *data, int argc, char **argv) { int i; GError *err = NULL; gchar *tmp; const gchar *out_suffix; struct ExportFormat *exporter = NULL; GArray *render_color_map = NULL; gchar *original_cwd = g_get_current_dir (); gtk_init_check (&argc, &argv); scm_init_guile (); libgeda_init (); scm_dynwind_begin (0); toplevel = s_toplevel_new (); edascm_dynwind_toplevel (toplevel); /* Now load rc files, if necessary */ if (getenv ("GAF_INHIBIT_RCFILES") == NULL) { g_rc_parse (toplevel, "gaf export", NULL, NULL); } i_vars_libgeda_set (toplevel); /* Ugh */ /* Parse configuration files */ export_config (); /* Parse command-line arguments */ export_command_line (argc, argv); /* If no format was specified, try and guess from output * filename. */ if (settings.format == NULL) { out_suffix = strrchr (settings.outfile, '.'); if (out_suffix != NULL) { out_suffix++; /* Skip '.' */ } else { fprintf (stderr, _("ERROR: Cannot infer output format from filename '%s'.\n"), settings.outfile); exit (1); } } /* Try and find an exporter function */ tmp = g_utf8_strdown ((settings.format == NULL) ? out_suffix : settings.format, -1); for (i = 0; formats[i].name != NULL; i++) { if (strcmp (tmp, formats[i].alias) == 0) { exporter = &formats[i]; break; } } if (exporter == NULL) { if (settings.format == NULL) { fprintf (stderr, _("ERROR: Cannot find supported format for filename '%s'.\n"), settings.outfile); exit (1); } else { fprintf (stderr, _("ERROR: Unsupported output format '%s'.\n"), settings.format); fprintf (stderr, see_help_msg); exit (1); } } g_free (tmp); /* If more than one schematic/symbol file was specified, check that * exporter supports multipage output. */ if ((settings.infilec > 1) && !(exporter->flags & OUTPUT_MULTIPAGE)) { fprintf (stderr, _("ERROR: Selected output format does not support multipage output\n")); exit (1); } /* Load schematic files */ while (optind < argc) { PAGE *page; tmp = argv[optind++]; page = s_page_new (toplevel, tmp); if (!f_open (toplevel, page, tmp, &err)) { fprintf (stderr, _("ERROR: Failed to load '%s': %s\n"), tmp, err->message); exit (1); } if (g_chdir (original_cwd) != 0) { fprintf (stderr, _("ERROR: Failed to change directory to '%s': %s\n"), original_cwd, g_strerror (errno)); exit (1); } } /* Create renderer */ renderer = eda_renderer_new (NULL, NULL); if (settings.font != NULL) { g_object_set (renderer, "font-name", settings.font, NULL); } /* Make sure libgeda knows how to calculate the bounds of text * taking into account font etc. */ o_text_set_rendered_bounds_func (toplevel, export_text_rendered_bounds, renderer); /* Create color map */ render_color_map = g_array_sized_new (FALSE, FALSE, sizeof(GedaColor), MAX_COLORS); render_color_map = g_array_append_vals (render_color_map, print_colors, MAX_COLORS); if (!settings.color) { /* Create a black and white color map. All non-background colors * are black. */ GedaColor white = {~0, ~0, ~0, ~0, TRUE}; GedaColor black = {0, 0, 0, ~0, TRUE}; for (i = 0; i < MAX_COLORS; i++) { GedaColor *c = &g_array_index (render_color_map, GedaColor, i); if (!c->enabled) continue; if (c->a == 0) { c->enabled = FALSE; continue; } if (i == OUTPUT_BACKGROUND_COLOR) { *c = white; } else { *c = black; } } } eda_renderer_set_color_map (renderer, render_color_map); /* Render */ exporter->func (); scm_dynwind_end (); exit (0); }
void main_prog(void *closure, int argc, char *argv[]) { int i; int argv_index; int exit_status; char *cwd; TOPLEVEL *pr_current; argv_index = parse_commandline(argc, argv); cwd = g_get_current_dir(); libgeda_init(); /* create log file right away */ /* even if logging is enabled */ x_log_update_func = s_log_update; s_log_init ("symcheck"); logging_dest=STDOUT_TTY; #if defined(__MINGW32__) && defined(DEBUG) fprintf(stderr, "This is the MINGW32 port.\n"); #endif logging_dest=-1; /* don't output to the screen for now */ /* register guile (scheme) functions */ g_register_funcs(); pr_current = s_toplevel_new (); g_rc_parse (pr_current, argv[0], "gsymcheckrc", rc_filename); i_vars_set(pr_current); i = argv_index; while (argv[i] != NULL) { gchar *filename; GError *err = NULL; if (g_path_is_absolute(argv[i])) { /* Path is already absolute so no need to do any concat of cwd */ filename = g_strdup (argv[i]); } else { filename = g_build_filename (cwd, argv[i], NULL); } s_page_goto (pr_current, s_page_new (pr_current, filename)); if (!f_open (pr_current, pr_current->page_current, s_page_get_filename (pr_current->page_current), &err)) { /* Not being able to load a file is apparently a fatal error */ logging_dest = STDOUT_TTY; g_warning ("%s\n", err->message); g_error_free (err); exit(2); } else { g_message (_("Loaded file [%1$s]\n"), filename); } i++; g_free (filename); } if (argv[argv_index] == NULL) { fprintf(stderr, _("\nERROR! You must specify at least one filename\n\n")); usage(argv[0]); } g_free(cwd); logging_dest=STDOUT_TTY; #if DEBUG s_page_print_all(pr_current); #endif if (!quiet_mode) s_log_message("\n"); exit_status = s_check_all(pr_current); s_page_delete_list(pr_current); gsymcheck_quit(); exit(exit_status); }
/*! \brief Opens a new page from a file. * \par Function Description * This function opens the file whose name is <B>filename</B> in a * new PAGE of <B>toplevel</B>. * * If there is no page for <B>filename</B> in <B>toplevel</B>'s list * of pages, it creates a new PAGE, loads the file in it and returns * a pointer on the new page. Otherwise it returns a pointer on the * existing page. * * If the filename passed is NULL, this function creates an empty, * untitled page. The name of the untitled page is build from * configuration data ('untitled-name') and a counter for uniqueness. * * The opened page becomes the current page of <B>toplevel</B>. * * \param [in] w_current The toplevel environment. * \param [in] filename The name of the file to open or NULL for a blank page. * \returns A pointer on the new page. * * \bug This code should check to make sure any untitled filename * does not conflict with a file on disk. */ PAGE* x_window_open_page (GSCHEM_TOPLEVEL *w_current, const gchar *filename) { TOPLEVEL *toplevel = w_current->toplevel; PAGE *old_current, *page; gchar *fn; g_return_val_if_fail (toplevel != NULL, NULL); /* Generate untitled filename if none was specified */ if (filename == NULL) { gchar *cwd, *tmp; cwd = g_get_current_dir (); tmp = g_strdup_printf ("%s_%d.sch", toplevel->untitled_name, ++w_current->num_untitled); fn = g_build_filename (cwd, tmp, NULL); g_free(cwd); g_free(tmp); } else { fn = g_strdup (filename); } /* Return existing page if it is already loaded */ page = s_page_search (toplevel, fn); if ( page != NULL ) { g_free(fn); return page; } old_current = toplevel->page_current; page = s_page_new (toplevel, fn); s_page_goto (toplevel, page); /* Load from file if necessary, otherwise just print a message */ if (filename != NULL) { GError *err = NULL; if (!quiet_mode) s_log_message (_("Loading schematic [%s]\n"), fn); if (!f_open (toplevel, page, (gchar *) fn, &err)) { GtkWidget *dialog; g_warning ("%s\n", err->message); dialog = gtk_message_dialog_new (GTK_WINDOW (w_current->main_window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, "%s", err->message); gtk_window_set_title (GTK_WINDOW (dialog), _("Failed to load file")); gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); g_error_free (err); } else { gtk_recent_manager_add_item (recent_manager, g_filename_to_uri(fn, NULL, NULL)); } } else { if (!quiet_mode) s_log_message (_("New file [%s]\n"), toplevel->page_current->page_filename); } if (scm_is_false (scm_hook_empty_p (new_page_hook))) scm_run_hook (new_page_hook, scm_cons (g_make_page_smob (toplevel, page), SCM_EOL)); a_zoom_extents (w_current, s_page_objects (toplevel->page_current), A_PAN_DONT_REDRAW); o_undo_savestate (w_current, UNDO_ALL); if ( old_current != NULL ) s_page_goto (toplevel, old_current); /* This line is generally un-needed, however if some code * wants to open a page, yet not bring it to the front, it is * needed needed to add it into the page manager. Otherwise, * it will get done in x_window_set_current_page(...) */ x_pagesel_update (w_current); /* ??? */ g_free (fn); return page; }
PAGE *ruby_page_to_c(VALUE page) { PAGE *pg; Data_Get_Struct(page, PAGE, pg); return pg; } static VALUE ruby_page_alloc(VALUE class) { TOPLEVEL *toplevel; PAGE *page; toplevel = ruby_get_c_toplevel(); page = s_page_new(ruby_get_c_toplevel(), "untitled"); return ruby_page_from_c(page); } static void ruby_page_mark(void *obj) { ///@todo } static void ruby_page_free(void *obj) { ///@todo #if 0 PAGE *page;
/*! \todo Finish function documentation!!! * \brief Search for schematic associated source files and load them. * \par Function Description * This function searches the associated source file refered by the * <B>filename</B> and loads it. If the <B>flag</B> is set to * <B>HIERARCHY_NORMAL_LOAD</B> and the page is allready in the list of * pages it will return the <B>pid</B> of that page. * If the <B>flag</B> is set to <B>HIERARCHY_FORCE_LOAD</B> then this * function will load the page again with a new page id. The second case * is mainly used by gnetlist where pushed down schematics MUST be unique. * * \param [in] toplevel The TOPLEVEL object. * \param [in] filename Schematic file name. * \param [in] parent The parent page of the schematic. * \param [in] page_control * \param [in] flag * \return The page loaded, or NULL if failed. * * \note * This function goes and finds the associated source files and * loads all up * It only works for schematic files though * this is basically push * flag can either be HIERARCHY_NORMAL_LOAD or HIERARCHY_FORCE_LOAD * flag is mainly used by gnetlist where pushed down schematics MUST be unique */ PAGE * s_hierarchy_down_schematic_single(TOPLEVEL *toplevel, const gchar *filename, PAGE *parent, int page_control, int flag) { gchar *string; PAGE *found = NULL; PAGE *forbear; g_return_val_if_fail ((toplevel != NULL), NULL); g_return_val_if_fail ((filename != NULL), NULL); g_return_val_if_fail ((parent != NULL), NULL); string = s_slib_search_single(filename); if (string == NULL) { return NULL; } switch (flag) { case HIERARCHY_NORMAL_LOAD: { gchar *filename = f_normalize_filename (string, NULL); found = s_page_search (toplevel, filename); g_free (filename); if (found) { /* check whether this page is in the parents list */ for (forbear = parent; forbear != NULL && found->pid != forbear->pid && forbear->up >= 0; forbear = s_page_search_by_page_id (toplevel->pages, forbear->up)) ; /* void */ if (found->pid == forbear->pid) { s_log_message(_("hierarchy loop detected while visiting page:\n" " \"%s\"\n"), found->page_filename); return NULL; /* error signal */ } s_page_goto (toplevel, found); if (page_control != 0) { found->page_control = page_control; } found->up = parent->pid; g_free (string); return found; } found = s_page_new (toplevel, string); f_open (toplevel, found, found->page_filename, NULL); } break; case HIERARCHY_FORCE_LOAD: { found = s_page_new (toplevel, string); f_open (toplevel, found, found->page_filename, NULL); } break; } if (page_control == 0) { page_control_counter++; found->page_control = page_control_counter; } else { found->page_control = page_control; } found->up = parent->pid; g_free (string); return found; }
/*! \todo Finish function documentation!!! * \brief * \par Function Description * * <B>type</B> can be one of the following values: * <DL> * <DT>*</DT><DD>UNDO_ACTION * <DT>*</DT><DD>REDO_ACTION * </DL> */ void o_undo_callback(GSCHEM_TOPLEVEL *w_current, int type) { TOPLEVEL *toplevel = w_current->toplevel; UNDO *u_current; UNDO *u_next; UNDO *save_bottom; UNDO *save_tos; UNDO *save_current; int save_logging; int find_prev_data=FALSE; char *save_filename; if (w_current->undo_control == FALSE) { s_log_message(_("Undo/Redo disabled in rc file\n")); return; } if (toplevel->page_current->undo_current == NULL) { return; } if (type == UNDO_ACTION) { u_current = toplevel->page_current->undo_current->prev; } else { u_current = toplevel->page_current->undo_current->next; } u_next = toplevel->page_current->undo_current; if (u_current == NULL) { return; } if (u_next->type == UNDO_ALL && u_current->type == UNDO_VIEWPORT_ONLY) { #if DEBUG printf("Type: %d\n", u_current->type); printf("Current is an undo all, next is viewport only!\n"); #endif find_prev_data = TRUE; if (w_current->undo_type == UNDO_DISK) { u_current->filename = o_undo_find_prev_filename(u_current); } else { u_current->object_list = o_undo_find_prev_object_head (u_current); } } /* save filename */ save_filename = g_strdup (toplevel->page_current->page_filename); /* save structure so it's not nuked */ save_bottom = toplevel->page_current->undo_bottom; save_tos = toplevel->page_current->undo_tos; save_current = toplevel->page_current->undo_current; toplevel->page_current->undo_bottom = NULL; toplevel->page_current->undo_tos = NULL; toplevel->page_current->undo_current = NULL; if (w_current->undo_type == UNDO_DISK && u_current->filename) { PAGE *p_new; s_page_delete (toplevel, toplevel->page_current); p_new = s_page_new(toplevel, u_current->filename); s_page_goto (toplevel, p_new); } else if (w_current->undo_type == UNDO_MEMORY && u_current->object_list) { PAGE *p_new; s_page_delete (toplevel, toplevel->page_current); p_new = s_page_new (toplevel, save_filename); s_page_goto (toplevel, p_new); } /* temporarily disable logging */ save_logging = do_logging; do_logging = FALSE; if (w_current->undo_type == UNDO_DISK && u_current->filename) { f_open(toplevel, toplevel->page_current, u_current->filename, NULL); x_manual_resize(w_current); toplevel->page_current->page_control = u_current->page_control; toplevel->page_current->up = u_current->up; toplevel->page_current->CHANGED=1; } else if (w_current->undo_type == UNDO_MEMORY && u_current->object_list) { s_page_delete_objects (toplevel, toplevel->page_current); s_page_append_list (toplevel, toplevel->page_current, o_glist_copy_all (toplevel, u_current->object_list, NULL)); x_manual_resize(w_current); toplevel->page_current->page_control = u_current->page_control; toplevel->page_current->up = u_current->up; toplevel->page_current->CHANGED=1; } /* do misc setups */ set_window(toplevel, toplevel->page_current, u_current->left, u_current->right, u_current->top, u_current->bottom); x_hscrollbar_update(w_current); x_vscrollbar_update(w_current); /* restore logging */ do_logging = save_logging; /* set filename right */ g_free(toplevel->page_current->page_filename); toplevel->page_current->page_filename = save_filename; /* final redraw */ x_pagesel_update (w_current); x_multiattrib_update (w_current); /* Let the caller to decide if redraw or not */ o_invalidate_all (w_current); i_update_menus(w_current); /* restore saved undo structures */ toplevel->page_current->undo_bottom = save_bottom; toplevel->page_current->undo_tos = save_tos; toplevel->page_current->undo_current = save_current; if (type == UNDO_ACTION) { if (toplevel->page_current->undo_current) { toplevel->page_current->undo_current = toplevel->page_current->undo_current->prev; if (toplevel->page_current->undo_current == NULL) { toplevel->page_current->undo_current = toplevel->page_current->undo_bottom; } } } else { /* type is REDO_ACTION */ if (toplevel->page_current->undo_current) { toplevel->page_current->undo_current = toplevel->page_current->undo_current->next; if (toplevel->page_current->undo_current == NULL) { toplevel->page_current->undo_current = toplevel->page_current->undo_tos; } } } /* don't have to free data here since filename, object_list are */ /* just pointers to the real data (lower in the stack) */ if (find_prev_data) { u_current->filename = NULL; u_current->object_list = NULL; } #if DEBUG printf("\n\n---Undo----\n"); s_undo_print_all(toplevel->page_current->undo_bottom); printf("TOS: %s\n", toplevel->page_current->undo_tos->filename); printf("CURRENT: %s\n", toplevel->page_current->undo_current->filename); printf("----\n"); #endif }
void main_prog(void *closure, int argc, char *argv[]) { int i; int argv_index; int exit_status; char *cwd; char *logfile; TOPLEVEL *pr_current; argv_index = parse_commandline(argc, argv); cwd = g_get_current_dir(); libgeda_init(); /* create log file right away */ /* even if logging is enabled */ logfile = g_build_filename (cwd, "gsymcheck.log", NULL); x_log_update_func = s_log_update; s_log_init (logfile); g_free (logfile); logging_dest=STDOUT_TTY; if (!quiet_mode) { s_log_message( "gEDA/gsymcheck version %s%s.%s\n", PREPEND_VERSION_STRING, DOTTED_VERSION, DATE_VERSION); s_log_message( "gEDA/symcheck comes with ABSOLUTELY NO WARRANTY; see COPYING for more details.\n"); s_log_message( "This is free software, and you are welcome to redistribute it under certain\n"); s_log_message( "conditions; please see the COPYING file for more details.\n\n"); } #ifdef __MINGW32__ fprintf(stderr, "This is the MINGW32 port.\n"); #endif logging_dest=-1; /* don't output to the screen for now */ /* register guile (scheme) functions */ g_register_funcs(); pr_current = s_toplevel_new (); g_rc_parse(pr_current, "gsymcheckrc", rc_filename); i_vars_set(pr_current); i = argv_index; while (argv[i] != NULL) { gchar *filename; GError *err = NULL; if (g_path_is_absolute(argv[i])) { /* Path is already absolute so no need to do any concat of cwd */ filename = g_strdup (argv[i]); } else { filename = g_build_filename (cwd, argv[i], NULL); } s_page_goto (pr_current, s_page_new (pr_current, filename)); if (!f_open (pr_current, pr_current->page_current->page_filename, &err)) { /* Not being able to load a file is apparently a fatal error */ logging_dest = STDOUT_TTY; g_warning ("%s\n", err->message); g_error_free (err); exit(2); } else { g_message ("Loaded file [%s]\n", filename); } i++; g_free (filename); } if (argv[argv_index] == NULL) { fprintf(stderr, "\nERROR! You must specify at least one filename\n\n"); usage(argv[0]); } g_free(cwd); logging_dest=STDOUT_TTY; #if DEBUG s_page_print_all(pr_current); #endif if (!quiet_mode) s_log_message("\n"); exit_status = s_check_all(pr_current); s_page_delete_list(pr_current); gsymcheck_quit(); exit(exit_status); }