no message

This commit is contained in:
gem
2025-02-18 15:21:31 +08:00
commit 2d133e56d7
1980 changed files with 465595 additions and 0 deletions

View File

@@ -0,0 +1,96 @@
const fs = require('fs');
const path = require('path');
const pkgCfg = path.join(__dirname, '../../../package.json');
if (!fs.existsSync(pkgCfg)) {
console.error(`Can not find package.json: ${pkgCfg}`);
process.exit(1);
}
let pkgJson = {};
try {
pkgJson = JSON.parse(fs.readFileSync(pkgCfg, 'utf8'));
} catch (err) {
console.error(`Error parsing ${pkgCfg}`);
console.error(err);
process.exit(1);
}
if (!pkgJson.version) {
console.error(`Can not find field 'version' in file ${pkgCfg}`);
process.exit(1);
}
const version_regex = /(\d+)\.(\d+)(\.(\d+))?(-(\w+))?/;
const version_str = pkgJson.version;
const version_result = version_str.match(version_regex);
if (!version_result) {
console.error(`Failed to parse version string: '${version_str}'`);
process.exit(1);
}
const majorVersion = parseInt(version_result[1]);
const minorVersion = parseInt(version_result[2]);
const patchVersion = version_result[4] ? parseInt(version_result[4]) : 0;
const preRelease = version_result[6] ? version_result[6] : 'release';
const versionIntValue = majorVersion * 10000 + minorVersion * 100 + patchVersion;
const fullYear = (new Date).getFullYear();
const version_header = `/****************************************************************************
Copyright (c) ${fullYear <= 2022 ? "2022" : "2022-"+fullYear} Xiamen Yaji Software Co., Ltd.
http://www.cocos.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#pragma once
#define COCOS_MAJOR_VERSION ${majorVersion}
#define COCOS_MINJOR_VERSION ${minorVersion}
#define COCOS_PATCH_VERSION ${patchVersion}
#define COCOS_VERSION_STRING "${majorVersion}.${minorVersion}.${patchVersion}"
#define COCOS_VERSION_DEFINED 1
#define COCOS_VERSION ${versionIntValue}
// #define COCOS_PRE_RELEASE "${preRelease}"
`;
const outputVersionFile = path.join(__dirname, '../../cocos/cocos-version.h');
if(!fs.existsSync(outputVersionFile) || !compareFileContent(outputVersionFile, version_header)) {
console.log(`Update cocos-version.h to ${version_str}`);
fs.writeFileSync(outputVersionFile, version_header);
} else {
console.log(`cocos-version.h is up to date`);
}
function compareFileContent(file, content) {
const srcLines = fs.readFileSync(file, 'utf8').split('\n').map(x=>x.trim());
const dstLines = content.split('\n').map(x => x.trim());
if(srcLines.length !== dstLines.length) {
return false;
}
for(let i = 0, l = srcLines.length; i < l; i++) {
if(srcLines[i] != dstLines[i]) {
return false;
}
}
return true;
}

View File

@@ -0,0 +1,47 @@
const Fs = require('fs');
const process = require('process');
const writeIfDifferent = require('./utils').writeIfDifferent;
if (process.argv.length !== 5) {
console.error('bad argument');
console.error(' - input file');
console.error(' - template file');
console.error(' - output file');
process.exit(-1);
}
const inputFile = process.argv[2];
const template = process.argv[3];
const outputFile = process.argv[4];
let buildDebugInfos = function() {
let readContent = Fs.readFileSync(inputFile, 'utf-8');
let titleRegExp = /### \d+/g;
let debugInfos = "";
let result1 = titleRegExp.exec(readContent);
while (result1) {
let result2 = titleRegExp.exec(readContent);
let errInfoHead = result1.index + result1[0].length;
let errInfoTail = result2? result2.index: readContent.length;
let errCode = /\d+/.exec(result1[0])[0];
let errInfo = readContent.slice(errInfoHead, errInfoTail);
errInfo = errInfo.replace(/```/g, ' ');
errInfo = errInfo.trim();
errInfo = errInfo.replace(/\r\n/g, '\n');
if (!errInfo.includes('<!-- DEPRECATED -->')) {
errInfo = errInfo.replace(/\n/g, "\\n").replace(/\"/g, "'").replace(/\\`/g, "`");
debugInfos = debugInfos.concat("{ ", errCode, ", \"", errInfo, "\" },\n");
}
result1 = result2;
}
let replaceData = Fs.readFileSync(template).toString('utf-8').replace("${PLACE_HOLDER}", debugInfos);
writeIfDifferent(outputFile, replaceData, { encoding: 'utf-8' });
};
buildDebugInfos();
process.exit(0);

View File

