FreeCalypso > hg > ueda-linux
comparison ueda/libueda/readmcl.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 is the MCL parser for the uEDA suite. | |
3 */ | |
4 | |
5 #include <stdio.h> | |
6 #include <ctype.h> | |
7 #include <strings.h> | |
8 #include "mcl.h" | |
9 | |
10 extern char *copystr(); | |
11 | |
12 #define MAX_COMPS 1024 | |
13 #define MAX_PARTDEFS 128 | |
14 #define MAX_ATTRS 2048 | |
15 #define MAX_REFDES_ON_LINE 16 | |
16 | |
17 char *MCLfile = "MCL"; | |
18 | |
19 /* the following vars capture the distilled output of the parser */ | |
20 struct component components[MAX_COMPS], partdefs[MAX_PARTDEFS]; | |
21 int ncomponents, npartdefs; | |
22 static struct attrib attrs[MAX_ATTRS]; | |
23 static int nattrs; | |
24 | |
25 /* the following static vars are used only in the reading & parsing process */ | |
26 static FILE *mclf; | |
27 static char line[1024]; /* size arbitrary, sizeof used in the code */ | |
28 static int lineno; | |
29 | |
30 static struct component *curcomp; | |
31 static char *curcomp_refdes[MAX_REFDES_ON_LINE]; | |
32 static int curcomp_nrefdes; | |
33 | |
34 read_MCL() | |
35 { | |
36 register char *cp, *name, *value; | |
37 | |
38 mclf = fopen(MCLfile, "r"); | |
39 if (!mclf) { | |
40 perror(MCLfile); | |
41 exit(1); | |
42 } | |
43 | |
44 for (lineno = 0, curcomp = NULL; getline(); ) { | |
45 /* ignore blank lines and comments */ | |
46 if (line[0] == '\0' || line[0] == '#') | |
47 continue; | |
48 if (!strncmp(line, "part", 4) && isspace(line[4])) { | |
49 finish_component(); | |
50 setup_partdef(line + 5); | |
51 } else if (!isspace(line[0])) { /* refdes */ | |
52 finish_component(); | |
53 parse_refdes_list(); | |
54 if (ncomponents >= MAX_COMPS) { | |
55 fprintf(stderr, | |
56 "%s: line %d: too many components\n", | |
57 MCLfile, lineno); | |
58 exit(1); | |
59 } | |
60 curcomp = components + ncomponents; | |
61 curcomp->name = curcomp_refdes[0]; | |
62 curcomp->attrs = attrs + nattrs; | |
63 curcomp->nattrs = 0; | |
64 ncomponents++; | |
65 } else { /* attribute */ | |
66 for (cp = line; isspace(*cp); cp++) | |
67 ; | |
68 name = cp; | |
69 cp = index(cp, '='); | |
70 if (!cp) { | |
71 invattr: fprintf(stderr, | |
72 "%s: line %d: invalid attribute line\n", | |
73 MCLfile, lineno); | |
74 exit(1); | |
75 } | |
76 *cp = '\0'; | |
77 value = cp + 1; | |
78 if (name[0] == '\0') | |
79 goto invattr; | |
80 if (!curcomp) { | |
81 fprintf(stderr, | |
82 "%s: line %d: attribute listed without a component\n", | |
83 MCLfile, lineno); | |
84 exit(1); | |
85 } | |
86 if (value[0] == '\0') { | |
87 fprintf(stderr, | |
88 "%s: line %d: attribute must have a value\n", | |
89 MCLfile, lineno); | |
90 exit(1); | |
91 } | |
92 if (nattrs >= MAX_ATTRS) { | |
93 fprintf(stderr, | |
94 "%s: line %d: too many attributes\n", | |
95 MCLfile, lineno); | |
96 exit(1); | |
97 } | |
98 attrs[nattrs].name = copystr(name); | |
99 attrs[nattrs].value = copystr(value); | |
100 nattrs++; | |
101 curcomp->nattrs++; | |
102 if (!strcmp(name, "part")) | |
103 handle_part_ref(value); | |
104 } | |
105 } | |
106 fclose(mclf); | |
107 finish_component(); | |
108 } | |
109 | |
110 static | |
111 setup_partdef(np) | |
112 register char *np; | |
113 { | |
114 register char *cp; | |
115 | |
116 while (isspace(*np)) | |
117 np++; | |
118 cp = index(np, ':'); | |
119 if (!cp || cp == np || cp[1]) { | |
120 fprintf(stderr, "%s: line %d: invalid part definition\n", | |
121 MCLfile, lineno); | |
122 exit(1); | |
123 } | |
124 *cp = '\0'; | |
125 if (npartdefs >= MAX_PARTDEFS) { | |
126 fprintf(stderr, "%s: line %d: too many part definitions\n", | |
127 MCLfile, lineno); | |
128 exit(1); | |
129 } | |
130 curcomp = partdefs + npartdefs; | |
131 curcomp->name = copystr(np); | |
132 curcomp->attrs = attrs + nattrs; | |
133 curcomp->nattrs = 0; | |
134 npartdefs++; | |
135 curcomp_nrefdes = 0; | |
136 } | |
137 | |
138 static | |
139 parse_refdes_list() | |
140 { | |
141 int i; | |
142 register char *cp, *np; | |
143 register int c; | |
144 | |
145 for (cp = line, i = 0; ; ) { | |
146 if (!isupper(*cp)) { | |
147 inv: fprintf(stderr, "%s: line %d: invalid refdes line\n", | |
148 MCLfile, lineno); | |
149 exit(1); | |
150 } | |
151 for (np = cp; isalnum(*cp); cp++) | |
152 ; | |
153 c = *cp; | |
154 if (c != ':' && c != ',') | |
155 goto inv; | |
156 *cp++ = '\0'; | |
157 curcomp_refdes[i++] = copystr(np); | |
158 if (c == ':') | |
159 break; | |
160 } | |
161 curcomp_nrefdes = i; | |
162 if (*cp) | |
163 goto inv; | |
164 } | |
165 | |
166 static | |
167 finish_component() | |
168 { | |
169 extern char *get_comp_attr(); | |
170 | |
171 if (curcomp_nrefdes == 0) | |
172 return; /* nothing to do for part defs */ | |
173 if (!curcomp->partdef && | |
174 (get_comp_attr(curcomp, "manufacturer") && | |
175 get_comp_attr(curcomp, "manufacturer_part_number") || | |
176 get_comp_attr(curcomp, "bom_part_title"))) | |
177 curcomp->partdef = curcomp; /* self-defines part */ | |
178 if (curcomp_nrefdes > 1) | |
179 clone_component(); | |
180 } | |
181 | |
182 static | |
183 clone_component() | |
184 { | |
185 register int i; | |
186 register struct component *newcomp; | |
187 | |
188 for (i = 1; i < curcomp_nrefdes; i++) { | |
189 if (ncomponents >= MAX_COMPS) { | |
190 fprintf(stderr, "%s: %s: too many components\n", | |
191 MCLfile, curcomp_refdes[i]); | |
192 exit(1); | |
193 } | |
194 newcomp = components + ncomponents; | |
195 bcopy(curcomp, newcomp, sizeof(struct component)); | |
196 newcomp->name = curcomp_refdes[i]; | |
197 ncomponents++; | |
198 } | |
199 } | |
200 | |
201 static | |
202 handle_part_ref(partname) | |
203 char *partname; | |
204 { | |
205 register struct component *part; | |
206 register int i; | |
207 | |
208 if (curcomp_nrefdes == 0) { | |
209 fprintf(stderr, | |
210 "%s: line %d: can't use a part reference in a part definition!\n", | |
211 MCLfile, lineno); | |
212 exit(1); | |
213 } | |
214 if (!strcmp(partname, "none")) { | |
215 curcomp->partdef = NULL; | |
216 return; | |
217 } | |
218 if (!strcmp(partname, "yes")) { | |
219 curcomp->partdef = curcomp; /* self-defines the part */ | |
220 return; | |
221 } | |
222 for (part = partdefs, i = 0; i < npartdefs; part++, i++) | |
223 if (!strcmp(part->name, partname)) { | |
224 gotit: curcomp->partdef = part; | |
225 return; | |
226 } | |
227 /* can also refer to a previous component that self-defines a part */ | |
228 for (part = components, i = 0; i < ncomponents-1; part++, i++) | |
229 if (!strcmp(part->name, partname)) { | |
230 if (part->partdef == part) | |
231 goto gotit; | |
232 else { | |
233 fprintf(stderr, | |
234 "%s: line %d: can't use %s as a part because it doesn't define a part\n", | |
235 MCLfile, lineno, partname); | |
236 exit(1); | |
237 } | |
238 } | |
239 fprintf(stderr, "%s: line %d: part %s not defined\n", MCLfile, lineno, | |
240 partname); | |
241 exit(1); | |
242 } | |
243 | |
244 static | |
245 getline() | |
246 { | |
247 register char *cp; | |
248 | |
249 if (fgets(line, sizeof line, mclf) == NULL) | |
250 return(0); | |
251 lineno++; | |
252 /* strip trailing comments and whitespace */ | |
253 cp = index(line, '#'); | |
254 if (!cp) | |
255 cp = index(line, '\0'); | |
256 while (cp > line && isspace(cp[-1])) | |
257 cp--; | |
258 *cp = '\0'; | |
259 return(1); | |
260 } |