summaryrefslogtreecommitdiffstats
path: root/toolkit/xre/test/win/TestXREMakeCommandLineWin.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--toolkit/xre/test/win/TestXREMakeCommandLineWin.cpp266
1 files changed, 266 insertions, 0 deletions
diff --git a/toolkit/xre/test/win/TestXREMakeCommandLineWin.cpp b/toolkit/xre/test/win/TestXREMakeCommandLineWin.cpp
new file mode 100644
index 0000000000..c12550c3d6
--- /dev/null
+++ b/toolkit/xre/test/win/TestXREMakeCommandLineWin.cpp
@@ -0,0 +1,266 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <windows.h>
+// Support for _setmode
+#include <fcntl.h>
+#include <io.h>
+
+#include "nsWindowsRestart.cpp"
+
+// CommandLineToArgvW may return different values for argv[0] since it contains
+// the path to the binary that was executed so we prepend an argument that is
+// quoted with a space to prevent argv[1] being appended to argv[0].
+#define DUMMY_ARG1 L"\"arg 1\" "
+
+#ifndef MAXPATHLEN
+# ifdef PATH_MAX
+# define MAXPATHLEN PATH_MAX
+# elif defined(MAX_PATH)
+# define MAXPATHLEN MAX_PATH
+# elif defined(_MAX_PATH)
+# define MAXPATHLEN _MAX_PATH
+# elif defined(CCHMAXPATH)
+# define MAXPATHLEN CCHMAXPATH
+# else
+# define MAXPATHLEN 1024
+# endif
+#endif
+
+#define TEST_NAME L"XRE MakeCommandLine"
+#define MAX_TESTS 100
+
+// Verbose output can be enabled by defining VERBOSE 1
+#define VERBOSE 0
+
+// Compares compareCmdLine with the output of MakeCommandLine. This is
+// accomplished by converting inCmdLine to an argument list with
+// CommandLineToArgvW and converting it back to a command line with
+// MakeCommandLine.
+static int verifyCmdLineCreation(wchar_t* inCmdLine, wchar_t* compareCmdLine,
+ bool passes, int testNum) {
+ int rv = 0;
+ int i;
+ int inArgc;
+ int outArgc;
+ bool isEqual;
+
+ // When debugging with command lines containing Unicode characters greater
+ // than 255 you can set the mode for stdout to Unicode so the console will
+ // receive the correct characters though it won't display them properly unless
+ // the console's font has been set to one that can display the characters. You
+ // can also redirect the console output to a file that has been saved as
+ // Unicode to view the characters.
+ // _setmode(_fileno(stdout), _O_WTEXT);
+
+ // Prepend an additional argument to the command line. CommandLineToArgvW
+ // handles argv[0] differently than other arguments since argv[0] is the path
+ // to the binary being executed and MakeCommandLine only handles argv[1] and
+ // larger.
+ wchar_t* inCmdLineNew = (wchar_t*)malloc(
+ (wcslen(DUMMY_ARG1) + wcslen(inCmdLine) + 1) * sizeof(wchar_t));
+ wcscpy(inCmdLineNew, DUMMY_ARG1);
+ wcscat(inCmdLineNew, inCmdLine);
+ LPWSTR* inArgv = CommandLineToArgvW(inCmdLineNew, &inArgc);
+
+ auto outCmdLine = mozilla::MakeCommandLine(inArgc - 1, inArgv + 1);
+ wchar_t* outCmdLineNew = (wchar_t*)malloc(
+ (wcslen(DUMMY_ARG1) + wcslen(outCmdLine.get()) + 1) * sizeof(wchar_t));
+ wcscpy(outCmdLineNew, DUMMY_ARG1);
+ wcscat(outCmdLineNew, outCmdLine.get());
+ LPWSTR* outArgv = CommandLineToArgvW(outCmdLineNew, &outArgc);
+
+ if (VERBOSE) {
+ wprintf(L"\n");
+ wprintf(L"Verbose Output\n");
+ wprintf(L"--------------\n");
+ wprintf(L"Input command line : >%s<\n", inCmdLine);
+ wprintf(L"MakeComandLine output: >%s<\n", outCmdLine.get());
+ wprintf(L"Expected command line: >%s<\n", compareCmdLine);
+
+ wprintf(L"input argc : %d\n", inArgc - 1);
+ wprintf(L"output argc: %d\n", outArgc - 1);
+
+ for (i = 1; i < inArgc; ++i) {
+ wprintf(L"input argv[%d] : >%s<\n", i - 1, inArgv[i]);
+ }
+
+ for (i = 1; i < outArgc; ++i) {
+ wprintf(L"output argv[%d]: >%s<\n", i - 1, outArgv[i]);
+ }
+ wprintf(L"\n");
+ }
+
+ isEqual = (inArgc == outArgc);
+ if (!isEqual) {
+ wprintf(L"TEST-%s-FAIL | %s | ARGC Comparison (check %2d)\n",
+ passes ? L"UNEXPECTED" : L"KNOWN", TEST_NAME, testNum);
+ if (passes) {
+ rv = 1;
+ }
+ LocalFree(inArgv);
+ LocalFree(outArgv);
+ free(inCmdLineNew);
+ free(outCmdLineNew);
+ return rv;
+ }
+
+ for (i = 1; i < inArgc; ++i) {
+ isEqual = (wcscmp(inArgv[i], outArgv[i]) == 0);
+ if (!isEqual) {
+ wprintf(L"TEST-%s-FAIL | %s | ARGV Comparison (check %2d)\n",
+ passes ? L"UNEXPECTED" : L"KNOWN", TEST_NAME, testNum);
+ if (passes) {
+ rv = 1;
+ }
+ LocalFree(inArgv);
+ LocalFree(outArgv);
+ free(inCmdLineNew);
+ free(outCmdLineNew);
+ return rv;
+ }
+ }
+
+ isEqual = (wcscmp(outCmdLine.get(), compareCmdLine) == 0);
+ if (!isEqual) {
+ wprintf(L"TEST-%s-FAIL | %s | Command Line Comparison (check %2d)\n",
+ passes ? L"UNEXPECTED" : L"KNOWN", TEST_NAME, testNum);
+ if (passes) {
+ rv = 1;
+ }
+ LocalFree(inArgv);
+ LocalFree(outArgv);
+ free(inCmdLineNew);
+ free(outCmdLineNew);
+ return rv;
+ }
+
+ if (rv == 0) {
+ if (passes) {
+ wprintf(L"TEST-PASS | %s | check %2d\n", TEST_NAME, testNum);
+ } else {
+ wprintf(L"TEST-UNEXPECTED-PASS | %s | check %2d\n", TEST_NAME, testNum);
+ rv = 1;
+ }
+ }
+
+ LocalFree(inArgv);
+ LocalFree(outArgv);
+ free(inCmdLineNew);
+ free(outCmdLineNew);
+ return rv;
+}
+
+int wmain(int argc, wchar_t* argv[]) {
+ int i;
+ int rv = 0;
+
+ if (argc > 1 && (_wcsicmp(argv[1], L"-check-one") != 0 || argc != 3)) {
+ fwprintf(stderr,
+ L"Displays and validates output from MakeCommandLine.\n\n");
+ fwprintf(stderr, L"Usage: %s -check-one <test number>\n\n", argv[0]);
+ fwprintf(stderr,
+ L" <test number>\tSpecifies the test number to run from the\n");
+ fwprintf(stderr, L"\t\tTestXREMakeCommandLineWin.ini file.\n");
+ return 255;
+ }
+
+ wchar_t inifile[MAXPATHLEN];
+ if (!::GetModuleFileNameW(0, inifile, MAXPATHLEN)) {
+ wprintf(L"TEST-UNEXPECTED-FAIL | %s | GetModuleFileNameW\n", TEST_NAME);
+ return 2;
+ }
+
+ WCHAR* slash = wcsrchr(inifile, '\\');
+ if (!slash) {
+ wprintf(L"TEST-UNEXPECTED-FAIL | %s | wcsrchr\n", TEST_NAME);
+ return 3;
+ }
+
+ wcscpy(slash + 1, L"TestXREMakeCommandLineWin.ini\0");
+
+ for (i = 0; i < MAX_TESTS; ++i) {
+ wchar_t sInputVal[MAXPATHLEN];
+ wchar_t sOutputVal[MAXPATHLEN];
+ wchar_t sPassesVal[MAXPATHLEN];
+ wchar_t sInputKey[MAXPATHLEN];
+ wchar_t sOutputKey[MAXPATHLEN];
+ wchar_t sPassesKey[MAXPATHLEN];
+
+ if (argc > 2 && _wcsicmp(argv[1], L"-check-one") == 0 && argc == 3) {
+ i = _wtoi(argv[2]);
+ }
+
+ _snwprintf(sInputKey, MAXPATHLEN, L"input_%d", i);
+ _snwprintf(sOutputKey, MAXPATHLEN, L"output_%d", i);
+ _snwprintf(sPassesKey, MAXPATHLEN, L"passes_%d", i);
+
+ if (!GetPrivateProfileStringW(L"MakeCommandLineTests", sInputKey, nullptr,
+ sInputVal, MAXPATHLEN, inifile)) {
+ if (i == 0 || (argc > 2 && _wcsicmp(argv[1], L"-check-one") == 0)) {
+ wprintf(L"TEST-UNEXPECTED-FAIL | %s | see following explanation:\n",
+ TEST_NAME);
+ wprintf(
+ L"ERROR: Either the TestXREMakeCommandLineWin.ini file doesn't "
+ L"exist\n");
+ if (argc > 1 && _wcsicmp(argv[1], L"-check-one") == 0 && argc == 3) {
+ wprintf(
+ L"ERROR: or the test is not defined in the MakeCommandLineTests "
+ L"section.\n");
+ } else {
+ wprintf(
+ L"ERROR: or it has no tests defined in the MakeCommandLineTests "
+ L"section.\n");
+ }
+ wprintf(L"ERROR: File: %s\n", inifile);
+ return 4;
+ }
+ break;
+ }
+
+ GetPrivateProfileStringW(L"MakeCommandLineTests", sOutputKey, nullptr,
+ sOutputVal, MAXPATHLEN, inifile);
+ GetPrivateProfileStringW(L"MakeCommandLineTests", sPassesKey, nullptr,
+ sPassesVal, MAXPATHLEN, inifile);
+
+ rv |= verifyCmdLineCreation(
+ sInputVal, sOutputVal,
+ (_wcsicmp(sPassesVal, L"false") == 0) ? FALSE : TRUE, i);
+
+ if (argc > 2 && _wcsicmp(argv[1], L"-check-one") == 0) {
+ break;
+ }
+ }
+
+ if (rv == 0) {
+ wprintf(L"TEST-PASS | %s | all checks passed\n", TEST_NAME);
+ } else {
+ wprintf(L"TEST-UNEXPECTED-FAIL | %s | some checks failed\n", TEST_NAME);
+ }
+
+ return rv;
+}
+
+#ifdef __MINGW32__
+
+/* MingW currently does not implement a wide version of the
+ startup routines. Workaround is to implement something like
+ it ourselves. See bug 411826 */
+
+# include <shellapi.h>
+
+int main(int argc, char** argv) {
+ LPWSTR commandLine = GetCommandLineW();
+ int argcw = 0;
+ LPWSTR* argvw = CommandLineToArgvW(commandLine, &argcw);
+ if (!argvw) return 127;
+
+ int result = wmain(argcw, argvw);
+ LocalFree(argvw);
+ return result;
+}
+#endif /* __MINGW32__ */