mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-17 20:44:37 +03:00
295 lines
6.6 KiB
JavaScript
295 lines
6.6 KiB
JavaScript
var assert = require("assert");
|
|
var fs = require("fs");
|
|
var path = require("path");
|
|
|
|
/**
|
|
* List all files that can be processed by sanitizer in the given directory.
|
|
*/
|
|
var filesToSanitize = (function() {
|
|
var listPrivate = function(array, dir, displayDir, accept) {
|
|
var files = fs.readdirSync(dir);
|
|
var subarray = [];
|
|
|
|
for (var i = 0; i < files.length; i++) {
|
|
var baseName = files[i];
|
|
var fullName = path.normalize(path.join(dir, baseName));
|
|
|
|
var stat = fs.lstatSync(fullName);
|
|
if (stat.isSymbolicLink()) {
|
|
continue;
|
|
}
|
|
|
|
if (stat.isDirectory()) {
|
|
subarray = listPrivate(subarray,
|
|
path.join(dir, baseName), displayDir ? displayDir + "/" + baseName : baseName, accept);
|
|
continue;
|
|
}
|
|
|
|
if (stat.isFile()) {
|
|
if (accept(baseName))
|
|
array.push({ name: fullName, display: displayDir ? displayDir + "/" + baseName : baseName });
|
|
continue;
|
|
}
|
|
}
|
|
|
|
return array.concat(subarray);
|
|
};
|
|
|
|
return function(dir, accept) {
|
|
return listPrivate([], dir, "", accept);
|
|
};
|
|
})();
|
|
|
|
/**
|
|
* Inject data into string.
|
|
*/
|
|
var inject = function(s, start, end, what) {
|
|
assert(start <= s.length);
|
|
assert(end <= s.length);
|
|
|
|
return s.substr(0, start) + what + s.substr(end);
|
|
};
|
|
|
|
/**
|
|
* Is the extension c++ header file?
|
|
*/
|
|
var isCppHeaderExt = function(ext) {
|
|
return ext === ".h" ||
|
|
ext === ".hh" ||
|
|
ext === ".hpp" ||
|
|
ext === ".hxx" ;
|
|
};
|
|
|
|
/**
|
|
* Is the extension c++ source file?
|
|
*/
|
|
var isCppSourceExt = function(ext) {
|
|
return ext === ".c" ||
|
|
ext === ".cc" ||
|
|
ext === ".cpp" ||
|
|
ext === ".cxx" ;
|
|
};
|
|
|
|
/**
|
|
* Filter that returns true if the given file name should be processed.
|
|
*/
|
|
var filesToAccept = function(name) {
|
|
var ext = path.extname(name).toLowerCase();
|
|
|
|
return isCppHeaderExt(ext) ||
|
|
isCppSourceExt(ext) ||
|
|
ext === ".cmake" ||
|
|
ext === ".m" ||
|
|
ext === ".md" ||
|
|
ext === ".mm" ;
|
|
};
|
|
|
|
/**
|
|
* Sanity spaces.
|
|
*/
|
|
var sanitySpaces = function(data, name) {
|
|
// Remove carriage return.
|
|
data = data.replace(/\r\n/g, "\n");
|
|
// Remove spaces before the end of the line.
|
|
data = data.replace(/[ \t]+\n/g, "\n");
|
|
// Convert tabs to spaces.
|
|
data = data.replace(/\t/g, " ");
|
|
|
|
return data;
|
|
};
|
|
|
|
/**
|
|
* Sanity header guards.
|
|
*/
|
|
var sanityHeaderGuards = (function() {
|
|
var parseGuardName = function(data, i) {
|
|
var m = data.substr(i).match(/[\w][\d\w]*/);
|
|
return m ? m[0] : null;
|
|
};
|
|
|
|
var makeGuardName = function(name) {
|
|
// Remove leading '/' or '\'.
|
|
if (/^[\\\/]/.test(name))
|
|
name = name.substr(1);
|
|
return "_" + name.toUpperCase().replace(/[\/\\\.-]/g, "_");
|
|
};
|
|
|
|
var directiveMarks = [
|
|
"#ifndef ",
|
|
"#endif // ",
|
|
"#define "
|
|
];
|
|
|
|
var directiveNames = [
|
|
"#ifndef ",
|
|
"#endif ",
|
|
"#define "
|
|
];
|
|
|
|
return function(data, name) {
|
|
var i = 0;
|
|
var nl = true;
|
|
|
|
var guard = "// " + "[Guard]" + "\n";
|
|
var nFound = 0;
|
|
|
|
while (i < data.length) {
|
|
if (nl && data.substr(i, guard.length) === guard) {
|
|
i += guard.length;
|
|
nFound++;
|
|
|
|
if (i >= data.length)
|
|
break;
|
|
|
|
for (var j = 0; j < directiveMarks.length; ) {
|
|
var m = directiveMarks[j];
|
|
if (data.substr(i, m.length) === m && data.charAt(i + m.length) === '_') {
|
|
i += directiveMarks[j].length;
|
|
|
|
var oldGuardName = parseGuardName(data, i);
|
|
var newGuardName;
|
|
|
|
if (oldGuardName) {
|
|
console.log(oldGuardName);
|
|
var startPosition = i;
|
|
var endPosition = i + oldGuardName.length;
|
|
|
|
newGuardName = makeGuardName(name);
|
|
if (oldGuardName !== newGuardName) {
|
|
console.log(name + ": " + directiveNames[j] + newGuardName);
|
|
data = inject(data, startPosition, endPosition, newGuardName);
|
|
|
|
i += newGuardName.length;
|
|
i = data.indexOf('\n', i);
|
|
|
|
if (i === -1) {
|
|
// Terminates the loop.
|
|
i = data.length;
|
|
j = 9999;
|
|
nl = false;
|
|
break;
|
|
}
|
|
else {
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
j += 2;
|
|
}
|
|
// Don't process '#define' directive if previous '#ifndef' wasn't matched.
|
|
else {
|
|
if (++j == 2)
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
nl = data.charAt(i) === '\n';
|
|
i++;
|
|
}
|
|
}
|
|
|
|
if (nFound & 1) {
|
|
console.log(name + ": Odd number of guards found: " + nFound);
|
|
}
|
|
|
|
return data;
|
|
};
|
|
})();
|
|
|
|
/**
|
|
* Sanity #include order.
|
|
*/
|
|
var sanityIncludeOrder = function(data, name, directive) {
|
|
var i = 0;
|
|
var nl = true;
|
|
|
|
var startPosition = -1;
|
|
var endPosition = -1;
|
|
var list = null;
|
|
var replacement;
|
|
|
|
while (i < data.length) {
|
|
if (nl && data.substr(i, directive.length) === directive) {
|
|
var iLocal = i
|
|
|
|
if (startPosition === -1) {
|
|
startPosition = i;
|
|
list = [];
|
|
}
|
|
|
|
for (;;) {
|
|
if (++i >= data.length) {
|
|
list.push(data.substring(iLocal, i));
|
|
break;
|
|
}
|
|
if (data.charAt(i) === '\n') {
|
|
list.push(data.substring(iLocal, i));
|
|
i++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else if (startPosition !== -1) {
|
|
assert(nl === true);
|
|
endPosition = i;
|
|
|
|
if (list.length > 1) {
|
|
list.sort();
|
|
replacement = list.join("\n") + "\n";
|
|
|
|
assert(replacement.length == endPosition - startPosition);
|
|
data = inject(data, startPosition, endPosition, replacement);
|
|
}
|
|
|
|
startPosition = -1;
|
|
endPosition = -1;
|
|
list = null;
|
|
|
|
nl = false;
|
|
i++;
|
|
}
|
|
else {
|
|
nl = data.charAt(i) === '\n';
|
|
i++;
|
|
}
|
|
}
|
|
|
|
return data;
|
|
};
|
|
|
|
/**
|
|
* Sanity the given data of file.
|
|
*/
|
|
var sanity = function(data, name) {
|
|
var ext = path.extname(name).toLowerCase();
|
|
|
|
// Sanity spaces.
|
|
data = sanitySpaces(data, name);
|
|
|
|
// Fix C/C++ header guards and sort '#include' files.
|
|
if (isCppHeaderExt(ext)) {
|
|
data = sanityHeaderGuards(data, name);
|
|
data = sanityIncludeOrder(data, name, "#include");
|
|
}
|
|
|
|
return data;
|
|
};
|
|
|
|
/**
|
|
* Entry.
|
|
*/
|
|
var main = function(dir) {
|
|
filesToSanitize(dir, filesToAccept).forEach(function(file) {
|
|
var oldData = fs.readFileSync(file.name, "utf8");
|
|
var newData = sanity(oldData, file.display);
|
|
|
|
if (oldData !== newData) {
|
|
console.log(file.display + ": Writing...");
|
|
fs.writeFileSync(file.name, newData, "utf8");
|
|
}
|
|
});
|
|
};
|
|
|
|
main(path.join(__dirname, "../src"));
|