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