FreeCalypso > hg > ueda-linux
annotate ueda/libunet/unetrd.c @ 26:b2b60ec8d9ca
unet-destar: output implemented
| author | Space Falcon <falcon@ivan.Harhan.ORG> |
|---|---|
| date | Thu, 06 Aug 2015 20:37:31 +0000 |
| parents | dda8e455c863 |
| children | 33e4c4cdf493 |
| 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 | |
| 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 (;;) { | |
|
18
52000ae7a6cf
ueda/libunet/unetrd.c: close the stdio stream on EOF
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
9
diff
changeset
|
173 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
|
174 fclose(state->stream); |
| 9 | 175 return(0); |
|
18
52000ae7a6cf
ueda/libunet/unetrd.c: close the stdio stream on EOF
Space Falcon <falcon@ivan.Harhan.ORG>
parents:
9
diff
changeset
|
176 } |
| 9 | 177 state->lineno++; |
| 178 cp = index(linebuf, '\n'); | |
| 179 if (!cp) { | |
| 180 fprintf(stderr, | |
| 181 "error: %s line %d is too long or unterminated\n", | |
| 182 state->filename, state->lineno); | |
| 183 exit(1); | |
| 184 } | |
| 185 *cp = '\0'; | |
| 186 for (cp = linebuf; isspace(*cp); cp++) | |
| 187 ; | |
| 188 if (*cp && *cp != '#') | |
| 189 break; | |
| 190 } | |
| 191 out->keyword = cp; | |
| 192 while (*cp && !isspace(*cp)) | |
| 193 cp++; | |
| 194 if (*cp) | |
| 195 *cp++ = '\0'; | |
| 196 for (tp = objmap; tp->keyword; tp++) | |
| 197 if (!strcmp(tp->keyword, out->keyword)) | |
| 198 break; | |
| 199 if (!tp->keyword) { | |
| 200 fprintf(stderr, "%s line %d: object type \"%s\" unknown\n", | |
| 201 state->filename, state->lineno, out->keyword); | |
| 202 exit(1); | |
| 203 } | |
| 204 out->typecode = tp->typecode; | |
| 205 if (tp->handler) | |
| 206 tp->handler(state, out, cp); | |
| 207 return(1); | |
| 208 } |
