FreeCalypso > hg > ueda-linux
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); +}