Skip to content

Instantly share code, notes, and snippets.

@sandsmark
Created November 30, 2019 15:12
Show Gist options
  • Save sandsmark/9f4cc47b6cf4b11f05d677624e0ae025 to your computer and use it in GitHub Desktop.
Save sandsmark/9f4cc47b6cf4b11f05d677624e0ae025 to your computer and use it in GitHub Desktop.
#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