static void build_command_line(int argc, char *argv[]) { const translation_info *transtable; const char *executable; const char *outstring = ""; char *dst = command_line; int output_is_first = 0; int param; DWORD exe_version; // if no parameters, show usage if (argc < 2) { fprintf(stderr, "Usage:\n vconv {gcc|ar|ld} [param [...]]\n"); exit(0); } // first parameter determines the type if (!strcmp(argv[1], "gcc")) { transtable = gcc_translate; executable = "cl.exe"; dst += sprintf(dst, "cl /nologo "); } else if (!strcmp(argv[1], "windres")) { transtable = windres_translate; executable = "rc.exe"; dst += sprintf(dst, "rc "); } else if (!strcmp(argv[1], "ld")) { transtable = ld_translate; executable = "link.exe"; dst += sprintf(dst, "link /nologo /debug "); } else if (!strcmp(argv[1], "ar")) { transtable = ar_translate; executable = "link.exe"; dst += sprintf(dst, "link /lib /nologo "); outstring = "/out:"; output_is_first = 1; } else { fprintf(stderr, "Error: unknown translation type '%s'\n", argv[1]); exit(-100); } // identify the version number of the EXE exe_version = get_exe_version(executable); // special case if (!strcmp(executable, "cl.exe") && (exe_version >= 0x00070000)) dst += sprintf(dst, "/wd4025 "); // iterate over parameters for (param = 2; param < argc; param++) { const char *src = argv[param]; int firstchar = src[0]; int srclen = strlen(src); int matched = FALSE; int i; // find a match for (i = 0; !matched && transtable[i].gcc_option != NULL; i++) { const char *compare = transtable[i].gcc_option; const char *replace; int j; // check version number if (exe_version < transtable[i].vc_version) continue; // find a match for (j = 0; j < srclen; j++) if (src[j] != compare[j]) break; // if we hit an asterisk, we're ok if (compare[j] == '*') { // if this is the end of the parameter, use the next one if (src[j] == 0) src = argv[++param]; else src += j; // copy the replacement up to the asterisk replace = transtable[i].vc_option; while (*replace && *replace != '*') { if (*replace == '~') { dst += sprintf(dst, "%s", outstring); replace++; } else *dst++ = *replace++; } // if we have an asterisk in the replacement, copy the rest of the source if (*replace == '*') { int addquote = (strchr(src, ' ') != NULL); if (addquote) *dst++ = '"'; while (*src) { *dst++ = (*src == '/') ? '\\' : *src; src++; } if (addquote) *dst++ = '"'; // if there's stuff after the asterisk, copy that replace++; while (*replace) *dst++ = *replace++; } // append a final space *dst++ = ' '; matched = TRUE; } // if we hit the end, we're also ok else if (compare[j] == 0 && j == srclen) { // copy the replacement up to the tilde replace = transtable[i].vc_option; while (*replace && *replace != '~') *dst++ = *replace++; // if we hit a tilde, set the new output if (*replace == '~') outstring = replace + 1; // append a final space *dst++ = ' '; matched = TRUE; } // else keep looking } // if we didn't match, process if (!matched) { // warn if we missed a parameter if (transtable[i].gcc_option == NULL && firstchar == '-') fprintf(stderr, "Unable to match parameter '%s'\n", src); // otherwise, assume it's a filename and copy translating slashes // it can also be a Windows-specific option which is passed through unscathed else if (firstchar != '-') { int dotrans = (*src != '/'); // if the output filename is implicitly first, append the out parameter if (output_is_first) { dst += sprintf(dst, "%s", outstring); output_is_first = 0; } // now copy the rest of the string while (*src) { *dst++ = (dotrans && *src == '/') ? '\\' : *src; src++; } *dst++ = ' '; } } } // trim remaining spaces and NULL terminate while (dst > command_line && dst[-1] == ' ') dst--; *dst = 0; }
// TODO: VS2012 and up enable SSE2 instructions by default for x86 - we should make older versions consistent with this static void build_command_line(int argc, char *argv[]) { const translation_info *transtable; const char *executable; const char *outstring = ""; char *dst = command_line; int output_is_first = 0; int icl_compile = 0; int parampos = 2; int param; DWORD exe_version = 0; // if no parameters, show usage if (argc < 2) { fprintf(stderr, "Usage:\n vconv {gcc|ar|ld} [-icl] [param [...]]\n"); exit(0); } if (!strcmp(argv[2], "-icl")) { icl_compile = 1; parampos = 3; } // first parameter determines the type if (!strcmp(argv[1], "gcc")) { transtable = gcc_translate; if (!icl_compile) { executable = "cl.exe"; dst += sprintf(dst, "cl /nologo "); } else { executable = "icl.exe"; dst += sprintf(dst, "icl /nologo"); /* ICL 14.0 generates more warnings than MSVC, for now turn them off */ dst += sprintf(dst, " /Qwd9 "); /* remark #9: nested comment is not allowed */ dst += sprintf(dst, " /Qwd82 "); /* remark #82: storage class is not first */ dst += sprintf(dst, " /Qwd111 "); /* remark #111: statement is unreachable */ dst += sprintf(dst, " /Qwd128 "); /* remark #128: loop is not reachable */ dst += sprintf(dst, " /Qwd177 "); /* remark #177: function "xxx" was declared but never referenced */ dst += sprintf(dst, " /Qwd181 "); /* remark #181: argument of type "UINT32={unsigned int}" is incompatible with format "%d", expecting argument of type "int" */ dst += sprintf(dst, " /Qwd185 "); /* remark #185: dynamic initialization in unreachable code */ dst += sprintf(dst, " /Qwd280 "); /* remark #280: selector expression is constant */ dst += sprintf(dst, " /Qwd344 "); /* remark #344: typedef name has already been declared (with same type) */ dst += sprintf(dst, " /Qwd411 "); /* remark #411: class "xxx" defines no constructor to initialize the following */ dst += sprintf(dst, " /Qwd869 "); /* remark #869: parameter "xxx" was never referenced */ dst += sprintf(dst, " /Qwd2545 "); /* remark #2545: empty dependent statement in "else" clause of if - statement */ dst += sprintf(dst, " /Qwd2553 "); /* remark #2553: nonstandard second parameter "TCHAR={WCHAR = { __wchar_t } } **" of "main", expected "char *[]" or "char **" extern "C" int _tmain(int argc, TCHAR **argv) */ dst += sprintf(dst, " /Qwd2557 "); /* remark #2557: comparison between signed and unsigned operands */ dst += sprintf(dst, " /Qwd3280 "); /* remark #3280: declaration hides member "attotime::seconds" (declared at line 126) static attotime from_seconds(INT32 seconds) { return attotime(seconds, 0); } */ dst += sprintf(dst, " /Qwd170 "); /* error #170: pointer points outside of underlying object */ dst += sprintf(dst, " /Qwd188 "); /* error #188: enumerated type mixed with another type */ dst += sprintf(dst, " /Qwd63 "); /* warning #63: shift count is too large */ dst += sprintf(dst, " /Qwd177 "); /* warning #177: label "xxx" was declared but never referenced */ dst += sprintf(dst, " /Qwd186 "); /* warning #186: pointless comparison of unsigned integer with zero */ dst += sprintf(dst, " /Qwd488 "); /* warning #488: template parameter "_FunctionClass" is not used in declaring the parameter types of function template "device_delegate<_Signature>::device_delegate<_FunctionClass>(delegate<_Signature>: */ dst += sprintf(dst, " /Qwd1478 "); /* warning #1478: function "xxx" (declared at line yyy of "zzz") was declared deprecated */ dst += sprintf(dst, " /Qwd1879 "); /* warning #1879: unimplemented pragma ignored */ dst += sprintf(dst, " /Qwd3291 "); /* warning #3291: invalid narrowing conversion from "double" to "int" */ // icl: command line warning #10120: overriding '/O2' with '/Od' } } else if (!strcmp(argv[1], "windres")) { transtable = windres_translate; executable = "rc.exe"; dst += sprintf(dst, "rc "); } else if (!strcmp(argv[1], "ld")) { transtable = ld_translate; if (!icl_compile) { executable = "link.exe"; dst += sprintf(dst, "link /nologo /debug "); } else { executable = "xilink.exe"; dst += sprintf(dst, "xilink /nologo /debug "); } } else if (!strcmp(argv[1], "ar")) { transtable = ar_translate; if (!icl_compile) { executable = "link.exe"; dst += sprintf(dst, "link /lib /nologo "); outstring = "/out:"; output_is_first = 1; } else { executable = "xilink.exe"; dst += sprintf(dst, "xilink /lib /nologo "); outstring = "/out:"; output_is_first = 1; } } else { fprintf(stderr, "Error: unknown translation type '%s'\n", argv[1]); exit(-100); } // identify the version number of the EXE if (!icl_compile) exe_version = get_exe_version(executable); else exe_version = 0x00110000; // assume this for ICL // special cases if (!icl_compile && !strcmp(executable, "cl.exe")) { if (exe_version >= 0x00070000) dst += sprintf(dst, "/wd4025 "); // fixes -j compiles with VS2013 if (exe_version >= 0x000C0000) dst += sprintf(dst, "/FS "); } // iterate over parameters for (param = parampos; param < argc; param++) { const char *src = argv[param]; int firstchar = src[0]; int srclen = strlen(src); int matched = FALSE; int i; // find a match for (i = 0; !matched && transtable[i].gcc_option != NULL; i++) { const char *compare = transtable[i].gcc_option; const char *replace; int j; // check version number if (exe_version < transtable[i].vc_version) continue; // find a match for (j = 0; j < srclen; j++) if (src[j] != compare[j]) break; // if we hit an asterisk, we're ok if (compare[j] == '*') { // if this is the end of the parameter, use the next one if (src[j] == 0) src = argv[++param]; else src += j; // copy the replacement up to the asterisk replace = transtable[i].vc_option; while (*replace && *replace != '*') { if (*replace == '~') { dst += sprintf(dst, "%s", outstring); replace++; } else *dst++ = *replace++; } // if we have an asterisk in the replacement, copy the rest of the source if (*replace == '*') { int addquote = (strchr(src, ' ') != NULL); if (addquote) *dst++ = '"'; while (*src) { *dst++ = (*src == '/') ? '\\' : *src; src++; } if (addquote) *dst++ = '"'; // if there's stuff after the asterisk, copy that replace++; while (*replace) *dst++ = *replace++; } // append a final space *dst++ = ' '; matched = TRUE; } // if we hit the end, we're also ok else if (compare[j] == 0 && j == srclen) { // copy the replacement up to the tilde replace = transtable[i].vc_option; while (*replace && *replace != '~') *dst++ = *replace++; // if we hit a tilde, set the new output if (*replace == '~') outstring = replace + 1; // append a final space *dst++ = ' '; matched = TRUE; } // else keep looking } // if we didn't match, process if (!matched) { // warn if we missed a parameter if (transtable[i].gcc_option == NULL && firstchar == '-') fprintf(stderr, "Unable to match parameter '%s'\n", src); // otherwise, assume it's a filename and copy translating slashes // it can also be a Windows-specific option which is passed through unscathed else if (firstchar != '-') { int dotrans = (*src != '/'); // if the output filename is implicitly first, append the out parameter if (output_is_first) { dst += sprintf(dst, "%s", outstring); output_is_first = 0; } // now copy the rest of the string while (*src) { *dst++ = (dotrans && *src == '/') ? '\\' : *src; src++; } *dst++ = ' '; } } } // trim remaining spaces and NULL terminate while (dst > command_line && dst[-1] == ' ') dst--; *dst = 0; }