FreeCalypso > hg > ueda-linux
comparison 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 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:cd92449fdb51 |
|---|---|
| 1 /* | |
| 2 * Pinout handling functions | |
| 3 */ | |
| 4 | |
| 5 #include <ctype.h> | |
| 6 #include <stdio.h> | |
| 7 #include <strings.h> | |
| 8 #include "mcl.h" | |
| 9 #include "pinouts.h" | |
| 10 | |
| 11 extern char *malloc(); | |
| 12 extern char *copystr(); | |
| 13 | |
| 14 extern struct component components[]; | |
| 15 extern int ncomponents; | |
| 16 | |
| 17 extern char *get_comp_attr(); | |
| 18 extern FILE *find_symlib_file(); | |
| 19 extern char sought_libfile_fullpath[]; | |
| 20 | |
| 21 struct pinout_def * | |
| 22 read_pinout_file(filename) | |
| 23 char *filename; | |
| 24 { | |
| 25 FILE *f; | |
| 26 char line[1024]; | |
| 27 int lineno; | |
| 28 struct pinout_def *head, **tailp; | |
| 29 register struct pinout_def *pin; | |
| 30 register char *cp; | |
| 31 char *pinname, *pinnumber; | |
| 32 | |
| 33 f = find_symlib_file(filename, NULL); | |
| 34 if (!f) { | |
| 35 fprintf(stderr, "Cannot find pinout file %s\n", filename); | |
| 36 exit(1); | |
| 37 } | |
| 38 | |
| 39 head = NULL; | |
| 40 tailp = &head; | |
| 41 for (lineno = 1; fgets(line, sizeof line, f); lineno++) { | |
| 42 for (cp = line; isspace(*cp); cp++) | |
| 43 ; | |
| 44 if (*cp == '\0' || *cp == '#') | |
| 45 continue; | |
| 46 if (!isgraph(*cp)) { | |
| 47 syntaxerr: fprintf(stderr, "%s: line %d: syntax error\n", | |
| 48 sought_libfile_fullpath, lineno); | |
| 49 exit(1); | |
| 50 } | |
| 51 for (pinname = cp; isgraph(*cp); cp++) | |
| 52 ; | |
| 53 if (!isspace(*cp)) | |
| 54 goto syntaxerr; | |
| 55 *cp++ = '\0'; | |
| 56 while (isspace(*cp)) | |
| 57 cp++; | |
| 58 if (!isgraph(*cp) || *cp == '#') | |
| 59 goto syntaxerr; | |
| 60 for (pinnumber = cp; isgraph(*cp); cp++) | |
| 61 ; | |
| 62 if (isspace(*cp)) | |
| 63 *cp++ = '\0'; | |
| 64 else if (*cp) | |
| 65 goto syntaxerr; | |
| 66 pin = (struct pinout_def *) malloc(sizeof(struct pinout_def)); | |
| 67 if (!pin) { | |
| 68 perror("malloc"); | |
| 69 exit(1); | |
| 70 } | |
| 71 pin->pinname = copystr(pinname); | |
| 72 pin->pinnumber = copystr(pinnumber); | |
| 73 pin->next = NULL; | |
| 74 *tailp = pin; | |
| 75 tailp = &pin->next; | |
| 76 } | |
| 77 fclose(f); | |
| 78 | |
| 79 if (!head) { | |
| 80 fprintf(stderr, "%s: empty pinout file\n", | |
| 81 sought_libfile_fullpath); | |
| 82 exit(1); | |
| 83 } | |
| 84 return(head); | |
| 85 } | |
| 86 | |
| 87 /* | |
| 88 * We implement an optimisation: when we read all pinouts into core in | |
| 89 * read_pinouts(), we cache them by name so that we don't have to re-read | |
| 90 * and re-parse the same pinout files multiple times for multiple components. | |
| 91 * The caching array is local to read_pinouts() and limited by MAX_PINOUTS. | |
| 92 * If that limit is exceeded, caching will stop but we'll continue reading | |
| 93 * pinouts, i.e., only the optimisation will be lost. | |
| 94 */ | |
| 95 | |
| 96 #define MAX_PINOUTS 128 | |
| 97 | |
| 98 read_pinouts() | |
| 99 { | |
| 100 char *pinout_file_names[MAX_PINOUTS]; | |
| 101 struct pinout_def *parsed_pinouts[MAX_PINOUTS]; | |
| 102 int cached_pinouts, i; | |
| 103 register struct component *comp; | |
| 104 register char *pinout_file; | |
| 105 register struct pinout_def *parsed_pinout; | |
| 106 register int j; | |
| 107 | |
| 108 for (cached_pinouts = i = 0, comp = components; i < ncomponents; | |
| 109 comp++, i++) { | |
| 110 pinout_file = get_comp_attr(comp, "pinout"); | |
| 111 if (!pinout_file) | |
| 112 continue; | |
| 113 for (j = 0; j < cached_pinouts; j++) | |
| 114 if (!strcmp(pinout_file_names[j], pinout_file)) { | |
| 115 comp->pinout = parsed_pinouts[j]; | |
| 116 continue; | |
| 117 } | |
| 118 parsed_pinout = read_pinout_file(pinout_file); | |
| 119 comp->pinout = parsed_pinout; | |
| 120 if (cached_pinouts < MAX_PINOUTS) { | |
| 121 pinout_file_names[cached_pinouts] = pinout_file; | |
| 122 parsed_pinouts[cached_pinouts] = parsed_pinout; | |
| 123 cached_pinouts++; | |
| 124 } | |
| 125 } | |
| 126 return(0); | |
| 127 } | |
| 128 | |
| 129 char * | |
| 130 pinname_to_pinnumber(comp, pinname, slot) | |
| 131 struct component *comp; | |
| 132 char *pinname, *slot; | |
| 133 { | |
| 134 char strbuf[512]; | |
| 135 register char *searchkey; | |
| 136 register struct pinout_def *pin; | |
| 137 | |
| 138 pin = comp->pinout; | |
| 139 if (!pin) { | |
| 140 fprintf(stderr, "%s has no pinout\n", comp->name); | |
| 141 return(NULL); | |
| 142 } | |
| 143 if (slot) { | |
| 144 sprintf(strbuf, "%s:%s", pinname, slot); | |
| 145 searchkey = strbuf; | |
| 146 } else | |
| 147 searchkey = pinname; | |
| 148 for (; pin; pin = pin->next) | |
| 149 if (!strcmp(pin->pinname, searchkey)) | |
| 150 return(pin->pinnumber); | |
| 151 fprintf(stderr, "%s: no pin named %s\n", comp->name, searchkey); | |
| 152 return(NULL); | |
| 153 } |
