static void shell_main (void *data, int argc, char **argv) { SCM setup_lst = SCM_EOL; /* We reverse! this before using it. */ SCM run_lst = SCM_EOL; /* We reverse! this before using it. */ int c; int interactive = 1; int inhibit_rc = 0; int status; TOPLEVEL *toplevel; #include "shell.x" /* Parse command-line arguments */ opterr = 0; while ((c = getopt (argc, argv, GETOPT_OPTIONS)) != -1) { switch (c) { case 's': /* Construct an application of LOAD to the script name */ run_lst = scm_cons (scm_list_2 (sym_load, scm_from_locale_string (optarg)), run_lst); interactive = 0; goto endoptloop; case 'c': /* We need to evaluate an expression */ run_lst = scm_cons (scm_list_2 (sym_eval_string, scm_from_locale_string (optarg)), run_lst); interactive = 0; goto endoptloop; case 'L': /* Add argument to %load-path */ setup_lst = scm_cons (scm_list_3 (sym_set_x, sym_load_path, scm_list_3 (sym_cons, scm_from_locale_string (optarg), sym_load_path)), setup_lst); break; case 'l': /* Same as -s, pretty much */ run_lst = scm_cons (scm_list_2 (sym_load, scm_from_locale_string (optarg)), run_lst); break; case 'q': inhibit_rc = 1; break; case 'h': usage (0); case 'V': version(); case '?': if ((optopt != ':') && (strchr (GETOPT_OPTIONS, optopt) != NULL)) { fprintf (stderr, "ERROR: -%c option requires an argument.\n\n", optopt); usage (1); } else if (isprint (optopt)) { fprintf (stderr, "ERROR: Unknown option -%c\n\n", optopt); usage (1); } else { fprintf (stderr, "ERROR: Unknown option character `\\x%x'.\n\n", optopt); usage (1); } default: g_assert_not_reached (); } } endoptloop: /* Set program arguments visible from Guile */ scm_set_program_arguments (argc - optind, argv + optind, "geda-shell"); /* If interactive mode, load readline and run top REPL. */ if (interactive) { run_lst = scm_cons (scm_list_2 (sym_use_modules, scm_list_2 (sym_ice_9, sym_readline)), run_lst); run_lst = scm_cons (scm_list_1 (sym_activate_readline), run_lst); run_lst = scm_cons (scm_list_1 (sym_top_repl), run_lst); /* Print GPL bumf if necessary */ if (isatty (1) && isatty (0)) { printf ( "gEDA " PACKAGE_GIT_VERSION "\n" "Copyright (C) 1998-2010 gEDA developers\n" "This is free software, and you are welcome to redistribute it under\n" "certain conditions. For details, see the file `COPYING', which is\n" "included in the gEDA distribution.\n" "There is NO WARRANTY, to the extent permitted by law.\n" ); } } else { run_lst = scm_cons (scm_list_1 (sym_quit), run_lst); } /* Reverse lists */ setup_lst = scm_reverse_x (setup_lst, SCM_UNDEFINED); run_lst = scm_reverse_x (run_lst, SCM_UNDEFINED); /* Initialise libgeda */ libgeda_init (); scm_dynwind_begin (0); toplevel = s_toplevel_new (); edascm_dynwind_toplevel (toplevel); /* First run the setup list */ if (setup_lst != SCM_EOL) { setup_lst = scm_cons (sym_begin, setup_lst); scm_eval_x (setup_lst, scm_current_module ()); } /* Now load rc files, if necessary */ if (!inhibit_rc) g_rc_parse (toplevel, argv[0], NULL, NULL); i_vars_libgeda_set (toplevel); /* Ugh */ /* Finally evaluate run list */ run_lst = scm_cons (sym_begin, run_lst); status = scm_exit_status (scm_eval_x (run_lst, scm_current_module ())); exit (status); scm_dynwind_end (); scm_remember_upto_here_2 (setup_lst, run_lst); }
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(); }