webamp/packages/webamp-modern-2/tools/parse-mi.js
2021-07-31 14:05:01 -07:00

67 lines
2.2 KiB
JavaScript

#!/usr/bin/env node
/**
* Based on extract_objects.pl from Ralf Engels<ralf.engels@gmx.de> Maki decompiler
*/
const fs = require("fs");
function parseFile(filePath) {
const mi = fs.readFileSync(filePath, "utf8");
const lines = mi.split("\n");
const objects = {};
lines.forEach((line, lineNumber) => {
const classDefinitionMatch =
/\s*extern\s+class\s*\@\{(........\s?-\s?....\s?-\s?....\s?-\s?....\s?-\s?............)\}\s*\@\s*(.*?)\s+(.*?);/.exec(
line
);
if (classDefinitionMatch) {
const id = classDefinitionMatch[1].replace(/[-\s]/g, "");
const parent = classDefinitionMatch[2];
const name = classDefinitionMatch[3]
.replace(/^_predecl /, "")
.replace(/^&/, "");
objects[name.toLowerCase()] = { id, name, parent, functions: [] };
}
const methodMatch = /\s*extern(\s+.*)?\s+(.*)\.(.*)\((.*)\);/.exec(line);
if (methodMatch) {
const result = methodMatch[1] == null ? "" : methodMatch[1].trim();
const className = methodMatch[2].toLowerCase();
const name = methodMatch[3].trim();
const rawArgs = methodMatch[4].split(/\s*,\s*/);
const parameters = rawArgs.filter(Boolean).map((rawArg) => {
const argMatch = /^\s*(.*\s+)?(.*)\s*/.exec(rawArg);
if (argMatch == null) {
throw new Error(`Could not find args in ${rawArg} in ${line}`);
}
const type = argMatch[1];
if (type == null) {
// console.warn(`Could not find args name in ${fileName}:${lineNum} "${line}"`);
return [argMatch[2], "unknown_arg_name"];
}
return [type.trim(), argMatch[2]];
});
if (objects[className] == null) {
throw new Error(
`"${className} not defined in ${filePath}:${lineNumber}. I have ${JSON.stringify(
Object.keys(objects)
)}`
);
}
objects[className].functions.push({ result, name, parameters });
}
});
const objectIds = {};
Object.keys(objects).forEach((normalizedName) => {
const { id, parent, functions, name } = objects[normalizedName];
objectIds[id] = { parent, functions, name };
});
return objectIds;
}
module.exports = { parseFile };