@@ -0,0 +1,846 @@
/*
* Generated by PEG.js 0.10.0.
*
* http://pegjs.org/
*/
"use strict";
function peg$subclass(child, parent) {
function ctor() { this.constructor = child; }
ctor.prototype = parent.prototype;
child.prototype = new ctor();
}
function peg$SyntaxError(message, expected, found, location) {
this.message = message;
this.expected = expected;
this.found = found;
this.location = location;
this.name = "SyntaxError";
if (typeof Error.captureStackTrace === "function") {
Error.captureStackTrace(this, peg$SyntaxError);
}
}
peg$subclass(peg$SyntaxError, Error);
peg$SyntaxError.buildMessage = function(expected, found) {
var DESCRIBE_EXPECTATION_FNS = {
literal: function(expectation) {
return "\"" + literalEscape(expectation.text) + "\"";
},
"class": function(expectation) {
var escapedParts = "",
i;
for (i = 0; i < expectation.parts.length; i++) {
escapedParts += expectation.parts[i] instanceof Array
? classEscape(expectation.parts[i][0]) + "-" + classEscape(expectation.parts[i][1])
: classEscape(expectation.parts[i]);
}
return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]";
},
any: function(expectation) {
return "any character";
},
end: function(expectation) {
return "end of input";
},
other: function(expectation) {
return expectation.description;
}
};
function hex(ch) {
return ch.charCodeAt(0).toString(16).toUpperCase();
}
function literalEscape(s) {
return s
.replace(/\\/g, '\\\\')
.replace(/"/g, '\\"')
.replace(/\0/g, '\\0')
.replace(/\t/g, '\\t')
.replace(/\n/g, '\\n')
.replace(/\r/g, '\\r')
.replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
.replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); });
}
function classEscape(s) {
return s
.replace(/\\/g, '\\\\')
.replace(/\]/g, '\\]')
.replace(/\^/g, '\\^')
.replace(/-/g, '\\-')
.replace(/\0/g, '\\0')
.replace(/\t/g, '\\t')
.replace(/\n/g, '\\n')
.replace(/\r/g, '\\r')
.replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); })
.replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); });
}
function describeExpectation(expectation) {
return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation);
}
function describeExpected(expected) {
var descriptions = new Array(expected.length),
i, j;
for (i = 0; i < expected.length; i++) {
descriptions[i] = describeExpectation(expected[i]);
}
descriptions.sort();
if (descriptions.length > 0) {
for (i = 1, j = 1; i < descriptions.length; i++) {
if (descriptions[i - 1] !== descriptions[i]) {
descriptions[j] = descriptions[i];
j++;
}
}
descriptions.length = j;
}
switch (descriptions.length) {
case 1:
return descriptions[0];
case 2:
return descriptions[0] + " or " + descriptions[1];
default:
return descriptions.slice(0, -1).join(", ")
+ ", or "
+ descriptions[descriptions.length - 1];
}
}
function describeFound(found) {
return found ? "\"" + literalEscape(found) + "\"" : "end of input";
}
return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found.";
};
function peg$parse(input, options) {
options = options !== void 0 ? options : {};
var peg$FAILED = {},
peg$startRuleIndices = { Expression: 0 },
peg$startRuleIndex = 0,
peg$consts = [
"||",
peg$literalExpectation("||", false),
function(head, tail) {
let s = [head];
s = s.concat(tail.map(x=>x[1]));
return new VersionSet(s);
},
peg$otherExpectation("Condition Items"),
function(head, tail) {
let s = [head];
s = s.concat(tail.map(x=> x[1]));
return s;
},
function(head) {
return [head];
},
">=",
peg$literalExpectation(">=", false),
function(v) {
v.op = OP_GE;
return v;
},
"<=",
peg$literalExpectation("<=", false),
function(v) {
v.op = OP_LE;
return v;
},
"!=",
peg$literalExpectation("!=", false),
function(v) {
v.op = OP_NOT;
return v;
},
"!",
peg$literalExpectation("!", false),
"=",
peg$literalExpectation("=", false),
function(v) {
v.op = OP_EQ;
return v;
},
"<",
peg$literalExpectation("<", false),
function(v) {
v.op = OP_LT;
return v;
},
">",
peg$literalExpectation(">", false),
function(v) {
v.op = OP_GT;
return v;
},
function(head) {
head.op = OP_IS;
return head;
},
peg$otherExpectation("version"),
peg$otherExpectation("major.minor.patch"),
".",
peg$literalExpectation(".", false),
function(v, n) { v.patch = n; return v},
peg$otherExpectation("major.minor"),
function(v, n) {v.minor = n; return v},
peg$otherExpectation("major"),
function(n) {let v = new Version; v.major = n; return v},
"*",
peg$literalExpectation("*", false),
"x",
peg$literalExpectation("x", false),
"X",
peg$literalExpectation("X", false),
function() {return '*';},
peg$otherExpectation("integer"),
/^[0-9]/,
peg$classExpectation([["0", "9"]], false, false),
function() { return parseInt(text(), 10); },
peg$otherExpectation("whitespace"),
/^[ \t\n\r]/,
peg$classExpectation([" ", "\t", "\n", "\r"], false, false)
],
peg$bytecode = [
peg$decode("%;!/k#$%2 \"\"6 7!/,#;!/#$+\")(\"'#&'#0<*%2 \"\"6 7!/,#;!/#$+\")(\"'#&'#&/)$8\":\"\"\"! )(\"'#&'#"),
peg$decode("<%;*/w#;\"/n$$%;)/,#;\"/#$+\")(\"'#&'#/9#06*%;)/,#;\"/#$+\")(\"'#&'#&&&#/2$;*/)$8$:$$\"\"!)($'#(#'#(\"'#&'#.D &%;*/:#;\"/1$;*/($8#:%#!!)(#'#(\"'#&'#=.\" 7#"),
peg$decode("%2&\"\"6&7'/:#;*/1$;#/($8#:(#! )(#'#(\"'#&'#.\u013D &%2)\"\"6)7*/:#;*/1$;#/($8#:+#! )(#'#(\"'#&'#.\u0110 &%2,\"\"6,7-/:#;*/1$;#/($8#:.#! )(#'#(\"'#&'#.\xE3 &%2/\"\"6/70/:#;*/1$;#/($8#:.#! )(#'#(\"'#&'#.\xB6 &%21\"\"6172/:#;*/1$;#/($8#:3#! )(#'#(\"'#&'#.\x89 &%24\"\"6475/:#;*/1$;#/($8#:6#! )(#'#(\"'#&'#.\\ &%27\"\"6778/:#;*/1$;#/($8#:9#! )(#'#(\"'#&'#./ &%;#/' 8!::!! )"),
peg$decode("<;$.) &;%.# &;&=.\" 7;"),
peg$decode("<%;%/A#2=\"\"6=7>/2$;'/)$8#:?#\"\" )(#'#(\"'#&'#=.\" 7<"),
peg$decode("<%;&/A#2=\"\"6=7>/2$;'/)$8#:A#\"\" )(#'#(\"'#&'#=.\" 7@"),
peg$decode("<%;'/' 8!:C!! )=.\" 7B"),
peg$decode("%2D\"\"6D7E.5 &2F\"\"6F7G.) &2H\"\"6H7I/& 8!:J! ).# &;("),
peg$decode("<%$4L\"\"5!7M/,#0)*4L\"\"5!7M&&&#/& 8!:N! )=.\" 7K"),
peg$decode("<$4P\"\"5!7Q/,#0)*4P\"\"5!7Q&&&#=.\" 7O"),
peg$decode("<$4P\"\"5!7Q0)*4P\"\"5!7Q&=.\" 7O")
],
peg$currPos = 0,
peg$savedPos = 0,
peg$posDetailsCache = [{ line: 1, column: 1 }],
peg$maxFailPos = 0,
peg$maxFailExpected = [],
peg$silentFails = 0,
peg$result;
if ("startRule" in options) {
if (!(options.startRule in peg$startRuleIndices)) {
throw new Error("Can't start parsing from rule \"" + options.startRule + "\".");
}
peg$startRuleIndex = peg$startRuleIndices[options.startRule];
}
function text() {
return input.substring(peg$savedPos, peg$currPos);
}
function location() {
return peg$computeLocation(peg$savedPos, peg$currPos);
}
function expected(description, location) {
location = location !== void 0 ? location : peg$computeLocation(peg$savedPos, peg$currPos)
throw peg$buildStructuredError(
[peg$otherExpectation(description)],
input.substring(peg$savedPos, peg$currPos),
location
);
}
function error(message, location) {
location = location !== void 0 ? location : peg$computeLocation(peg$savedPos, peg$currPos)
throw peg$buildSimpleError(message, location);
}
function peg$literalExpectation(text, ignoreCase) {
return { type: "literal", text: text, ignoreCase: ignoreCase };
}
function peg$classExpectation(parts, inverted, ignoreCase) {
return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase };
}
function peg$anyExpectation() {
return { type: "any" };
}
function peg$endExpectation() {
return { type: "end" };
}
function peg$otherExpectation(description) {
return { type: "other", description: description };
}
function peg$computePosDetails(pos) {
var details = peg$posDetailsCache[pos], p;
if (details) {
return details;
} else {
p = pos - 1;
while (!peg$posDetailsCache[p]) {
p--;
}
details = peg$posDetailsCache[p];
details = {
line: details.line,
column: details.column
};
while (p < pos) {
if (input.charCodeAt(p) === 10) {
details.line++;
details.column = 1;
} else {
details.column++;
}
p++;
}
peg$posDetailsCache[pos] = details;
return details;
}
}
function peg$computeLocation(startPos, endPos) {
var startPosDetails = peg$computePosDetails(startPos),
endPosDetails = peg$computePosDetails(endPos);
return {
start: {
offset: startPos,
line: startPosDetails.line,
column: startPosDetails.column
},
end: {
offset: endPos,
line: endPosDetails.line,
column: endPosDetails.column
}
};
}
function peg$fail(expected) {
if (peg$currPos < peg$maxFailPos) { return; }
if (peg$currPos > peg$maxFailPos) {
peg$maxFailPos = peg$currPos;
peg$maxFailExpected = [];
}
peg$maxFailExpected.push(expected);
}
function peg$buildSimpleError(message, location) {
return new peg$SyntaxError(message, null, null, location);
}
function peg$buildStructuredError(expected, found, location) {
return new peg$SyntaxError(
peg$SyntaxError.buildMessage(expected, found),
expected,
found,
location
);
}
function peg$decode(s) {
var bc = new Array(s.length), i;
for (i = 0; i < s.length; i++) {
bc[i] = s.charCodeAt(i) - 32;
}
return bc;
}
function peg$parseRule(index) {
var bc = peg$bytecode[index],
ip = 0,
ips = [],
end = bc.length,
ends = [],
stack = [],
params, i;
while (true) {
while (ip < end) {
switch (bc[ip]) {
case 0:
stack.push(peg$consts[bc[ip + 1]]);
ip += 2;
break;
case 1:
stack.push(void 0);
ip++;
break;
case 2:
stack.push(null);
ip++;
break;
case 3:
stack.push(peg$FAILED);
ip++;
break;
case 4:
stack.push([]);
ip++;
break;
case 5:
stack.push(peg$currPos);
ip++;
break;
case 6:
stack.pop();
ip++;
break;
case 7:
peg$currPos = stack.pop();
ip++;
break;
case 8:
stack.length -= bc[ip + 1];
ip += 2;
break;
case 9:
stack.splice(-2, 1);
ip++;
break;
case 10:
stack[stack.length - 2].push(stack.pop());
ip++;
break;
case 11:
stack.push(stack.splice(stack.length - bc[ip + 1], bc[ip + 1]));
ip += 2;
break;
case 12:
stack.push(input.substring(stack.pop(), peg$currPos));
ip++;
break;
case 13:
ends.push(end);
ips.push(ip + 3 + bc[ip + 1] + bc[ip + 2]);
if (stack[stack.length - 1]) {
end = ip + 3 + bc[ip + 1];
ip += 3;
} else {
end = ip + 3 + bc[ip + 1] + bc[ip + 2];
ip += 3 + bc[ip + 1];
}
break;
case 14:
ends.push(end);
ips.push(ip + 3 + bc[ip + 1] + bc[ip + 2]);
if (stack[stack.length - 1] === peg$FAILED) {
end = ip + 3 + bc[ip + 1];
ip += 3;
} else {
end = ip + 3 + bc[ip + 1] + bc[ip + 2];
ip += 3 + bc[ip + 1];
}
break;
case 15:
ends.push(end);
ips.push(ip + 3 + bc[ip + 1] + bc[ip + 2]);
if (stack[stack.length - 1] !== peg$FAILED) {
end = ip + 3 + bc[ip + 1];
ip += 3;
} else {
end = ip + 3 + bc[ip + 1] + bc[ip + 2];
ip += 3 + bc[ip + 1];
}
break;
case 16:
if (stack[stack.length - 1] !== peg$FAILED) {
ends.push(end);
ips.push(ip);
end = ip + 2 + bc[ip + 1];
ip += 2;
} else {
ip += 2 + bc[ip + 1];
}
break;
case 17:
ends.push(end);
ips.push(ip + 3 + bc[ip + 1] + bc[ip + 2]);
if (input.length > peg$currPos) {
end = ip + 3 + bc[ip + 1];
ip += 3;
} else {
end = ip + 3 + bc[ip + 1] + bc[ip + 2];
ip += 3 + bc[ip + 1];
}
break;
case 18:
ends.push(end);
ips.push(ip + 4 + bc[ip + 2] + bc[ip + 3]);
if (input.substr(peg$currPos, peg$consts[bc[ip + 1]].length) === peg$consts[bc[ip + 1]]) {
end = ip + 4 + bc[ip + 2];
ip += 4;
} else {
end = ip + 4 + bc[ip + 2] + bc[ip + 3];
ip += 4 + bc[ip + 2];
}
break;
case 19:
ends.push(end);
ips.push(ip + 4 + bc[ip + 2] + bc[ip + 3]);
if (input.substr(peg$currPos, peg$consts[bc[ip + 1]].length).toLowerCase() === peg$consts[bc[ip + 1]]) {
end = ip + 4 + bc[ip + 2];
ip += 4;
} else {
end = ip + 4 + bc[ip + 2] + bc[ip + 3];
ip += 4 + bc[ip + 2];
}
break;
case 20:
ends.push(end);
ips.push(ip + 4 + bc[ip + 2] + bc[ip + 3]);
if (peg$consts[bc[ip + 1]].test(input.charAt(peg$currPos))) {
end = ip + 4 + bc[ip + 2];
ip += 4;
} else {
end = ip + 4 + bc[ip + 2] + bc[ip + 3];
ip += 4 + bc[ip + 2];
}
break;
case 21:
stack.push(input.substr(peg$currPos, bc[ip + 1]));
peg$currPos += bc[ip + 1];
ip += 2;
break;
case 22:
stack.push(peg$consts[bc[ip + 1]]);
peg$currPos += peg$consts[bc[ip + 1]].length;
ip += 2;
break;
case 23:
stack.push(peg$FAILED);
if (peg$silentFails === 0) {
peg$fail(peg$consts[bc[ip + 1]]);
}
ip += 2;
break;
case 24:
peg$savedPos = stack[stack.length - 1 - bc[ip + 1]];
ip += 2;
break;
case 25:
peg$savedPos = peg$currPos;
ip++;
break;
case 26:
params = bc.slice(ip + 4, ip + 4 + bc[ip + 3]);
for (i = 0; i < bc[ip + 3]; i++) {
params[i] = stack[stack.length - 1 - params[i]];
}
stack.splice(
stack.length - bc[ip + 2],
bc[ip + 2],
peg$consts[bc[ip + 1]].apply(null, params)
);
ip += 4 + bc[ip + 3];
break;
case 27:
stack.push(peg$parseRule(bc[ip + 1]));
ip += 2;
break;
case 28:
peg$silentFails++;
ip++;
break;
case 29:
peg$silentFails--;
ip++;
break;
default:
throw new Error("Invalid opcode: " + bc[ip] + ".");
}
}
if (ends.length > 0) {
end = ends.pop();
ip = ips.pop();
} else {
break;
}
}
return stack[0];
}
const OP_EQ = "equal";
const OP_IS = OP_EQ;
const OP_GT = "greater";
const OP_GE= "greaterequal";
const OP_LT= "less";
const OP_LE= "lessequal";
const OP_NOT = "not";
const VERBOSE = false;
function Version(){
this.major = null;
this.minor = null;
this.patch = null;
this.op = null;
}
const P = Version.prototype;
P.toString = function() {
return `[${this.op ? this.op : "?"}]/v${this.major}.${this.minor}.${this.patch}`;
}
Object.defineProperty(Version.prototype, 'wildcard', {
get: function() {
return this.major === '*' || this.minor === '*' || this.patch === '*';
}
});
Object.defineProperty(Version.prototype, 'anyMajor', {
get: function() { return this.major === '*';}
});
Object.defineProperty(Version.prototype, 'anyMinor', {
get: function() { return this.minor === '*';}
});
Object.defineProperty(Version.prototype, 'anyPatch', {
get: function() { return this.patch === '*';}
});
P.toArray = function() {
const r = [];
if(this.major !== null) {
r.push(this.major);
}
if(this.minor !== null) {
r.push(this.minor);
}
if(this.patch !== null) {
r.push(this.patch);
}
return r;
};
P.assertNotWildcard = function() {
if(this.wildcard) {
throw new Error("Source version should not be wildcard: "+this.toString());
}
}
P.compareTo = function(o) {
this.assertNotWildcard();
if(o.wildcard) {
throw new Error("Reference version should not be wildcard when comparing!");
}
const va = this.toArray();
const vb = o.toArray();
const l = Math.min(va.length, vb.length);
let fillZeros = (a, l, ml) =>{ for(let i = l; i < ml; i++) a[i] = 0;}
fillZeros(va, l, 3);
fillZeros(vb, l, 3);
let toFactor = (v) => {return (v[0] << 20) + (v[1] << 10) + (v[2]);}
return toFactor(va) - toFactor(vb);
};
P.match = function(o) {
if(VERBOSE) {
console.log(`try match ${o}`);
}
this.assertNotWildcard();
if(!o.wildcard) {
throw new Error("Reference version should be wildcard when matching!");
}
if(VERBOSE) {
console.log(` match major ${o.major}, any ${o.anyMajor}, ${this.major} <> ${o.major}`);
}
if(o.anyMajor) return true;
if(this.major !== o.major) return false;
if(VERBOSE) {
console.log(` match minor ${o.minor}, any ${o.anyMinor}, ${this.minor} <> ${o.minor}`);
}
if(o.anyMinor) return true;
if(this.minor !== o.minor) return false;
if(VERBOSE) {
console.log(` match patch ${o.patch}, any ${o.anyPatch}`);
}
if(o.anyPatch) return true;
return this.patch == o.patch;
};
P.test = function(o) {
let op = o.op;
if(op === OP_EQ) {
return o.wildcard ? this.match(o) : this.compareTo(o) === 0;
}
if(op === OP_NOT) {
return o.wildcard ? !this.match(o) : this.compareTo(o) !== 0;
}
if(o.wildcard){
throw new Error("Can not compare to wildcard version");
}
const R = this.compareTo(o);
if(op === OP_GE) {
return R >= 0;
}
if(op === OP_LE) {
return R <= 0;
}
if(op === OP_GT) {
return R > 0;
}
if(op === OP_LT) {
return R < 0;
}
throw new Error("invalidate operation " + op);
};
function VersionSet(data) {
this.conds = data;
}
function allMatch(v, versions) {
let t;
let r = true;
for(let c of versions) {
t = v.test(c);
if(VERBOSE) {
console.log(`test ${v} with ${c} => ${t}`);
}
if(!t){
r = false;
if(!VERBOSE) {
return false;
}
}
}
return r;
}
function arrElmOr(arr, idx, dft){
if(arr[idx] === undefined) return dft;
return arr[idx];
}
VersionSet.prototype.match = function(o) {
let ps = o.split('.');
let v = new Version;
v.major = parseInt(arrElmOr(ps, 0, 0), 10);
v.minor = parseInt(arrElmOr(ps, 1, 0), 10);
v.patch = parseInt(arrElmOr(ps, 2, 0), 10);
if(VERBOSE) {
console.log(`match version ${v}`);
}
for(let c of this.conds){
if(allMatch(v, c)) {
return true;
}
}
return false;
};
peg$result = peg$parseRule(peg$startRuleIndex);
if (peg$result !== peg$FAILED && peg$currPos === input.length) {
return peg$result;
} else {
if (peg$result !== peg$FAILED && peg$currPos < input.length) {
peg$fail(peg$endExpectation());
}
throw peg$buildStructuredError(
peg$maxFailExpected,
peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null,
peg$maxFailPos < input.length
? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1)
: peg$computeLocation(peg$maxFailPos, peg$maxFailPos)
);
}
}
module.exports = {
SyntaxError: peg$SyntaxError,
parse: peg$parse
};

