110 lines
3.0 KiB
TypeScript
110 lines
3.0 KiB
TypeScript
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;
|
|
} |