FreeCalypso > hg > ueda-linux
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ueda/libunet/unetrd.c Sat Aug 01 20:50:59 2015 +0000 @@ -0,0 +1,206 @@ +/* + * This module provides library functions for reading and parsing + * netlist files in our unet format. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <string.h> +#include <strings.h> +#include "unetrd.h" + +open_unet_input_file(filename, state) + char *filename; + struct unetrd_state *state; +{ + state->filename = filename; + state->stream = fopen(filename, "r"); + if (!state->stream) { + perror(filename); + exit(1); + } + state->lineno = 0; +} + +static void +handle_name_only(state, out, rest) + struct unetrd_state *state; + struct unetrd_out *out; + char *rest; +{ + char *cp; + + for (cp = rest; isspace(cp); cp++) + ; + if (*cp == '\0' || *cp == '#') { + fprintf(stderr, "%s line %d: a name is expected after %s\n", + state->filename, state->lineno, out->keyword); + exit(1); + } + out->objname = cp; + while (*cp && !isspace(*cp)) + cp++; + if (*cp) + *cp++ = '\0'; + while (isspace(*cp)) + cp++; + if (*cp && *cp != '#') { + fprintf(stderr, + "%s line %d: unexpected extra fields on %s line\n", + state->filename, state->lineno, out->keyword); + exit(1); + } +} + +static void +handle_component_opening(state, out, rest) + struct unetrd_state *state; + struct unetrd_out *out; + char *rest; +{ + char *cp; + + for (cp = rest; isspace(cp); cp++) + ; + if (*cp == '\0' || *cp == '#') { + fprintf(stderr, "%s line %d: a name is expected after %s\n", + state->filename, state->lineno, out->keyword); + exit(1); + } + out->objname = cp; + while (*cp && !isspace(*cp)) + cp++; + if (*cp) + *cp++ = '\0'; + while (isspace(*cp)) + cp++; + if (*cp != '{') { + fprintf(stderr, + "%s line %d: expected '{' at the end of %s line\n", + state->filename, state->lineno, out->keyword); + exit(1); + } +} + +static void +handle_pin_line(state, out, rest) + struct unetrd_state *state; + struct unetrd_out *out; + char *rest; +{ + char *cp = rest, *fields[3]; + int i; + + for (i = 0; i < 3; i++) { + while (isspace(*cp)) + cp++; + if (*cp == '\0' || *cp == '#') { +error: fprintf(stderr, + "%s line %d: invalid syntax on %s line\n", + state->filename, state->lineno, out->keyword); + exit(1); + } + fields[i] = cp; + while (*cp && !isspace(*cp)) + cp++; + if (*cp) + *cp++ = '\0'; + } + out->objname = fields[0]; + if (strcmp(fields[1], "=")) + goto error; + if (!strcmp(fields[2], "NET")) { + while (isspace(*cp)) + cp++; + if (*cp == '\0' || *cp == '#') + goto error; + out->connect_to_net = cp; + while (*cp && !isspace(*cp)) + cp++; + if (*cp) + *cp++ = '\0'; + } else if (!strcmp(fields[2], "NC")) { + out->connect_to_net = 0; + while (isspace(*cp)) + cp++; + if (*cp++ != '(') + goto error; + out->nc_comment = cp; + while (*cp && *cp != ')') + cp++; + if (*cp != ')') + goto error; + *cp++ = '\0'; + } else + goto error; + while (isspace(*cp)) + cp++; + if (*cp && *cp != '#') { + fprintf(stderr, + "%s line %d: unexpected extra fields on %s line\n", + state->filename, state->lineno, out->keyword); + exit(1); + } +} + +static struct objmap { + char *keyword; + int typecode; + void (*handler)(); +} objmap[] = { + {"}", UNETOBJ_CLOSINGBRACE, 0}, + {"NET", UNETOBJ_NET, handle_name_only}, + {"COMPONENT", UNETOBJ_COMPONENT, handle_component_opening}, + {"STARPOINT", UNETOBJ_STARPOINT, handle_component_opening}, + {"PRIMITIVE", UNETOBJ_PRIMITIVE, handle_name_only}, + {"ALTNAME", UNETOBJ_ALTNAME, handle_name_only}, + {"PIN", UNETOBJ_PIN, handle_pin_line}, + {"PINMAP", UNETOBJ_PINMAP, handle_pin_line}, + {0, 0, 0} +}; + +read_unet_line(state, out) + struct unetrd_state *state; + struct unetrd_out *out; +{ + static char linebuf[256]; + char *cp; + struct objmap *tp; + + /* read lines until we get a non-empty, non-comment line or EOF */ + for (;;) { + if (!fgets(linebuf, sizeof linebuf, state->stream)) + return(0); + state->lineno++; + cp = index(linebuf, '\n'); + if (!cp) { + fprintf(stderr, + "error: %s line %d is too long or unterminated\n", + state->filename, state->lineno); + exit(1); + } + *cp = '\0'; + for (cp = linebuf; isspace(*cp); cp++) + ; + if (*cp && *cp != '#') + break; + } + out->keyword = cp; + while (*cp && !isspace(*cp)) + cp++; + if (*cp) + *cp++ = '\0'; + for (tp = objmap; tp->keyword; tp++) + if (!strcmp(tp->keyword, out->keyword)) + break; + if (!tp->keyword) { + fprintf(stderr, "%s line %d: object type \"%s\" unknown\n", + state->filename, state->lineno, out->keyword); + exit(1); + } + out->typecode = tp->typecode; + if (tp->handler) + tp->handler(state, out, cp); + return(1); +}