View File

@@ -0,0 +1,251 @@
// Simple Version Grammar
{
const OP_EQ = "equal";
const OP_IS = OP_EQ;
const OP_GT = "greater";
const OP_GE= "greaterequal";
const OP_LT= "less";
const OP_LE= "lessequal";
const OP_NOT = "not";
const VERBOSE = false;
function Version(){
this.major = null;
this.minor = null;
this.patch = null;
this.op = null;
}
const P = Version.prototype;
P.toString = function() {
return `[${this.op ? this.op : "?"}]/v${this.major}.${this.minor}.${this.patch}`;
}
Object.defineProperty(Version.prototype, 'wildcard', {
get: function() {
return this.major === '*' || this.minor === '*' || this.patch === '*';
}
});
Object.defineProperty(Version.prototype, 'anyMajor', {
get: function() { return this.major === '*';}
});
Object.defineProperty(Version.prototype, 'anyMinor', {
get: function() { return this.minor === '*';}
});
Object.defineProperty(Version.prototype, 'anyPatch', {
get: function() { return this.patch === '*';}
});
P.toArray = function() {
const r = [];
if(this.major !== null) {
r.push(this.major);
}
if(this.minor !== null) {
r.push(this.minor);
}
if(this.patch !== null) {
r.push(this.patch);
}
return r;
};
P.assertNotWildcard = function() {
if(this.wildcard) {
throw new Error("Source version should not be wildcard: "+this.toString());
}
}
P.compareTo = function(o) {
this.assertNotWildcard();
if(o.wildcard) {
throw new Error("Reference version should not be wildcard when comparing!");
}
const va = this.toArray();
const vb = o.toArray();
const l = Math.min(va.length, vb.length);
let fillZeros = (a, l, ml) =>{ for(let i = l; i < ml; i++) a[i] = 0;}
fillZeros(va, l, 3);
fillZeros(vb, l, 3);
let toFactor = (v) => {return (v[0] << 20) + (v[1] << 10) + (v[2]);}
return toFactor(va) - toFactor(vb);
};
P.match = function(o) {
if(VERBOSE) {
console.log(`try match ${o}`);
}
this.assertNotWildcard();
if(!o.wildcard) {
throw new Error("Reference version should be wildcard when matching!");
}
if(VERBOSE) {
console.log(` match major ${o.major}, any ${o.anyMajor}, ${this.major} <> ${o.major}`);
}
if(o.anyMajor) return true;
if(this.major !== o.major) return false;
if(VERBOSE) {
console.log(` match minor ${o.minor}, any ${o.anyMinor}, ${this.minor} <> ${o.minor}`);
}
if(o.anyMinor) return true;
if(this.minor !== o.minor) return false;
if(VERBOSE) {
console.log(` match patch ${o.patch}, any ${o.anyPatch}`);
}
if(o.anyPatch) return true;
return this.patch == o.patch;
};
P.test = function(o) {
let op = o.op;
if(op === OP_EQ) {
return o.wildcard ? this.match(o) : this.compareTo(o) === 0;
}
if(op === OP_NOT) {
return o.wildcard ? !this.match(o) : this.compareTo(o) !== 0;
}
if(o.wildcard){
throw new Error("Can not compare to wildcard version");
}
const R = this.compareTo(o);
if(op === OP_GE) {
return R >= 0;
}
if(op === OP_LE) {
return R <= 0;
}
if(op === OP_GT) {
return R > 0;
}
if(op === OP_LT) {
return R < 0;
}
throw new Error("invalidate operation " + op);
};
function VersionSet(data) {
this.conds = data;
}
function allMatch(v, versions) {
let t;
let r = true;
for(let c of versions) {
t = v.test(c);
if(VERBOSE) {
console.log(`test ${v} with ${c} => ${t}`);
}
if(!t){
r = false;
if(!VERBOSE) {
return false;
}
}
}
return r;
}
function arrElmOr(arr, idx, dft){
if(arr[idx] === undefined) return dft;
return arr[idx];
}
VersionSet.prototype.match = function(o) {
let ps = o.split('.');
let v = new Version;
v.major = parseInt(arrElmOr(ps, 0, 0), 10);
v.minor = parseInt(arrElmOr(ps, 1, 0), 10);
v.patch = parseInt(arrElmOr(ps, 2, 0), 10);
if(VERBOSE) {
console.log(`match version ${v}`);
}
for(let c of this.conds){
if(allMatch(v, c)) {
return true;
}
}
return false;
};
}
Expression
= head:Conds tail:('||' Conds)* {
let s = [head];
s = s.concat(tail.map(x=>x[1]));
return new VersionSet(s);
}
Conds "Condition Items"
= _ head:Cond tail:(S Cond)+ _ {
let s = [head];
s = s.concat(tail.map(x=> x[1]));
return s;
}
/ _ head: Cond _ {
return [head];
}
Cond
= '>=' _ v:Version {
v.op = OP_GE;
return v;
}
/ '<=' _ v:Version {
v.op = OP_LE;
return v;
}
/ '!=' _ v:Version {
v.op = OP_NOT;
return v;
}
/ '!' _ v:Version {
v.op = OP_NOT;
return v;
}
/ '=' _ v:Version {
v.op = OP_EQ;
return v;
}
/ '<' _ v:Version {
v.op = OP_LT;
return v;
}
/ '>'_ v:Version {
v.op = OP_GT;
return v;
}
/ head:Version {
head.op = OP_IS;
return head;
}
Version "version"
= V3 / V2 / V1
V3 "major.minor.patch"
= v:V2 '.' n:Factor { v.patch = n; return v}
V2 "major.minor"
= v:V1 '.' n:Factor {v.minor = n; return v}
V1 "major"
= n:Factor {let v = new Version; v.major = n; return v}
Factor
= ('*' / 'x' / 'X') {return '*';}
/ Integer
Integer "integer"
= [0-9]+ { return parseInt(text(), 10); }
S "whitespace"
= [ \t\n\r]+
_ "whitespace"
= [ \t\n\r]*

