shithub: scc

Download patch

ref: 7b0fd4ce8ee3dfe5317288e68d6999d813e1f422
parent: 5ae8cb41158a3af9db313ff45d98c20735231ec9
author: Roberto E. Vargas Caballero <[email protected]>
date: Sun Jan 24 11:18:01 EST 2016

Add a driver

This is a very simple driver, but it simplifies the process of debugging.

--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
 
 include config.mk
 
-SUBDIRS  = lib cc1 cc2
+SUBDIRS  = lib cc1 cc2 driver/$(DRIVER)
 ARCHS   = z80 i386-sysv amd64-sysv
 
 all clean:
@@ -12,7 +12,10 @@
 		(cd $$i; ${MAKE} -$(MAKEFLAGS) $@ || exit); \
 	done
 
-multi:
+scc: lib/libcc.a
+	cd driver/$(DRIVER) && make $@
+
+multi: lib/libcc.a
 	for i in $(ARCHS) ; \
 	do \
 		$(MAKE) -$(MAKEFLAGS) $$i || exit ;\
@@ -32,10 +35,19 @@
 	ln -f cc1/cc1 bin/cc1-$@
 	ln -f cc2/cc2 bin/cc2-$@
 
-install:
-	mkdir -p $(DESTDIR)$(PREFIX)/libexec/scc/
-	cp -f bin/cc[12]-*
-	cd $(DESTDIR)$(PREFIX)/libexec/scc/ && chmod 755 cc[12]-*
+install: scc
+	mkdir -p $(PREFIX)/libexec/scc/
+	mkdir -p $(PREFIX)/bin/
+	cp -f bin/cc[12]-* $(PREFIX)/libexec/scc/
+	cp -f driver/$(DRIVER)/scc $(PREFIX)/bin/
+	cd $(PREFIX)/libexec/scc/ && ln -f cc1-$(ARCH) cc1
+	cd $(PREFIX)/libexec/scc/ && ln -f cc2-$(ARCH) cc2
+	cd $(PREFIX)/libexec/scc/ && ln -f cc1 cpp
+	cd $(PREFIX)/libexec/scc/ && chmod 755 cc[12]-* cc1 cc2 cpp
+
+uninstall:
+	rm -rf $(PREFIX)/libexec/scc/
+	rm -f $(PREFIX)/bin/scc
 
 
 distclean: clean
--- a/config.mk
+++ b/config.mk
@@ -3,9 +3,10 @@
 
 # Customize below to fit your system
 ARCH = z80
+DRIVER = posix
 
 # paths
-PREFIX    = /usr/local/
+PREFIX    = $(HOME)
 MANPREFIX = ${PREFIX}/share/man
 
 # if your system is not POSIX maybe you want to use cc or gcc
--- /dev/null
+++ b/driver/posix/Makefile
@@ -1,0 +1,6 @@
+include ../../config.mk
+
+all: scc
+
+clean:
+	rm -f scc
binary files /dev/null b/driver/posix/scc differ
--- /dev/null
+++ b/driver/posix/scc.c
@@ -1,0 +1,154 @@
+
+#define _POSIX_SOURCE
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "../../inc/cc.h"
+
+#define NARGS 64
+static char cmd[FILENAME_MAX];
+static char *argcc1[NARGS];
+static char *argcc2[NARGS];
+
+static pid_t pid_cc1, pid_cc2;
+static char *arch;
+
+static void
+terminate(void)
+{
+	if (pid_cc1)
+		kill(pid_cc1, SIGTERM);
+	if (pid_cc2)
+		kill(pid_cc2, SIGTERM);
+}
+
+void
+cc1(int fd)
+{
+	pid_t pid;
+	char *fmt;
+	int r;
+
+	switch (pid = fork()) {
+	case -1:
+		perror("scc:cc1");
+		exit(1);
+	case 0:
+		close(1);
+		dup(fd);
+		fmt = (arch) ? "%s/libexec/scc/cc1-%s" : "%s/libexec/scc/cc1";
+		r = snprintf(cmd, sizeof(cmd), fmt, PREFIX, arch);
+		if (r == sizeof(cmd)) {
+			fputs("scc:incorrect prefix\n", stderr);
+			exit(1);
+		}
+		execv(cmd, argcc1);
+		perror("scc:execv cc1");
+		abort();
+	default:
+		pid_cc1 = pid;
+		close(fd);
+		break;
+	}
+}
+
+pid_t
+cc2(int fd)
+{
+	pid_t pid;
+	char *fmt;
+	int r;
+
+	switch (pid = fork()) {
+	case -1:
+		perror("scc:cc2");
+		exit(1);
+	case 0:
+		close(0);
+		dup(fd);
+		fmt = (arch) ? "%s/libexec/scc/cc2-%s" : "%s/libexec/scc/cc2";
+		r = snprintf(cmd, sizeof(cmd), fmt, PREFIX, arch);
+		if (r == sizeof(cmd)) {
+			fputs("scc:incorrect prefix\n", stderr);
+			exit(1);
+		}
+		execv(cmd, argcc2);
+		perror("scc:execv cc2");
+		abort();
+	default:
+		pid_cc2 = pid;
+		close(fd);
+		break;
+	}
+}
+
+static void
+usage(void)
+{
+	fputs("scc [-m arch] file.c\n", stderr);
+	exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+	int fds[2], st, i;
+	char *p;
+	pid_t pid;
+
+	atexit(terminate);
+	if (p = getenv("ARCH"))
+		arch = p;
+
+	for (--argc; *++argv; --argc) {
+		if (argv[0][0] != '-' || argv[0][1] == '-')
+			break;
+		for (p = &argv[0][1]; *p; ++p) {
+			switch (*p) {
+			case 'm':
+				if ((arch = *++argv) == NULL)
+					goto usage;
+				--argc;
+				break;
+			default:
+			usage:
+				usage();
+				break;
+			}
+		}
+	}
+
+	if (argc == 0) {
+		fputs("scc: fatal error: no input files\n", stderr);
+		exit(1);
+	}
+	if (pipe(fds)) {
+		perror("scc: pipe");
+		exit(1);
+	}
+
+	argcc1[0] = "cc1";
+	argcc1[1] = *argv;
+
+	cc1(fds[1]);
+	cc2(fds[0]);
+
+	for (i = 0; i < 2; ++i) {
+		pid = wait(&st);
+		if (pid == pid_cc1)
+			pid_cc1 = 0;
+		else if (pid == pid_cc2)
+			pid_cc2 = 0;
+		if (!WIFEXITED(st) || WEXITSTATUS(st) != 0)
+			exit(-1);
+	}
+
+	return 0;
+}
--- a/scc
+++ /dev/null
@@ -1,5 +1,0 @@
-#!/bin/sh
-
-PATH="$PWD/cc1:$PWD/cc2"
-
-cc1 < "$1" | cc2