1/*
2 * Copyright (C) 2013 University of Szeged. All rights reserved.
3 * Copyright (C) 2013 Samsung Electronics. All rights reserved.
4 * Copyright (C) 2015-2018 Apple Inc. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY UNIVERSITY OF SZEGED ``AS IS'' AND ANY
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF SZEGED OR
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include "config.h"
29#include "Options.h"
30
31#include <string.h>
32
33namespace WTR {
34
35static bool handleOptionNoTimeout(Options& options, const char*, const char*)
36{
37 options.useWaitToDumpWatchdogTimer = false;
38 options.forceNoTimeout = true;
39 return true;
40}
41
42static bool handleOptionVerbose(Options& options, const char*, const char*)
43{
44 options.verbose = true;
45 return true;
46}
47
48static bool handleOptionGcBetweenTests(Options& options, const char*, const char*)
49{
50 options.gcBetweenTests = true;
51 return true;
52}
53
54static bool handleOptionPixelTests(Options& options, const char*, const char*)
55{
56 options.shouldDumpPixelsForAllTests = true;
57 return true;
58}
59
60static bool handleOptionPrintSupportedFeatures(Options& options, const char*, const char*)
61{
62 options.printSupportedFeatures = true;
63 return true;
64}
65
66static bool handleOptionComplexText(Options& options, const char*, const char*)
67{
68 options.forceComplexText = true;
69 return true;
70}
71
72static bool handleOptionAcceleratedDrawing(Options& options, const char*, const char*)
73{
74 options.shouldUseAcceleratedDrawing = true;
75 return true;
76}
77
78static bool handleOptionRemoteLayerTree(Options& options, const char*, const char*)
79{
80 options.shouldUseRemoteLayerTree = true;
81 return true;
82}
83
84static bool handleOptionShowWebView(Options& options, const char*, const char*)
85{
86 options.shouldShowWebView = true;
87 return true;
88}
89
90static bool handleOptionShowTouches(Options& options, const char*, const char*)
91{
92 options.shouldShowTouches = true;
93 return true;
94}
95
96static bool handleOptionCheckForWorldLeaks(Options& options, const char*, const char*)
97{
98 options.checkForWorldLeaks = true;
99 return true;
100}
101
102static bool handleOptionAllowAnyHTTPSCertificateForAllowedHosts(Options& options, const char*, const char*)
103{
104 options.allowAnyHTTPSCertificateForAllowedHosts = true;
105 return true;
106}
107
108static bool handleOptionAllowedHost(Options& options, const char*, const char* host)
109{
110 options.allowedHosts.insert(host);
111 return true;
112}
113
114static bool handleOptionUnmatched(Options& options, const char* option, const char*)
115{
116 if (option[0] && option[1] && option[0] == '-' && option[1] == '-')
117 return true;
118 options.paths.push_back(option);
119 return true;
120}
121
122OptionsHandler::OptionsHandler(Options& o)
123 : options(o)
124{
125 optionList.append(Option("--no-timeout", "Disables all timeouts.", handleOptionNoTimeout));
126 optionList.append(Option("--verbose", "Turns on messages.", handleOptionVerbose));
127 optionList.append(Option("--gc-between-tests", "Garbage collection between tests.", handleOptionGcBetweenTests));
128 optionList.append(Option("--pixel-tests", "Check pixels.", handleOptionPixelTests));
129 optionList.append(Option("-p", "Check pixels.", handleOptionPixelTests));
130 optionList.append(Option("--print-supported-features", "For DumpRenderTree compatibility.", handleOptionPrintSupportedFeatures));
131 optionList.append(Option("--complex-text", "Force complex tests.", handleOptionComplexText));
132 optionList.append(Option("--accelerated-drawing", "Use accelerated drawing.", handleOptionAcceleratedDrawing));
133 optionList.append(Option("--remote-layer-tree", "Use remote layer tree.", handleOptionRemoteLayerTree));
134 optionList.append(Option("--allowed-host", "Allows access to the specified host from tests.", handleOptionAllowedHost, true));
135 optionList.append(Option("--allow-any-certificate-for-allowed-hosts", "Allows any HTTPS certificate for an allowed host.", handleOptionAllowAnyHTTPSCertificateForAllowedHosts));
136 optionList.append(Option("--show-webview", "Show the WebView during test runs (for debugging)", handleOptionShowWebView));
137 optionList.append(Option("--show-touches", "Show the touches during test runs (for debugging)", handleOptionShowTouches));
138 optionList.append(Option("--world-leaks", "Check for leaks of world objects (currently, documents)", handleOptionCheckForWorldLeaks));
139
140 optionList.append(Option(0, 0, handleOptionUnmatched));
141}
142
143const char * OptionsHandler::usage = "Usage: WebKitTestRunner [options] filename [filename2..n]";
144const char * OptionsHandler::help = "Displays this help.";
145
146Option::Option(const char* name, const char* description, std::function<bool(Options&, const char*, const char*)> parameterHandler, bool hasArgument)
147 : name(name), description(description), parameterHandler(parameterHandler), hasArgument(hasArgument) { };
148
149bool Option::matches(const char* option)
150{
151 return !name || !strcmp(name, option);
152}
153
154bool OptionsHandler::parse(int argc, const char* argv[])
155{
156 bool status = true;
157 for (int argCounter = 1; argCounter < argc; ++argCounter) {
158 if (!strcmp(argv[argCounter], "--help") || !strcmp(argv[argCounter], "-h")) {
159 printHelp();
160 return false;
161 }
162 const char* currentOption = argv[argCounter];
163 for (Option& option : optionList) {
164 if (option.matches(currentOption)) {
165 if (!option.parameterHandler)
166 status = false;
167 else if (option.hasArgument) {
168 const char * currentArgument = argv[++argCounter];
169 if (currentArgument)
170 status &= option.parameterHandler(options, currentOption, currentArgument);
171 else
172 status = false;
173 } else
174 status &= option.parameterHandler(options, currentOption, 0);
175 break;
176 }
177 }
178 }
179 return status;
180}
181
182void OptionsHandler::printHelp(FILE* channel)
183{
184 fputs(usage, channel);
185 fputs("\n\n -h|--help\n\t", channel);
186 fputs(help, channel);
187 fputs("\n\n", channel);
188 for (Option& option : optionList) {
189 if (!option.name)
190 continue;
191 fputs(" ", channel);
192 fputs(option.name, channel);
193 fputs((option.hasArgument ? " <param>\n\t" : "\n\t"), channel);
194 fputs(option.description, channel);
195 fputs("\n\n", channel);
196 }
197}
198
199} // namespace WTR
200