View File

@@ -0,0 +1,133 @@
const parser = require('./plugin_cfg.js');
const input_text = `3.4.x 3.5 3 3.* * 6.2.* || > 3.5 <= 3.2 > 2.4 <= 33.2 >=133.222.2 !333 != 22 || 4`;
// let r = parser.parse(input_text);
function assert(label, blk) {
console.log(`run ${label}`);
let r = blk();
if (!r) {
console.error(` failed!`);
}
}
// r.match("3.2");
// r.match("3.4");
{
let vs = ["3.4", "3.4.*", "3.4.x", "3.4.X"];
for (let v of vs) {
let s = parser.parse(v);
let label = `Simple match ${v}`;
assert(`${label} 1`, () => {
return s.match("3.4");
});
assert(`${label} 2`, () => {
return !s.match("3.2");
});
assert(`${label} 2`, () => {
return s.match("3.4.3");
});
assert(`${label} 3`, () => {
return s.match("3.4.6");
});
assert(`${label} 4`, () => {
return !s.match("3.444");
});
assert("dont match", () => {
let cases = [
"2.4",
"2.4.2",
"6.4",
"3"
]
return !cases.reduce((p, cs) => p || s.match(cs), false);
});
}
}
{
let s = parser.parse("*");
assert("match all", () => {
let cases = [
"2.4",
"2.4.2",
"6.4",
"3"
]
return cases.reduce((p, cs) => p && s.match(cs), true);
});
}
{
function assert_match(target, versions, bad_versions) {
let s = parser.parse(target);
for (let v of versions) {
assert(`test ${v}`, () => {
return s.match(v);
});
}
for (let v of bad_versions) {
assert(`test not match ${v}`, () => {
return !s.match(v);
});
}
}
assert_match(">3.3 <3.6", [
'3.4',
'3.4.1',
'3.4.2',
'3.5',
'3.5.0',
'3.5.1',
'3.5.2',
],
[
'3.3',
'3.3.2',
'2.3',
'3.6.0',
'3.6',
]
);
assert_match(">=3.3 <= 3.6.0", [
'3.3.0',
'3.3.1',
'3.4',
'3.4.1',
'3.4.2',
'3.5',
'3.5.0',
'3.5.1',
'3.5.2',
'3.6.0'
],
[
'3.2.9',
'2.3',
'3.6.1',
]
);
assert_match(">=3.3 <= 3.6.0 !3.5.2|| 4.x", [
'3.3.0',
'3.3.1',
'3.4',
'3.4.1',
'3.4.2',
'3.5',
'3.5.0',
'4.0',
'4.1',
'4.2',
'3.5.1',
'3.6.0'
],
[
'3.2.9',
'2.3',
'3.6.1',
'3.5.2'
]
);
}

