| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- const {
- getDataType,
- normalizeGroup
- } = require('../../domain/parameter-groups/model.js')
- const {
- parseStructCatalog,
- parseStructDefinition: parseStructDefinitionSource
- } = require('../../domain/parameter-groups/struct-parser.js')
- function getRegisterByteLengthFromConfig(register) {
- const dataType = getDataType(register.dataType).key
- if (dataType === 'ascii' || dataType === 'utf8') return Math.max(1, Number(register.textByteLength) || 1)
- if (dataType === 'float' || dataType === 'int32_t' || dataType === 'uint32_t') return 4
- if (dataType === 'int8_t' || dataType === 'uint8_t') return 1
- return 2
- }
- function getRegistersByteLength(registers = []) {
- const explicitByteEnds = registers.map((register) => {
- const byteStart = Number(register && register.byteStart)
- if (!Number.isFinite(byteStart)) return null
- if (register.isBitField) {
- const bitOffset = Math.min(Math.max(Math.floor(Number(register.bitOffset) || 0), 0), 7)
- const bitWidth = Math.max(1, Math.round(Number(register.bitWidth) || 1))
- return Math.max(0, Math.floor(byteStart)) + Math.max(1, Math.ceil((bitOffset + bitWidth) / 8))
- }
- return Math.max(0, Math.floor(byteStart)) + getRegisterByteLengthFromConfig(register)
- }).filter((value) => Number.isFinite(value))
- if (explicitByteEnds.length) return Math.max.apply(null, explicitByteEnds)
- return registers.reduce((total, register) => total + getRegisterByteLengthFromConfig(register), 0)
- }
- function normalizeSymbolText(value) {
- return String(value || '')
- .replace(/^(?:IDATA|XDATA|DATA|CODE)[\s:_-]+/i, '')
- .replace(/^_+/, '')
- .replace(/[^A-Za-z0-9]/g, '')
- .toLowerCase()
- }
- function findStructCompletion(group, catalog) {
- const symbolName = group.sourceSymbolName || group.name
- const direct = catalog.variablesByName[normalizeSymbolText(symbolName)]
- || catalog.variablesByName[symbolName]
- if (direct) return direct
- const normalizedSymbol = normalizeSymbolText(symbolName)
- const normalizedType = normalizeSymbolText(group.sourceSymbolType)
- const expectedBytes = Number(group.sourceByteLength || group.byteLength || 0)
- const matchedStruct = catalog.structs.find((structInfo) => {
- const normalizedStructName = normalizeSymbolText(structInfo.name)
- if (normalizedType && normalizedType === normalizedStructName) {
- return true
- }
- if (normalizedSymbol && (
- normalizedSymbol === normalizedStructName
- || normalizedSymbol.indexOf(normalizedStructName) >= 0
- || normalizedStructName.indexOf(normalizedSymbol) >= 0
- )) {
- return true
- }
- return expectedBytes > 0 && getRegistersByteLength(structInfo.registers) === expectedBytes
- })
- return matchedStruct
- ? {
- name: symbolName,
- registers: matchedStruct.registers,
- structName: matchedStruct.name
- }
- : null
- }
- function createCompletedRegisters(group, completion) {
- const existingRemarksByByteStart = (Array.isArray(group.registers) ? group.registers : []).reduce((remarks, register) => {
- const byteStart = Number(register && register.byteStart)
- const remark = String(register && register.remark ? register.remark : '').trim()
- if (Number.isFinite(byteStart) && remark) remarks[Math.floor(byteStart)] = remark
- return remarks
- }, {})
- return completion.registers.map((register) => ({
- ...register,
- isStructField: true,
- remark: register.remark || existingRemarksByByteStart[Math.floor(Number(register.byteStart) || 0)] || '',
- sourceMemoryArea: group.sourceMemoryArea,
- sourceMemoryClass: group.sourceMemoryClass,
- sourceSymbolName: group.sourceSymbolName,
- sourceSymbolType: completion.structName || register.sourceSymbolType
- }))
- }
- function completeStructInstanceGroups(groups, sourceText, options = {}) {
- const catalog = parseStructCatalog(sourceText)
- let completedCount = 0
- let skippedCount = 0
- const nextGroups = groups.map((group) => {
- if (!group.sourceSymbolName || !group.sourceMemoryArea) return group
- const completion = findStructCompletion(group, catalog)
- if (!completion || !completion.registers || !completion.registers.length) {
- skippedCount += 1
- return group
- }
- const expectedBytes = Number(group.sourceByteLength || group.byteLength || 0)
- const actualBytes = getRegistersByteLength(completion.registers)
- if (expectedBytes > 0 && actualBytes !== expectedBytes && options.strictLength !== false) {
- skippedCount += 1
- return group
- }
- completedCount += 1
- return normalizeGroup({
- ...group,
- layout: 'struct',
- quantity: completion.registers.length,
- registers: createCompletedRegisters(group, completion)
- })
- })
- return {
- completedCount,
- groups: nextGroups,
- skippedCount,
- structCount: catalog.structs.length,
- variableCount: Object.keys(catalog.variablesByName).length
- }
- }
- function parseStructDefinition(sourceText) {
- return parseStructDefinitionSource(sourceText)
- }
- module.exports = {
- completeStructInstanceGroups,
- getRegistersByteLength,
- parseStructDefinition
- }
|