FreeCalypso > hg > ueda-linux
comparison ueda/unet-utils/unet2pads.c @ 33:2af4a85daf89
unet2pads program written, compiles
author | Space Falcon <falcon@ivan.Harhan.ORG> |
---|---|
date | Sat, 08 Aug 2015 23:06:59 +0000 |
parents | |
children | bc465afed423 |
comparison
equal
deleted
inserted
replaced
32:6c7c79d37eff | 33:2af4a85daf89 |
---|---|
1 #include <stdio.h> | |
2 #include <stdlib.h> | |
3 #include <string.h> | |
4 #include <strings.h> | |
5 #include <unistd.h> | |
6 #include "../libunet/unetrd.h" | |
7 #include "../libunet/nethash.h" | |
8 | |
9 extern struct net *enter_net_object(); | |
10 extern struct net *find_net_by_name(); | |
11 extern struct net *net_list_head; | |
12 | |
13 static char *input_filename, *output_filename; | |
14 static struct unetrd_state rdstate; | |
15 static struct unetrd_out rdout; | |
16 static FILE *tempFILE, *outFILE; | |
17 static int no_parttype_errors; | |
18 | |
19 struct netextra { | |
20 struct netmember *head; | |
21 struct netmember **tailp; | |
22 }; | |
23 | |
24 struct netmember { | |
25 char *name; | |
26 struct netmember *next; | |
27 }; | |
28 | |
29 static FILE * | |
30 tempfile() | |
31 { | |
32 char template[16]; | |
33 register int fd; | |
34 register FILE *f; | |
35 | |
36 strcpy(template, "/tmp/uedaXXXXXX"); | |
37 fd = mkstemp(template); | |
38 if (fd < 0) { | |
39 perror("mkstemp"); | |
40 exit(1); | |
41 } | |
42 unlink(template); | |
43 f = fdopen(fd, "r+w"); | |
44 if (!f) { | |
45 perror("fdopen"); | |
46 exit(1); | |
47 } | |
48 return(f); | |
49 } | |
50 | |
51 static void | |
52 dump_tempfile() | |
53 { | |
54 register FILE *inf = tempFILE; | |
55 register FILE *outf = outFILE; | |
56 register int c; | |
57 | |
58 rewind(inf); | |
59 while ((c = getc(inf)) != EOF) | |
60 putc(c, outf); | |
61 fclose(inf); | |
62 } | |
63 | |
64 static void | |
65 process_pin_connect(compname) | |
66 char *compname; | |
67 { | |
68 register struct net *n; | |
69 register struct netextra *nx; | |
70 register struct netmember *nm; | |
71 | |
72 n = find_net_by_name(rdout.connect_to_net); | |
73 nx = (struct netextra *)(n + 1); | |
74 nm = (struct netmember *) malloc(sizeof(struct netmember) + | |
75 strlen(compname) + | |
76 strlen(rdout.objname) + 2); | |
77 if (!nm) { | |
78 perror("malloc"); | |
79 exit(1); | |
80 } | |
81 nm->name = (char *)(nm + 1); | |
82 sprintf(nm->name, "%s.%s", compname, rdout.objname); | |
83 nm->next = 0; | |
84 *nx->tailp = nm; | |
85 nx->tailp = &nm->next; | |
86 } | |
87 | |
88 static void | |
89 process_component() | |
90 { | |
91 char compname[64]; | |
92 int parttype_seen = 0; | |
93 | |
94 strcpy(compname, rdout.objname); | |
95 for (;;) { | |
96 if (!read_unet_line(&rdstate, &rdout)) { | |
97 fprintf(stderr, "%s error: EOF in COMPONENT block\n", | |
98 input_filename); | |
99 exit(1); | |
100 } | |
101 if (rdout.typecode == UNETOBJ_CLOSINGBRACE) | |
102 break; | |
103 switch(rdout.typecode) { | |
104 case UNETOBJ_PRIMITIVE: | |
105 case UNETOBJ_ALTNAME: | |
106 continue; | |
107 case UNETOBJ_ATTR: | |
108 if (strcmp(rdout.objname, "pads_parttype")) | |
109 continue; | |
110 if (parttype_seen) { | |
111 fprintf(stderr, | |
112 "%s lind %d: duplicate ATTR pads_parttype for COMPONENT %s\n", | |
113 input_filename, rdstate.lineno, | |
114 compname); | |
115 exit(1); | |
116 } | |
117 fprintf(tempFILE, "%s %s\n", compname, | |
118 rdout.attr_value); | |
119 parttype_seen = 1; | |
120 continue; | |
121 case UNETOBJ_PIN: | |
122 if (rdout.connect_to_net) | |
123 process_pin_connect(compname); | |
124 continue; | |
125 case UNETOBJ_PINMAP: | |
126 fprintf(stderr, | |
127 "%s line %d: PINMAP objects not expected in unet2pads input\n", | |
128 input_filename, rdstate.lineno); | |
129 exit(1); | |
130 default: | |
131 fprintf(stderr, | |
132 "%s line %d: object type %s unexpected in COMPONENT block\n", | |
133 input_filename, rdstate.lineno, rdout.keyword); | |
134 exit(1); | |
135 } | |
136 } | |
137 if (!parttype_seen) { | |
138 fprintf(stderr, | |
139 "error: component %s has no pads_parttype set\n", | |
140 compname); | |
141 no_parttype_errors++; | |
142 } | |
143 } | |
144 | |
145 static void | |
146 process_input_unet() | |
147 { | |
148 struct net *n; | |
149 struct netextra *nx; | |
150 | |
151 open_unet_input_file(input_filename, &rdstate); | |
152 while (read_unet_line(&rdstate, &rdout)) { | |
153 switch(rdout.typecode) { | |
154 case UNETOBJ_CLOSINGBRACE: | |
155 fprintf(stderr, | |
156 "%s line %d: unexpected '}' outside of component block\n", | |
157 input_filename, rdstate.lineno); | |
158 exit(1); | |
159 case UNETOBJ_NET: | |
160 n = enter_net_object(rdout.objname, | |
161 sizeof(struct netextra)); | |
162 nx = (struct netextra *)(n + 1); | |
163 nx->head = 0; | |
164 nx->tailp = &nx->head; | |
165 continue; | |
166 case UNETOBJ_COMPONENT: | |
167 if (!tempFILE) | |
168 tempFILE = tempfile(); | |
169 process_component(); | |
170 continue; | |
171 case UNETOBJ_STARPOINT: | |
172 fprintf(stderr, | |
173 "error: STARPOINT objects not expected in unet2pads input (%s line %d)\n", | |
174 input_filename, rdstate.lineno); | |
175 exit(1); | |
176 default: | |
177 fprintf(stderr, | |
178 "%s line %d: unexpected object type %s\n", | |
179 input_filename, rdstate.lineno, rdout.keyword); | |
180 exit(1); | |
181 } | |
182 } | |
183 if (!tempFILE) { | |
184 fprintf(stderr, "error: no components found in %s input!\n", | |
185 input_filename); | |
186 exit(1); | |
187 } | |
188 } | |
189 | |
190 static void | |
191 output_nets() | |
192 { | |
193 struct net *n; | |
194 struct netextra *nx; | |
195 register struct netmember *nm; | |
196 int linelen; | |
197 | |
198 fputs("*NET*\n", outFILE); | |
199 for (n = net_list_head; n; n = n->nextinlist) { | |
200 nx = (struct netextra *)(n + 1); | |
201 fprintf(outFILE, "*SIG* %s\n", n->name); | |
202 linelen = 0; | |
203 for (nm = nx->head; nm; nm = nm->next) { | |
204 if (linelen && linelen + strlen(nm->name) + 1 > 79) { | |
205 putc('\n', outFILE); | |
206 linelen = 0; | |
207 } | |
208 if (linelen) { | |
209 putc(' ', outFILE); | |
210 linelen++; | |
211 } | |
212 fputs(nm->name, outFILE); | |
213 linelen += strlen(nm->name); | |
214 } | |
215 if (linelen) | |
216 putc('\n', outFILE); | |
217 } | |
218 } | |
219 | |
220 static void | |
221 generate_output() | |
222 { | |
223 if (output_filename) { | |
224 outFILE = fopen(output_filename, "w"); | |
225 if (!outFILE) { | |
226 perror(output_filename); | |
227 exit(1); | |
228 } | |
229 } else | |
230 outFILE = stdout; | |
231 fputs("!PADS-POWERPCB-V3.0-MILS! DESIGN DATABASE ASCII FILE 2.0\n\n", | |
232 outFILE); | |
233 fputs("*PART* ITEMS\n", outFILE); | |
234 dump_tempfile(); | |
235 putc('\n', outFILE); | |
236 output_nets(); | |
237 fputs("\n*END* OF ASCII OUTPUT FILE\n", outFILE); | |
238 if (outFILE != stdout) | |
239 fclose(outFILE); | |
240 } | |
241 | |
242 main(argc, argv) | |
243 char **argv; | |
244 { | |
245 if (argc < 2 || argc > 3) { | |
246 fprintf(stderr, "usage: %s input.unet [output.unet]\n", | |
247 argv[0]); | |
248 exit(1); | |
249 } | |
250 input_filename = argv[1]; | |
251 output_filename = argv[2]; | |
252 process_input_unet(); | |
253 generate_output(); | |
254 exit(0); | |
255 } |