import { INDENT } from './common'; import { SimpleProperty } from './property'; // List Of Supported C++ Types const CPP_TYPES = [ 'std::string', 'std::vector<', 'std::map<' ]; const CPP_HEADERS = [ 'string', 'vector', 'map' ]; // Get Fake Type Name function isGeneric(type: string) { return type.endsWith('<'); } function removeGeneric(type: string) { if (isGeneric(type)) { // Remove Generic Parameters type = type.substring(0, type.length - 1); } return type; } function getFakeName(type: string) { return removeGeneric(type).replaceAll('std::', '_std_'); } // Generate C Type Definition function generateStruct(type: string) { // Get Information const property = new SimpleProperty(0, type, 'fake'); const size = property.propertySize(); const alignment = property.propertyAlignment(); // Generate let struct = ''; struct += `typedef struct __attribute__((aligned(${alignment}))) __attribute__((packed)) {\n`; struct += `${INDENT}uchar data[${size}];\n`; struct += `} ${getFakeName(type)};\n`; return struct; } // Turn A C++ Header Into A C/C++ Headeer export function fixupCpp(data: string) { // Replace Types for (const type of CPP_TYPES) { // Check If Type Is Generic if (isGeneric(type)) { // Generic while (data.includes(type)) { // Find Type let index = data.indexOf(type); // Replace Type data = data.substring(0, index) + getFakeName(type) + '(' + data.substring(index + type.length); // Replace > With ( index = data.indexOf('>', index); if (index !== -1) { data = data.substring(0, index) + ')' + data.substring(index + 1); } } } else { // Normal data = data.replaceAll(type, getFakeName(type)); } } // Setup Macros let header = ''; header += '// C++ Types\n'; // C++ Support header += '#ifdef __cplusplus\n'; for (const headerFile of CPP_HEADERS) { header += `#include <${headerFile}>\n`; } for (const type of CPP_TYPES) { const fakeName = getFakeName(type); if (isGeneric(type)) { header += `#define ${fakeName}(...) ${type}__VA_ARGS__>\n`; } else { header += `#define ${fakeName} ${type}\n`; } } // C Support header += '#else\n'; for (let type of CPP_TYPES) { const fakeName = getFakeName(type); header += generateStruct(type); // Strip Generic Information if (isGeneric(type)) { type = removeGeneric(type); header += `#define ${fakeName}(...) ${fakeName}\n`; } } header += '#endif\n'; // Cleanup Macros let footer = ''; footer += '// Cleanup C++ Types\n'; for (const type of CPP_TYPES) { const fakeName = getFakeName(type); footer += `#undef ${fakeName}\n`; } // Return return header + '\n' + data + '\n' + footer; }