Generate warnings for Preferences files
[WebKit-https.git] / Source / WebKit / Scripts / GeneratePreferences.rb
1 #!/usr/bin/env ruby
2 #
3 # Copyright (c) 2017 Apple Inc. 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 APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24 # THE POSSIBILITY OF SUCH DAMAGE.
25
26 require "fileutils"
27 require 'erb'
28 require 'optparse'
29 require 'yaml'
30
31 options = {
32   :input => nil,
33   :outputDirectory => nil
34 }
35 optparse = OptionParser.new do |opts|
36     opts.banner = "Usage: #{File.basename($0)} --input file"
37
38     opts.separator ""
39
40     opts.on("--input input", "file to generate settings from") { |input| options[:input] = input }
41     opts.on("--outputDir output", "directory to generate file in") { |output| options[:outputDirectory] = output }
42 end
43
44 optparse.parse!
45
46 if !options[:input]
47   puts optparse
48   exit -1
49 end
50
51 if !options[:outputDirectory]
52   options[:outputDirectory] = Dir.getwd
53 end
54
55 FileUtils.mkdir_p(options[:outputDirectory])
56
57 parsedPreferences = begin
58   YAML.load_file(options[:input])
59 rescue ArgumentError => e
60   puts "Could not parse input file: #{e.message}"
61   exit(-1)
62 end
63
64 class Preference
65   attr_accessor :name
66   attr_accessor :type
67   attr_accessor :defaultValue
68   attr_accessor :humanReadableName
69   attr_accessor :humanReadableDescription
70   attr_accessor :category
71   attr_accessor :webcoreBinding
72   attr_accessor :condition
73   attr_accessor :hidden
74
75   def initialize(name, opts)
76     @name = name
77     @type = opts["type"]
78     @defaultValue = opts["defaultValue"]
79     @humanReadableName = '"' + (opts["humanReadableName"] || "") + '"'
80     @humanReadableDescription = '"' + (opts["humanReadableDescription"] || "") + '"'
81     @category = opts["category"]
82     @getter = opts["getter"]
83     @webcoreBinding = opts["webcoreBinding"]
84     @webcoreName = opts["webcoreName"]
85     @condition = opts["condition"]
86     @hidden = opts["hidden"] || false
87   end
88
89   def nameLower
90     if @getter
91       @getter
92     elsif @name.start_with?("CSS", "XSS", "FTP", "DOM", "DNS", "PDF", "ICE")
93       @name[0..2].downcase + @name[3..@name.length]
94     elsif @name.start_with?("HTTP")
95       @name[0..3].downcase + @name[4..@name.length]
96     else
97       @name[0].downcase + @name[1..@name.length]
98     end
99   end
100
101   def webcoreNameUpper
102     if @webcoreName
103       @webcoreName[0].upcase + @webcoreName[1..@webcoreName.length]
104     else
105       @name
106     end
107   end
108
109   def typeUpper
110     if @type == "uint32_t"
111       "UInt32"
112     else
113       @type.capitalize
114     end
115   end
116
117 end
118
119 class Conditional
120   attr_accessor :condition
121   attr_accessor :preferences
122
123   def initialize(condition, settings)
124     @condition = condition
125     @preferences = preferences
126   end
127 end
128
129 class Preferences
130   attr_accessor :preferences
131
132   def initialize(hash, outputDirectory)
133     @outputDirectory = outputDirectory
134
135     @preferences = []
136     hash.each do |name, options|
137       @preferences << Preference.new(name, options)
138     end
139     @preferences.sort! { |x, y| x.name <=> y.name }
140
141     @preferencesNotDebug = @preferences.select { |p| !p.category }
142     @preferencesDebug = @preferences.select { |p| p.category == "debug" }
143     @experimentalFeatures = @preferences.select { |p| p.category == "experimental" }
144     @internalDebugFeatures = @preferences.select { |p| p.category == "internal" }
145
146     @preferencesBoundToSetting = @preferences.select { |p| !p.webcoreBinding }
147     @preferencesBoundToDeprecatedGlobalSettings = @preferences.select { |p| p.webcoreBinding == "DeprecatedGlobalSettings" }
148     @preferencesBoundToRuntimeEnabledFeatures = @preferences.select { |p| p.webcoreBinding == "RuntimeEnabledFeatures" }
149
150     @warning = "THIS FILE WAS AUTOMATICALLY GENERATED, DO NOT EDIT."
151   end
152
153   def renderTemplate(template)
154     templateFile = File.join(File.dirname(__FILE__), "PreferencesTemplates", template + ".erb")
155
156     output = ERB.new(File.read(templateFile), 0, "-").result(binding)
157     File.open(File.join(@outputDirectory, template), "w+") do |f|
158       f.write(output)
159     end
160   end
161 end
162
163 preferences = Preferences.new(parsedPreferences, options[:outputDirectory])
164 preferences.renderTemplate("WebPreferencesDefinitions.h")
165 preferences.renderTemplate("WebPageUpdatePreferences.cpp")
166 preferences.renderTemplate("WebPreferencesKeys.h")
167 preferences.renderTemplate("WebPreferencesKeys.cpp")
168 preferences.renderTemplate("WebPreferencesStoreDefaultsMap.cpp")
169 preferences.renderTemplate("WebPreferencesInternalDebugFeatures.cpp")
170 preferences.renderTemplate("WebPreferencesExperimentalFeatures.cpp")