view ueda/uschem-netlist/main.c @ 101:ffab0a4424ad

ueda: unet-bind program moved into sensibly named unet-bind subdir
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 29 Sep 2019 22:42:41 +0000
parents cd92449fdb51
children
line wrap: on
line source

#include <sys/types.h>
#include <stdio.h>
#include <strings.h>
#include "../libuschem/schemstruct.h"

extern int optind;
extern char *optarg;

extern char *MCLfile;

extern struct schem *read_schem();

extern int pcb_netlist_output();
extern int pinlist_output();
extern int stats_output();

struct schem *curschem;
int allow_unnamed_nets, check_completeness, sort_netlist_output;
int global_errflag;
char *outfilename;
FILE *outfile;
int (*do_output)() = pcb_netlist_output;

main(argc, argv)
	char **argv;
{
	register int c;
	register struct schem *schem;
	char **avp;

	while ((c = getopt(argc, argv, "cI:M:o:O:su")) != EOF)
		switch (c) {
		case 'c':
			check_completeness++;
			break;
		case 'I':
			add_symfile_dir(optarg);
			break;
		case 'M':
			MCLfile = optarg;
			break;
		case 'o':
			outfilename = optarg;
			break;
		case 'O':
			select_output_backend(optarg);
			break;
		case 's':
			sort_netlist_output++;
			break;
		case 'u':
			allow_unnamed_nets++;
			break;
		default:
usage:			fprintf(stderr, "usage: %s [-options] schemfile...\n",
				argv[0]);
			exit(1);
		}
	if (!argv[optind])
		goto usage;

	read_MCL();
	hash_MCL();
	set_default_sympath();
	read_pinouts();
	alloc_nlcomp_array();

	for (avp = argv + optind; *avp; avp++) {
		schem = read_schem(*avp);
		curschem = schem;
		match_schem_to_mcl(schem);
		if (hash_component_instances(schem) < 0)
			exit(1);
		if (preen_graphnets(schem, 1, 0, 0, 0) < 0)
			exit(1);
		process_schem();
	}
	if (global_errflag)
		fprintf(stderr, "Errors found; netlist may be incomplete\n");
	do_output();

	exit(0);
}

process_schem()
{
	register struct schemobj *obj;
	int has_netlines = 0;

	for (obj = curschem->obj_next; obj != (struct schemobj *)curschem;
	     obj = obj->obj_next)
	switch (obj->obj_type) {
	case OBJTYPE_COMPINST:
		check_compinst_pintonet(obj);
		continue;
	case OBJTYPE_NET:
	case OBJTYPE_GRAPHNET:
		process_netobj(obj);
		continue;
	case OBJTYPE_NETLINE:
		if (!has_netlines) {
			fprintf(stderr,
		"%s contains NetLine objects which are not netlistable\n",
				curschem->orig_filename);
			has_netlines++;
			global_errflag++;
		}
		continue;
	}
}

struct output_backend_spec {
	char *keyword;
	int (*func)();
} output_backend_list[] = {
	{"pcb", pcb_netlist_output},
	{"geda", pcb_netlist_output},
	{"pinlist", pinlist_output},
	{"stats", stats_output},
	{NULL, NULL}};

select_output_backend(arg)
	char *arg;
{
	register struct output_backend_spec *tp;

	for (tp = output_backend_list; tp->keyword; tp++)
		if (!strcmp(tp->keyword, arg))
			break;
	if (!tp->func) {
		fprintf(stderr, "%s: unknown or unimplemented output backend\n",
			arg);
		exit(1);
	}
	do_output = tp->func;
}

open_output_file()
{
	if (outfilename) {
		outfile = fopen(outfilename, "w");
		if (!outfile) {
			perror(outfilename);
			exit(1);
		}
	} else
		outfile = stdout;
}