# HG changeset patch # User Space Falcon # Date 1438462259 0 # Node ID faeb83c43f1c8206c370869177bd0122d814cedd # Parent 640ba9db0e9d7f7b107fc06078afb990e0433ee7 libunet started diff -r 640ba9db0e9d -r faeb83c43f1c ueda/libunet/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ueda/libunet/Makefile Sat Aug 01 20:50:59 2015 +0000 @@ -0,0 +1,14 @@ +CC= gcc +CFLAGS= -O2 +LIBOBJS=unetrd.o + +all: libunet.a + +libunet.a: ${LIBOBJS} + ar rcu $@ ${LIBOBJS} + ranlib $@ + +clean: + rm -f *.[ao] a.out core errs + +install: diff -r 640ba9db0e9d -r faeb83c43f1c ueda/libunet/unetrd.c --- /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 +#include +#include +#include +#include +#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); +} diff -r 640ba9db0e9d -r faeb83c43f1c ueda/libunet/unetrd.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ueda/libunet/unetrd.h Sat Aug 01 20:50:59 2015 +0000 @@ -0,0 +1,26 @@ +/* + * Data structures for the unet reader + */ + +struct unetrd_state { + char *filename; + FILE *stream; + int lineno; +}; + +struct unetrd_out { + int typecode; + char *keyword; + char *objname; + char *connect_to_net; + char *nc_comment; +}; + +#define UNETOBJ_CLOSINGBRACE 0 +#define UNETOBJ_NET 1 +#define UNETOBJ_COMPONENT 2 +#define UNETOBJ_STARPOINT 3 +#define UNETOBJ_PRIMITIVE 4 +#define UNETOBJ_ALTNAME 5 +#define UNETOBJ_PIN 6 +#define UNETOBJ_PINMAP 7