comparison ueda/libueda/xga.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 * This module contains the function that implements the reading of PGA/BGA
3 * package description files and some related functions.
4 */
5
6 #include <ctype.h>
7 #include <stdio.h>
8 #include <strings.h>
9 #include "xga.h"
10
11 extern char *malloc();
12 extern char *copystr();
13
14 extern FILE *find_symlib_file();
15 extern char sought_libfile_fullpath[];
16
17 parse_xga_pinnumber(desc, pinstr, parsed)
18 register struct grid_pkg_desc *desc;
19 register char *pinstr;
20 struct xga_parsed_pinnum *parsed;
21 {
22 char *rowfind;
23 int col;
24
25 if (!isupper(pinstr[0]) || !isdigit(pinstr[1]))
26 return(-1);
27 rowfind = index(desc->row_letters, pinstr[0]);
28 if (!rowfind)
29 return(-1);
30 if (!string_is_valid_decnum(pinstr + 1))
31 return(-1);
32 col = atoi(pinstr + 1);
33 if (col < 1 || col > desc->ncolumns)
34 return(-1);
35 parsed->row_0based = rowfind - desc->row_letters;
36 parsed->col_0based = col - 1;
37 return(0);
38 }
39
40 static void
41 check_complete(desc)
42 register struct grid_pkg_desc *desc;
43 {
44 register char *array;
45
46 if (desc->holes_array) /* already allocated */
47 return;
48 if (!desc->nrows || !desc->ncolumns) /* not specified yet */
49 return;
50 /* allocate it! */
51 array = malloc(desc->nrows * desc->ncolumns);
52 if (!array) {
53 perror("malloc");
54 exit(1);
55 }
56 desc->holes_array = array;
57 bzero(array, desc->nrows * desc->ncolumns);
58 }
59
60 static void
61 validate_rows_arg(arg, filename, lineno)
62 char *arg, *filename;
63 int lineno;
64 {
65 register char *cp;
66 register int c, prev;
67
68 prev = 0;
69 for (cp = arg; c = *cp++; prev = c) {
70 if (c < 'A' || c > 'Z') {
71 fprintf(stderr,
72 "%s line %d: rows setting: only uppercase letters are allowed\n",
73 filename, lineno);
74 exit(1);
75 }
76 if (c <= prev) {
77 fprintf(stderr,
78 "%s line %d: rows setting: letters must be increasing\n",
79 filename, lineno);
80 exit(1);
81 }
82 }
83 }
84
85 static void
86 handle_rows_line(desc, arg, filename, lineno)
87 struct grid_pkg_desc *desc;
88 char *arg, *filename;
89 int lineno;
90 {
91 register char *cp, *np;
92
93 if (desc->row_letters) {
94 fprintf(stderr, "%s line %d: duplicate rows setting\n",
95 filename, lineno);
96 exit(1);
97 }
98 for (cp = arg; isspace(*cp); cp++)
99 ;
100 if (*cp == '\0' || *cp == '#') {
101 fprintf(stderr, "%s line %d: rows setting has no argument\n",
102 filename, lineno);
103 exit(1);
104 }
105 for (np = cp; *cp && !isspace(*cp); cp++)
106 ;
107 if (*cp)
108 *cp++ = '\0';
109 validate_rows_arg(np, filename, lineno);
110 desc->row_letters = copystr(np);
111 desc->nrows = strlen(np);
112 check_complete(desc);
113 }
114
115 static void
116 handle_columns_line(desc, arg, filename, lineno)
117 struct grid_pkg_desc *desc;
118 char *arg, *filename;
119 int lineno;
120 {
121 register char *cp, *np;
122
123 if (desc->ncolumns) {
124 fprintf(stderr, "%s line %d: duplicate columns setting\n",
125 filename, lineno);
126 exit(1);
127 }
128 for (cp = arg; isspace(*cp); cp++)
129 ;
130 if (*cp == '\0' || *cp == '#') {
131 fprintf(stderr, "%s line %d: columns setting has no argument\n",
132 filename, lineno);
133 exit(1);
134 }
135 for (np = cp; *cp && !isspace(*cp); cp++)
136 ;
137 if (*cp)
138 *cp++ = '\0';
139 if (!string_is_valid_decnum(np)) {
140 fprintf(stderr,
141 "%s line %d: columns setting must be a number\n",
142 filename, lineno);
143 exit(1);
144 }
145 desc->ncolumns = atoi(np);
146 if (desc->ncolumns < 1) {
147 fprintf(stderr, "%s line %d: columns number must be positive\n",
148 filename, lineno);
149 exit(1);
150 }
151 check_complete(desc);
152 }
153
154 static void
155 handle_hole_spec(desc, arg, filename, lineno)
156 register struct grid_pkg_desc *desc;
157 char *arg, *filename;
158 int lineno;
159 {
160 char *arg2;
161 struct xga_parsed_pinnum start_parsed, end_parsed;
162 register int r, c;
163
164 arg2 = index(arg, '-');
165 if (arg2)
166 *arg2++ = '\0';
167 else
168 arg2 = arg;
169 if (parse_xga_pinnumber(desc, arg, &start_parsed) < 0) {
170 fprintf(stderr,
171 "%s line %d: \"%s\" is not a valid pin position for this package\n",
172 filename, lineno, arg);
173 exit(1);
174 }
175 if (parse_xga_pinnumber(desc, arg2, &end_parsed) < 0) {
176 fprintf(stderr,
177 "%s line %d: \"%s\" is not a valid pin position for this package\n",
178 filename, lineno, arg2);
179 exit(1);
180 }
181 if (start_parsed.row_0based == end_parsed.row_0based) {
182 r = start_parsed.row_0based;
183 if (start_parsed.col_0based > end_parsed.col_0based) {
184 error_reversed: fprintf(stderr,
185 "%s line %d: hole ranges need to be increasing\n",
186 filename, lineno);
187 exit(1);
188 }
189 for (c = start_parsed.col_0based; c <= end_parsed.col_0based;
190 c++)
191 desc->holes_array[r * desc->ncolumns + c] = 1;
192 } else if (start_parsed.col_0based == end_parsed.col_0based) {
193 c = start_parsed.col_0based;
194 if (start_parsed.row_0based > end_parsed.row_0based)
195 goto error_reversed;
196 for (r = start_parsed.row_0based; r <= end_parsed.row_0based;
197 r++)
198 desc->holes_array[r * desc->ncolumns + c] = 1;
199 } else {
200 fprintf(stderr,
201 "%s line %d: hole ranges must be horizontal or vertical\n",
202 filename, lineno);
203 exit(1);
204 }
205 }
206
207 static void
208 handle_hole_line(desc, arg, filename, lineno)
209 struct grid_pkg_desc *desc;
210 char *arg, *filename;
211 int lineno;
212 {
213 register char *cp, *np;
214
215 if (!desc->holes_array) {
216 fprintf(stderr,
217 "%s line %d: rows and columns must be defined before holes\n",
218 filename, lineno);
219 exit(1);
220 }
221 for (cp = arg; ; ) {
222 while (isspace(*cp))
223 cp++;
224 if (*cp == '\0' || *cp == '#')
225 break;
226 for (np = cp; *cp && !isspace(*cp); cp++)
227 ;
228 if (*cp)
229 *cp++ = '\0';
230 handle_hole_spec(desc, np, filename, lineno);
231 }
232 }
233
234 struct grid_pkg_desc *
235 read_grid_pkg_file(filename)
236 char *filename;
237 {
238 FILE *f;
239 char linebuf[1024];
240 int lineno;
241 register char *cp, *np;
242 struct grid_pkg_desc *desc;
243
244 f = find_symlib_file(filename, NULL);
245 if (!f) {
246 fprintf(stderr, "Cannot find xGA definition file %s\n",
247 filename);
248 exit(1);
249 }
250 desc = (struct grid_pkg_desc *) malloc(sizeof(struct grid_pkg_desc));
251 if (!desc) {
252 perror("malloc");
253 exit(1);
254 }
255 bzero(desc, sizeof(struct grid_pkg_desc));
256 for (lineno = 1; fgets(linebuf, sizeof linebuf, f); lineno++) {
257 for (cp = linebuf; isspace(*cp); cp++)
258 ;
259 if (*cp == '\0' || *cp == '#')
260 continue;
261 for (np = cp; *cp && !isspace(*cp); cp++)
262 ;
263 if (*cp)
264 *cp++ = '\0';
265 if (!strcmp(np, "rows"))
266 handle_rows_line(desc, cp, sought_libfile_fullpath,
267 lineno);
268 else if (!strcmp(np, "columns"))
269 handle_columns_line(desc, cp, sought_libfile_fullpath,
270 lineno);
271 else if (!strcmp(np, "hole"))
272 handle_hole_line(desc, cp, sought_libfile_fullpath,
273 lineno);
274 else {
275 fprintf(stderr,
276 "%s line %d: setting \"%s\" not understood\n",
277 sought_libfile_fullpath, lineno, np);
278 exit(1);
279 }
280 }
281 fclose(f);
282
283 if (!desc->nrows) {
284 fprintf(stderr, "error: %s contains no rows setting\n",
285 sought_libfile_fullpath);
286 exit(1);
287 }
288 if (!desc->ncolumns) {
289 fprintf(stderr, "error: %s contains no columns setting\n",
290 sought_libfile_fullpath);
291 exit(1);
292 }
293 return(desc);
294 }
295
296 free_grid_pkg_desc(desc)
297 struct grid_pkg_desc *desc;
298 {
299 free(desc->row_letters);
300 free(desc->holes_array);
301 free(desc);
302 }