Esempio n. 1
0
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;
}
Esempio n. 2
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;
}