Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | 20x 124x 124x 124x 124x 124x 124x 124x 121x 3x 3x 3x 2x 1x 57x 57x 2x 55x 55x 55x 55x 124x 124x 124x 55x 55x | /**
* Struct Header Generator
*
* Generates C typedef struct declarations from symbol information.
* Used by HeaderGenerator to emit full struct definitions in headers.
*/
import IHeaderTypeInput from "./IHeaderTypeInput";
import typeUtils from "./mapType";
import CppNamespaceUtils from "../../../../utils/CppNamespaceUtils";
const { mapType } = typeUtils;
/**
* Resolve the C type for a struct field, checking for callback types first.
*/
function resolveFieldCType(fieldType: string, input: IHeaderTypeInput): string {
// ADR-029: Check if field type is a callback type and use typedef name
const callbackInfo = input.callbackTypes?.get(fieldType);
Iif (callbackInfo) {
return callbackInfo.typedefName;
}
// Issue #502/#522: Convert C++ namespace types from _ to :: format
const convertedType = CppNamespaceUtils.convertToCppNamespace(
fieldType,
input.symbolTable,
);
return mapType(convertedType);
}
/**
* Generate the field line for a struct member, handling embedded dimensions.
*
* Issue #461: Handle string<N> types which map to char[N+1]
* The embedded dimension must come after array dimensions in C syntax.
* Example: string<64> arr[4] -> char arr[4][65], not char[65] arr[4]
*/
function generateFieldLine(
fieldName: string,
cType: string,
dims: readonly number[] | undefined,
): string {
const dimSuffix =
dims && dims.length > 0 ? dims.map((d) => `[${d}]`).join("") : "";
const embeddedMatch = /^(\w+)\[(\d+)\]$/.exec(cType);
if (!embeddedMatch) {
return ` ${cType} ${fieldName}${dimSuffix};`;
}
const baseType = embeddedMatch[1];
const embeddedDim = embeddedMatch[2];
// When dims are provided, they already include string capacity from StructCollector
if (dims && dims.length > 0) {
return ` ${baseType} ${fieldName}${dimSuffix};`;
}
return ` ${baseType} ${fieldName}[${embeddedDim}];`;
}
/**
* Generate a C typedef struct declaration for the given struct name.
*
* Output format (Issue #296: uses named struct for forward declaration compatibility):
* ```c
* typedef struct StructName {
* uint32_t field1;
* uint8_t buffer[256];
* } StructName;
* ```
*
* @param name - The struct type name
* @param input - Symbol information containing struct fields
* @returns C typedef struct declaration, or forward declaration if data unavailable
*/
function generateStructHeader(name: string, input: IHeaderTypeInput): string {
const fields = input.structFields.get(name);
// Graceful fallback if struct data not available
if (!fields || fields.size === 0) {
return `typedef struct ${name} ${name};`;
}
const dimensions = input.structFieldDimensions.get(name);
const lines: string[] = [];
// Issue #296: Use named struct for forward declaration compatibility
lines.push(`typedef struct ${name} {`);
// Iterate fields in insertion order (Map preserves order)
for (const [fieldName, fieldType] of fields) {
const cType = resolveFieldCType(fieldType, input);
const dims = dimensions?.get(fieldName);
lines.push(generateFieldLine(fieldName, cType, dims));
}
lines.push(`} ${name};`);
return lines.join("\n");
}
export default generateStructHeader;
|