scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit dd194c252f66d8fe13bfe23d6bc4ac422f61eb64
parent f6c0db7557a8e8663fa06d87b805e1c9e41b58c0
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Wed, 16 Jan 2019 23:04:39 +0000

[scc] Move cc1 cc2 and driver to cmd/scc

Diffstat:
Msrc/cmd/Makefile | 9++++++++-
Dsrc/cmd/cc1/Makefile | 38--------------------------------------
Dsrc/cmd/cc2/Makefile | 40----------------------------------------
Asrc/cmd/scc/Makefile | 14++++++++++++++
Asrc/cmd/scc/cc1/Makefile | 38++++++++++++++++++++++++++++++++++++++
Rsrc/cmd/cc1/TODO -> src/cmd/scc/cc1/TODO | 0
Rsrc/cmd/cc1/builtin.c -> src/cmd/scc/cc1/builtin.c | 0
Rsrc/cmd/cc1/cc1.h -> src/cmd/scc/cc1/cc1.h | 0
Rsrc/cmd/cc1/code.c -> src/cmd/scc/cc1/code.c | 0
Rsrc/cmd/cc1/cpp.c -> src/cmd/scc/cc1/cpp.c | 0
Rsrc/cmd/cc1/decl.c -> src/cmd/scc/cc1/decl.c | 0
Rsrc/cmd/cc1/deps.mk -> src/cmd/scc/cc1/deps.mk | 0
Rsrc/cmd/cc1/error.c -> src/cmd/scc/cc1/error.c | 0
Rsrc/cmd/cc1/expr.c -> src/cmd/scc/cc1/expr.c | 0
Rsrc/cmd/cc1/fold.c -> src/cmd/scc/cc1/fold.c | 0
Rsrc/cmd/cc1/init.c -> src/cmd/scc/cc1/init.c | 0
Rsrc/cmd/cc1/ir.md -> src/cmd/scc/cc1/ir.md | 0
Rsrc/cmd/cc1/lex.c -> src/cmd/scc/cc1/lex.c | 0
Rsrc/cmd/cc1/main.c -> src/cmd/scc/cc1/main.c | 0
Rsrc/cmd/cc1/stmt.c -> src/cmd/scc/cc1/stmt.c | 0
Rsrc/cmd/cc1/symbol.c -> src/cmd/scc/cc1/symbol.c | 0
Rsrc/cmd/cc1/target/amd64-sysv/arch.c -> src/cmd/scc/cc1/target/amd64-sysv/arch.c | 0
Rsrc/cmd/cc1/target/amd64-sysv/arch.mk -> src/cmd/scc/cc1/target/amd64-sysv/arch.mk | 0
Rsrc/cmd/cc1/target/arm64-sysv/arch.c -> src/cmd/scc/cc1/target/arm64-sysv/arch.c | 0
Rsrc/cmd/cc1/target/arm64-sysv/arch.mk -> src/cmd/scc/cc1/target/arm64-sysv/arch.mk | 0
Rsrc/cmd/cc1/target/i386-sysv/arch.c -> src/cmd/scc/cc1/target/i386-sysv/arch.c | 0
Rsrc/cmd/cc1/target/i386-sysv/arch.mk -> src/cmd/scc/cc1/target/i386-sysv/arch.mk | 0
Rsrc/cmd/cc1/target/z80-scc/arch.c -> src/cmd/scc/cc1/target/z80-scc/arch.c | 0
Rsrc/cmd/cc1/target/z80-scc/arch.mk -> src/cmd/scc/cc1/target/z80-scc/arch.mk | 0
Rsrc/cmd/cc1/types.c -> src/cmd/scc/cc1/types.c | 0
Rsrc/cmd/cc2/.gitignore -> src/cmd/scc/cc2/.gitignore | 0
Asrc/cmd/scc/cc2/Makefile | 40++++++++++++++++++++++++++++++++++++++++
Rsrc/cmd/cc2/cc2.h -> src/cmd/scc/cc2/cc2.h | 0
Rsrc/cmd/cc2/code.c -> src/cmd/scc/cc2/code.c | 0
Rsrc/cmd/cc2/deps.mk -> src/cmd/scc/cc2/deps.mk | 0
Rsrc/cmd/cc2/generror.awk -> src/cmd/scc/cc2/generror.awk | 0
Rsrc/cmd/cc2/main.c -> src/cmd/scc/cc2/main.c | 0
Rsrc/cmd/cc2/node.c -> src/cmd/scc/cc2/node.c | 0
Rsrc/cmd/cc2/optm.c -> src/cmd/scc/cc2/optm.c | 0
Rsrc/cmd/cc2/parser.c -> src/cmd/scc/cc2/parser.c | 0
Rsrc/cmd/cc2/peep.c -> src/cmd/scc/cc2/peep.c | 0
Rsrc/cmd/cc2/symbol.c -> src/cmd/scc/cc2/symbol.c | 0
Rsrc/cmd/cc2/target/amd64-sysv/arch.h -> src/cmd/scc/cc2/target/amd64-sysv/arch.h | 0
Rsrc/cmd/cc2/target/amd64-sysv/cgen.c -> src/cmd/scc/cc2/target/amd64-sysv/cgen.c | 0
Rsrc/cmd/cc2/target/amd64-sysv/code.c -> src/cmd/scc/cc2/target/amd64-sysv/code.c | 0
Rsrc/cmd/cc2/target/amd64-sysv/optm.c -> src/cmd/scc/cc2/target/amd64-sysv/optm.c | 0
Rsrc/cmd/cc2/target/amd64-sysv/target.mk -> src/cmd/scc/cc2/target/amd64-sysv/target.mk | 0
Rsrc/cmd/cc2/target/amd64-sysv/types.c -> src/cmd/scc/cc2/target/amd64-sysv/types.c | 0
Rsrc/cmd/cc2/target/arm64-sysv/types.c -> src/cmd/scc/cc2/target/arm64-sysv/types.c | 0
Rsrc/cmd/cc2/target/i386-sysv/arch.h -> src/cmd/scc/cc2/target/i386-sysv/arch.h | 0
Rsrc/cmd/cc2/target/i386-sysv/cgen.c -> src/cmd/scc/cc2/target/i386-sysv/cgen.c | 0
Rsrc/cmd/cc2/target/i386-sysv/code.c -> src/cmd/scc/cc2/target/i386-sysv/code.c | 0
Rsrc/cmd/cc2/target/i386-sysv/optm.c -> src/cmd/scc/cc2/target/i386-sysv/optm.c | 0
Rsrc/cmd/cc2/target/i386-sysv/target.mk -> src/cmd/scc/cc2/target/i386-sysv/target.mk | 0
Rsrc/cmd/cc2/target/i386-sysv/types.c -> src/cmd/scc/cc2/target/i386-sysv/types.c | 0
Rsrc/cmd/cc2/target/qbe/arch.h -> src/cmd/scc/cc2/target/qbe/arch.h | 0
Rsrc/cmd/cc2/target/qbe/cgen.c -> src/cmd/scc/cc2/target/qbe/cgen.c | 0
Rsrc/cmd/cc2/target/qbe/code.c -> src/cmd/scc/cc2/target/qbe/code.c | 0
Rsrc/cmd/cc2/target/qbe/optm.c -> src/cmd/scc/cc2/target/qbe/optm.c | 0
Rsrc/cmd/cc2/target/qbe_amd64-sysv/target.mk -> src/cmd/scc/cc2/target/qbe_amd64-sysv/target.mk | 0
Rsrc/cmd/cc2/target/qbe_arm64-sysv/target.mk -> src/cmd/scc/cc2/target/qbe_arm64-sysv/target.mk | 0
Rsrc/cmd/cc2/target/z80-scc/arch.h -> src/cmd/scc/cc2/target/z80-scc/arch.h | 0
Rsrc/cmd/cc2/target/z80-scc/cgen.c -> src/cmd/scc/cc2/target/z80-scc/cgen.c | 0
Rsrc/cmd/cc2/target/z80-scc/code.c -> src/cmd/scc/cc2/target/z80-scc/code.c | 0
Rsrc/cmd/cc2/target/z80-scc/optm.c -> src/cmd/scc/cc2/target/z80-scc/optm.c | 0
Rsrc/cmd/cc2/target/z80-scc/target.mk -> src/cmd/scc/cc2/target/z80-scc/target.mk | 0
Rsrc/cmd/cc2/target/z80-scc/types.c -> src/cmd/scc/cc2/target/z80-scc/types.c | 0
Asrc/cmd/scc/posix/Makefile | 39+++++++++++++++++++++++++++++++++++++++
Rsrc/driver/posix/cpp.sh -> src/cmd/scc/posix/cpp.sh | 0
Asrc/cmd/scc/posix/deps.mk | 8++++++++
Rsrc/driver/posix/config.sh -> src/cmd/scc/posix/mkconf | 0
Asrc/cmd/scc/posix/scc.c | 617+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dsrc/driver/Makefile | 8--------
Dsrc/driver/posix/Makefile | 39---------------------------------------
Dsrc/driver/posix/config.h | 5-----
Dsrc/driver/posix/deps.mk | 8--------
Dsrc/driver/posix/scc.c | 617-------------------------------------------------------------------------------
77 files changed, 764 insertions(+), 756 deletions(-)

