Files
pkgsrc-ng/pkgtools/cwrappers/files/bin/normalise-cc.c
2016-01-21 23:42:40 +01:00

214 lines
6.6 KiB
C

/* $NetBSD: normalise-cc.c,v 1.3 2015/07/07 15:00:25 jperkin Exp $ */
/*-
* Copyright (c) 2009 Joerg Sonnenberger <joerg@NetBSD.org>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <nbcompat.h>
#include <nbcompat/err.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
static void
normalise_path_list(struct arglist *args, struct argument *arg,
const char *prefix, const char *val, int strip_relative)
{
const char *sep;
struct argument *arg2;
while ((sep = strchr(val, ':')) != NULL) {
if (sep == val || (strip_relative && val[0] != '/')) {
val = sep + 1;
continue;
}
arg2 = argument_new(concat2(prefix, val, sep - val));
TAILQ_INSERT_AFTER(args, arg, arg2, link);
arg = arg2;
val = sep + 1;
}
if (val[0] == '\0' || (strip_relative && val[0] != '/'))
return;
arg2 = argument_new(concat(prefix, val));
TAILQ_INSERT_AFTER(args, arg, arg2, link);
arg = arg2;
}
void
normalise_cc(struct arglist *args)
{
struct argument *arg, *arg2, *arg3;
const char *next, *last;
size_t len;
TAILQ_FOREACH_SAFE(arg, args, link, arg2) {
if (arg->val[0] != '-')
continue;
if (strcmp(arg->val, "-Xlinker") == 0) {
if (arg2 == NULL)
errx(255, "Missing argument for %s", arg->val);
if (strncmp(arg2->val, "-Wl,", 4) == 0) {
argument_unlink(args, &arg);
continue;
}
argument_update(arg2, concat("-Wl,", arg2->val));
argument_unlink(args, &arg);
continue;
}
if (strncmp(arg->val, "-Wl,", 4) == 0 &&
(next = strchr(arg->val + 4, ',')) != NULL) {
last = arg->val + 4;
do {
arg3 = argument_new(concat2("-Wl,", last,
next - last));
if (arg2 != NULL)
TAILQ_INSERT_BEFORE(arg2, arg3, link);
else
TAILQ_INSERT_TAIL(args, arg3, link);
last = next + 1;
} while ((next = strchr(last, ',')) != NULL);
arg3 = argument_new(concat("-Wl,", last));
if (arg2 != NULL)
TAILQ_INSERT_BEFORE(arg2, arg3, link);
else
TAILQ_INSERT_TAIL(args, arg3, link);
argument_unlink(args, &arg);
continue;
}
}
TAILQ_FOREACH_SAFE(arg, args, link, arg2) {
if (strcmp(arg->val, "-o") == 0 ||
strcmp(arg->val, "-dylib_file") == 0 ||
strcmp(arg->val, "-dylib_install_name") == 0 ||
strcmp(arg->val, "-install_name") == 0 ||
strcmp(arg->val, "-seg_addr_table_filename") == 0 ||
strcmp(arg->val, "--dynamic-linker") == 0) {
if (arg2 == NULL || arg2->val[0] == '-')
errx(255, "Missing argument for %s", arg->val);
arg2 = TAILQ_NEXT(arg2, link);
continue;
}
if (arg->val[0] == '/') {
next = strrchr(arg->val, '/');
++next;
if (strncmp(next, "lib", 3))
continue;
next += 3;
len = strspn(next, library_name_chars);
if (len == 0)
continue;
last = next + len;
if (strncmp(last, ".so", 3) == 0 ||
strncmp(last, ".sl", 3) == 0)
last += 3;
else if (strncmp(last, ".dylib", 6) == 0)
last += 6;
else
continue;
if (last[0] &&
(last[0] != '.' || last[1] < '0' || last[1] > '9'))
continue;
arg3 = argument_new(xasprintf("-l%*.*s", (int)len,
(int)len, next));
next = strrchr(arg->val, '/');
len = next - arg->val;
argument_update(arg, xasprintf("-L%*.*s", (int)len,
(int)len, arg->val));
TAILQ_INSERT_AFTER(args, arg, arg3, link);
continue;
}
if (arg->val[0] != '-')
continue;
if (strcmp(arg->val, "-I") == 0 ||
strcmp(arg->val, "-D") == 0 ||
strcmp(arg->val, "-L") == 0) {
if (arg2 == NULL || arg2->val[0] == '-')
errx(255, "Missing argument for %s", arg->val);
argument_update(arg, concat(arg->val, arg2->val));
argument_unlink(args, &arg2);
continue;
}
if (strcmp(arg->val, "-Wl,-L") == 0) {
if (arg2 == NULL || strncmp(arg2->val, "-Wl,", 4))
errx(255, "Missing argument for %s", arg->val);
argument_update(arg, concat("-L", arg2->val + 4));
argument_unlink(args, &arg2);
continue;
}
if (strcmp(arg->val, "-Wl,-rpath-link") == 0) {
if (arg2 == NULL || strncmp(arg2->val, "-Wl,", 4))
errx(255, "Missing argument for %s", arg->val);
normalise_path_list(args, arg, "-Wl,-rpath-link,",
arg2->val + 4, 0);
argument_unlink(args, &arg);
argument_unlink(args, &arg2);
continue;
}
if (strcmp(arg->val, "-R") == 0) {
if (arg2 == NULL || arg2->val[0] == '-')
errx(255, "Missing argument for %s", arg->val);
normalise_path_list(args, arg, "-Wl,-rpath,",
arg2->val, 1);
argument_unlink(args, &arg);
argument_unlink(args, &arg2);
continue;
}
if (strcmp(arg->val, "-Wl,-R") == 0 ||
strcmp(arg->val, "-Wl,-rpath") == 0 ||
strcmp(arg->val, "-Wl,--rpath") == 0) {
if (arg2 == NULL || strncmp(arg2->val, "-Wl,", 4))
errx(255, "Missing argument for %s", arg->val);
normalise_path_list(args, arg, "-Wl,-rpath,",
arg2->val + 4, 1);
argument_unlink(args, &arg);
argument_unlink(args, &arg2);
continue;
}
if (strncmp(arg->val, "-Wl,-R", 6) == 0) {
normalise_path_list(args, arg, "-Wl,-rpath,",
arg->val + 6, 1);
argument_unlink(args, &arg);
continue;
}
if (strncmp(arg->val, "-R", 2) == 0) {
normalise_path_list(args, arg, "-Wl,-rpath,",
arg->val + 2, 1);
argument_unlink(args, &arg);
continue;
}
if (strncmp(arg->val, "-Wl,-rpath,", 10) == 0) {
normalise_path_list(args, arg, "-Wl,-rpath,",
arg->val + 10, 1);
argument_unlink(args, &arg);
continue;
}
}
}