chris
[tamarin-stm.git] / utils / apivergen.as
blob54888ddb544eb580f845338946874e95d04460e8
1 /* -*- Mode: Java; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
2 /* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
3 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
16 * The Original Code is [Open Source Virtual Machine.].
18 * The Initial Developer of the Original Code is
19 * Adobe System Incorporated.
20 * Portions created by the Initial Developer are Copyright (C) 2009
21 * the Initial Developer. All Rights Reserved.
23 * Contributor(s):
24 * Adobe AS3 Team
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 /* Usage:
42 * avmshell apivergen.abc -- ... api-versions.xml
44 * All arguments except the last are ignored.
46 package apivergen
48 import avmplus.*;
50 var DO_NOT_EDIT =
51 "/* DO NOT EDIT THIS FILE! It was generated by utils/apivergen.abc. */\n\n";
53 var LICENSE_BLOCK =
54 "/* ***** BEGIN LICENSE BLOCK *****\n" +
55 " * Version: MPL 1.1/GPL 2.0/LGPL 2.1\n" +
56 " *\n" +
57 " * The contents of this file are subject to the Mozilla Public License Version\n" +
58 " * 1.1 (the \"License+\"); you may not use this file except in compliance with\n" +
59 " * the License. You may obtain a copy of the License at\n" +
60 " * http://www.mozilla.org/MPL/\n" +
61 " *\n" +
62 " * Software distributed under the License is distributed on an \"AS IS\" basis,\n" +
63 " * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\n" +
64 " * for the specific language governing rights and limitations under the\n" +
65 " * License.\n" +
66 " *\n" +
67 " * The Original Code is [Open Source Virtual Machine].\n" +
68 " *\n" +
69 " * The Initial Developer of the Original Code is\n" +
70 " * Adobe System Incorporated.\n" +
71 " * Portions created by the Initial Developer are Copyright (C) 2008\n" +
72 " * the Initial Developer. All Rights Reserved.\n" +
73 " *\n" +
74 " * Contributor(s):\n" +
75 " * Adobe AS3 Team\n" +
76 " *\n" +
77 " * Alternatively, the contents of this file may be used under the terms of\n" +
78 " * either the GNU General Public License Version 2 or later (the \"GPL+\"), or\n" +
79 " * the GNU Lesser General Public License Version 2.1 or later (the \"LGPL\"),\n" +
80 " * in which case the provisions of the GPL or the LGPL are applicable instead\n" +
81 " * of those above. If you wish to allow use of your version of this file only\n" +
82 " * under the terms of either the GPL or the LGPL, and not to allow others to\n" +
83 " * use your version of this file under the terms of the MPL, indicate your\n" +
84 " * decision by deleting the provisions above and replace them with the notice\n" +
85 " * and other provisions required by the GPL or the LGPL. If you do not delete\n" +
86 " * the provisions above, a recipient may use your version of this file under\n" +
87 " * the terms of any one of the MPL, the GPL or the LGPL.\n" +
88 " *\n" +
89 " * ***** END LICENSE BLOCK ***** */\n" +
90 "\n";
92 /**
93 * find the coordinates of a value in an n-dim matrix
95 * v = value to look for
96 * m = array of array of ... of value
97 * dim = dimensionality of m
100 function find(v, m, dim)
102 if (dim == 0)
103 return m == v ? [] : null;
104 for ( var i=0 ; i < m.length ; i++ ) {
105 var probe = find(v, m[i], dim-1);
106 if (probe) {
107 probe.unshift(i);
108 return probe;
111 return null;
115 * emit the values in positions outside of a given position
116 * in an n-dim matrix
118 * m = array of array of ... of value
119 * coord = array of int
120 * dim = dimensionality of m; length of coord
121 * f = function to call on each value
124 function gen(m, coord, dim, f): void
126 if (dim == 0) {
127 f(m);
128 return;
130 for (var i=coord[coord.length-dim] ; i < m.length ; i++)
131 gen(m[i], coord, dim-1, f);
134 function process (fname) {
135 var api = new XML (File.read (fname));
136 var versions = api.versions;
137 var uris = api.uris;
138 var releases = versions..release;
139 var products = releases[releases.length()-1]..product;
140 var profiles = products[products.length()-1]..profile;
141 var release_ids = [];
142 var product_ids = [];
143 var profile_ids = [];
144 for each (var v in releases) {
145 release_ids.push(v.@id);
148 for each (var v in products) {
149 product_ids.push(v.@id);
152 for each (var v in profiles) {
153 profile_ids.push(v.@id);
156 var default_version = -1; // default
158 // build the compatiblity matrix (emitting a comment on which
159 // versions are which)
161 var frag = {};
162 var out = DO_NOT_EDIT + LICENSE_BLOCK;
163 var d1 = [];
164 var min_version = Number.MAX_VALUE;
165 var max_version = 0;
166 var maximalNonSys = 0;
167 var config_names = [];
168 out += "/*\n";
169 for each (var release_id in release_ids) {
170 var d2 = [];
171 d1.push(d2);
172 var release = versions.release.(@id == release_id);
173 default_version = release.version==void 0 ? default_version : release.version.@id;
174 for each (var product_id in product_ids) {
175 var d3 = [];
176 d2.push(d3);
177 var product = release.product.(@id == product_id);
178 var default_version = product.version==void 0 ? default_version : product.version.@id;
179 for each (var profile_id in profile_ids) {
180 var profile = product.profile.(@id == profile_id);
181 var version = profile.version==void 0 ? default_version : profile.version.@id;
182 if(version >= 0) {
183 out += "["+release_id+","+product_id+","+profile_id+"]="+version+":"+profile.version.@alias+"\n";
184 if (!String(profile.version.@alias).match(/_SYS$/))
185 maximalNonSys = Math.max(maximalNonSys, parseInt(String(version)));
186 config_names.push({name: String(profile.version.@alias), value: version});
188 d3.push(version);
189 if (version > max_version) {
190 max_version = version;
192 if (version >=0 && version < min_version) {
193 min_version = version;
198 out += "*/\n\n";
199 frag.documentation = out;
200 out = "";
201 frag.maximalNonSys = String(maximalNonSys) + ";\n";
202 frag.config_names = config_names;
204 // emit the array of versions_count array
205 var version_count;
206 out += "[] = {";
207 for (var v = min_version; v <= max_version; ++v) {
208 version_count = 0;
209 gen(d1,find(v,d1,3),3, function (x) { if(x>=0) version_count += 1 });
210 out += version_count + ", ";
212 out += "};\n\n";
213 frag.versions_count = out;
214 out = "";
216 // emit the versions matrix
217 frag.versions = "["+(Number(max_version)-Number(min_version)+1)+"]";
218 out += "{\n";
219 for (var v = min_version; v <= max_version; ++v) {
220 out += " {";
221 gen(d1,find(v,d1,3),3, function (x) { if(x>=0) out += x + ", " });
222 out += "},\n";
224 out += "};\n";
225 frag.versions_initializer = out;
227 frag.uris_count = "" + uris.uri.length() + ";\n";
228 out = "{\n";
229 for each (var v in uris.uri) {
230 out += " \"" + v.@id + "\",\n";
232 out += "};\n";
233 frag.uris = out;
234 frag.min_version_num = min_version + ";\n";
235 frag.max_version_num = max_version + ";\n";
237 out = "{";
238 for (var v = min_version; v <= max_version; ++v) {
239 var api = 0;
240 gen(d1,find(v,d1,3),3, function (x) { if(x>=0) api |= 0x1 << x-min_version });
241 out += "0x" + api.toString(16) + ", ";
243 out += "};\n";
244 frag.api_compat_initializer = out;
246 return frag;
250 emit c code
253 function emitc(frag) {
254 var out = frag.documentation;
255 out += "static const uint32_t _min_version_num = " + frag.min_version_num;
256 out += "static const uint32_t _max_version_num = " + frag.max_version_num;
257 out += "static const uint32_t _versions_count" + frag.versions_count;
258 out += "static const uint32_t _versions []" + frag.versions;
259 out += " = " + frag.versions_initializer;
260 out += "static const uint32_t _uris_count = " + frag.uris_count;
261 out += "static const char* _uris [] = " + frag.uris;
262 out += "static const int32_t _api_compat [] = " + frag.api_compat_initializer;
263 out += "static const uint32_t _max_nonsys_version_num = " + frag.maximalNonSys;
264 return out;
268 emit java
271 function emitj(frag) {
272 var out = frag.documentation;
273 out += "package macromedia.asc.util;\n";
274 out += "public class APIVersions {\n";
275 out += "public static int min_version_num = " + frag.min_version_num;
276 out += "public static int max_version_num = " + frag.max_version_num;
277 out += "public static int versions [][]";
278 out += " = " + frag.versions_initializer;
279 out += "public static String uris [] = " + frag.uris;
280 out += "public static int api_compat [] = " + frag.api_compat_initializer;
281 out += "};\n";
282 return out;
286 emit actionscript
288 function emitas(frag) {
289 var out = DO_NOT_EDIT + LICENSE_BLOCK;
290 var c = frag.config_names;
291 for ( var i=0 ; i < c.length ; i++ )
292 out += "CONFIG const " + c[i].name + " = " + c[i].value + ";\n";
293 return out;
297 get file name from the command-line and go. ignore all but the last
298 argument, which is treated as the file name
301 var argv = System.argv;
302 var fname = argv[argv.length-1];
303 var frags = process(fname);
304 File.write("api-versions.h", emitc(frags));
305 File.write("api-versions.java", emitj(frags));
306 File.write("api-versions.as", emitas(frags));