Files
asmjit/tools/src-sanity.js
kobalicekp 5c7123fbb3 Initial.
2014-02-02 03:17:30 +01:00

178 lines
3.9 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()) {
listPrivate(subarray, path.join(dir, baseName), displayDir + baseName, accept);
continue;
}
if (stat.isFile()) {
if (accept(baseName))
array.push({ name: fullName, display: displayDir + baseName });
continue;
}
}
return array.concat(subarray);
};
return function(dir, accept) {
return listPrivate([], dir, "", accept);
};
})();
var isCppHeaderExt = function(ext) {
return ext === ".h" ||
ext === ".hh" ||
ext === ".hpp" ||
ext === ".hxx" ;
};
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" ;
};
var sanitySpaces = function(data) {
// 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;
};
var sanityHeaderGuards = function(data) {
return data;
};
var sanityIncludeOrder = function(data, 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.indexOf(directive, i) === i) {
var iLocal = i
if (startPosition === -1) {
startPosition = i;
list = [];
}
for (;;) {
if (++i >= data.length) {
list.push(data.substring(iLocal, i));
break;
}
if (data[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");
assert(replacement.length == endPosition - startPosition - 1);
data = data.substring(0, startPosition) +
replacement +
"\n" +
data.substring(endPosition);
}
startPosition = -1;
endPosition = -1;
list = null;
nl = false;
i++;
}
else {
nl = data[i] === '\n';
i++;
}
}
return data;
};
var sanity = function(data, name) {
var ext = path.extname(name).toLowerCase();
// Sanity spaces.
data = sanitySpaces(data);
// Fix C/C++ header guards.
if (isCppHeaderExt(ext)) {
data = sanityHeaderGuards(data);
}
// Sort #include files.
if (isCppHeaderExt(ext) || isCppSourceExt(ext)) {
data = sanityIncludeOrder(data, "#include");
}
return data;
};
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("Sanitizing: " + file.display);
fs.writeFileSync(file.name, newData, "utf8");
}
});
};
main(path.join(__dirname, "../src"));