FreeCalypso > hg > ueda-linux
view ueda/libunet/unetrd.c @ 139:bf188727e606
donl-rename-parts reader: no tEDAx-style escapes
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 07 Sep 2020 04:25:11 +0000 |
parents | 33e4c4cdf493 |
children |
line wrap: on
line source
/* * 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 void handle_attr(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 == '#') { error: fprintf(stderr, "%s line %d: invalid syntax on ATTR line\n", state->filename, state->lineno); exit(1); } out->objname = cp; cp = index(cp, '='); if (!cp) goto error; *cp++ = '\0'; out->attr_value = cp; } 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}, {"ATTR", UNETOBJ_ATTR, handle_attr}, {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)) { fclose(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); }