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);
+}