145 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			145 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
const fs = require('fs');
 | 
						|
const path = require('path');
 | 
						|
 | 
						|
const headers = {};
 | 
						|
 | 
						|
function miniPreprocessor(source) {
 | 
						|
	const normal = 0;
 | 
						|
	const lineStart = 1;
 | 
						|
	const pragma = 2;
 | 
						|
	let mode = lineStart;
 | 
						|
	let currentPragma = null;
 | 
						|
 | 
						|
	let processed = '';
 | 
						|
	
 | 
						|
	for (let i = 0; i < source.length; ++i) {
 | 
						|
		if (mode === normal) {
 | 
						|
			if (source.charAt(i) === '\n' || source.charAt(i) === '\r') {
 | 
						|
				mode = lineStart;
 | 
						|
			}
 | 
						|
			processed += source.charAt(i);
 | 
						|
		}
 | 
						|
		else if (mode === lineStart) {
 | 
						|
			if (source.charAt(i) === '#') {
 | 
						|
				currentPragma = '';
 | 
						|
				mode = pragma;
 | 
						|
			}
 | 
						|
			else if (source.charAt(i) === '\n' || source.charAt(i) === '\r') {
 | 
						|
				processed += source.charAt(i);
 | 
						|
				mode = lineStart;
 | 
						|
			}
 | 
						|
			else {
 | 
						|
				processed += source.charAt(i);
 | 
						|
				mode = normal;
 | 
						|
			}
 | 
						|
		}
 | 
						|
		else if (mode === pragma) {
 | 
						|
			if (source.charAt(i) === '\n' || source.charAt(i) === '\r') {
 | 
						|
				if (currentPragma.startsWith('include')) {
 | 
						|
					let start = currentPragma.indexOf('<');
 | 
						|
					if (start < 0) {
 | 
						|
						start = currentPragma.indexOf('"');
 | 
						|
					}
 | 
						|
					let end = currentPragma.lastIndexOf('>');
 | 
						|
					if (end < 0) {
 | 
						|
						end = currentPragma.lastIndexOf('"');
 | 
						|
					}
 | 
						|
 | 
						|
					if (start >= 0 && end >= 0 && currentPragma.length > start + 1) {
 | 
						|
						const headerPath = currentPragma.substring(start + 1, end);
 | 
						|
 | 
						|
						if (currentPragma.substring(start + 1).startsWith('kinc')) {
 | 
						|
							let filePath = null;
 | 
						|
							if (headerPath.includes('FileReaderImpl') || headerPath.includes('Android')) {
 | 
						|
								if (!headers[headerPath]) {
 | 
						|
									headers[headerPath] = true;
 | 
						|
									processed += '#' + currentPragma + source.charAt(i);
 | 
						|
								}
 | 
						|
							}
 | 
						|
							else {
 | 
						|
								if (headerPath.startsWith('kinc/backend')) {
 | 
						|
									filePath = path.resolve('Backends', 'System', 'Microsoft', 'Sources', headerPath);
 | 
						|
								}
 | 
						|
								else {
 | 
						|
									filePath = path.resolve('Sources', headerPath);
 | 
						|
								}
 | 
						|
							
 | 
						|
								if (!headers[headerPath]) {
 | 
						|
									headers[headerPath] = true;
 | 
						|
 | 
						|
									let header = fs.readFileSync(filePath, {encoding: 'utf8'});
 | 
						|
									console.log('Preprocessing ' + filePath);
 | 
						|
									header = miniPreprocessor(header);
 | 
						|
									processed += header;
 | 
						|
								}
 | 
						|
							}
 | 
						|
						}
 | 
						|
						else {
 | 
						|
							if (!headers[headerPath]) {
 | 
						|
								headers[headerPath] = true;
 | 
						|
								processed += '#' + currentPragma + source.charAt(i);
 | 
						|
							}
 | 
						|
						}
 | 
						|
					}
 | 
						|
					else {
 | 
						|
						processed += '#' + currentPragma + source.charAt(i);
 | 
						|
					}
 | 
						|
				}
 | 
						|
				else if (currentPragma.startsWith('pragma once')) {
 | 
						|
					// ignore
 | 
						|
				}
 | 
						|
				else {
 | 
						|
					processed += '#' + currentPragma + source.charAt(i);
 | 
						|
				}
 | 
						|
				mode = lineStart;
 | 
						|
			}
 | 
						|
			else {
 | 
						|
				currentPragma += source.charAt(i);
 | 
						|
			}
 | 
						|
		}
 | 
						|
		else {
 | 
						|
			throw 'Unknown mode';
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return processed;
 | 
						|
}
 | 
						|
 | 
						|
function findHeader(headerPath) {
 | 
						|
	const cachedHeader = headers[headerPath];
 | 
						|
	if (cachedHeader) {
 | 
						|
		return cachedHeader;
 | 
						|
	}
 | 
						|
 | 
						|
	const filePath = path.resolve('Sources', headerPath);
 | 
						|
	let header = fs.readFileSync(filePath, {encoding: 'utf8'});
 | 
						|
	header = header.replace('#pragma once', '');
 | 
						|
	for (const headerPath in headers) {
 | 
						|
		header = header.replace('#include <' + headerPath + '>', '');
 | 
						|
	}
 | 
						|
	header = header.trim();
 | 
						|
	headers[headerPath] = header;
 | 
						|
	return header;
 | 
						|
}
 | 
						|
 | 
						|
function insertHeaders(file, headerPaths) {
 | 
						|
	for (const headerPath of headerPaths) {
 | 
						|
		file = file.replace('#include <' + headerPath + '>', findHeader(headerPath));
 | 
						|
	}
 | 
						|
	return file;
 | 
						|
}
 | 
						|
 | 
						|
const audio2_header = fs.readFileSync(path.resolve('Sources', 'kinc', 'audio2', 'audio.h'), {encoding: 'utf8'});
 | 
						|
let lib = '#pragma once\n' + miniPreprocessor(audio2_header);
 | 
						|
 | 
						|
let windows_backend = fs.readFileSync(path.resolve('Backends', 'Audio2', 'WASAPI', 'Sources', 'kinc', 'backend', 'wasapi.c'), {encoding: 'utf8'});
 | 
						|
windows_backend = windows_backend.replace('#include <kinc/audio2/audio.h>', '');
 | 
						|
windows_backend = miniPreprocessor(windows_backend);
 | 
						|
 | 
						|
lib = lib.replace('// BACKENDS-PLACEHOLDER', '#ifdef KINC_WINDOWS\n' + windows_backend + '\n#endif');
 | 
						|
 | 
						|
if (!fs.existsSync('single_header_libs')) {
 | 
						|
	fs.mkdirSync('single_header_libs');
 | 
						|
}
 | 
						|
fs.writeFileSync(path.resolve('single_header_libs', 'kinc_audio2.h'), lib, {encoding: 'utf8'});
 |