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