Created
November 30, 2019 15:12
-
-
Save sandsmark/9f4cc47b6cf4b11f05d677624e0ae025 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <errno.h> | |
int main(int argc, char *argv[]) | |
{ | |
int outfds[2]; | |
int infds[2]; | |
int ret = pipe(outfds); | |
if (ret == -1) { | |
fprintf(stderr, "Failed to open stdout pipe: %s (%d)\n", strerror(errno), errno); | |
return 1; | |
} | |
ret = pipe(infds); | |
if (ret == -1) { | |
fprintf(stderr, "Failed to open stdin pipe: %s (%d)\n", strerror(errno), errno); | |
return 1; | |
} | |
int outRead = outfds[0]; | |
int outWrite = outfds[1]; | |
int inRead = infds[0]; | |
int inWrite = infds[1]; | |
int is_clang = 0; | |
int found_native = 1; | |
int dummy1, dummy2; | |
int *ignore_range_min = &dummy1, *ignore_range_max = &dummy2; | |
char ***ret_newargv = &argv; | |
int extra_args = 0; | |
const char *compiler = "gcc"; | |
switch (fork()) { | |
case -1: | |
fprintf(stderr, "Failed to fork: %s (%d)", strerror(errno), errno); | |
return 1; | |
case 0: { // Child | |
close(outWrite); | |
dup2(outRead, STDIN_FILENO); | |
close(outRead); | |
close(inRead); | |
dup2(inWrite, STDERR_FILENO); | |
close(inWrite); | |
execlp(compiler, compiler, "-v", "-E", "-x", "c", "-march=native", "-mtune=native", "-", NULL); | |
break; | |
} | |
default: { | |
close(outWrite); | |
close(outRead); | |
close(inWrite); | |
char buff[16384]; | |
int i, j, l = argc; | |
FILE *in = fdopen(inRead, "r"); | |
while(fgets(buff, sizeof(buff), in) != NULL) | |
{ | |
char* cc1 = strstr(buff, "cc1"); | |
if (cc1) | |
{ | |
char* args = strstr(cc1, " - "); | |
if (args) | |
{ | |
args += 3; | |
char* end = strstr(args, " -v "); | |
if (!end) end = strstr(args, "\n"); | |
if (end) *end = 0; | |
int n_arguments = 1; | |
for (const char* ptr = args;*ptr;ptr++) { | |
if (*ptr == ' ') n_arguments++; | |
} | |
close(inRead); | |
if (is_clang) n_arguments *= 2; /* must prepend all clang cc1 options with -Xclang */ | |
char **b; | |
b = malloc((l+1+extra_args+n_arguments-1) * (sizeof argv[0])); | |
if (b == NULL) { | |
fprintf(stderr, "failed to allocate copy of argv"); | |
return 1; | |
} | |
j = 0; | |
for (i = 0; i < l; i++) { | |
if (!strcmp(argv[i], "-march=native") || !strcmp(argv[i], "-mtune=native")) { | |
if (found_native == 1) { | |
/* insert only once, at the position of the first native argument */ | |
*ignore_range_min = j; | |
const char* ptr_insert = args; | |
int clang_force_next = 0; | |
for (char* ptr = args;*ptr;ptr++) { | |
if (*ptr == ' ' || *ptr == 0) { | |
if (*ptr == ' ') *(ptr++) = 0; | |
const char* insert = ptr_insert; | |
ptr_insert = ptr; | |
if (is_clang) { | |
if (strncmp(insert, "-target", strlen("-target")) == 0) { | |
clang_force_next = 1; /* need to forward the following option */ | |
} else { | |
if (!clang_force_next) continue; /* discard non-target options */ | |
clang_force_next = 0; | |
} | |
if ((b[j++] = strdup("-Xclang")) == NULL) { | |
fprintf(stderr, "failed to duplicate element %d\n", i); | |
return 1; | |
} | |
} | |
puts(insert); | |
if ((b[j++] = strdup(insert)) == NULL) { | |
fprintf(stderr, "failed to duplicate element %d\n", i); | |
return 1; | |
} | |
} | |
} | |
found_native = 2; | |
*ignore_range_max = j; | |
} | |
continue; | |
} | |
if ((b[j++] = strdup(argv[i])) == NULL) { | |
fprintf(stderr, "failed to duplicate element %d\n", i); | |
return 1; | |
} | |
} | |
b[j] = NULL; | |
*ret_newargv = b; | |
return 0; | |
} | |
} | |
} | |
fprintf(stderr, "%p", *ret_newargv); | |
break; | |
} | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment