commit 7b0fd4ce8ee3dfe5317288e68d6999d813e1f422
parent 5ae8cb41158a3af9db313ff45d98c20735231ec9
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date: Sun, 24 Jan 2016 16:18:01 +0100
Add a driver
This is a very simple driver, but it simplifies the process of debugging.
Diffstat:
6 files changed, 180 insertions(+), 12 deletions(-)
diff --git 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 @@ all clean:
(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 @@ $(ARCHS): lib/libcc.a
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
diff --git a/config.mk b/config.mk
@@ -3,9 +3,10 @@ VERSION = 0.1
# 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
diff --git a/driver/posix/Makefile b/driver/posix/Makefile
@@ -0,0 +1,6 @@
+include ../../config.mk
+
+all: scc
+
+clean:
+ rm -f scc
diff --git a/driver/posix/scc b/driver/posix/scc
Binary files differ.
diff --git a/driver/posix/scc.c b/driver/posix/scc.c
@@ -0,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;
+}
diff --git a/scc b/scc
@@ -1,5 +0,0 @@
-#!/bin/sh
-
-PATH="$PWD/cc1:$PWD/cc2"
-
-cc1 < "$1" | cc2