FreeCalypso > hg > ueda-linux
view ueda/libueda/pinouts.c @ 2:c91e7a30fab3
ueda/libueda Linuxified
author | Space Falcon <falcon@ivan.Harhan.ORG> |
---|---|
date | Mon, 20 Jul 2015 00:38:43 +0000 |
parents | cd92449fdb51 |
children |
line wrap: on
line source
/* * Pinout handling functions */ #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include "mcl.h" #include "pinouts.h" 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); }