176378Sschweikh/*-
2330449Seadler * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3330449Seadler *
476378Sschweikh * This is the Posix.2 mandated C compiler.  Basically, a hook to the
576378Sschweikh * cc(1) command.
676378Sschweikh *
776378Sschweikh * Copyright (c) 2001 by Jens Schweikhardt
876378Sschweikh *
976378Sschweikh * Redistribution and use in source and binary forms, with or without
1076378Sschweikh * modification, are permitted provided that the following conditions
1176378Sschweikh * are met:
1276378Sschweikh * 1. Redistributions of source code must retain the above copyright
1376378Sschweikh *    notice, this list of conditions and the following disclaimer.
1476378Sschweikh * 2. Redistributions in binary form must reproduce the above copyright
1576378Sschweikh *    notice, this list of conditions and the following disclaimer in the
1676378Sschweikh *    documentation and/or other materials provided with the distribution.
1776378Sschweikh *
1876378Sschweikh * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
1976378Sschweikh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2076378Sschweikh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2176378Sschweikh * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2276378Sschweikh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2376378Sschweikh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2476378Sschweikh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2576378Sschweikh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2676378Sschweikh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2776378Sschweikh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2876378Sschweikh * SUCH DAMAGE.
2976378Sschweikh *
3076378Sschweikh */
3176378Sschweikh
3287258Smarkm#include <sys/cdefs.h>
3387258Smarkm__FBSDID("$FreeBSD: stable/11/usr.bin/c89/c89.c 330449 2018-03-05 07:26:05Z eadler $");
3487258Smarkm
3576378Sschweikh#include <err.h>
3676378Sschweikh#include <stdio.h>
3776378Sschweikh#include <stdlib.h>
38200462Sdelphij#include <string.h>
3976378Sschweikh
4076378Sschweikh#include <unistd.h>
4176378Sschweikh
4276378Sschweikh#define	CC "/usr/bin/cc"	/* The big kahuna doing the actual work. */
4376378Sschweikh#define	N_ARGS_PREPENDED (sizeof(args_prepended) / sizeof(args_prepended[0]))
4476378Sschweikh
4576378Sschweikh/*
4676378Sschweikh * We do not add -D_POSIX_SOURCE here because any POSIX source is supposed to
4776378Sschweikh * define it before inclusion of POSIX headers. This has the additional
4876378Sschweikh * benefit of making c89 -D_ANSI_SOURCE do the right thing (or any other
4976378Sschweikh * -D_FOO_SOURCE feature test macro we support.)
5076378Sschweikh */
5187210Smarkmstatic const char	*args_prepended[] = {
5276378Sschweikh	"-std=iso9899:199409",
5376378Sschweikh	"-pedantic"
5476378Sschweikh};
5576378Sschweikh
5676378Sschweikhstatic void	usage(void);
5776378Sschweikh
5876378Sschweikh/*
5976378Sschweikh * Prepend the strings from args_prepended[] to the arg list; parse options,
6076378Sschweikh * accepting only the POSIX c89 mandated options. Then exec cc to do the
6176378Sschweikh * actual work.
6276378Sschweikh */
6376378Sschweikhint
6476378Sschweikhmain(int argc, char **argv)
6576378Sschweikh{
6676378Sschweikh	int Argc, i;
6787210Smarkm	size_t j;
6887210Smarkm	union {
6987210Smarkm		const char **a;
7087210Smarkm		char * const *b;
7187210Smarkm	} Argv;
7276378Sschweikh
7376378Sschweikh	Argc = 0;
7487210Smarkm	Argv.a = malloc((argc + 1 + N_ARGS_PREPENDED) * sizeof *Argv.a);
7587210Smarkm	if (Argv.a == NULL)
7676378Sschweikh		err(1, "malloc");
77247951Sdim	Argv.a[Argc++] = CC;
7887210Smarkm	for (j = 0; j < N_ARGS_PREPENDED; ++j)
7987210Smarkm		Argv.a[Argc++] = args_prepended[j];
8076378Sschweikh	while ((i = getopt(argc, argv, "cD:EgI:l:L:o:OsU:")) != -1) {
8176378Sschweikh		if (i == '?')
8276378Sschweikh			usage();
8376378Sschweikh		if (i == 'l') {
8476378Sschweikh			if (argv[optind - 1][0] == '-') /* -llib */
8576378Sschweikh				optind -= 1;
8676378Sschweikh			else                            /* -l lib */
8776378Sschweikh				optind -= 2;
8876378Sschweikh			break; /* -llib or -l lib starts the operands. */
8976378Sschweikh		}
9076378Sschweikh	}
9176378Sschweikh	if (argc == optind) {
9276378Sschweikh		warnx("missing operand");
9376378Sschweikh		usage();
9476378Sschweikh	}
9576378Sschweikh
9687210Smarkm	/* Append argv[1..] at the end of Argv[].a. */
9776378Sschweikh	for (i = 1; i <= argc; ++i)
9887210Smarkm		Argv.a[Argc++] = argv[i];
9987210Smarkm	(void)execv(CC, Argv.b);
10076378Sschweikh	err(1, "execv(" CC ")");
10176378Sschweikh}
10276378Sschweikh
10376378Sschweikhstatic void
10476378Sschweikhusage(void)
10576378Sschweikh{
10676378Sschweikh	fprintf(stderr,
107146466Sru"usage: c89 [-cEgOs] [-D name[=value]] ... [-I directory] ... [-L directory] ...\n"
108146466Sru"           [-o outfile] [-U name] ... operand ...\n"
10976378Sschweikh"\n"
11076378Sschweikh"       where operand is one or more of file.c, file.o, file.a\n"
11176378Sschweikh"       or -llibrary\n");
11276378Sschweikh	exit(1);
11376378Sschweikh}
114