Dear friends, I have modified gschem.c to use command line arguments from GOptionContext. I did not find the version control repository from gEDA, so I have used the source from the Ubuntu deb for version 1.6.1 as a base. Instead of sending a patch, I will hereafter enumerate the changes. I. When including: #include <glib/gi18n.h> to define _() and N_() II. Just before main_prog, tell which are the command line arguments and respective variables. static const gchar **remaining_files = NULL; /*! The command line options recognized by the application, to be added to those of GTK+. */ static const GOptionEntry cmdline_options[] = { { "quiet", 'q', 0, G_OPTION_ARG_NONE, &quiet_mode, N_("Quiet mode"), NULL }, { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose_mode, N_("Verbose_mode"), NULL }, { "auto-place", 'p', 0, G_OPTION_ARG_NONE, &auto_place_mode, N_("Automatically place window"), NULL }, { "stroke-info", 't', 0, G_OPTION_ARG_NONE, &stroke_info_mode, N_("Print stroke information"), NULL }, { "rc", 'r', 0, G_OPTION_ARG_FILENAME, &rc_filename, N_("RC file name"), N_("filename") }, { "script", 's', 0, G_OPTION_ARG_FILENAME, &rc_filename, N_("Script (guile) file name"), N_("filename") }, { "output", 'o', 0, G_OPTION_ARG_FILENAME, &rc_filename, N_("Output filename (for printing)"), N_("filename") }, { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &remaining_files, N_("The files to open."), N_("[files...]") }, { NULL } }; We have all the command line options pot in the globals.c Now, the remaining files to open are writen in the variable <remaining_files>. We either pass in no file, and then <remaining_files> is NULL, or it is a NULL terminated array of strings. III. Finally, main_prog. There are quite a few changes. We have to declare a GError and a GOptionContext first (if it was only for GCC...). We replace gtk_main and parse_cmdline with GOptionContext creation, parsing and error handling. Finally, we open the files in <remaining_files> without the need anymore of argv_index. I have not compiled the code, because I cannot compile in this machine, but I have used the same code in various other applications, and I actually copied, pasted and adapted from one of my applications. Please tell me if it fits your purposes. I enclose the whole file, as main_prog is quite large. Sorry for the trouble, but I think that being the first time I actually have a look at the code, and not being the latest version control code, a patch could create more troubles than the ones that solves. Thanks for your attention, Francisco ColaÃo -- Francisco Miguel ColaÃo <francisco.colaco@xxxxxxxxx>
/* gEDA - GPL Electronic Design Automation * gschem - gEDA Schematic Capture * Copyright (C) 1998-2010 Ales Hvezda * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA */ #include <config.h> #include <version.h> #include <stdio.h> #ifdef HAVE_STRING_H #include <string.h> #endif #ifdef HAVE_UNISTD_H #include <unistd.h> #endif #include <glib.h> #include <glib/gi18n.h> #include "gschem.h" #ifdef HAVE_LIBDMALLOC #include <dmalloc.h> #endif #ifdef HAVE_LOCALE_H #include <locale.h> #endif typedef struct { gschem_atexit_func func; gpointer arg; } gschem_atexit_struct; static GList *exit_functions = NULL; /*! \brief Register a function to be called on program exit * * \par Function Description * This function registers a function to be called on * program exit. Multiple functions will be executed in * the order they are registered. * * \param [in] func a pointer to the function to be registered * \param [in] data an arbitrary argument provided to the function * when it is called */ void gschem_atexit(gschem_atexit_func func, gpointer data) { gschem_atexit_struct *p; p = g_new(gschem_atexit_struct, 1); p->func = func; p->arg = data; exit_functions = g_list_append(exit_functions, p); } /*! \brief Cleanup gSchem on exit. * \par Function Description * This function cleans up all memory objects allocated during the * gSchem runtime. */ void gschem_quit(void) { GList *list; gschem_atexit_struct *p; /* Call all registered functions in order */ list = exit_functions; while(list != NULL) { p = (gschem_atexit_struct *) list->data; p->func(p->arg); g_free(p); list = g_list_next(list); } g_list_free(exit_functions); s_clib_free(); s_slib_free(); s_menu_free(); /* o_text_freeallfonts();*/ s_attrib_free(); s_papersizes_free(); #ifdef HAVE_LIBSTROKE x_stroke_free (); #endif /* HAVE_LIBSTROKE */ o_undo_cleanup(); /* s_stroke_free(); no longer needed */ i_vars_freenames(); i_vars_libgeda_freenames(); /* x_window_free_head(); can't do this since it causes a * condition in which window_head->... is still being refered * after this */ /* enable this to get more memory usage from glib */ /* You also have to enable something in glib I think */ /* g_mem_profile();*/ gtk_main_quit(); } static const gchar **remaining_files = NULL; /*! The command line options recognized by the application, to be added to those of GTK+. */ static const GOptionEntry cmdline_options[] = { { "quiet", 'q', 0, G_OPTION_ARG_NONE, &quiet_mode, N_("Quiet mode"), NULL }, { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose_mode, N_("Verbose_mode"), NULL }, { "auto-place", 'p', 0, G_OPTION_ARG_NONE, &auto_place_mode, N_("Automatically place window"), NULL }, { "stroke-info", 't', 0, G_OPTION_ARG_NONE, &stroke_info_mode, N_("Print stroke information"), NULL }, { "rc", 'r', 0, G_OPTION_ARG_FILENAME, &rc_filename, N_("RC file name"), N_("filename") }, { "script", 's', 0, G_OPTION_ARG_FILENAME, &rc_filename, N_("Script (guile) file name"), N_("filename") }, { "output", 'o', 0, G_OPTION_ARG_FILENAME, &rc_filename, N_("Output filename (for printing)"), N_("filename") }, { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &remaining_files, N_("The files to open."), N_("[files...]") }, { NULL } }; /*! \brief Main Scheme(GUILE) program function. * \par Function Description * This function is the main program called from scm_boot_guile. * It handles initializing all libraries and gSchem variables * and passes control to the gtk main loop. */ void main_prog(void *closure, int argc, char *argv[]) { int i; char *cwd = NULL; GSCHEM_TOPLEVEL *w_current = NULL; char *input_str = NULL; int argv_index; int first_page = 1; char *filename; SCM scm_tmp; GError *error = NULL; GOptionContext *context; #ifdef HAVE_GTHREAD /* Gschem isn't threaded, but some of GTK's file chooser * backends uses threading so we need to call g_thread_init(). * GLib requires threading be initialised before any other GLib * functions are called. Do it now if its not already setup. */ if (!g_thread_supported ()) g_thread_init (NULL); #endif #if ENABLE_NLS /* this should be equivalent to setlocale (LC_ALL, "") */ gtk_set_locale(); /* This must be the same for all locales */ setlocale(LC_NUMERIC, "C"); /* Disable gtk's ability to set the locale. */ /* If gtk is allowed to set the locale, then it will override the */ /* setlocale for LC_NUMERIC (which is important for proper PS output. */ /* This may look funny here, given we make a call to gtk_set_locale() */ /* above. I don't know yet, if this is really the right thing to do. */ gtk_disable_setlocale(); #endif /* gtk_init(&argc, &argv); argv_index = parse_commandline(argc, argv); */ context = g_option_context_new (""); g_option_context_set_summary (context, N_("gEDA Schematic editor.")); //g_option_context_set_description (context, N_("Add text to display *after* the list of command line options in the help message")); g_option_context_set_translation_domain (context, "geda-gschem"); g_option_context_add_main_entries (context, cmdline_options, "geda-gschem"); g_option_context_add_group (context, gtk_get_option_group (TRUE)); if (!g_option_context_parse (context, &argc, &argv, &error)) { switch (error->code) { case G_OPTION_ERROR_UNKNOWN_OPTION: g_printerr (_("There was an unknown command line option: %s\n"), error->message); break; case G_OPTION_ERROR_BAD_VALUE: g_printerr (_("There was a bad value passed to a command line option: %s\n"), error->message); break; case G_OPTION_ERROR_FAILED: g_printerr (_("The command line parsing failed: %s\n"), error->message); break; default: g_printerr (_("Unknown error %d when parsing the command line arguments: %s\n"), error->code, error->message); break; } g_clear_error (&error); g_option_context_free (context); return 1; } // Free the option context, for it is no longer needed. g_option_context_free (context); cwd = g_get_current_dir(); libgeda_init(); /* Install various libgeda callbacks */ arc_draw_func = o_arc_draw; box_draw_func = o_box_draw; bus_draw_func = o_bus_draw; circle_draw_func = o_circle_draw; complex_draw_func = o_complex_draw; line_draw_func = o_line_draw; net_draw_func = o_net_draw; picture_draw_func = o_picture_draw; path_draw_func = o_path_draw; pin_draw_func = o_pin_draw; text_draw_func = o_text_draw; select_func = o_select_object; /* create log file right away even if logging is enabled */ s_log_init ("gschem"); s_log_message( _("gEDA/gschem version %s%s.%s\n"), PREPEND_VERSION_STRING, PACKAGE_DOTTED_VERSION, PACKAGE_DATE_VERSION); s_log_message( _("gEDA/gschem 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")); #endif #if DEBUG fprintf(stderr, _("Current locale settings: %s\n"), setlocale(LC_ALL, NULL)); #endif /* init global buffers */ o_buffer_init(); /* register guile (scheme) functions */ g_register_funcs(); /* initialise color map (need to do this before reading rc files */ x_color_init (); o_undo_init(); if (s_path_sys_data () == NULL) { gchar *message = _("You must set the GEDADATA environment variable!\n\n" "gschem cannot locate its data files. You must set the GEDADATA\n" "environment variable to point to the correct location.\n"); GtkWidget* error_diag = gtk_message_dialog_new (NULL, 0, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, message); gtk_dialog_run (GTK_DIALOG (error_diag)); g_error (message); } /* Allocate w_current */ w_current = gschem_toplevel_new (); w_current->toplevel = s_toplevel_new (); global_window_current = w_current; w_current->toplevel->load_newer_backup_func = x_fileselect_load_backup; w_current->toplevel->load_newer_backup_data = w_current; o_text_set_rendered_bounds_func (w_current->toplevel, o_text_get_rendered_bounds, w_current); /* Now read in RC files. */ g_rc_parse_gtkrc(); g_rc_parse(w_current->toplevel, "gschemrc", rc_filename); /* By this point, libgeda should have setup the Guile load path, so * we can take advantage of that. */ scm_tmp = scm_sys_search_load_path (scm_from_locale_string ("gschem.scm")); if (scm_is_false (scm_tmp)) { s_log_message (_("Couldn't find init scm file [%s]\n"), "gschem.scm"); } input_str = scm_to_locale_string (scm_tmp); if (g_read_file(input_str) != -1) { s_log_message(_("Read init scm file [%s]\n"), input_str); } else { /*! \todo These two messages are the same. Should be * integrated. */ s_log_message(_("Failed to read init scm file [%s]\n"), input_str); } free (input_str); /* M'allocated by scm_to_locale_string() */ scm_remember_upto_here_1 (scm_tmp); /* Load recent files list. This must be done * before calling x_window_setup(). */ recent_files_load(); gschem_atexit(recent_files_save, NULL); /* Set default icon */ x_window_set_default_icon(); /* At end, complete set up of window. */ x_color_allocate(); x_window_setup (w_current); #ifdef HAVE_LIBSTROKE x_stroke_init (); #endif /* HAVE_LIBSTROKE */ if (remaining_files) { gchar *filename; for (int i = 0; remaining_files[i]; i++) { if (g_path_is_absolute (remaining_files[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 (first_page) first_page = 0; } /* * SDB notes: at this point the filename might be unnormalized, like * /path/to/foo/../bar/baz.sch. Bad filenames will be normalized in * f_open (called by x_window_open_page). This works for Linux and MINGW32. */ x_window_open_page(w_current, filename); g_free (filename); } /* for (i = argv_index; i < argc; i++) { 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 ( first_page ) first_page = 0; /* * SDB notes: at this point the filename might be unnormalized, like * /path/to/foo/../bar/baz.sch. Bad filenames will be normalized in * f_open (called by x_window_open_page). This works for Linux and MINGW32. */ x_window_open_page(w_current, filename); g_free (filename); } */ g_free(cwd); /* If no page has been loaded (wasn't specified in the command line.) */ /* Then create an untitled page */ if ( first_page ) { x_window_open_page( w_current, NULL ); } /* Update the window to show the current page */ x_window_set_current_page( w_current, w_current->toplevel->page_current ); #if DEBUG scm_c_eval_string ("(display \"hello guile\n\")"); #endif if (w_current->toplevel->scheme_directory == NULL) { fprintf(stderr, _("Scheme directory NOT set!\n")); exit(-1); } /* Execute a script if it exists */ if (script_filename) { s_log_message(_("Executing guile script [%s]\n"), script_filename); g_read_file(script_filename); } /* open up log window on startup */ if (w_current->log_window == MAP_ON_STARTUP) { x_log_open (); } /* if there were any symbols which had major changes, put up an error */ /* dialog box */ major_changed_dialog(w_current); /* enter main loop */ gtk_main(); } /*! \brief Main executable entrance point. * \par Function Description * This is the main function for gSchem. It sets up the Scheme(GUILE) * environment and passes control to via scm_boot_guile to * the #main_prog function. */ int main (int argc, char *argv[]) { #if ENABLE_NLS setlocale(LC_ALL, ""); setlocale(LC_NUMERIC, "C"); bindtextdomain("geda-gschem", LOCALEDIR); textdomain("geda-gschem"); bind_textdomain_codeset("geda-gschem", "UTF-8"); #endif /* disable the deprecated warnings in guile 1.6.3 */ /* Eventually the warnings will need to be fixed */ if(getenv("GUILE_WARN_DEPRECATED") == NULL) putenv("GUILE_WARN_DEPRECATED=no"); scm_boot_guile (argc, argv, main_prog, 0); return 0; }
Attachment:
signature.asc
Description: This is a digitally signed message part
_______________________________________________ geda-user mailing list geda-user@xxxxxxxxxxxxxx http://www.seul.org/cgi-bin/mailman/listinfo/geda-user