FreeCalypso > hg > ueda-linux
annotate ueda/libunet/unetrd.c @ 45:3bdb1b5ff3d0
pads2gpcb: gpcb dimension output implemented
| author | Mychaela Falconia <falcon@ivan.Harhan.ORG> |
|---|---|
| date | Sat, 30 Jan 2016 07:15:31 +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 } |
