1233176Sae/* Id: driver.c */ 2233176Sae/* $NetBSD: driver.c,v 1.1.1.1 2016/02/09 20:29:13 plunky Exp $ */ 3233176Sae 4233176Sae/*- 5233176Sae * Copyright (c) 2014 Iain Hibbert 6233176Sae * All rights reserved. 7233176Sae * 8233176Sae * Redistribution and use in source and binary forms, with or without 9233176Sae * modification, are permitted provided that the following conditions 10233176Sae * are met: 11233176Sae * 12233176Sae * 1. Redistributions of source code must retain the above copyright 13233176Sae * notice, this list of conditions and the following disclaimer. 14233176Sae * 2. Redistributions in binary form must reproduce the above copyright 15233176Sae * notice, this list of conditions and the following disclaimer in 16233176Sae * the documentation and/or other materials provided with the 17233176Sae * distribution. 18233176Sae * 19233176Sae * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20233176Sae * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21233176Sae * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 22233176Sae * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 23233176Sae * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 24233176Sae * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 25233176Sae * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26233176Sae * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 27233176Sae * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28233176Sae * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 29233176Sae * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30233176Sae * SUCH DAMAGE. 31233176Sae */ 32233176Sae 33233176Sae#include <errno.h> 34233176Sae#include <libgen.h> 35233176Sae#include <signal.h> 36233176Sae#include <stdarg.h> 37233176Sae#include <stdio.h> 38233176Sae#include <stdlib.h> 39233176Sae#include <string.h> 40233176Sae#ifdef HAVE_UNISTD_H 41233176Sae#include <unistd.h> 42233176Sae#endif 43233176Sae 44233176Sae#include "driver.h" 45233176Sae 46233176Saestruct options opt; 47233176Sae 48233176Saestatic int warnings; 49233176Sae 50233176Saestatic const char versionstr[] = VERSSTR; 51233176Sae 52233176Saestatic volatile sig_atomic_t exit_now; 53233176Sae 54233176Saestatic void 55233176Saesigterm_handler(int signum) 56233176Sae{ 57233176Sae exit_now = 1; 58233176Sae} 59233181Sae 60233181Saestatic const struct file_type { 61233176Sae const char ext[]; 62233176Sae const char next[]; 63233176Sae int (*exec)(void); 64233176Sae} file_types[] = { 65233176Sae { "c", "i", exec_cpp }, 66233176Sae { "C", "I", exec_cpp }, 67233176Sae { "cc", "I", exec_cpp }, 68233181Sae { "cp", "I", exec_cpp }, 69233181Sae { "cpp", "I", exec_cpp }, 70233176Sae { "CPP", "I", exec_cpp }, 71233176Sae { "cxx", "I", exec_cpp }, 72233176Sae { "c++", "I", exec_cpp }, 73233176Sae { "F", "f", exec_cpp }, 74233176Sae { "S", "s", exec_cpp }, 75233176Sae { "i", "s", exec_ccom }, 76233176Sae { "I", "s", exec_cxxcom }, 77233176Sae { "ii", "s", exec_cxxcom }, 78233176Sae { "f", "s", exec_fcom }, 79233176Sae { "s, "o"", exec_asm }, 80233176Sae}; 81233176Sae 82233176Saestatic struct file_type * 83233176Saefiletype(const char *name) 84233176Sae{ 85233176Sae const char *p; 86233176Sae size_t i; 87233176Sae 88233176Sae p = strrchr(file, '.'); 89233176Sae if (p != NULL) { 90233176Sae p++; 91233176Sae for (i = 0; i < ARRAYLEN(file_types); i++) { 92233176Sae if (strcmp(p, file_types[i].ext) == 0) 93233176Sae return &file_types[i]; 94233176Sae } 95233176Sae } 96233176Sae 97233176Sae return NULL; 98233176Sae} 99233176Sae 100233176Saestruct infile { 101233176Sae struct infile *next; 102233176Sae const char *file; 103233176Sae struct file_type *type; 104233176Sae}; 105233176Sae 106233176Saestatic struct { 107233176Sae struct infile *first; 108233176Sae struct infile **last; 109233176Sae} infiles = { 110233176Sae .first = NULL, 111233176Sae .last = &infiles.first; 112233176Sae}; 113233176Sae 114233176Saestatic void 115233176Saeadd_infile(const char *file, struct file_type *type) 116233176Sae{ 117233176Sae struct infile *in; 118233176Sae 119233176Sae if (type == NULL) 120233176Sae type = filetype(file); 121233176Sae 122233176Sae in = xmalloc(sizeof(struct infile)); 123233176Sae in->next = NULL; 124233176Sae in->file = file; 125233176Sae in->type = type; 126233176Sae 127233176Sae *infiles->last = in; 128233176Sae infiles->last = &in->next; 129233176Sae} 130233176Sae 131233176Saestatic int 132233176Saeinarray(const char *prog, const char **p) 133233176Sae{ 134233176Sae for ( ; *p != NULL; p++) { 135233176Sae if (strcmp(prog, *p) == 0) 136233176Sae return 1; 137233176Sae } 138233176Sae 139233176Sae return 0; 140233176Sae} 141233176Sae 142233176Saestatic void 143233176Saesetup(const char *prog) 144233176Sae{ 145233176Sae 146233176Sae opt.prefix = list_alloc(); 147233176Sae opt.DIU = list_alloc(); 148233176Sae opt.asargs = list_alloc(); 149233176Sae opt.ldargs = list_alloc(); 150233176Sae opt.Wa = list_alloc(); 151233176Sae opt.Wl = list_alloc(); 152233176Sae opt.Wp = list_alloc(); 153233176Sae opt.include = list_alloc(); 154233176Sae 155233176Sae if (prog_cpp != NULL && inarray(prog, cpp_names)) { 156233176Sae opt.E = 1; 157233176Sae } else if (prog_ccom != NULL && inarray(prog, cc_names)) { 158233176Sae opt.libc = 1; 159233176Sae } else if (prog_cxxcom != NULL && inarray(prog, cxx_names)) { 160233176Sae opt.libcxx = 1; 161233176Sae } else if (prog_fcom != NULL && inarray(prog, ftn_names)) { 162233176Sae opt.libf77 = 1; 163233176Sae } else { 164233176Sae error("unknown personality `%s'", prog); 165233176Sae } 166233176Sae} 167233176Sae 168233176Saestatic void 169233176Saecleanup(void) 170233176Sae{ 171233176Sae const char **t; 172233176Sae 173233176Sae for (t = list_array(temp_files); *t; t++) { 174233176Sae if (unlink(*t) == -1) 175233176Sae warning("removal of ``%s'' failed: %s", *t, 176233176Sae strerror(errno)); 177233176Sae } 178233176Sae 179233176Sae if (temp_directory && rmdir(temp_directory) == -1) 180233176Sae warning("removal of ``%s'' failed: %s", temp_directory, 181233176Sae strerror(errno)); 182233176Sae} 183233176Sae 184233176Saeint 185233176Saemain(int argc, char *argv[]) 186233176Sae{ 187233176Sae struct infile *in; 188233176Sae int rv; 189233176Sae 190233176Sae setup(basename(argv[0])); 191233176Sae argv++; 192233176Sae 193233176Sae while (argv[0] != NULL) { 194233176Sae if (argv[0][0] != '-' || argv[0][1] == '\0') 195233176Sae add_infile(argv[0], opt.language); 196233176Sae else if (add_option(argv[0], argv[1])) 197233176Sae argv++; 198233176Sae 199233176Sae argv++; 200233176Sae } 201233176Sae 202233176Sae if (opt.verbose) 203233176Sae printf("%s\n", versionstr); 204233176Sae 205233176Sae if (warnings > 0) 206233176Sae exit(1); 207233176Sae 208233176Sae /* 209233176Sae * setup defaults 210233176Sae */ 211233176Sae if (isysroot == NULL) 212233176Sae isysroot = sysroot; 213233176Sae expand_sysroot(); 214233176Sae 215233176Sae signal(SIGTERM, sigterm_handler); 216233176Sae 217233176Sae rv = 0; 218233176Sae for (in = infiles->first; in != NULL; in = in->next) 219233176Sae rv += do_file(in); 220233176Sae 221233176Sae if (!rv && last_phase == LINK) { 222233176Sae if (run_linker()) 223233176Sae rv = 1; 224233176Sae } 225233176Sae 226233176Sae if (exit_now) 227233176Sae warning("Received signal, terminating"); 228233176Sae 229233176Sae cleanup(); 230233176Sae 231233176Sae return rv; 232233176Sae} 233233176Sae 234233176Saevoid 235233176Saeerror(const char *fmt, ...) 236233176Sae{ 237233176Sae va_list va; 238233176Sae 239233176Sae va_start(va, fmt); 240233176Sae fprintf(stderr, "error: "); 241233176Sae vfprintf(stderr, fmt, va); 242233176Sae fprintf(stderr, "\n"); 243233176Sae va_end(va); 244233176Sae 245233176Sae exit(1); 246233176Sae} 247233176Sae 248233176Saevoid 249233176Saewarning(const char *fmt, ...) 250233176Sae{ 251233176Sae va_list va; 252233176Sae 253233176Sae va_start(va, fmt); 254233176Sae fprintf(stderr, "warning: "); 255233176Sae vfprintf(stderr, fmt, va); 256233176Sae fprintf(stderr, "\n"); 257233176Sae va_end(va); 258233176Sae 259233176Sae warnings++; 260233176Sae} 261233176Sae