FreeCalypso > hg > ueda-linux
annotate ueda/libunet/unetrd.c @ 49:b3b7013d9228
pads2gpcb.c/decals.c: allow underscores in written decal file names
author | Mychaela Falconia <falcon@ivan.Harhan.ORG> |
---|---|
date | Sat, 30 Jan 2016 17:38:47 +0000 |
parents | 33e4c4cdf493 |
children |
rev | line source |
---|---|
9 | 1 /* |
2 * This module provides library functions for reading and parsing | |
3 * netlist files in our unet format. | |
4 */ | |
5 | |
6 #include <stdio.h> | |
7 #include <stdlib.h> | |
8 #include <ctype.h> | |
9 #include <string.h> | |
10 #include <strings.h> | |
11 #include "unetrd.h" | |
12 | |
13 open_unet_input_file(filename, state) | |
14 char *filename; | |
15 struct unetrd_state *state; | |
16 { | |
17 state->filename = filename; | |
18 state->stream = fopen(filename, "r"); | |
19 if (!state->stream) { | |
20 perror(filename); | |
21 exit(1); | |
22 } | |
23 state->lineno = 0; | |
24 } | |
25 | |
26 static void | |
27 handle_name_only(state, out, rest) | |
28 struct unetrd_state *state; | |
29 struct unetrd_out *out; | |
30 char *rest; | |
31 { | |
32 char *cp; | |
33 | |
20
dda8e455c863
unet-bind works to the point of reporting unbound instances
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
18
diff
changeset
|
34 for (cp = rest; isspace(*cp); cp++) |
9 | 35 ; |
36 if (*cp == '\0' || *cp == '#') { | |
37 fprintf(stderr, "%s line %d: a name is expected after %s\n", | |
38 state->filename, state->lineno, out->keyword); | |
39 exit(1); | |
40 } | |
41 out->objname = cp; | |
42 while (*cp && !isspace(*cp)) | |
43 cp++; | |
44 if (*cp) | |
45 *cp++ = '\0'; | |
46 while (isspace(*cp)) | |
47 cp++; | |
48 if (*cp && *cp != '#') { | |
49 fprintf(stderr, | |
50 "%s line %d: unexpected extra fields on %s line\n", | |
51 state->filename, state->lineno, out->keyword); | |
52 exit(1); | |
53 } | |
54 } | |
55 | |
56 static void | |
57 handle_component_opening(state, out, rest) | |
58 struct unetrd_state *state; | |
59 struct unetrd_out *out; | |
60 char *rest; | |
61 { | |
62 char *cp; | |
63 | |
20
dda8e455c863
unet-bind works to the point of reporting unbound instances
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
18
diff
changeset
|
64 for (cp = rest; isspace(*cp); cp++) |
9 | 65 ; |
66 if (*cp == '\0' || *cp == '#') { | |
67 fprintf(stderr, "%s line %d: a name is expected after %s\n", | |
68 state->filename, state->lineno, out->keyword); | |
69 exit(1); | |
70 } | |
71 out->objname = cp; | |
72 while (*cp && !isspace(*cp)) | |
73 cp++; | |
74 if (*cp) | |
75 *cp++ = '\0'; | |
76 while (isspace(*cp)) | |
77 cp++; | |
78 if (*cp != '{') { | |
79 fprintf(stderr, | |
80 "%s line %d: expected '{' at the end of %s line\n", | |
81 state->filename, state->lineno, out->keyword); | |
82 exit(1); | |
83 } | |
84 } | |
85 | |
86 static void | |
87 handle_pin_line(state, out, rest) | |
88 struct unetrd_state *state; | |
89 struct unetrd_out *out; | |
90 char *rest; | |
91 { | |
92 char *cp = rest, *fields[3]; | |
93 int i; | |
94 | |
95 for (i = 0; i < 3; i++) { | |
96 while (isspace(*cp)) | |
97 cp++; | |
98 if (*cp == '\0' || *cp == '#') { | |
99 error: fprintf(stderr, | |
100 "%s line %d: invalid syntax on %s line\n", | |
101 state->filename, state->lineno, out->keyword); | |
102 exit(1); | |
103 } | |
104 fields[i] = cp; | |
105 while (*cp && !isspace(*cp)) | |
106 cp++; | |
107 if (*cp) | |
108 *cp++ = '\0'; | |
109 } | |
110 out->objname = fields[0]; | |
111 if (strcmp(fields[1], "=")) | |
112 goto error; | |
113 if (!strcmp(fields[2], "NET")) { | |
114 while (isspace(*cp)) | |
115 cp++; | |
116 if (*cp == '\0' || *cp == '#') | |
117 goto error; | |
118 out->connect_to_net = cp; | |
119 while (*cp && !isspace(*cp)) | |
120 cp++; | |
121 if (*cp) | |
122 *cp++ = '\0'; | |
123 } else if (!strcmp(fields[2], "NC")) { | |
124 out->connect_to_net = 0; | |
125 while (isspace(*cp)) | |
126 cp++; | |
127 if (*cp++ != '(') | |
128 goto error; | |
129 out->nc_comment = cp; | |
130 while (*cp && *cp != ')') | |
131 cp++; | |
132 if (*cp != ')') | |
133 goto error; | |
134 *cp++ = '\0'; | |
135 } else | |
136 goto error; | |
137 while (isspace(*cp)) | |
138 cp++; | |
139 if (*cp && *cp != '#') { | |
140 fprintf(stderr, | |
141 "%s line %d: unexpected extra fields on %s line\n", | |
142 state->filename, state->lineno, out->keyword); | |
143 exit(1); | |
144 } | |
145 } | |
146 | |
28
33e4c4cdf493
libunet: reading of ATTR lines implemented
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
20
diff
changeset
|
147 static void |
33e4c4cdf493
libunet: reading of ATTR lines implemented
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
20
diff
changeset
|
148 handle_attr(state, out, rest) |
33e4c4cdf493
libunet: reading of ATTR lines implemented
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
20
diff
changeset
|
149 struct unetrd_state *state; |
33e4c4cdf493
libunet: reading of ATTR lines implemented
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
20
diff
changeset
|
150 struct unetrd_out *out; |
33e4c4cdf493
libunet: reading of ATTR lines implemented
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
20
diff
changeset
|
151 char *rest; |
33e4c4cdf493
libunet: reading of ATTR lines implemented
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
20
diff
changeset
|
152 { |
33e4c4cdf493
libunet: reading of ATTR lines implemented
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
20
diff
changeset
|
153 char *cp; |
33e4c4cdf493
libunet: reading of ATTR lines implemented
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
20
diff
changeset
|
154 |
33e4c4cdf493
libunet: reading of ATTR lines implemented
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
20
diff
changeset
|
155 for (cp = rest; isspace(*cp); cp++) |
33e4c4cdf493
libunet: reading of ATTR lines implemented
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
20
diff
changeset
|
156 ; |
33e4c4cdf493
libunet: reading of ATTR lines implemented
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
20
diff
changeset
|
157 if (*cp == '\0' || *cp == '#') { |
33e4c4cdf493
libunet: reading of ATTR lines implemented
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
20
diff
changeset
|
158 error: fprintf(stderr, "%s line %d: invalid syntax on ATTR line\n", |
33e4c4cdf493
libunet: reading of ATTR lines implemented
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
20
diff
changeset
|
159 state->filename, state->lineno); |
33e4c4cdf493
libunet: reading of ATTR lines implemented
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
20
diff
changeset
|
160 exit(1); |
33e4c4cdf493
libunet: reading of ATTR lines implemented
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
20
diff
changeset
|
161 } |
33e4c4cdf493
libunet: reading of ATTR lines implemented
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
20
diff
changeset
|
162 out->objname = cp; |
33e4c4cdf493
libunet: reading of ATTR lines implemented
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
20
diff
changeset
|
163 cp = index(cp, '='); |
33e4c4cdf493
libunet: reading of ATTR lines implemented
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
20
diff
changeset
|
164 if (!cp) |
33e4c4cdf493
libunet: reading of ATTR lines implemented
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
20
diff
changeset
|
165 goto error; |
33e4c4cdf493
libunet: reading of ATTR lines implemented
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
20
diff
changeset
|
166 *cp++ = '\0'; |
33e4c4cdf493
libunet: reading of ATTR lines implemented
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
20
diff
changeset
|
167 out->attr_value = cp; |
33e4c4cdf493
libunet: reading of ATTR lines implemented
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
20
diff
changeset
|
168 } |
33e4c4cdf493
libunet: reading of ATTR lines implemented
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
20
diff
changeset
|
169 |
9 | 170 static struct objmap { |
171 char *keyword; | |
172 int typecode; | |
173 void (*handler)(); | |
174 } objmap[] = { | |
175 {"}", UNETOBJ_CLOSINGBRACE, 0}, | |
176 {"NET", UNETOBJ_NET, handle_name_only}, | |
177 {"COMPONENT", UNETOBJ_COMPONENT, handle_component_opening}, | |
178 {"STARPOINT", UNETOBJ_STARPOINT, handle_component_opening}, | |
179 {"PRIMITIVE", UNETOBJ_PRIMITIVE, handle_name_only}, | |
180 {"ALTNAME", UNETOBJ_ALTNAME, handle_name_only}, | |
181 {"PIN", UNETOBJ_PIN, handle_pin_line}, | |
182 {"PINMAP", UNETOBJ_PINMAP, handle_pin_line}, | |
28
33e4c4cdf493
libunet: reading of ATTR lines implemented
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
20
diff
changeset
|
183 {"ATTR", UNETOBJ_ATTR, handle_attr}, |
9 | 184 {0, 0, 0} |
185 }; | |
186 | |
187 read_unet_line(state, out) | |
188 struct unetrd_state *state; | |
189 struct unetrd_out *out; | |
190 { | |
191 static char linebuf[256]; | |
192 char *cp; | |
193 struct objmap *tp; | |
194 | |
195 /* read lines until we get a non-empty, non-comment line or EOF */ | |
196 for (;;) { | |
18
52000ae7a6cf
ueda/libunet/unetrd.c: close the stdio stream on EOF
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
9
diff
changeset
|
197 if (!fgets(linebuf, sizeof linebuf, state->stream)) { |
52000ae7a6cf
ueda/libunet/unetrd.c: close the stdio stream on EOF
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
9
diff
changeset
|
198 fclose(state->stream); |
9 | 199 return(0); |
18
52000ae7a6cf
ueda/libunet/unetrd.c: close the stdio stream on EOF
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
9
diff
changeset
|
200 } |
9 | 201 state->lineno++; |
202 cp = index(linebuf, '\n'); | |
203 if (!cp) { | |
204 fprintf(stderr, | |
205 "error: %s line %d is too long or unterminated\n", | |
206 state->filename, state->lineno); | |
207 exit(1); | |
208 } | |
209 *cp = '\0'; | |
210 for (cp = linebuf; isspace(*cp); cp++) | |
211 ; | |
212 if (*cp && *cp != '#') | |
213 break; | |
214 } | |
215 out->keyword = cp; | |
216 while (*cp && !isspace(*cp)) | |
217 cp++; | |
218 if (*cp) | |
219 *cp++ = '\0'; | |
220 for (tp = objmap; tp->keyword; tp++) | |
221 if (!strcmp(tp->keyword, out->keyword)) | |
222 break; | |
223 if (!tp->keyword) { | |
224 fprintf(stderr, "%s line %d: object type \"%s\" unknown\n", | |
225 state->filename, state->lineno, out->keyword); | |
226 exit(1); | |
227 } | |
228 out->typecode = tp->typecode; | |
229 if (tp->handler) | |
230 tp->handler(state, out, cp); | |
231 return(1); | |
232 } |