diff ueda/utils/cutelements.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 e2130f1ef720
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ueda/utils/cutelements.c	Mon Jul 20 00:24:37 2015 +0000
@@ -0,0 +1,191 @@
+/*
+ * This program cuts the "elements PCB" constructed by the
+ * ueda-getfps | ueda-runm4 pipeline into one file per element.
+ *
+ * Alternatively, this program can also be used to extract all elements
+ * out of any PCB layout file.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <strings.h>
+
+char *inputname;
+FILE *inf;
+int lineno, in_element, parencount;
+FILE *elemf;
+
+char *
+do_element_line(cp)
+	register char *cp;
+{
+	char copybuf[1024];
+	char opench, closech;
+	char *fields[11], *pcbname;
+	int nfields;
+	register int c;
+	char *err;
+
+	if (in_element) {
+		fprintf(stderr, "%s: line %d: nested Element\n", inputname,
+			lineno);
+		exit(1);
+	}
+	if (parencount) {
+		fprintf(stderr,
+			"%s: line %d: Element not at the top nesting level\n",
+			inputname, lineno);
+		exit(1);
+	}
+
+	while (isspace(*cp))
+		cp++;
+	opench = *cp++;
+	switch (opench) {
+	case '(':
+		closech = ')';
+		break;
+	case '[':
+		closech = ']';
+		break;
+	default:
+		err = "no valid opening char";
+inv:		fprintf(stderr, "%s: line %d: invalid Element line: %s\n",
+			inputname, lineno, err);
+		exit(1);
+	}
+
+	strcpy(copybuf, cp);
+	cp = copybuf;
+
+	for (nfields = 0; ; ) {
+		while (isspace(*cp))
+			cp++;
+		if (!*cp) {
+badeol:			err = "missing closing char";
+			goto inv;
+		}
+		if (*cp == closech) {
+			cp++;
+			break;
+		}
+		if (nfields >= 11) {
+			err = "too many fields";
+			goto inv;
+		}
+		if (*cp == '\"') {
+			cp++;
+			for (fields[nfields++] = cp; c = *cp; cp++)
+				if (c == '\"')
+					break;
+		} else {
+			fields[nfields++] = cp;
+			while ((c = *cp) && !isspace(c) && c != closech)
+				cp++;
+		}
+		if (!c)
+			goto badeol;
+		*cp++ = '\0';
+		if (c == closech)
+			break;
+	}
+
+	switch (nfields) {
+	case 7:
+		pcbname = fields[1];
+		break;
+	case 8:
+	case 9:
+	case 11:
+		pcbname = fields[2];
+		break;
+	default:
+		err = "unrecognized format";
+		goto inv;
+	}
+	open_element(pcbname);
+
+	return(cp);
+}
+
+open_element(name)
+	register char *name;
+{
+	elemf = fopen(name, "w");
+	if (!elemf) {
+		fprintf(stderr, "cannot create file: %s\n", name);
+		exit(1);
+	}
+	in_element = 1;
+}
+
+main(argc, argv)
+	char **argv;
+{
+	char linebuf[1024];
+	register char *cp;
+
+	if (argc > 2) {
+		fprintf(stderr, "usage: %s [collection_file]\n", argv[0]);
+		exit(1);
+	}
+	if (argc == 2) {
+		inputname = argv[1];
+		inf = fopen(inputname, "r");
+		if (!inf) {
+			perror(inputname);
+			exit(1);
+		}
+	} else {
+		inputname = "stdin";
+		inf = stdin;
+	}
+
+	for (lineno = 1; fgets(linebuf, sizeof linebuf, inf); lineno++) {
+		for (cp = linebuf; isspace(*cp); cp++)
+			;
+		if (!strncmp(cp, "Element", 7) &&
+		    (cp[7] == '(' || cp[7] == '[' || isspace(cp[7])))
+			cp = do_element_line(cp + 7);
+		if (in_element)
+			fputs(linebuf, elemf);
+		scan_parens(cp);
+	}
+
+	if (parencount || in_element) {
+		fprintf(stderr, "%s: unclosed structure(s) at the end\n",
+			inputname);
+		exit(1);
+	}
+	exit(0);
+}
+
+scan_parens(line)
+	char *line;
+{
+	register char *cp;
+	register int c;
+
+	for (cp = line; c = *cp; cp++) {
+		if (c == '\'' && cp[1] && cp[2] == '\'') {
+			cp += 2;
+			continue;
+		}
+		if (c == '(' || c == '[')
+			parencount++;
+		else if (c == ')' || c == ']') {
+			parencount--;
+			if (parencount < 0) {
+				fprintf(stderr,
+					"%s: line %d: negative paren count\n",
+					inputname, lineno);
+				exit(1);
+			}
+			if ((parencount == 0) && in_element) {
+				fclose(elemf);
+				in_element = 0;
+			}
+		} else if (c == '#')
+			return;
+	}
+}