FreeCalypso > hg > ueda-linux
comparison ueda/libunet/unetrd.c @ 9:faeb83c43f1c
libunet started
author | Space Falcon <falcon@ivan.Harhan.ORG> |
---|---|
date | Sat, 01 Aug 2015 20:50:59 +0000 |
parents | |
children | 52000ae7a6cf |
comparison
equal
deleted
inserted
replaced
8:640ba9db0e9d | 9:faeb83c43f1c |
---|---|
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 | |
34 for (cp = rest; isspace(cp); cp++) | |
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 | |
64 for (cp = rest; isspace(cp); cp++) | |
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 | |
147 static struct objmap { | |
148 char *keyword; | |
149 int typecode; | |
150 void (*handler)(); | |
151 } objmap[] = { | |
152 {"}", UNETOBJ_CLOSINGBRACE, 0}, | |
153 {"NET", UNETOBJ_NET, handle_name_only}, | |
154 {"COMPONENT", UNETOBJ_COMPONENT, handle_component_opening}, | |
155 {"STARPOINT", UNETOBJ_STARPOINT, handle_component_opening}, | |
156 {"PRIMITIVE", UNETOBJ_PRIMITIVE, handle_name_only}, | |
157 {"ALTNAME", UNETOBJ_ALTNAME, handle_name_only}, | |
158 {"PIN", UNETOBJ_PIN, handle_pin_line}, | |
159 {"PINMAP", UNETOBJ_PINMAP, handle_pin_line}, | |
160 {0, 0, 0} | |
161 }; | |
162 | |
163 read_unet_line(state, out) | |
164 struct unetrd_state *state; | |
165 struct unetrd_out *out; | |
166 { | |
167 static char linebuf[256]; | |
168 char *cp; | |
169 struct objmap *tp; | |
170 | |
171 /* read lines until we get a non-empty, non-comment line or EOF */ | |
172 for (;;) { | |
173 if (!fgets(linebuf, sizeof linebuf, state->stream)) | |
174 return(0); | |
175 state->lineno++; | |
176 cp = index(linebuf, '\n'); | |
177 if (!cp) { | |
178 fprintf(stderr, | |
179 "error: %s line %d is too long or unterminated\n", | |
180 state->filename, state->lineno); | |
181 exit(1); | |
182 } | |
183 *cp = '\0'; | |
184 for (cp = linebuf; isspace(*cp); cp++) | |
185 ; | |
186 if (*cp && *cp != '#') | |
187 break; | |
188 } | |
189 out->keyword = cp; | |
190 while (*cp && !isspace(*cp)) | |
191 cp++; | |
192 if (*cp) | |
193 *cp++ = '\0'; | |
194 for (tp = objmap; tp->keyword; tp++) | |
195 if (!strcmp(tp->keyword, out->keyword)) | |
196 break; | |
197 if (!tp->keyword) { | |
198 fprintf(stderr, "%s line %d: object type \"%s\" unknown\n", | |
199 state->filename, state->lineno, out->keyword); | |
200 exit(1); | |
201 } | |
202 out->typecode = tp->typecode; | |
203 if (tp->handler) | |
204 tp->handler(state, out, cp); | |
205 return(1); | |
206 } |