diff ueda/libueda/pinouts.c @ 0:cd92449fdb51

initial import of ueda and ifctf-part-lib from ifctfvax CVS
author Space Falcon <falcon@ivan.Harhan.ORG>
date Mon, 20 Jul 2015 00:24:37 +0000
parents
children c91e7a30fab3
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ueda/libueda/pinouts.c	Mon Jul 20 00:24:37 2015 +0000
@@ -0,0 +1,153 @@
+/*
+ * Pinout handling functions
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <strings.h>
+#include "mcl.h"
+#include "pinouts.h"
+
+extern char *malloc();
+extern char *copystr();
+
+extern struct component components[];
+extern int ncomponents;
+
+extern char *get_comp_attr();
+extern FILE *find_symlib_file();
+extern char sought_libfile_fullpath[];
+
+struct pinout_def *
+read_pinout_file(filename)
+	char *filename;
+{
+	FILE *f;
+	char line[1024];
+	int lineno;
+	struct pinout_def *head, **tailp;
+	register struct pinout_def *pin;
+	register char *cp;
+	char *pinname, *pinnumber;
+
+	f = find_symlib_file(filename, NULL);
+	if (!f) {
+		fprintf(stderr, "Cannot find pinout file %s\n", filename);
+		exit(1);
+	}
+
+	head = NULL;
+	tailp = &head;
+	for (lineno = 1; fgets(line, sizeof line, f); lineno++) {
+		for (cp = line; isspace(*cp); cp++)
+			;
+		if (*cp == '\0' || *cp == '#')
+			continue;
+		if (!isgraph(*cp)) {
+syntaxerr:		fprintf(stderr, "%s: line %d: syntax error\n",
+				sought_libfile_fullpath, lineno);
+			exit(1);
+		}
+		for (pinname = cp; isgraph(*cp); cp++)
+			;
+		if (!isspace(*cp))
+			goto syntaxerr;
+		*cp++ = '\0';
+		while (isspace(*cp))
+			cp++;
+		if (!isgraph(*cp) || *cp == '#')
+			goto syntaxerr;
+		for (pinnumber = cp; isgraph(*cp); cp++)
+			;
+		if (isspace(*cp))
+			*cp++ = '\0';
+		else if (*cp)
+			goto syntaxerr;
+		pin = (struct pinout_def *) malloc(sizeof(struct pinout_def));
+		if (!pin) {
+			perror("malloc");
+			exit(1);
+		}
+		pin->pinname = copystr(pinname);
+		pin->pinnumber = copystr(pinnumber);
+		pin->next = NULL;
+		*tailp = pin;
+		tailp = &pin->next;
+	}
+	fclose(f);
+
+	if (!head) {
+		fprintf(stderr, "%s: empty pinout file\n",
+			sought_libfile_fullpath);
+		exit(1);
+	}
+	return(head);
+}
+
+/*
+ * We implement an optimisation: when we read all pinouts into core in
+ * read_pinouts(), we cache them by name so that we don't have to re-read
+ * and re-parse the same pinout files multiple times for multiple components.
+ * The caching array is local to read_pinouts() and limited by MAX_PINOUTS.
+ * If that limit is exceeded, caching will stop but we'll continue reading
+ * pinouts, i.e., only the optimisation will be lost.
+ */
+
+#define	MAX_PINOUTS	128
+
+read_pinouts()
+{
+	char *pinout_file_names[MAX_PINOUTS];
+	struct pinout_def *parsed_pinouts[MAX_PINOUTS];
+	int cached_pinouts, i;
+	register struct component *comp;
+	register char *pinout_file;
+	register struct pinout_def *parsed_pinout;
+	register int j;
+
+	for (cached_pinouts = i = 0, comp = components; i < ncomponents;
+	     comp++, i++) {
+		pinout_file = get_comp_attr(comp, "pinout");
+		if (!pinout_file)
+			continue;
+		for (j = 0; j < cached_pinouts; j++)
+			if (!strcmp(pinout_file_names[j], pinout_file)) {
+				comp->pinout = parsed_pinouts[j];
+				continue;
+			}
+		parsed_pinout = read_pinout_file(pinout_file);
+		comp->pinout = parsed_pinout;
+		if (cached_pinouts < MAX_PINOUTS) {
+			pinout_file_names[cached_pinouts] = pinout_file;
+			parsed_pinouts[cached_pinouts] = parsed_pinout;
+			cached_pinouts++;
+		}
+	}
+	return(0);
+}
+
+char *
+pinname_to_pinnumber(comp, pinname, slot)
+	struct component *comp;
+	char *pinname, *slot;
+{
+	char strbuf[512];
+	register char *searchkey;
+	register struct pinout_def *pin;
+
+	pin = comp->pinout;
+	if (!pin) {
+		fprintf(stderr, "%s has no pinout\n", comp->name);
+		return(NULL);
+	}
+	if (slot) {
+		sprintf(strbuf, "%s:%s", pinname, slot);
+		searchkey = strbuf;
+	} else
+		searchkey = pinname;
+	for (; pin; pin = pin->next)
+		if (!strcmp(pin->pinname, searchkey))
+			return(pin->pinnumber);
+	fprintf(stderr, "%s: no pin named %s\n", comp->name, searchkey);
+	return(NULL);
+}