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 }