diff --git a/src/cmd/Makefile b/src/cmd/Makefile @@ -13,8 +13,12 @@ TARGET = $(BINDIR)/nm \ $(BINDIR)/addr2line \ LIBS = -lmach +DIRS = as ld scc -all: $(TARGET) as ld cc1 cc2 +all: $(TARGET) $(DIRS) + +$(DIRS): FORCE + @+cd $@ && $(MAKE) $(TARGET): $(LIBDIR)/libmach.a @@ -44,4 +48,7 @@ $(BINDIR)/ar: ar.o $(DRIVER).o dep: inc-dep +clean: + $(FORALL) + include deps.mk diff --git a/src/cmd/cc1/Makefile b/src/cmd/cc1/Makefile @@ -1,38 +0,0 @@ -.POSIX: - -PROJECTDIR = ../../.. -include $(PROJECTDIR)/scripts/rules.mk - -OBJS = types.o \ - decl.o \ - lex.o \ - error.o \ - symbol.o \ - main.o \ - expr.o \ - code.o \ - stmt.o \ - cpp.o \ - fold.o \ - init.o \ - builtin.o \ - -TARGET = $(LIBEXEC)/cc1-amd64-sysv \ - $(LIBEXEC)/cc1-arm64-sysv \ - $(LIBEXEC)/cc1-i386-sysv \ - $(LIBEXEC)/cc1-z80-scc \ - -all: $(TARGET) - -$(TARGET): $(LIBDIR)/libscc.a - -dep: inc-dep - -clean: - rm -f target/*/*.o - -include target/amd64-sysv/arch.mk -include target/arm64-sysv/arch.mk -include target/i386-sysv/arch.mk -include target/z80-scc/arch.mk -include deps.mk diff --git a/src/cmd/cc2/Makefile b/src/cmd/cc2/Makefile @@ -1,40 +0,0 @@ -.POSIX: - -PROJECTDIR = ../../.. -include $(PROJECTDIR)/scripts/rules.mk - -MORECFLAGS = -I$(INCDIR)/$(STD) - -OBJS = main.o \ - parser.o \ - peep.o \ - symbol.o \ - node.o \ - code.o \ - optm.o \ - -TARGET = $(LIBEXEC)/cc2-amd64-sysv \ - $(LIBEXEC)/cc2-i386-sysv \ - $(LIBEXEC)/cc2-qbe_amd64-sysv \ - $(LIBEXEC)/cc2-z80-scc \ - -all: $(TARGET) - -$(TARGET): error.h - -error.h: cc2.h - rm -f $@;\ - trap 'r=$?;rm -f $$$$.h;exit $r' EXIT INT QUIT ;\ - awk -f generror.awk cc2.h > $$$$.h && mv $$$$.h $@ - -dep: inc-dep - -clean: - rm -f target/*/*.o error.h - -include target/amd64-sysv/target.mk -include target/i386-sysv/target.mk -include target/qbe_amd64-sysv/target.mk -include target/qbe_arm64-sysv/target.mk -include target/z80-scc/target.mk -include deps.mk diff --git a/src/cmd/scc/Makefile b/src/cmd/scc/Makefile @@ -0,0 +1,14 @@ +.POSIX: + +PROJECTDIR = ../../.. +include $(PROJECTDIR)/scripts/rules.mk + +DIRS = cc1 cc2 $(DRIVER) + +all: $(DIRS) + +$(DIRS): FORCE + +@cd $@ && $(MAKE) + +clean: + $(FORALL) diff --git a/src/cmd/scc/cc1/Makefile b/src/cmd/scc/cc1/Makefile @@ -0,0 +1,38 @@ +.POSIX: + +PROJECTDIR = ../../../.. +include $(PROJECTDIR)/scripts/rules.mk + +OBJS = types.o \ + decl.o \ + lex.o \ + error.o \ + symbol.o \ + main.o \ + expr.o \ + code.o \ + stmt.o \ + cpp.o \ + fold.o \ + init.o \ + builtin.o \ + +TARGET = $(LIBEXEC)/cc1-amd64-sysv \ + $(LIBEXEC)/cc1-arm64-sysv \ + $(LIBEXEC)/cc1-i386-sysv \ + $(LIBEXEC)/cc1-z80-scc \ + +all: $(TARGET) + +$(TARGET): $(LIBDIR)/libscc.a + +dep: inc-dep + +clean: + rm -f target/*/*.o + +include target/amd64-sysv/arch.mk +include target/arm64-sysv/arch.mk +include target/i386-sysv/arch.mk +include target/z80-scc/arch.mk +include deps.mk diff --git a/src/cmd/cc1/TODO b/src/cmd/scc/cc1/TODO diff --git a/src/cmd/cc1/builtin.c b/src/cmd/scc/cc1/builtin.c diff --git a/src/cmd/cc1/cc1.h b/src/cmd/scc/cc1/cc1.h diff --git a/src/cmd/cc1/code.c b/src/cmd/scc/cc1/code.c diff --git a/src/cmd/cc1/cpp.c b/src/cmd/scc/cc1/cpp.c diff --git a/src/cmd/cc1/decl.c b/src/cmd/scc/cc1/decl.c diff --git a/src/cmd/cc1/deps.mk b/src/cmd/scc/cc1/deps.mk diff --git a/src/cmd/cc1/error.c b/src/cmd/scc/cc1/error.c diff --git a/src/cmd/cc1/expr.c b/src/cmd/scc/cc1/expr.c diff --git a/src/cmd/cc1/fold.c b/src/cmd/scc/cc1/fold.c diff --git a/src/cmd/cc1/init.c b/src/cmd/scc/cc1/init.c diff --git a/src/cmd/cc1/ir.md b/src/cmd/scc/cc1/ir.md diff --git a/src/cmd/cc1/lex.c b/src/cmd/scc/cc1/lex.c diff --git a/src/cmd/cc1/main.c b/src/cmd/scc/cc1/main.c diff --git a/src/cmd/cc1/stmt.c b/src/cmd/scc/cc1/stmt.c diff --git a/src/cmd/cc1/symbol.c b/src/cmd/scc/cc1/symbol.c diff --git a/src/cmd/cc1/target/amd64-sysv/arch.c b/src/cmd/scc/cc1/target/amd64-sysv/arch.c diff --git a/src/cmd/cc1/target/amd64-sysv/arch.mk b/src/cmd/scc/cc1/target/amd64-sysv/arch.mk diff --git a/src/cmd/cc1/target/arm64-sysv/arch.c b/src/cmd/scc/cc1/target/arm64-sysv/arch.c diff --git a/src/cmd/cc1/target/arm64-sysv/arch.mk b/src/cmd/scc/cc1/target/arm64-sysv/arch.mk diff --git a/src/cmd/cc1/target/i386-sysv/arch.c b/src/cmd/scc/cc1/target/i386-sysv/arch.c diff --git a/src/cmd/cc1/target/i386-sysv/arch.mk b/src/cmd/scc/cc1/target/i386-sysv/arch.mk diff --git a/src/cmd/cc1/target/z80-scc/arch.c b/src/cmd/scc/cc1/target/z80-scc/arch.c diff --git a/src/cmd/cc1/target/z80-scc/arch.mk b/src/cmd/scc/cc1/target/z80-scc/arch.mk diff --git a/src/cmd/cc1/types.c b/src/cmd/scc/cc1/types.c diff --git a/src/cmd/cc2/.gitignore b/src/cmd/scc/cc2/.gitignore diff --git a/src/cmd/scc/cc2/Makefile b/src/cmd/scc/cc2/Makefile @@ -0,0 +1,40 @@ +.POSIX: + +PROJECTDIR = ../../../.. +include $(PROJECTDIR)/scripts/rules.mk + +MORECFLAGS = -I$(INCDIR)/$(STD) + +OBJS = main.o \ + parser.o \ + peep.o \ + symbol.o \ + node.o \ + code.o \ + optm.o \ + +TARGET = $(LIBEXEC)/cc2-amd64-sysv \ + $(LIBEXEC)/cc2-i386-sysv \ + $(LIBEXEC)/cc2-qbe_amd64-sysv \ + $(LIBEXEC)/cc2-z80-scc \ + +all: $(TARGET) + +$(TARGET): error.h + +error.h: cc2.h + rm -f $@;\ + trap 'r=$?;rm -f $$$$.h;exit $r' EXIT INT QUIT ;\ + awk -f generror.awk cc2.h > $$$$.h && mv $$$$.h $@ + +dep: inc-dep + +clean: + rm -f target/*/*.o error.h + +include target/amd64-sysv/target.mk +include target/i386-sysv/target.mk +include target/qbe_amd64-sysv/target.mk +include target/qbe_arm64-sysv/target.mk +include target/z80-scc/target.mk +include deps.mk diff --git a/src/cmd/cc2/cc2.h b/src/cmd/scc/cc2/cc2.h diff --git a/src/cmd/cc2/code.c b/src/cmd/scc/cc2/code.c diff --git a/src/cmd/cc2/deps.mk b/src/cmd/scc/cc2/deps.mk diff --git a/src/cmd/cc2/generror.awk b/src/cmd/scc/cc2/generror.awk diff --git a/src/cmd/cc2/main.c b/src/cmd/scc/cc2/main.c diff --git a/src/cmd/cc2/node.c b/src/cmd/scc/cc2/node.c diff --git a/src/cmd/cc2/optm.c b/src/cmd/scc/cc2/optm.c diff --git a/src/cmd/cc2/parser.c b/src/cmd/scc/cc2/parser.c diff --git a/src/cmd/cc2/peep.c b/src/cmd/scc/cc2/peep.c diff --git a/src/cmd/cc2/symbol.c b/src/cmd/scc/cc2/symbol.c diff --git a/src/cmd/cc2/target/amd64-sysv/arch.h b/src/cmd/scc/cc2/target/amd64-sysv/arch.h diff --git a/src/cmd/cc2/target/amd64-sysv/cgen.c b/src/cmd/scc/cc2/target/amd64-sysv/cgen.c diff --git a/src/cmd/cc2/target/amd64-sysv/code.c b/src/cmd/scc/cc2/target/amd64-sysv/code.c diff --git a/src/cmd/cc2/target/amd64-sysv/optm.c b/src/cmd/scc/cc2/target/amd64-sysv/optm.c diff --git a/src/cmd/cc2/target/amd64-sysv/target.mk b/src/cmd/scc/cc2/target/amd64-sysv/target.mk diff --git a/src/cmd/cc2/target/amd64-sysv/types.c b/src/cmd/scc/cc2/target/amd64-sysv/types.c diff --git a/src/cmd/cc2/target/arm64-sysv/types.c b/src/cmd/scc/cc2/target/arm64-sysv/types.c diff --git a/src/cmd/cc2/target/i386-sysv/arch.h b/src/cmd/scc/cc2/target/i386-sysv/arch.h diff --git a/src/cmd/cc2/target/i386-sysv/cgen.c b/src/cmd/scc/cc2/target/i386-sysv/cgen.c diff --git a/src/cmd/cc2/target/i386-sysv/code.c b/src/cmd/scc/cc2/target/i386-sysv/code.c diff --git a/src/cmd/cc2/target/i386-sysv/optm.c b/src/cmd/scc/cc2/target/i386-sysv/optm.c diff --git a/src/cmd/cc2/target/i386-sysv/target.mk b/src/cmd/scc/cc2/target/i386-sysv/target.mk diff --git a/src/cmd/cc2/target/i386-sysv/types.c b/src/cmd/scc/cc2/target/i386-sysv/types.c diff --git a/src/cmd/cc2/target/qbe/arch.h b/src/cmd/scc/cc2/target/qbe/arch.h diff --git a/src/cmd/cc2/target/qbe/cgen.c b/src/cmd/scc/cc2/target/qbe/cgen.c diff --git a/src/cmd/cc2/target/qbe/code.c b/src/cmd/scc/cc2/target/qbe/code.c diff --git a/src/cmd/cc2/target/qbe/optm.c b/src/cmd/scc/cc2/target/qbe/optm.c diff --git a/src/cmd/cc2/target/qbe_amd64-sysv/target.mk b/src/cmd/scc/cc2/target/qbe_amd64-sysv/target.mk diff --git a/src/cmd/cc2/target/qbe_arm64-sysv/target.mk b/src/cmd/scc/cc2/target/qbe_arm64-sysv/target.mk diff --git a/src/cmd/cc2/target/z80-scc/arch.h b/src/cmd/scc/cc2/target/z80-scc/arch.h diff --git a/src/cmd/cc2/target/z80-scc/cgen.c b/src/cmd/scc/cc2/target/z80-scc/cgen.c diff --git a/src/cmd/cc2/target/z80-scc/code.c b/src/cmd/scc/cc2/target/z80-scc/code.c diff --git a/src/cmd/cc2/target/z80-scc/optm.c b/src/cmd/scc/cc2/target/z80-scc/optm.c diff --git a/src/cmd/cc2/target/z80-scc/target.mk b/src/cmd/scc/cc2/target/z80-scc/target.mk diff --git a/src/cmd/cc2/target/z80-scc/types.c b/src/cmd/scc/cc2/target/z80-scc/types.c diff --git a/src/cmd/scc/posix/Makefile b/src/cmd/scc/posix/Makefile @@ -0,0 +1,39 @@ +.POSIX: + +PROJECTDIR = ../../../.. +include $(PROJECTDIR)/scripts/rules.mk + +# SYSLST is a list of backend-arch-abi-sys. First +# element of the list becomes the default target + +SYSLST = amd64-sysv-linux-elf z80-scc-none-none \ + i386-sysv-linux-elf amd64-sysv-openbsd-elf + +STDCFLAGS = + +TARGETS = $(BINDIR)/scc $(BINDIR)/scpp + +all: $(TARGETS) + +$(BINDIR)/scc: scc.o + $(CC) $(SCC_LDFLAGS) scc.o -lscc -o $@ + +$(BINDIR)/scpp: cpp.sh + set -x ;\ + trap "rm -f $$$$.sh" 0 2 3;\ + rm -f $@ ;\ + sed "s%@PREFIX@%$(PREFIX)%" < cpp.sh > $$$$.sh && \ + chmod +x $$$$.sh && \ + mv $$$$.sh $@ + +config.h: + PREFIX=$(PREFIX) mkconf $(SYSLST) + +dep: inc-dep + +clean: + rm -f scc scpp *.o + rm -f $(TARGETS) + rm -f config.h + +include deps.mk diff --git a/src/driver/posix/cpp.sh b/src/cmd/scc/posix/cpp.sh diff --git a/src/cmd/scc/posix/deps.mk b/src/cmd/scc/posix/deps.mk @@ -0,0 +1,8 @@ +#deps +scc.o: $(INCDIR)/scc/scc/arg.h +scc.o: $(INCDIR)/scc/scc/ldflags.h +scc.o: $(INCDIR)/scc/scc/scc.h +scc.o: $(INCDIR)/scc/scc/syscrts.h +scc.o: $(INCDIR)/scc/scc/sysincludes.h +scc.o: $(INCDIR)/scc/scc/syslibs.h +scc.o: config.h diff --git a/src/driver/posix/config.sh b/src/cmd/scc/posix/mkconf diff --git a/src/cmd/scc/posix/scc.c b/src/cmd/scc/posix/scc.c @@ -0,0 +1,617 @@ +static char sccsid[] = "@(#) ./driver/posix/scc.c"; +#define _POSIX_SOURCE +#define _XOPEN_SOURCE 500 +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> + +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "config.h" +#include <scc/arg.h> +#include <scc/scc.h> +#include <scc/syscrts.h> +#include <scc/sysincludes.h> +#include <scc/syslibs.h> +#include <scc/ldflags.h> + +enum { + CC1, + TEEIR, + CC2, + TEEQBE, + QBE, + TEEAS, + AS, + LD, + STRIP, + LAST_TOOL, +}; + +static struct tool { + char cmd[PATH_MAX]; + char bin[32]; + char *outfile; + struct items args; + unsigned nparams; + int in, out, init; + pid_t pid; +} tools[] = { + [CC1] = { .cmd = "cc1" }, + [TEEIR] = { .bin = "tee", .cmd = "tee", }, + [CC2] = { .cmd = "cc2" }, + [TEEQBE] = { .bin = "tee", .cmd = "tee", }, + [QBE] = { .bin = "qbe", .cmd = "qbe", }, + [TEEAS] = { .bin = "tee", .cmd = "tee", }, + [AS] = { .bin = "as", .cmd = "as", }, + [LD] = { .bin = "ld", .cmd = "ld", }, + [STRIP] = { .bin = "strip", .cmd = "strip", }, +}; + +char *argv0; +static char *arch, *sys, *abi, *format; +static char *prefix, *objfile, *outfile; +static char *tmpdir; +static size_t tmpdirln; +static struct items objtmp, objout; +static int Mflag, Eflag, Sflag, cflag, dflag, kflag, sflag, Qflag = 1; /* TODO: Remove Qflag */ +static int devnullfd = -1; + +extern int failure; + +static void +terminate(void) +{ + unsigned i; + + if (!kflag) { + for (i = 0; i < objtmp.n; ++i) + unlink(objtmp.s[i]); + } +} + +static void +addarg(int tool, char *arg) +{ + struct tool *t = &tools[tool]; + + if (t->args.n < 1) + t->args.n = 1; + + newitem(&t->args, arg); +} + +static void +setargv0(int tool, char *arg) +{ + struct tool *t = &tools[tool]; + + if (t->args.n > 0) + t->args.s[0] = arg; + else + newitem(&t->args, arg); +} + +static int +qbe(int tool) +{ + if (tool != CC2 || !Qflag) + return 0; + if (!strcmp(arch, "amd64") && !strcmp(abi, "sysv")) + return 1; + return 0; +} + +static int +inittool(int tool) +{ + struct tool *t = &tools[tool]; + char *crt, *fmt; + int n; + + if (t->init) + return tool; + + switch (tool) { + case CC1: + for (n = 0; sysincludes[n]; ++n) { + addarg(tool, "-I"); + addarg(tool, sysincludes[n]); + } + case CC2: + fmt = (qbe(tool)) ? "%s-qbe_%s-%s" : "%s-%s-%s"; + n = snprintf(t->bin, sizeof(t->bin), fmt, t->cmd, arch, abi); + if (n < 0 || n >= sizeof(t->bin)) + die("scc: target tool name too long"); + + n = snprintf(t->cmd, sizeof(t->cmd), + "%s/libexec/scc/%s", prefix, t->bin); + if (n < 0 || n >= sizeof(t->cmd)) + die("scc: target tool path too long"); + break; + case LD: + for (n = 0; ldflags[n]; ++n) + addarg(tool, ldflags[n]); + addarg(tool, "-o"); + t->outfile = outfile ? outfile : xstrdup("a.out"); + addarg(tool, t->outfile); + for (n = 0; syslibs[n]; ++n) { + addarg(tool, "-L"); + addarg(tool, syslibs[n]); + } + if (syscrts[0]) { + for (n = 0; syscrts[n]; ++n) + addarg(tool, syscrts[n]); + break; + } + n = snprintf(NULL, 0, + "%s/lib/scc/%s-%s-%s/crt.o", + prefix, arch, abi, sys); + if (n < 0) + die("scc: wrong crt file name"); + crt = xmalloc(++n); + sprintf(crt, + "%s/lib/scc/%s-%s-%s/crt.o", + prefix, arch, abi, sys); + addarg(tool, crt); + break; + case AS: + addarg(tool, "-o"); + break; + default: + break; + } + + setargv0(tool, t->bin); + t->nparams = t->args.n; + t->init = 1; + + return tool; +} + +static char * +outfname(char *path, char *type) +{ + char *new, sep, *p; + size_t newsz, pathln; + int tmpfd, n; + + if (path) { + sep = '.'; + if (p = strrchr(path, '/')) + path = p + 1; + pathln = strlen(path); + if (p = strrchr(path, '.')) + pathln -= strlen(p); + } else { + sep = '/'; + type = "scc-XXXXXX"; + path = tmpdir; + pathln = tmpdirln; + } + + newsz = pathln + 1 + strlen(type) + 1; + new = xmalloc(newsz); + n = snprintf(new, newsz, "%.*s%c%s", (int)pathln, path, sep, type); + if (n < 0 || n >= newsz) + die("scc: wrong output filename"); + if (sep == '/') { + if ((tmpfd = mkstemp(new)) < 0) + die("scc: could not create output file '%s': %s", + new, strerror(errno)); + close(tmpfd); + } + + return new; +} + +static int +settool(int tool, char *infile, int nexttool) +{ + struct tool *t = &tools[tool]; + unsigned i; + int fds[2]; + static int fdin = -1; + + switch (tool) { + case TEEIR: + t->outfile = outfname(infile, "ir"); + addarg(tool, t->outfile); + break; + case TEEQBE: + t->outfile = outfname(infile, "qbe"); + addarg(tool, t->outfile); + break; + case TEEAS: + t->outfile = outfname(infile, "s"); + addarg(tool, t->outfile); + break; + case AS: + if (cflag && outfile) { + objfile = outfile; + } else { + objfile = (cflag || kflag) ? infile : NULL; + objfile = outfname(objfile, "o"); + } + t->outfile = xstrdup(objfile); + addarg(tool, t->outfile); + break; + case STRIP: + if (cflag || kflag) { + for (i = 0; i < objout.n; ++i) + addarg(tool, xstrdup(objout.s[i])); + } + if (!cflag && tools[LD].outfile) + addarg(tool, tools[LD].outfile); + break; + default: + break; + } + + if (fdin > -1) { + t->in = fdin; + fdin = -1; + } else { + t->in = -1; + if (infile) + addarg(tool, xstrdup(infile)); + } + + if (nexttool < LAST_TOOL) { + if (pipe(fds)) + die("scc: pipe: %s", strerror(errno)); + t->out = fds[1]; + fdin = fds[0]; + } else { + t->out = -1; + } + + addarg(tool, NULL); + + return tool; +} + +static void +spawn(int tool) +{ + struct tool *t = &tools[tool]; + + switch (t->pid = fork()) { + case -1: + die("scc: %s: %s", t->bin, strerror(errno)); + case 0: + if (t->out > -1) + dup2(t->out, 1); + if (t->in > -1) + dup2(t->in, 0); + if (!dflag && tool != CC1 && tool != LD) + dup2(devnullfd, 2); + execvp(t->cmd, t->args.s); + if (dflag) { + fprintf(stderr, + "scc: execvp %s: %s\n", + t->cmd, + strerror(errno)); + } + abort(); + default: + if (t->in > -1) + close(t->in); + if (t->out > -1) + close(t->out); + break; + } +} + +static int +toolfor(char *file) +{ + char *dot = strrchr(file, '.'); + + if (dot) { + if (!strcmp(dot, ".c")) + return CC1; + if (!strcmp(dot, ".ir")) + return CC2; + if (!strcmp(dot, ".qbe")) + return QBE; + if (!strcmp(dot, ".s")) + return AS; + if (!strcmp(dot, ".o")) + return LD; + if (!strcmp(dot, ".a")) + return LD; + } else if (!strcmp(file, "-")) { + return CC1; + } + + die("scc: do not recognize filetype of %s", file); +} + +static int +valid(int tool, struct tool *t) +{ + int st; + + if (waitpid(t->pid, &st, 0) == -1 || WIFSIGNALED(st)) + goto internal; + if (WIFEXITED(st) && WEXITSTATUS(st) == 0) + return 1; + if (!failure && (tool == CC1 || tool == LD)) + goto fail; + +internal: + fprintf(stderr, "scc:%s: internal error\n", t->bin); +fail: + failure = 1; + return 0; +} + +static int +validatetools(void) +{ + struct tool *t; + unsigned i; + int tool, st, failed = LAST_TOOL; + + for (tool = 0; tool < LAST_TOOL; ++tool) { + t = &tools[tool]; + if (!t->pid) + continue; + if (!valid(tool, t)) + failed = tool; + if (tool >= failed && t->outfile) + unlink(t->outfile); + for (i = t->nparams; i < t->args.n; ++i) + free(t->args.s[i]); + t->args.n = t->nparams; + t->pid = 0; + } + if (failed < LAST_TOOL) { + unlink(objfile); + free(objfile); + objfile = NULL; + return 0; + } + + return 1; +} + +static int +buildfile(char *file, int tool) +{ + int nexttool; + + for (; tool < LAST_TOOL; tool = nexttool) { + switch (tool) { + case CC1: + if (Eflag || Mflag) + nexttool = LAST_TOOL; + else + nexttool = kflag ? TEEIR : CC2; + break; + case TEEIR: + nexttool = CC2; + break; + case CC2: + if (Qflag) + nexttool = kflag ? TEEQBE : QBE; + else + nexttool = (Sflag || kflag) ? TEEAS : AS; + break; + case TEEQBE: + nexttool = QBE; + break; + case QBE: + nexttool = (Sflag || kflag) ? TEEAS : AS; + break; + case TEEAS: + nexttool = Sflag ? LAST_TOOL : AS; + break; + case AS: + nexttool = LAST_TOOL; + break; + default: + nexttool = LAST_TOOL; + continue; + } + + spawn(settool(inittool(tool), file, nexttool)); + } + + return validatetools(); +} + +static void +build(struct items *chain, int link) +{ + int i, tool; + + if (link) + inittool(LD); + + for (i = 0; i < chain->n; ++i) { + if (!strcmp(chain->s[i], "-l")) { + if (link) { + addarg(LD, xstrdup(chain->s[i++])); + addarg(LD, xstrdup(chain->s[i])); + } else { + ++i; + } + continue; + } + tool = toolfor(chain->s[i]); + if (tool == LD) { + if (link) + addarg(LD, xstrdup(chain->s[i])); + continue; + } + if (buildfile(chain->s[i], tool)) { + if (link) + addarg(LD, xstrdup(objfile)); + newitem((!link || kflag) ? &objout : &objtmp, objfile); + } + } +} + +static void +usage(void) +{ + fputs("usage: scc [-D def[=val]]... [-U def]... [-I dir]... " + "[-L dir]... [-l dir]...\n" + " [-dgksw] [-m arch] [-M|-E|-S] [-o outfile] file...\n" + " scc [-D def[=val]]... [-U def]... [-I dir]... " + "[-L dir]... [-l dir]...\n" + " [-dgksw] [-m arch] [-M|-E|-S] -c file...\n" + " scc [-D def[=val]]... [-U def]... [-I dir]... " + "[-L dir]... [-l dir]...\n" + " [-dgksw] [-m arch] -c -o outfile file\n", stderr); + exit(1); +} + +int +main(int argc, char *argv[]) +{ + struct items linkchain = { .n = 0, }; + int link; + + atexit(terminate); + + if (!(arch = getenv("ARCH"))) + arch = ARCH; + if (!(sys = getenv("SYS"))) + sys = SYS; + if (!(abi = getenv("ABI"))) + abi = ABI; + if (!(format = getenv("FORMAT"))) + format = FORMAT; + if (!(prefix = getenv("SCCPREFIX"))) + prefix = PREFIX; + + ARGBEGIN { + case 'D': + addarg(CC1, "-D"); + addarg(CC1, EARGF(usage())); + break; + case 'M': + Mflag = 1; + addarg(CC1, "-M"); + break; + case 'E': + Eflag = 1; + addarg(CC1, "-E"); + break; + case 'I': + addarg(CC1, "-I"); + addarg(CC1, EARGF(usage())); + break; + case 'L': + addarg(LD, "-L"); + addarg(LD, EARGF(usage())); + break; + case 'O': + EARGF(usage()); + break; + case 'S': + Sflag = 1; + break; + case 'U': + addarg(CC1, "-U"); + addarg(CC1, EARGF(usage())); + break; + case 'c': + cflag = 1; + break; + case 'd': + dflag = 1; + break; + case 'g': + addarg(AS, "-g"); + addarg(LD, "-g"); + break; + case 'k': + kflag = 1; + break; + case 'l': + newitem(&linkchain, "-l"); + newitem(&linkchain, EARGF(usage())); + break; + case 'm': + arch = EARGF(usage()); + break; + case 'o': + outfile = xstrdup(EARGF(usage())); + break; + case 's': + sflag = 1; + break; + case 't': + sys = EARGF(usage()); + break; + case 'W': + EARGF(usage()); + case 'w': + addarg(CC1, "-w"); + break; + case 'q': + Qflag = 0; + break; + case 'Q': + Qflag = 1; + break; + case '-': + fprintf(stderr, + "scc: ignored parameter --%s\n", EARGF(usage())); + break; + default: + usage(); + } ARGOPERAND { +operand: + newitem(&linkchain, ARGOP()); + } ARGEND + + for (; *argv; --argc, ++argv) + goto operand; + + if (Eflag && linkchain.n == 0) + newitem(&linkchain, "-"); + + if (Eflag && Mflag || + (Eflag || Mflag) && (Sflag || kflag) || + linkchain.n == 0 || + linkchain.n > 1 && cflag && outfile) + usage(); + + if (!dflag) { + if ((devnullfd = open("/dev/null", O_WRONLY)) < 0) + fputs("scc: could not open /dev/null\n", stderr); + } + + if (!(tmpdir = getenv("TMPDIR")) || !tmpdir[0]) + tmpdir = "."; + tmpdirln = strlen(tmpdir); + + build(&linkchain, (link = !(Mflag || Eflag || Sflag || cflag))); + + if (!(link || cflag)) + return failure; + + if (link && !failure) { + addarg(LD, xstrdup("-lc")); + spawn(settool(LD, NULL, LAST_TOOL)); + validatetools(); + } + + if (sflag) { + spawn(settool(inittool(STRIP), NULL, LAST_TOOL)); + validatetools(); + } + + return failure; +} diff --git a/src/driver/Makefile b/src/driver/Makefile @@ -1,8 +0,0 @@ -.POSIX: - -DRIVER = posix -PROJECTDIR = ../.. -include $(PROJECTDIR)/scripts/rules.mk - -all dep clean: - +@cd $(DRIVER) && $(MAKE) $@ diff --git a/src/driver/posix/Makefile b/src/driver/posix/Makefile @@ -1,39 +0,0 @@ -.POSIX: - -PROJECTDIR = ../.. -include $(PROJECTDIR)/rules.mk - -# SYSLST is a list of backend-arch-abi-sys. First -# element of the list becomes the default target - -SYSLST = amd64-sysv-linux-elf z80-scc-none-none \ - i386-sysv-linux-elf amd64-sysv-openbsd-elf - -STDCFLAGS = - -TARGETS = $(BINDIR)/scc $(BINDIR)/scpp - -all: $(TARGETS) - -$(BINDIR)/scc: scc.o - $(CC) $(SCC_LDFLAGS) scc.o -lscc -o $@ - -$(BINDIR)/scpp: cpp.sh config.h - set -x ;\ - trap "rm -f $$$$.sh" 0 2 3;\ - rm -f $@ ;\ - sed "s%@PREFIX@%$(PREFIX)%" < cpp.sh > $$$$.sh && \ - chmod +x $$$$.sh && \ - mv $$$$.sh $@ - -config.h: - PREFIX=$(PREFIX) config.sh $(SYSLST) - -dep: inc-dep - -clean: - rm -f scc scpp *.o - rm -f $(TARGETS) - rm -f config.h - -include deps.mk diff --git a/src/driver/posix/config.h b/src/driver/posix/config.h @@ -1,5 +0,0 @@ -#define PREFIX "/home/robvar01/src/tools/scc/driver/posix/../../root" -#define ARCH "amd64" -#define SYS "linux" -#define ABI "sysv" -#define FORMAT "elf" diff --git a/src/driver/posix/deps.mk b/src/driver/posix/deps.mk @@ -1,8 +0,0 @@ -#deps -scc.o: ../../inc/arg.h -scc.o: ../../inc/ldflags.h -scc.o: ../../inc/scc.h -scc.o: ../../inc/syscrts.h -scc.o: ../../inc/sysincludes.h -scc.o: ../../inc/syslibs.h -scc.o: config.h diff --git a/src/driver/posix/scc.c b/src/driver/posix/scc.c @@ -1,617 +0,0 @@ -static char sccsid[] = "@(#) ./driver/posix/scc.c"; -#define _POSIX_SOURCE -#define _XOPEN_SOURCE 500 -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> - -#include <errno.h> -#include <fcntl.h> -#include <limits.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "config.h" -#include "../../inc/arg.h" -#include "../../inc/scc.h" -#include "../../inc/syscrts.h" -#include "../../inc/sysincludes.h" -#include "../../inc/syslibs.h" -#include "../../inc/ldflags.h" - -enum { - CC1, - TEEIR, - CC2, - TEEQBE, - QBE, - TEEAS, - AS, - LD, - STRIP, - LAST_TOOL, -}; - -static struct tool { - char cmd[PATH_MAX]; - char bin[32]; - char *outfile; - struct items args; - unsigned nparams; - int in, out, init; - pid_t pid; -} tools[] = { - [CC1] = { .cmd = "cc1" }, - [TEEIR] = { .bin = "tee", .cmd = "tee", }, - [CC2] = { .cmd = "cc2" }, - [TEEQBE] = { .bin = "tee", .cmd = "tee", }, - [QBE] = { .bin = "qbe", .cmd = "qbe", }, - [TEEAS] = { .bin = "tee", .cmd = "tee", }, - [AS] = { .bin = "as", .cmd = "as", }, - [LD] = { .bin = "ld", .cmd = "ld", }, - [STRIP] = { .bin = "strip", .cmd = "strip", }, -}; - -char *argv0; -static char *arch, *sys, *abi, *format; -static char *prefix, *objfile, *outfile; -static char *tmpdir; -static size_t tmpdirln; -static struct items objtmp, objout; -static int Mflag, Eflag, Sflag, cflag, dflag, kflag, sflag, Qflag = 1; /* TODO: Remove Qflag */ -static int devnullfd = -1; - -extern int failure; - -static void -terminate(void) -{ - unsigned i; - - if (!kflag) { - for (i = 0; i < objtmp.n; ++i) - unlink(objtmp.s[i]); - } -} - -static void -addarg(int tool, char *arg) -{ - struct tool *t = &tools[tool]; - - if (t->args.n < 1) - t->args.n = 1; - - newitem(&t->args, arg); -} - -static void -setargv0(int tool, char *arg) -{ - struct tool *t = &tools[tool]; - - if (t->args.n > 0) - t->args.s[0] = arg; - else - newitem(&t->args, arg); -} - -static int -qbe(int tool) -{ - if (tool != CC2 || !Qflag) - return 0; - if (!strcmp(arch, "amd64") && !strcmp(abi, "sysv")) - return 1; - return 0; -} - -static int -inittool(int tool) -{ - struct tool *t = &tools[tool]; - char *crt, *fmt; - int n; - - if (t->init) - return tool; - - switch (tool) { - case CC1: - for (n = 0; sysincludes[n]; ++n) { - addarg(tool, "-I"); - addarg(tool, sysincludes[n]); - } - case CC2: - fmt = (qbe(tool)) ? "%s-qbe_%s-%s" : "%s-%s-%s"; - n = snprintf(t->bin, sizeof(t->bin), fmt, t->cmd, arch, abi); - if (n < 0 || n >= sizeof(t->bin)) - die("scc: target tool name too long"); - - n = snprintf(t->cmd, sizeof(t->cmd), - "%s/libexec/scc/%s", prefix, t->bin); - if (n < 0 || n >= sizeof(t->cmd)) - die("scc: target tool path too long"); - break; - case LD: - for (n = 0; ldflags[n]; ++n) - addarg(tool, ldflags[n]); - addarg(tool, "-o"); - t->outfile = outfile ? outfile : xstrdup("a.out"); - addarg(tool, t->outfile); - for (n = 0; syslibs[n]; ++n) { - addarg(tool, "-L"); - addarg(tool, syslibs[n]); - } - if (syscrts[0]) { - for (n = 0; syscrts[n]; ++n) - addarg(tool, syscrts[n]); - break; - } - n = snprintf(NULL, 0, - "%s/lib/scc/%s-%s-%s/crt.o", - prefix, arch, abi, sys); - if (n < 0) - die("scc: wrong crt file name"); - crt = xmalloc(++n); - sprintf(crt, - "%s/lib/scc/%s-%s-%s/crt.o", - prefix, arch, abi, sys); - addarg(tool, crt); - break; - case AS: - addarg(tool, "-o"); - break; - default: - break; - } - - setargv0(tool, t->bin); - t->nparams = t->args.n; - t->init = 1; - - return tool; -} - -static char * -outfname(char *path, char *type) -{ - char *new, sep, *p; - size_t newsz, pathln; - int tmpfd, n; - - if (path) { - sep = '.'; - if (p = strrchr(path, '/')) - path = p + 1; - pathln = strlen(path); - if (p = strrchr(path, '.')) - pathln -= strlen(p); - } else { - sep = '/'; - type = "scc-XXXXXX"; - path = tmpdir; - pathln = tmpdirln; - } - - newsz = pathln + 1 + strlen(type) + 1; - new = xmalloc(newsz); - n = snprintf(new, newsz, "%.*s%c%s", (int)pathln, path, sep, type); - if (n < 0 || n >= newsz) - die("scc: wrong output filename"); - if (sep == '/') { - if ((tmpfd = mkstemp(new)) < 0) - die("scc: could not create output file '%s': %s", - new, strerror(errno)); - close(tmpfd); - } - - return new; -} - -static int -settool(int tool, char *infile, int nexttool) -{ - struct tool *t = &tools[tool]; - unsigned i; - int fds[2]; - static int fdin = -1; - - switch (tool) { - case TEEIR: - t->outfile = outfname(infile, "ir"); - addarg(tool, t->outfile); - break; - case TEEQBE: - t->outfile = outfname(infile, "qbe"); - addarg(tool, t->outfile); - break; - case TEEAS: - t->outfile = outfname(infile, "s"); - addarg(tool, t->outfile); - break; - case AS: - if (cflag && outfile) { - objfile = outfile; - } else { - objfile = (cflag || kflag) ? infile : NULL; - objfile = outfname(objfile, "o"); - } - t->outfile = xstrdup(objfile); - addarg(tool, t->outfile); - break; - case STRIP: - if (cflag || kflag) { - for (i = 0; i < objout.n; ++i) - addarg(tool, xstrdup(objout.s[i])); - } - if (!cflag && tools[LD].outfile) - addarg(tool, tools[LD].outfile); - break; - default: - break; - } - - if (fdin > -1) { - t->in = fdin; - fdin = -1; - } else { - t->in = -1; - if (infile) - addarg(tool, xstrdup(infile)); - } - - if (nexttool < LAST_TOOL) { - if (pipe(fds)) - die("scc: pipe: %s", strerror(errno)); - t->out = fds[1]; - fdin = fds[0]; - } else { - t->out = -1; - } - - addarg(tool, NULL); - - return tool; -} - -static void -spawn(int tool) -{ - struct tool *t = &tools[tool]; - - switch (t->pid = fork()) { - case -1: - die("scc: %s: %s", t->bin, strerror(errno)); - case 0: - if (t->out > -1) - dup2(t->out, 1); - if (t->in > -1) - dup2(t->in, 0); - if (!dflag && tool != CC1 && tool != LD) - dup2(devnullfd, 2); - execvp(t->cmd, t->args.s); - if (dflag) { - fprintf(stderr, - "scc: execvp %s: %s\n", - t->cmd, - strerror(errno)); - } - abort(); - default: - if (t->in > -1) - close(t->in); - if (t->out > -1) - close(t->out); - break; - } -} - -static int -toolfor(char *file) -{ - char *dot = strrchr(file, '.'); - - if (dot) { - if (!strcmp(dot, ".c")) - return CC1; - if (!strcmp(dot, ".ir")) - return CC2; - if (!strcmp(dot, ".qbe")) - return QBE; - if (!strcmp(dot, ".s")) - return AS; - if (!strcmp(dot, ".o")) - return LD; - if (!strcmp(dot, ".a")) - return LD; - } else if (!strcmp(file, "-")) { - return CC1; - } - - die("scc: do not recognize filetype of %s", file); -} - -static int -valid(int tool, struct tool *t) -{ - int st; - - if (waitpid(t->pid, &st, 0) == -1 || WIFSIGNALED(st)) - goto internal; - if (WIFEXITED(st) && WEXITSTATUS(st) == 0) - return 1; - if (!failure && (tool == CC1 || tool == LD)) - goto fail; - -internal: - fprintf(stderr, "scc:%s: internal error\n", t->bin); -fail: - failure = 1; - return 0; -} - -static int -validatetools(void) -{ - struct tool *t; - unsigned i; - int tool, st, failed = LAST_TOOL; - - for (tool = 0; tool < LAST_TOOL; ++tool) { - t = &tools[tool]; - if (!t->pid) - continue; - if (!valid(tool, t)) - failed = tool; - if (tool >= failed && t->outfile) - unlink(t->outfile); - for (i = t->nparams; i < t->args.n; ++i) - free(t->args.s[i]); - t->args.n = t->nparams; - t->pid = 0; - } - if (failed < LAST_TOOL) { - unlink(objfile); - free(objfile); - objfile = NULL; - return 0; - } - - return 1; -} - -static int -buildfile(char *file, int tool) -{ - int nexttool; - - for (; tool < LAST_TOOL; tool = nexttool) { - switch (tool) { - case CC1: - if (Eflag || Mflag) - nexttool = LAST_TOOL; - else - nexttool = kflag ? TEEIR : CC2; - break; - case TEEIR: - nexttool = CC2; - break; - case CC2: - if (Qflag) - nexttool = kflag ? TEEQBE : QBE; - else - nexttool = (Sflag || kflag) ? TEEAS : AS; - break; - case TEEQBE: - nexttool = QBE; - break; - case QBE: - nexttool = (Sflag || kflag) ? TEEAS : AS; - break; - case TEEAS: - nexttool = Sflag ? LAST_TOOL : AS; - break; - case AS: - nexttool = LAST_TOOL; - break; - default: - nexttool = LAST_TOOL; - continue; - } - - spawn(settool(inittool(tool), file, nexttool)); - } - - return validatetools(); -} - -static void -build(struct items *chain, int link) -{ - int i, tool; - - if (link) - inittool(LD); - - for (i = 0; i < chain->n; ++i) { - if (!strcmp(chain->s[i], "-l")) { - if (link) { - addarg(LD, xstrdup(chain->s[i++])); - addarg(LD, xstrdup(chain->s[i])); - } else { - ++i; - } - continue; - } - tool = toolfor(chain->s[i]); - if (tool == LD) { - if (link) - addarg(LD, xstrdup(chain->s[i])); - continue; - } - if (buildfile(chain->s[i], tool)) { - if (link) - addarg(LD, xstrdup(objfile)); - newitem((!link || kflag) ? &objout : &objtmp, objfile); - } - } -} - -static void -usage(void) -{ - fputs("usage: scc [-D def[=val]]... [-U def]... [-I dir]... " - "[-L dir]... [-l dir]...\n" - " [-dgksw] [-m arch] [-M|-E|-S] [-o outfile] file...\n" - " scc [-D def[=val]]... [-U def]... [-I dir]... " - "[-L dir]... [-l dir]...\n" - " [-dgksw] [-m arch] [-M|-E|-S] -c file...\n" - " scc [-D def[=val]]... [-U def]... [-I dir]... " - "[-L dir]... [-l dir]...\n" - " [-dgksw] [-m arch] -c -o outfile file\n", stderr); - exit(1); -} - -int -main(int argc, char *argv[]) -{ - struct items linkchain = { .n = 0, }; - int link; - - atexit(terminate); - - if (!(arch = getenv("ARCH"))) - arch = ARCH; - if (!(sys = getenv("SYS"))) - sys = SYS; - if (!(abi = getenv("ABI"))) - abi = ABI; - if (!(format = getenv("FORMAT"))) - format = FORMAT; - if (!(prefix = getenv("SCCPREFIX"))) - prefix = PREFIX; - - ARGBEGIN { - case 'D': - addarg(CC1, "-D"); - addarg(CC1, EARGF(usage())); - break; - case 'M': - Mflag = 1; - addarg(CC1, "-M"); - break; - case 'E': - Eflag = 1; - addarg(CC1, "-E"); - break; - case 'I': - addarg(CC1, "-I"); - addarg(CC1, EARGF(usage())); - break; - case 'L': - addarg(LD, "-L"); - addarg(LD, EARGF(usage())); - break; - case 'O': - EARGF(usage()); - break; - case 'S': - Sflag = 1; - break; - case 'U': - addarg(CC1, "-U"); - addarg(CC1, EARGF(usage())); - break; - case 'c': - cflag = 1; - break; - case 'd': - dflag = 1; - break; - case 'g': - addarg(AS, "-g"); - addarg(LD, "-g"); - break; - case 'k': - kflag = 1; - break; - case 'l': - newitem(&linkchain, "-l"); - newitem(&linkchain, EARGF(usage())); - break; - case 'm': - arch = EARGF(usage()); - break; - case 'o': - outfile = xstrdup(EARGF(usage())); - break; - case 's': - sflag = 1; - break; - case 't': - sys = EARGF(usage()); - break; - case 'W': - EARGF(usage()); - case 'w': - addarg(CC1, "-w"); - break; - case 'q': - Qflag = 0; - break; - case 'Q': - Qflag = 1; - break; - case '-': - fprintf(stderr, - "scc: ignored parameter --%s\n", EARGF(usage())); - break; - default: - usage(); - } ARGOPERAND { -operand: - newitem(&linkchain, ARGOP()); - } ARGEND - - for (; *argv; --argc, ++argv) - goto operand; - - if (Eflag && linkchain.n == 0) - newitem(&linkchain, "-"); - - if (Eflag && Mflag || - (Eflag || Mflag) && (Sflag || kflag) || - linkchain.n == 0 || - linkchain.n > 1 && cflag && outfile) - usage(); - - if (!dflag) { - if ((devnullfd = open("/dev/null", O_WRONLY)) < 0) - fputs("scc: could not open /dev/null\n", stderr); - } - - if (!(tmpdir = getenv("TMPDIR")) || !tmpdir[0]) - tmpdir = "."; - tmpdirln = strlen(tmpdir); - - build(&linkchain, (link = !(Mflag || Eflag || Sflag || cflag))); - - if (!(link || cflag)) - return failure; - - if (link && !failure) { - addarg(LD, xstrdup("-lc")); - spawn(settool(LD, NULL, LAST_TOOL)); - validatetools(); - } - - if (sflag) { - spawn(settool(inittool(STRIP), NULL, LAST_TOOL)); - validatetools(); - } - - return failure; -}