View File

@@ -0,0 +1,271 @@
const fs = require('fs');
const path = require('path');
const version_parser = require('./plugin_support/plugin_cfg');
const MAX_SEARCH_LEVEL = 7;
const CC_PLUGIN_JSON_STR = 'cc_plugin.json';
const node_path = process.argv.shift();
const script_path = process.argv.shift();
const search_path_input_file = process.argv.shift();
const plugin_cmake_output_file = process.argv.shift();
const PLATFORM_NAME_FROM_CMAKE = process.argv.shift();
const PROJ_SEARCH_PATHS = fs.readFileSync(search_path_input_file, 'utf8').
split('\n').
map(x => x.trim()).
filter(x => x.length > 0 && !x.startsWith("#"));
const cc_config_json_list = [];
function search_cc_config_json_levels(dir, depth) {
// console.log(`[searching plugins] search dir ${dir}`);
if (depth > MAX_SEARCH_LEVEL) return;
const st = fs.statSync(dir);
if (!st.isDirectory()) return;
let subfiles = fs.readdirSync(dir);
let subdirs = [];
for (let item of subfiles) {
if (item === "." || item === "..") continue;
let fp = path.join(dir, item);
const subst = fs.statSync(fp);
if (subst.isFile() && item === CC_PLUGIN_JSON_STR) {
cc_config_json_list.push(dir);
return;
}
if (subst.isDirectory()) {
subdirs.push(fp);
}
}
for (let sd of subdirs) {
search_cc_config_json_levels(sd, depth + 1);
}
}
for (let searchPath of PROJ_SEARCH_PATHS) {
if (!fs.existsSync(searchPath)) {
console.log(`[searching plugins] directory ${searchPath} does not exist`);
continue;
}
search_cc_config_json_levels(searchPath, 1);
}
if (cc_config_json_list.length === 0) {
console.log("[searching plugins] no plugins found!");
process.exit(0)
}
for (let dir of cc_config_json_list) {
console.log(`[searching plugins] plugin dir found: ${dir}`)
}
function read_engine_version() {
const pkg = path.join(__dirname, '../../../package.json');
return require(pkg).version;
}
function parse_package_dependency(info) {
let pkgs = [];
for (let m of info.modules) {
if (m.platforms && m.platforms.indexOf(PLATFORM_NAME_FROM_CMAKE) < 0) {
continue;
}
pkgs.push({ target: m.target, depends: typeof m.depends === 'string' ? [m.depends] : (m.depends || []) });
}
return pkgs;
}
function get_property_variants(obj, ...names) {
for (let n of names) {
if (obj.hasOwnProperty(n)) {
return obj[n];
}
if (n.indexOf('_') >= 0) {
const k = n.replace(/_/g, '-');
if (obj.hasOwnProperty(k)) {
return obj[k];
}
}
if (n.indexOf('-') >= 0) {
const k = n.replace(/-/g, '_');
if (obj.hasOwnProperty(k)) {
return obj[k];
}
}
}
return undefined;
}
function test_enable_by_configurations(config) {
const support_platforms = get_property_variants(config, "platforms") || [];
const enabled_default = get_property_variants(config, "enable", "enabled");
const enable_all = enabled_default === undefined ? true : enabled_default;
const disable_all = (get_property_variants(config, "disable", "disabled") || false) || !enable_all;
const disabled_platforms = get_property_variants(config, "disable-by-platforms", "disabled-by-platforms") || [];
const engine_version_value = get_property_variants(config, "engine-version");
if (disable_all) {
// all disabled
console.log(` plugin is disabled.`);
return false;
}
if (support_platforms.length > 0 && support_platforms.indexOf(PLATFORM_NAME_FROM_CMAKE) < 0) {
// unsupported platform
console.log(` plugin is not supported by current platform ${PLATFORM_NAME_FROM_CMAKE}.`);
return false;
}
if (disabled_platforms.indexOf(PLATFORM_NAME_FROM_CMAKE) > -1) {
// disable by user settings
console.log(` plugin is disabled by setting.`);
return false;
}
const ENGINE_VERSION = read_engine_version().replace(/^(v|V)/, '');
try {
const version_filter = version_parser.parse(engine_version_value);
const version_valid = version_filter.match(ENGINE_VERSION);
if (!version_valid) {
console.warn(` Engine version '${ENGINE_VERSION}' mismatch '${engine_version_value}'`);
}
} catch (e) {
console.error(` Failed to parse 'engine-version', value: '${engine_version_value}'`);
console.error(e);
return false;
}
return true;
}
function validate_cc_plugin_json_format(tag, content) {
const field_required = (obj, field_name) => {
if (Object.hasOwnProperty(obj, field_name)) {
console.warn(`${tag} field '${field_name}' is not set`);
return false;
}
return true;
}
const required_fields = ["name", "version", "engine-version", "author", "description", "modules", "platforms"];
for (const f of required_fields) {
if (!field_required(content, f)) {
return false;
}
}
const modules = content["modules"];
if (modules.length == 0) {
console.warn(`${tag} modules field is empty`);
return false;
}
for (let m of modules) {
const mod_fields = ["target"];
for (const f of mod_fields) {
if (!field_required(m, f)) {
console.warn(`${tag} module field ${f} is not set`);
return false;
}
}
}
return true;
}
function add_search_path_suffix(dir, platform) {
if (platform.match(/^android/i)) {
return [`${dir}/android/\${ANDROID_ABI}`, `${dir}/android`];
} else if (platform.match(/^win/i)) {
return [`${dir}/windows/x86_64`, `${dir}/windows`];
} else if (platform.match(/^iphonesimulator/i)) {
return [`${dir}/iphonesimulator`, `${dir}/ios`];
} else if (platform.match(/^ios/i)) {
return [`${dir}/ios`];
} else if (platform.match(/^mac/i) || platform.match(/^darwin/i)) {
return [`${dir}/mac/\${CMAKE_SYSTEM_PROCESSOR}`, `${dir}/mac`];
} else {
console.warn(`Don't knowm suffix for '${platform}`)
return [];
}
}
console.log(`Engine version: ${read_engine_version()}`);
/// Generate Pre-AutoLoadPlugins.cmake
let output_lines = ["# plugins found & enabled in search path",
"# To disable automatic update of this file, set SKIP_SCAN_PLUGINS to ON.",
""];
for (let plugin_dir of cc_config_json_list) {
let load_plugins = [];
try {
let maybe_plugin_name = path.basename(plugin_dir);
console.log(`Parsing plugin directory ${maybe_plugin_name}`);
let cc_plugin_file = path.join(plugin_dir, CC_PLUGIN_JSON_STR);
let cc_plugin_content = fs.readFileSync(cc_plugin_file, { encoding: 'utf8' });
let cc_plugin_json = JSON.parse(cc_plugin_content);
if (!validate_cc_plugin_json_format(`Parsing module ${maybe_plugin_name}:`, cc_plugin_json)) {
continue;
}
if (!test_enable_by_configurations(cc_plugin_json)) {
console.log(` ${maybe_plugin_name} disabled by configuration`);
continue;
}
const plugin_name = cc_plugin_json.name;
const module_type = get_property_variants(cc_plugin_json, "module_type")
if (module_type !== undefined && module_type !== 'release') {
console.log(` plugin ${plugin_name} is not a release, should be include or add_subdirectory in dev env.`);
continue;
}
const packages = parse_package_dependency(cc_plugin_json);
const cc_project_dir = path.dirname(plugin_cmake_output_file);
let project_to_plugin_dir = path.relative(cc_project_dir, plugin_dir).replace(/\\/g, '/');
project_to_plugin_dir = `\${CC_PROJECT_DIR}/${project_to_plugin_dir}`;
const plugin_root_path_for_platform = add_search_path_suffix(project_to_plugin_dir, PLATFORM_NAME_FROM_CMAKE);
for (let pkg of packages) {
const [target_name, target_version] = pkg.target.split('@');
output_lines.push(`set(${target_name}_ROOT\n${plugin_root_path_for_platform.map(x => ` "${x}"`).join("\n")}\n)`, "");
output_lines.push(`list(APPEND CMAKE_FIND_ROOT_PATH \${${target_name}_ROOT})`)
load_plugins = load_plugins.concat([...pkg.depends, target_name + (target_version !== undefined ? '@' + target_version : '')]);
output_lines.push(`list(APPEND CC_REGISTERED_PLUGINS`);
output_lines = output_lines.concat(` ${target_name}`);
output_lines.push(`)`);
}
let plugin_names = load_plugins.map(x => x.split(/@/));
for (let plg of plugin_names) {
output_lines.push("");
if (plg[1] && plg.length > 0) {
output_lines.push(`find_package(${plg[0]} ${plg[1]}`);
} else {
output_lines.push(`find_package(${plg[0]}`);
}
output_lines.push(` REQUIRED`);
output_lines.push(` NAMES "${plg[0]}"`);
output_lines.push(`# NO_DEFAULT_PATH`);
output_lines.push(`)`);
}
if (packages.length > 0) {
console.log(` record plugin ${plugin_name}`);
} else {
console.log(` no sub module found`);
}
} catch (e) {
console.error(`Parsing plugin directory: ${plugin_dir}`)
console.error(e);
}
}
if (cc_config_json_list.length == 0) {
console.log(`Try unlink file ${out_file}`)
if (fs.existsSync(out_file)) {
fs.unlinkSync(out_file);
}
} else {
let old_content = null;
let new_content = output_lines.join("\n") + "\n";
if (fs.existsSync(plugin_cmake_output_file)) {
old_content = fs.readFileSync(plugin_cmake_output_file);
}
if (old_content !== new_content) {
fs.writeFileSync(plugin_cmake_output_file, output_lines.join("\n") + "\n", { encoding: 'utf8' });
}
}
process.exit(0);

38
cmake/scripts/utils.js Normal file
View File

@@ -0,0 +1,38 @@
const fs = require('fs');
function all_eql(a, b) {
if (a.length !== b.length) {
return false;
}
const l = a.length;
for (let i = 0; i < l; i++) {
if (a[i] !== b[i]) {
return false;
}
}
return true;
}
function equals_ignore_spaces(a, b) {
const lines_a = a.split('\n').map(x => x.trim());
const lines_b = b.split('\n').map(x => x.trim());
return all_eql(lines_a, lines_b);
}
function writeIfDifferent(file, data, args) {
if (fs.existsSync(file)) {
let content = fs.readFileSync(file, args).toString(args.encoding);
if (equals_ignore_spaces(content, data)) {
console.log(`Skip update ${file}`);
return;
}
}
fs.writeFileSync(file, data, args);
console.log(` write to file ${file}`);
}
exports.writeIfDifferent = writeIfDifferent;