InFilesCompiler.pm 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. #!/usr/bin/perl -w
  2. # Copyright (C) 2011 Adam Barth <abarth@webkit.org>
  3. #
  4. # Redistribution and use in source and binary forms, with or without
  5. # modification, are permitted provided that the following conditions
  6. # are met:
  7. # 1. Redistributions of source code must retain the above copyright
  8. # notice, this list of conditions and the following disclaimer.
  9. # 2. Redistributions in binary form must reproduce the above copyright
  10. # notice, this list of conditions and the following disclaimer in the
  11. # documentation and/or other materials provided with the distribution.
  12. #
  13. # THIS SOFTWARE IS PROVIDED BY GOOGLE, INC. ``AS IS'' AND ANY
  14. # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15. # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
  17. # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  18. # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  19. # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  20. # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  21. # OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  23. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. #
  25. use strict;
  26. use Config;
  27. use Getopt::Long;
  28. use File::Path;
  29. use File::Spec;
  30. use IO::File;
  31. use InFilesParser;
  32. require Config;
  33. package InFilesCompiler;
  34. my $inputFile = "";
  35. my $outputDir = ".";
  36. my $defaultItemFactory;
  37. my %parsedItems;
  38. my %parsedParameters;
  39. sub itemHandler($$$)
  40. {
  41. my ($itemName, $property, $value) = @_;
  42. $parsedItems{$itemName} = { &$defaultItemFactory($itemName) } if !defined($parsedItems{$itemName});
  43. return unless $property;
  44. die "Unknown property $property for $itemName\n" if !defined($parsedItems{$itemName}{$property});
  45. $parsedItems{$itemName}{$property} = $value;
  46. }
  47. sub parameterHandler($$)
  48. {
  49. my ($parameter, $value) = @_;
  50. die "Unknown parameter $parameter\n" if !defined($parsedParameters{$parameter});
  51. $parsedParameters{$parameter} = $value;
  52. }
  53. sub new()
  54. {
  55. my $object = shift;
  56. my $reference = { };
  57. my $defaultParametersRef = shift;
  58. %parsedParameters = %{ $defaultParametersRef };
  59. $defaultItemFactory = shift;
  60. %parsedItems = ();
  61. bless($reference, $object);
  62. return $reference;
  63. }
  64. sub initializeFromCommandLine()
  65. {
  66. ::GetOptions(
  67. 'input=s' => \$inputFile,
  68. 'outputDir=s' => \$outputDir,
  69. );
  70. die "You must specify --input <file>" unless length($inputFile);
  71. ::mkpath($outputDir);
  72. # FIXME: Should we provide outputDir via an accessor?
  73. return $outputDir;
  74. }
  75. sub compile()
  76. {
  77. my $object = shift;
  78. my $generateCode = shift;
  79. my $file = new IO::File;
  80. open($file, $inputFile) or die "Failed to open file: $!";
  81. my $InParser = InFilesParser->new();
  82. $InParser->parse($file, \&parameterHandler, \&itemHandler);
  83. close($file);
  84. die "Failed to read from file: $inputFile" if (keys %parsedItems == 0);
  85. &$generateCode(\%parsedParameters, \%parsedItems);
  86. }
  87. sub license()
  88. {
  89. return "/*
  90. * THIS FILE WAS AUTOMATICALLY GENERATED, DO NOT EDIT.
  91. *
  92. * Copyright (C) 2011 Google Inc. All rights reserved.
  93. *
  94. * Redistribution and use in source and binary forms, with or without
  95. * modification, are permitted provided that the following conditions
  96. * are met:
  97. * 1. Redistributions of source code must retain the above copyright
  98. * notice, this list of conditions and the following disclaimer.
  99. * 2. Redistributions in binary form must reproduce the above copyright
  100. * notice, this list of conditions and the following disclaimer in the
  101. * documentation and/or other materials provided with the distribution.
  102. *
  103. * THIS SOFTWARE IS PROVIDED BY GOOGLE, INC. ``AS IS'' AND ANY
  104. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  105. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  106. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
  107. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  108. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  109. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  110. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  111. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  112. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  113. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  114. */
  115. ";
  116. }
  117. sub interfaceForItem($)
  118. {
  119. my $object = shift;
  120. my $itemName = shift;
  121. my $interfaceName = $parsedItems{$itemName}{"interfaceName"};
  122. $interfaceName = $itemName unless $interfaceName;
  123. return $interfaceName;
  124. }
  125. sub toMacroStyle($$)
  126. {
  127. my $object = shift;
  128. my $camelCase = shift;
  129. return "EVENT" if $camelCase eq "Event";
  130. return "EVENT_TARGET" if $camelCase eq "EventTarget";
  131. return "EXCEPTION" if $camelCase eq "Exception";
  132. die "Ok, you got me. This script is really just a giant hack. (\$camelCase=${camelCase})";
  133. }
  134. sub preferredConditional()
  135. {
  136. my $object = shift;
  137. my $conditional = shift;
  138. my @conditionals = split('\\|', $conditional);
  139. return $conditionals[0];
  140. }
  141. sub conditionalStringFromAttributeValue()
  142. {
  143. my $object = shift;
  144. my $conditional = shift;
  145. return "ENABLE(" . join(') || ENABLE(', split('\\|', $conditional)) . ")";
  146. }
  147. sub generateInterfacesHeader()
  148. {
  149. my $object = shift;
  150. my $F;
  151. my $namespace = $parsedParameters{"namespace"};
  152. my $outputFile = "$outputDir/${namespace}Interfaces.h";
  153. open F, ">$outputFile" or die "Failed to open file: $!";
  154. print F license();
  155. print F "#ifndef ${namespace}Interfaces_h\n";
  156. print F "#define ${namespace}Interfaces_h\n";
  157. print F "\n";
  158. my %unconditionalInterfaces = ();
  159. my %interfacesByConditional = ();
  160. for my $itemName (sort keys %parsedItems) {
  161. my $conditional = $parsedItems{$itemName}{"conditional"};
  162. my $interfaceName = $object->interfaceForItem($itemName);
  163. if ($conditional) {
  164. if (!defined($interfacesByConditional{$conditional})) {
  165. $interfacesByConditional{$conditional} = ();
  166. }
  167. $interfacesByConditional{$conditional}{$interfaceName} = 1;
  168. } else {
  169. $unconditionalInterfaces{$interfaceName} = 1
  170. }
  171. }
  172. my $macroStyledNamespace = $object->toMacroStyle($namespace);
  173. for my $conditional (sort keys %interfacesByConditional) {
  174. my $preferredConditional = $object->preferredConditional($conditional);
  175. print F "#if " . $object->conditionalStringFromAttributeValue($conditional) . "\n";
  176. print F "#define DOM_${macroStyledNamespace}_INTERFACES_FOR_EACH_$preferredConditional(macro) \\\n";
  177. for my $interface (sort keys %{ $interfacesByConditional{$conditional} }) {
  178. next if defined($unconditionalInterfaces{$interface});
  179. print F " macro($interface) \\\n";
  180. }
  181. print F "// End of DOM_${macroStyledNamespace}_INTERFACES_FOR_EACH_$preferredConditional\n";
  182. print F "#else\n";
  183. print F "#define DOM_${macroStyledNamespace}_INTERFACES_FOR_EACH_$preferredConditional(macro)\n";
  184. print F "#endif\n";
  185. print F "\n";
  186. }
  187. print F "#define DOM_${macroStyledNamespace}_INTERFACES_FOR_EACH(macro) \\\n";
  188. print F " \\\n";
  189. for my $interface (sort keys %unconditionalInterfaces) {
  190. print F " macro($interface) \\\n";
  191. }
  192. print F " \\\n";
  193. for my $conditional (sort keys %interfacesByConditional) {
  194. my $preferredConditional = $object->preferredConditional($conditional);
  195. print F " DOM_${macroStyledNamespace}_INTERFACES_FOR_EACH_$preferredConditional(macro) \\\n";
  196. }
  197. print F "\n";
  198. print F "#endif // ${namespace}Interfaces_h\n";
  199. close F;
  200. }
  201. sub generateHeadersHeader()
  202. {
  203. my $object = shift;
  204. my $F;
  205. my $namespace = $parsedParameters{"namespace"};
  206. my $outputFile = "$outputDir/${namespace}Headers.h";
  207. open F, ">$outputFile" or die "Failed to open file: $!";
  208. print F license();
  209. print F "#ifndef ${namespace}Headers_h\n";
  210. print F "#define ${namespace}Headers_h\n";
  211. print F "\n";
  212. my %includedInterfaces = ();
  213. for my $itemName (sort keys %parsedItems) {
  214. my $conditional = $parsedItems{$itemName}{"conditional"};
  215. my $interfaceName = $object->interfaceForItem($itemName);
  216. next if defined($includedInterfaces{$interfaceName});
  217. $includedInterfaces{$interfaceName} = 1;
  218. print F "#if " . $object->conditionalStringFromAttributeValue($conditional) . "\n" if $conditional;
  219. print F "#include \"$interfaceName.h\"\n";
  220. print F "#include \"JS$interfaceName.h\"\n";
  221. print F "#endif\n" if $conditional;
  222. }
  223. print F "\n";
  224. print F "#endif // ${namespace}Headers_h\n";
  225. close F;
  226. }
  227. 1;