diff ueda/libuschem/rdschem_lex.c @ 0:cd92449fdb51

initial import of ueda and ifctf-part-lib from ifctfvax CVS
author Space Falcon <falcon@ivan.Harhan.ORG>
date Mon, 20 Jul 2015 00:24:37 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ueda/libuschem/rdschem_lex.c	Mon Jul 20 00:24:37 2015 +0000
@@ -0,0 +1,205 @@
+/*
+ * token lexer for the schematic parser
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <strings.h>
+#include "schemstruct.h"
+#include "parserint.h"
+
+extern char *malloc();
+
+extern struct schem_parse_state schem_parse_state;
+
+static
+my_getchar()
+{
+	register int c;
+
+	c = getc(schem_parse_state.file);
+	if (c < 0)
+		return(c);
+	if (!isascii(c)) {
+		rdschem_error("non-ASCII character");
+		exit(1);
+	}
+	if (iscntrl(c) && c != '\n' && c != '\t') {
+		rdschem_error("invalid control character");
+		exit(1);
+	}
+	return(c);
+}
+
+rdschem_token()
+{
+	register int c;
+	register char *cp;
+	register int len;
+	static char delims[] = "\n\"%(),;={}";
+
+	if (c = schem_parse_state.pushback_token) {
+		schem_parse_state.pushback_token = 0;
+		return(c);
+	}
+loop:	c = my_getchar();
+	switch (c) {
+	case EOF:
+		return(0);
+	case ' ':
+	case '\t':
+		goto loop;
+	case '"':
+		yylex_qstr();
+		return(QSTRING);
+	case '%':
+		do
+			c = my_getchar();
+		while (c != EOF && c != '\n');
+		if (c == EOF)
+			return(0);
+		/* FALL THRU */
+	case '\n':
+		schem_parse_state.lineno++;
+		goto loop;
+	case '(':
+	case ')':
+	case ',':
+	case ';':
+	case '=':
+	case '{':
+	case '}':
+		return(c);
+	}
+	cp = schem_parse_state.string;
+	*cp++ = c;
+	for (len = 1; ; ) {
+		c = my_getchar();
+		if (c == EOF || c == ' ' || c == '\t')
+			break;
+		if (index(delims, c)) {
+			ungetc(c, schem_parse_state.file);
+			break;
+		}
+		if (len >= MAXSTRING)
+			rdschem_error("text token is too long");
+		*cp++ = c;
+		len++;
+	}
+	*cp = '\0';
+	return(STRING);
+}
+
+static
+yylex_qstr()
+{
+	register int c;
+	register char *cp;
+	register int len;
+
+	cp = schem_parse_state.string;
+	for (len = 0; ; ) {
+		c = my_getchar();
+		if (c == EOF || c == '\n')
+unterm:			rdschem_error("unterminated quoted string");
+		if (c == '"')
+			break;
+		if (c == '\\') {
+			c = my_getchar();
+			if (c == EOF || c == '\n')
+				goto unterm;
+		}
+		if (len >= MAXSTRING)
+			rdschem_error("quoted string is too long");
+		*cp++ = c;
+		len++;
+	}
+	*cp = '\0';
+}
+
+struct graphblock *
+rdschem_graphblock(type)
+{
+	struct graphblock *blk;
+	register int c, n;
+
+	blk = (struct graphblock *) malloc(sizeof(struct graphblock));
+	if (!blk) {
+		perror("malloc");
+		exit(1);
+	}
+	blk->type = type;
+	blk->lineno = schem_parse_state.lineno;
+	c = my_getchar();
+	if (c == EOF)
+badeof:		rdschem_error("EOF in a graphical block");
+	if (c == '\n')
+		schem_parse_state.lineno++;
+	else
+		ungetc(c, schem_parse_state.file);
+	blk->offset = ftell(schem_parse_state.file);
+
+	for (n = 0; n >= 0; ) {
+		c = my_getchar();
+		switch (c) {
+		case EOF:
+			goto badeof;
+		case '%':
+			for (;;) {
+				c = my_getchar();
+				if (c == EOF)
+					goto badeof;
+				if (c == '\n')
+					break;
+			}
+			/* FALL THRU */
+		case '\n':
+			schem_parse_state.lineno++;
+			continue;
+		case '(':
+			skip_over_ps_string();
+			continue;
+		case ')':
+			rdschem_error("unmatched \')\' in a graphical block");
+		case '{':
+			n++;
+			continue;
+		case '}':
+			n--;
+			continue;
+		}
+	}
+	blk->length = ftell(schem_parse_state.file) - blk->offset - 1;
+	return(blk);
+}
+
+static
+skip_over_ps_string()
+{
+	register int c, n;
+
+	for (n = 1; n > 0; ) {
+		c = my_getchar();
+		switch (c) {
+		case EOF:
+badeof:		      rdschem_error("EOF in a PS string in a graphical block");
+		case '\n':
+			schem_parse_state.lineno++;
+			continue;
+		case '(':
+			n++;
+			continue;
+		case ')':
+			n--;
+			continue;
+		case '\\':
+			c = my_getchar();
+			if (c == EOF)
+				goto badeof;
+			if (c == '\n')
+				schem_parse_state.lineno++;
+			continue;
+		}
+	}
+}