gnetlist
|
00001 /* gEDA - GPL Electronic Design Automation 00002 * gnetlist - gEDA Netlist 00003 * Copyright (C) 1998-2010 Ales Hvezda 00004 * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details) 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00021 #include <config.h> 00022 #include <version.h> 00023 #include <missing.h> 00024 00025 #include <stdio.h> 00026 #ifdef HAVE_STRING_H 00027 #include <string.h> 00028 #endif 00029 #ifdef HAVE_UNISTD_H 00030 #include <unistd.h> 00031 #endif 00032 00033 #ifdef HAVE_GETOPT_H 00034 #include <getopt.h> 00035 #endif 00036 00037 #include <libgeda/libgeda.h> 00038 00039 #include "../include/globals.h" 00040 #include "../include/prototype.h" 00041 00042 #ifdef HAVE_LIBDMALLOC 00043 #include <dmalloc.h> 00044 #endif 00045 00046 #define OPTIONS "c:g:hil:L:m:o:O:qvV" 00047 00048 #ifndef OPTARG_IN_UNISTD 00049 extern char *optarg; 00050 extern int optind; 00051 #endif 00052 00053 00054 /* Added by SDB 3.3.2006. */ 00055 #ifdef HAVE_GETOPT_LONG 00056 struct option long_options[] = 00057 { 00058 {"help", 0, 0, 'h'}, 00059 {"list-backends", 0, &list_backends, TRUE}, 00060 {"verbose", 0, 0, 'v'}, 00061 {"version", 0, 0, 'V'}, 00062 {0, 0, 0, 0} 00063 }; 00064 #endif 00065 00066 00067 00068 void usage(char *cmd) 00069 { 00070 printf ( 00071 "Usage: %s [OPTION ...] [-g BACKEND] [--] FILE ...\n" 00072 "\n" 00073 "Generate a netlist from one or more gEDA schematic FILEs.\n" 00074 "\n" 00075 "General options:\n" 00076 " -q Quiet mode.\n" 00077 " -v, --verbose Verbose mode.\n" 00078 " -o FILE Filename for netlist data output.\n" 00079 " -L DIR Add DIR to Scheme search path.\n" 00080 " -g BACKEND Specify netlist backend to use.\n" 00081 " -O STRING Pass an option string to backend.\n" 00082 " -l FILE Load Scheme file before loading backend.\n" 00083 " -m FILE Load Scheme file after loading backend.\n" 00084 " -c EXPR Evaluate Scheme expression at startup.\n" 00085 " -i Enter interactive Scheme REPL after loading.\n" 00086 " --list-backends Print a list of available netlist backends.\n" 00087 " -h, --help Help; this message.\n" 00088 " -V, --version Show version information.\n" 00089 " -- Treat all remaining arguments as filenames.\n" 00090 "\n" 00091 "Report bugs at <https://bugs.launchpad.net/geda>\n" 00092 "gEDA/gaf homepage: <http://www.geda-project.org/>\n", 00093 cmd); 00094 exit (0); 00095 } 00096 00102 static void 00103 version () 00104 { 00105 printf( 00106 "gEDA %s (g%.7s)\n" 00107 "Copyright (C) 1998-2012 gEDA developers\n" 00108 "This is free software, and you are welcome to redistribute it under\n" 00109 "certain conditions. For details, see the file `COPYING', which is\n" 00110 "included in the gEDA distribution.\n" 00111 "There is NO WARRANTY, to the extent permitted by law.\n", 00112 PACKAGE_DOTTED_VERSION, PACKAGE_GIT_COMMIT); 00113 exit (0); 00114 } 00115 00116 /* from guile (libguile/gh_init.c) */ 00117 static SCM 00118 catch_handler (void *data, SCM tag, SCM throw_args) 00119 { 00120 fprintf (stderr, "\nJust got an error; tag is\n "); 00121 scm_display (tag, scm_current_output_port ()); 00122 scm_newline (scm_current_output_port ()); 00123 scm_newline (scm_current_output_port ()); 00124 return SCM_BOOL_F; 00125 } 00126 00127 00128 int 00129 parse_commandline (int argc, char *argv[]) 00130 { 00131 int ch; 00132 SCM sym_begin = scm_from_utf8_symbol ("begin"); 00133 SCM sym_cons = scm_from_utf8_symbol ("cons"); 00134 SCM sym_load = scm_from_utf8_symbol ("load"); 00135 SCM sym_set_x = scm_from_utf8_symbol ("set!"); 00136 SCM sym_load_path = scm_from_utf8_symbol ("%load-path"); 00137 00138 #ifdef HAVE_GETOPT_LONG 00139 /* int option_index = 0; */ 00140 00141 while ((ch = getopt_long(argc, argv, OPTIONS, long_options, NULL /* &option_index */)) != -1) { 00142 #else 00143 while ((ch = getopt(argc, argv, OPTIONS)) != -1) { 00144 #endif 00145 switch (ch) { 00146 00147 case 0: 00148 /* This is a long-form-only flag option, and has already been 00149 * dealt with by getopt_long(). */ 00150 break; 00151 00152 case 'v': 00153 backend_params = g_slist_append(backend_params, "verbose_mode"); 00154 verbose_mode = TRUE; 00155 break; 00156 00157 case 'i': 00158 backend_params = g_slist_append(backend_params, "interactive_mode"); 00159 interactive_mode = TRUE; 00160 break; 00161 00162 case 'q': 00163 backend_params = g_slist_append(backend_params, "quiet_mode"); 00164 quiet_mode = TRUE; 00165 break; 00166 00167 case 'L': 00168 /* Argument is a directory to add to the Scheme load path. 00169 * Add the necessary expression to be evaluated before rc file 00170 * loading. */ 00171 pre_rc_list = 00172 scm_cons (scm_list_3 (sym_set_x, 00173 sym_load_path, 00174 scm_list_3 (sym_cons, 00175 scm_from_locale_string (optarg), 00176 sym_load_path)), 00177 pre_rc_list); 00178 break; 00179 00180 case 'g': 00181 guile_proc = g_strdup(optarg); 00182 break; 00183 00184 case 'l': 00185 /* Argument is filename of a Scheme script to be run before 00186 * loading gnetlist backend. */ 00187 pre_backend_list = 00188 scm_cons (scm_list_2 (sym_load, scm_from_locale_string (optarg)), 00189 pre_backend_list); 00190 break; 00191 00192 case 'm': 00193 /* Argument is filename of a Scheme script to be run after 00194 * loading gnetlist backend. */ 00195 post_backend_list = 00196 scm_cons (scm_list_2 (sym_load, scm_from_locale_string (optarg)), 00197 post_backend_list); 00198 break; 00199 00200 case 'o': 00201 g_free(output_filename); 00202 output_filename = g_strdup(optarg); 00203 break; 00204 00205 case 'O': 00206 backend_params = g_slist_append(backend_params, optarg); 00207 break; 00208 00209 case 'c': 00210 scm_internal_stack_catch (SCM_BOOL_T, 00211 (scm_t_catch_body) scm_c_eval_string, 00212 (void *) optarg, 00213 (scm_t_catch_handler) catch_handler, 00214 (void *) optarg); 00215 break; 00216 00217 case 'h': 00218 usage(argv[0]); 00219 break; 00220 00221 case 'V': 00222 version(); 00223 break; 00224 00225 case '?': 00226 #ifndef HAVE_GETOPT_LONG 00227 if ((optopt != ':') && (strchr (GETOPT_OPTIONS, optopt) != NULL)) { 00228 fprintf (stderr, 00229 "ERROR: -%c option requires an argument.\n\n", 00230 optopt); 00231 } else if (isprint (optopt)) { 00232 fprintf (stderr, "ERROR: Unknown option -%c.\n\n", optopt); 00233 } else { 00234 fprintf (stderr, "ERROR: Unknown option character `\\x%x'.\n\n", 00235 optopt); 00236 } 00237 #endif 00238 fprintf (stderr, "\nRun `%s --help' for more information.\n", argv[0]); 00239 exit (1); 00240 break; 00241 00242 default: 00243 g_assert_not_reached (); 00244 } 00245 } 00246 00247 if (quiet_mode) { 00248 verbose_mode = FALSE; 00249 } 00250 00251 /* Make sure Scheme expressions can be passed straight to eval */ 00252 pre_rc_list = scm_cons (sym_begin, 00253 scm_reverse_x (pre_rc_list, SCM_UNDEFINED)); 00254 scm_gc_protect_object (pre_rc_list); 00255 pre_backend_list = scm_cons (sym_begin, 00256 scm_reverse_x (pre_backend_list, SCM_UNDEFINED)); 00257 scm_gc_protect_object (pre_backend_list); 00258 post_backend_list = scm_cons (sym_begin, 00259 scm_reverse_x (post_backend_list, SCM_UNDEFINED)); 00260 scm_gc_protect_object (post_backend_list); 00261 00262 return (optind); 00263 }