scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

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:
MMakefile | 24++++++++++++++++++------
Mconfig.mk | 3++-
Adriver/posix/Makefile | 6++++++
Adriver/posix/scc | 0
Adriver/posix/scc.c | 154+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dscc | 5-----
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