1 /* gEDA - GPL Electronic Design Automation
2 * gnetlist - gEDA Netlist
3 * Copyright (C) 1998-2007 Ales Hvezda
4 * Copyright (C) 1998-2007 gEDA Contributors (see ChangeLog for details)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA
24 #include <sys/param.h>
25 #include <sys/types.h>
40 #include <libgeda/libgeda.h>
42 #include "../include/globals.h"
43 #include "../include/prototype.h"
45 #ifdef HAVE_LIBDMALLOC
49 #define BACKEND_LIST_COLS 3
51 void gnetlist_quit(void)
55 s_rename_destroy_all();
57 /* o_text_freeallfonts(); */
59 /* Free GSList *backend_params */
60 g_slist_free (backend_params
);
63 /** @brief Prints a list of all installed gnetlist backends to standard output.
65 * @param current Pointer to the toplevel struct.
67 void gnetlist_backends(TOPLEVEL
*current
)
74 schemedir
=opendir(current
->scheme_directory
);
76 fprintf(stderr
, "\nERROR! Can't open directory %s: %s\n",
77 current
->scheme_directory
,
82 printf("List of available backends:\n\n");
86 entry
=readdir(schemedir
);
87 if(entry
==NULL
) break;
89 filename
=strdup(entry
->d_name
);
91 if(g_str_has_prefix(filename
, "gnet-")&&
92 g_str_has_suffix(filename
, ".scm")) {
94 /* strip the suffix */
95 filename
[strlen(filename
)-4]='\0';
96 /* and skip the prefix */
97 printf("%-25s", &filename
[5]);
98 if(n
>=BACKEND_LIST_COLS
) {
110 void main_prog(void *closure
, int argc
, char *argv
[])
113 char input_str
[2048];
119 TOPLEVEL
*pr_current
;
121 /* set default output filename */
122 output_filename
= g_strdup("output.net");
124 argv_index
= parse_commandline(argc
, argv
);
125 cwd
= g_get_current_dir();
127 /* this is a kludge to make sure that spice mode gets set */
128 /* Hacked by SDB to allow spice netlisters of arbitrary name
129 * as long as they begin with "spice". For example, this spice
130 * netlister is valid: "spice-sdb".
133 if (strncmp(guile_proc
, "spice", 5) == 0) {
134 netlist_mode
= SPICE
;
135 command_line
= create_command_line(argc
, argv
);
137 printf("Command line passed = %s \n", command_line
);
144 /* create log file right away */
145 /* even if logging is enabled */
146 logfile
= g_build_filename (cwd
, "gnetlist.log", NULL
);
147 s_log_init (logfile
);
150 s_log_message("gEDA/gnetlist version %s%s.%s\n", PREPEND_VERSION_STRING
,
151 DOTTED_VERSION
, DATE_VERSION
);
153 ("gEDA/gnetlist comes with ABSOLUTELY NO WARRANTY; see COPYING for more details.\n");
155 ("This is free software, and you are welcome to redistribute it under certain\n");
157 ("conditions; please see the COPYING file for more details.\n\n");
160 fprintf(stderr
, "gEDA/gnetlist version %s%s.%s\n",
161 PREPEND_VERSION_STRING
, DOTTED_VERSION
, DATE_VERSION
);
163 "gEDA/gnetlist comes with ABSOLUTELY NO WARRANTY; see COPYING for more details.\n");
165 "This is free software, and you are welcome to redistribute it under certain\n");
167 "conditions; please see the COPYING file for more details.\n\n");
171 fprintf(stderr
, "This is the MINGW32 port.\n\n");
174 s_log_message ("Remember to check that your schematic has no errors using the drc2 backend.\n");
175 s_log_message ("You can do it running 'gnetlist -g drc2 your_schematic.sch -o drc_output.txt'\n");
176 s_log_message ("and seeing the contents of the file drc_output.txt.\n\n");
179 fprintf (stderr
, "Remember to check that your schematic has no errors using the drc2 backend.\n");
180 fprintf (stderr
, "You can do it running 'gnetlist -g drc2 your_schematic.sch -o drc_output.txt'\n");
181 fprintf (stderr
, "and seeing the contents of the file drc_output.txt.\n\n");
183 /* register guile (scheme) functions */
186 pr_current
= s_toplevel_new ();
187 g_rc_parse(pr_current
, "gnetlistrc", rc_filename
);
188 /* immediately setup user params */
189 i_vars_set (pr_current
);
193 if(guile_proc
!=NULL
) {
194 if(!strcmp(guile_proc
, "help")) {
195 gnetlist_backends(pr_current
);
200 /* Load the first set of scm files before we load any schematic files */
201 list_pnt
= pre_backend_list
;
203 if (g_read_file(list_pnt
->data
) != -1) {
204 s_log_message("Read scm file [%s]\n",
205 (char *) list_pnt
->data
);
207 s_log_message("Failed to read scm file [%s]\n",
208 (char *) list_pnt
->data
);
209 fprintf(stderr
, "Failed to read scm file [%s]\n",
210 (char *) list_pnt
->data
);
212 list_pnt
= g_slist_next(list_pnt
);
214 /* Free now the list of configuration files */
215 g_slist_free(pre_backend_list
);
218 while (argv
[i
] != NULL
) {
223 if (g_path_is_absolute(argv
[i
])) {
224 /* Path is already absolute so no need to do any concat of cwd */
225 filename
= g_strdup (argv
[i
]);
227 filename
= g_build_filename (cwd
, argv
[i
], NULL
);
231 s_log_message ("Loading schematic [%s]\n", filename
);
232 printf ("Loading schematic [%s]\n", filename
);
235 page
= s_page_new(pr_current
, filename
);
236 s_toplevel_goto_page(pr_current
, page
);
238 if (!f_open(pr_current
, page
, filename
, &err
)) {
239 g_warning ("%s\n", err
->message
);
240 fprintf (stderr
, "%s\n", err
->message
);
248 /* Change back to the directory where we started. This is done */
249 /* since gnetlist is a command line utility and will deposit its output */
250 /* in the current directory. Having the output go to a different */
251 /* directory will confuse the user (confused me, at first). */
253 /* Error occurred with chdir */
254 #warning FIXME: What do we do?
256 /* free(cwd); - Defered; see below */
258 if (argv
[argv_index
] == NULL
) {
260 "\nERROR! You must specify at least one filename\n\n");
264 g_set_project_current(pr_current
);
266 s_page_print_all(pr_current
);
269 /* temporarly reuse input_str */
270 sprintf(input_str
, "%s%cgnetlist.scm", pr_current
->scheme_directory
,
273 if (g_read_file(input_str
) != -1) {
274 s_log_message("Read init scm file [%s]\n", input_str
);
276 s_log_message("Failed to read init scm file [%s]\n", input_str
);
277 fprintf(stderr
, "Failed to read init scm file [%s]\n", input_str
);
281 /* load the appropriate scm file */
282 sprintf(input_str
, "%s%cgnet-%s.scm", pr_current
->scheme_directory
,
283 G_DIR_SEPARATOR
, guile_proc
);
285 if (g_read_file(input_str
) != -1) {
286 s_log_message("Read %s scm file [%s]\n", guile_proc
,
289 s_log_message("Failed to read %s scm file [%s]\n",
290 guile_proc
, input_str
);
291 fprintf(stderr
, "Failed to read %s scm file [%s]\n",
292 guile_proc
, input_str
);
295 /* Load second set of scm files */
296 list_pnt
= post_backend_list
;
298 if (g_read_file(list_pnt
->data
) != -1) {
299 s_log_message("Read scm file [%s]\n",
300 (char *) list_pnt
->data
);
302 s_log_message("Failed to read scm file [%s]\n",
303 (char *) list_pnt
->data
);
304 fprintf(stderr
, "Failed to read scm file [%s]\n",
305 (char *) list_pnt
->data
);
307 list_pnt
= g_slist_next(list_pnt
);
309 /* Free now the list of configuration files */
310 g_slist_free(post_backend_list
);
314 s_traverse_start(pr_current
);
316 /* Change back to the directory where we started AGAIN. This is done */
317 /* because the s_traverse functions can change the Current Working Directory. */
319 /* Error occurred with chdir */
320 #warning FIXME: What do we do?
324 /* temporarly reuse input_str */
325 sprintf(input_str
, "%s%cgnetlist-post.scm", pr_current
->scheme_directory
,
328 if (g_read_file(input_str
) != -1) {
329 s_log_message("Read post traversal scm file [%s]\n", input_str
);
331 s_log_message("Failed to read post traversal scm file [%s]\n", input_str
);
332 fprintf(stderr
, "Failed to read post traversal scm file [%s]\n", input_str
);
337 int exception_caught
= 0;
339 retval
= g_scm_apply_protected(g_scm_safe_ref_lookup(guile_proc
),
340 scm_list_1(scm_from_locale_string(output_filename
)),
341 &g_scm_exception_witness
, &exception_caught
);
344 if (exception_caught
|| scm_is_false(retval
)) {
349 } else if (interactive_mode
) {
350 /* FIXME: set-repl-prompt! is deprecated or nonexistent. */
351 scm_c_eval_string ("(set-repl-prompt! \"gnetlist> \")");
352 /* FIXME scm_shell does not return, so arrange to call gnetlist_quit. */
356 "You gave neither backend to execute nor interactive mode!\n");
359 /* However we got here, it's an error. */
364 int main(int argc
, char *argv
[])
366 /* disable the deprecated warnings in guile 1.6.3 */
367 /* Eventually the warnings will need to be fixed */
368 if(getenv("GUILE_WARN_DEPRECATED")==NULL
)
369 putenv("GUILE_WARN_DEPRECATED=no");
371 scm_boot_guile (argc
, argv
, main_prog
, 0);