UNPKG

cpp-merge

Version:

Command line tool to produce single source file from multiple C/C++ files

106 lines 4.73 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const path_1 = __importDefault(require("path")); const os_1 = require("os"); const stringUtils_1 = require("../common/stringUtils"); const CppFileParser_1 = __importDefault(require("./CppFileParser")); const errors_1 = require("./errors"); const utils_1 = require("./utils"); const headerFileExtensions = [".h", ".hpp"]; const sourceFileExtensions = [".c", ".cpp"]; class CppFileMerger { constructor(params = {}) { this.parser = new CppFileParser_1.default(); this.systemIncludes = new Set(); this.processedOnce = new Set(); this.workingDirectory = ""; this.includeDirectory = params.includeDirectory ? path_1.default.resolve(params.includeDirectory) : undefined; this.sourceDirectory = params.sourceDirectory ? path_1.default.resolve(params.sourceDirectory) : undefined; } parse(filePath) { this.systemIncludes.clear(); this.processedOnce.clear(); this.workingDirectory = path_1.default.dirname(filePath); const content = this.parseFile(filePath); const sourceFilesContent = this.parseSourceFiles(); const systemIncludesContent = Array.from(this.systemIncludes.values()) .sort((a, b) => a.localeCompare(b)) .map(file => `#include <${file}>`) .join(os_1.EOL); const finalContent = [ systemIncludesContent, content, sourceFilesContent ] .filter(content => !!content) .join(os_1.EOL); return (0, stringUtils_1.removeDoubleEmptyLines)(finalContent); } parseFile(filePath) { if (this.processedOnce.has(filePath)) { return ""; } const fileContent = (0, utils_1.readFile)(filePath); const result = this.parser.parse(fileContent); result.systemIncludes.forEach(include => this.systemIncludes.add(include)); if (result.processOnce) { this.processedOnce.add(filePath); } const currentDirectory = path_1.default.dirname(filePath); const localIncludesContent = result.localIncludes.map(includeFilePath => { return this.parseIncludedFile(includeFilePath, currentDirectory, filePath); }); return [ ...localIncludesContent, result.content ].join(os_1.EOL); } parseIncludedFile(filePath, currentDirectory, processedFilePath) { const searchFilePaths = [currentDirectory]; if (this.includeDirectory) { searchFilePaths.push(this.includeDirectory); } const foundFilePath = (0, utils_1.findFile)(filePath, searchFilePaths); if (!foundFilePath) { throw new errors_1.IncludeFileNotFoundError(processedFilePath, filePath); } return this.parseFile(foundFilePath); } parseSourceFiles() { const contents = []; const searchDirectories = [this.workingDirectory]; if (this.sourceDirectory) { searchDirectories.push(this.sourceDirectory); } this.processedOnce.forEach(filePath => { const relativeFilePath = this.getHeaderRelativePath(filePath); const extension = path_1.default.extname(relativeFilePath); if (!headerFileExtensions.find(headerFileExtension => headerFileExtension === extension)) { return; } const relativeFilePathWithoutExtension = relativeFilePath.substr(0, relativeFilePath.length - extension.length); for (const sourceFileExtension of sourceFileExtensions) { const sourceFileName = `${relativeFilePathWithoutExtension}${sourceFileExtension}`; const foundFilePath = (0, utils_1.findFile)(sourceFileName, searchDirectories); if (!foundFilePath) { continue; } const sourceFileContent = this.parseFile(foundFilePath); if (sourceFileContent) { contents.push(sourceFileContent); } } }); return contents.join(os_1.EOL); } getHeaderRelativePath(filePath) { const fileDirectory = path_1.default.dirname(filePath); const baseDirectory = this.includeDirectory && fileDirectory.startsWith(this.includeDirectory) ? this.includeDirectory : this.workingDirectory; return path_1.default.relative(baseDirectory, filePath); } } exports.default = CppFileMerger; //# sourceMappingURL=CppFileMerger.js.map