@microtronics/studio-cli 0.60.0 → 0.62.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -2
- package/README.md +17 -0
- package/dist/main.js +54 -57
- package/dist/studio-cli.d.ts +1 -0
- package/out/api.js +137 -149
- package/out/studio-cli.d.ts +5297 -0
- package/package.json +4 -4
- package/out/DeviceProfiles.js +0 -436
- package/out/FS.js +0 -43
- package/out/crc.js +0 -93
- package/out/dde/coreDefinitions.js +0 -541
- package/out/dde/dde.js +0 -618
- package/out/dde/dynamic-dde.schema.json +0 -1061
- package/out/dde/fileGenerators/api.js +0 -688
- package/out/dde/fileGenerators/dlo.js +0 -1007
- package/out/dde/fileGenerators/dloLocalData.js +0 -383
- package/out/dde/fileGenerators/xml.js +0 -180
- package/out/dde/yamlDdePreCompiler.js +0 -889
- package/out/defaultFiles.js +0 -114
- package/out/dependencies.js +0 -578
- package/out/dfiles/dfiles.js +0 -205
- package/out/diagnostics.js +0 -10
- package/out/dlo/CustomWasmFS.js +0 -258
- package/out/dlo/compiler.js +0 -231
- package/out/dlo/dlo.js +0 -33
- package/out/dlo/dlocc.js +0 -3799
- package/out/dlo/fileSequencer.js +0 -40
- package/out/dlo/preCompiler.js +0 -442
- package/out/dotenv.js +0 -28
- package/out/globals.js +0 -402
- package/out/helper.js +0 -145
- package/out/log.js +0 -60
- package/out/manifest.js +0 -492
- package/out/myDatanetClient.js +0 -291
- package/out/package/apm.js +0 -294
- package/out/package/library.js +0 -165
- package/out/package/package.js +0 -518
- package/out/registryAPI.js +0 -326
- package/out/scriptRunner.js +0 -107
- package/out/typings/registry.js +0 -7
|
@@ -1,1007 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.AutoDDEGenerator = void 0;
|
|
27
|
-
exports.getPawnTypeDefinition = getPawnTypeDefinition;
|
|
28
|
-
exports.generateAutoIncFromMap = generateAutoIncFromMap;
|
|
29
|
-
exports.generateAutoUplinkIncFromMap = generateAutoUplinkIncFromMap;
|
|
30
|
-
exports.generateMainDDEIncFromMap = generateMainDDEIncFromMap;
|
|
31
|
-
exports.buildDefaultInc = buildDefaultInc;
|
|
32
|
-
const semver = __importStar(require("semver"));
|
|
33
|
-
const coreDefinitions_1 = require("../coreDefinitions");
|
|
34
|
-
const DeviceProfiles_1 = require("../../DeviceProfiles");
|
|
35
|
-
const manifest_1 = require("../../manifest");
|
|
36
|
-
const helper_1 = require("../../helper");
|
|
37
|
-
var ContainerType = coreDefinitions_1.DDE_Core.ContainerType;
|
|
38
|
-
var TransferDirection = coreDefinitions_1.DDE_Core.TransferDirection;
|
|
39
|
-
var regexRelation = coreDefinitions_1.DDE_Core.regexRelation;
|
|
40
|
-
var CONFIG_CONTAINER = coreDefinitions_1.DDE_Core.CONFIG_CONTAINER;
|
|
41
|
-
var CONTAINER_DEF_DLO_CID_BASE = coreDefinitions_1.DDE_Core.CONTAINER_DEF_DLO_CID_BASE;
|
|
42
|
-
var CONTAINER_DEFS = coreDefinitions_1.DDE_Core.CONTAINER_DEFS;
|
|
43
|
-
var fieldTypeDefinitions = coreDefinitions_1.DDE_Core.fieldTypeDefinitions;
|
|
44
|
-
const vscode_uri_1 = require("vscode-uri");
|
|
45
|
-
const defaultFiles_1 = require("../../defaultFiles");
|
|
46
|
-
const dependencies_1 = require("../../dependencies");
|
|
47
|
-
var isNumeric = helper_1.Helper.isNumeric;
|
|
48
|
-
const apm_1 = require("../../package/apm");
|
|
49
|
-
/** get effective field type for pawn access (may be overriden or skipped using attribute dlorw=...)
|
|
50
|
-
* @return {*} | 'skip' | null - null=error occured
|
|
51
|
-
*/
|
|
52
|
-
function getPawnTypeDefinition(field) {
|
|
53
|
-
const tdef = fieldTypeDefinitions[field.type]; // just a shorthand
|
|
54
|
-
// supplement default values
|
|
55
|
-
if (!tdef.pwn.rwp) {
|
|
56
|
-
tdef.pwn.rwp = '%n';
|
|
57
|
-
}
|
|
58
|
-
if (!tdef.pwn.htype) {
|
|
59
|
-
tdef.pwn.htype = tdef.pwn.rwfunc;
|
|
60
|
-
}
|
|
61
|
-
// regular pawn access
|
|
62
|
-
return tdef.pwn;
|
|
63
|
-
}
|
|
64
|
-
const MICROTRONICS_DLO_CORE = 'Microtronics/dlo-core';
|
|
65
|
-
function getIncludedDloCoreVersion(manifest) {
|
|
66
|
-
if (manifest_1.Manifest.isLibrary(manifest) && manifest.name === 'dlo-core') {
|
|
67
|
-
return manifest.version;
|
|
68
|
-
}
|
|
69
|
-
else if (manifest.libraryDependencies && Object.hasOwn(manifest.libraryDependencies, MICROTRONICS_DLO_CORE)) {
|
|
70
|
-
return dependencies_1.Dependencies.rangeToVersion(manifest.libraryDependencies[MICROTRONICS_DLO_CORE]);
|
|
71
|
-
}
|
|
72
|
-
else if (manifest.libraryDevDependencies && Object.hasOwn(manifest.libraryDevDependencies, MICROTRONICS_DLO_CORE)) {
|
|
73
|
-
return dependencies_1.Dependencies.rangeToVersion(manifest.libraryDevDependencies[MICROTRONICS_DLO_CORE]);
|
|
74
|
-
}
|
|
75
|
-
return null;
|
|
76
|
-
}
|
|
77
|
-
function getApmVersion(manifest) {
|
|
78
|
-
const requiredVersion = getIncludedDloCoreVersion(manifest);
|
|
79
|
-
if (requiredVersion === null || semver.gte(requiredVersion, '0.3.0')) {
|
|
80
|
-
return semver.valid(manifest.version) ? manifest.version : semver.coerce(`${manifest.version}`);
|
|
81
|
-
}
|
|
82
|
-
else {
|
|
83
|
-
return semver.coerce(manifest.version)?.major;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* Determines if the dlo-core library version described in the provided manifest supports live data functionality.
|
|
88
|
-
*
|
|
89
|
-
* @param {Manifest.Manifest} manifest - The manifest object containing details about the DLO core.
|
|
90
|
-
* @return {boolean} Returns true if the dlo-core version supports live data, otherwise false.
|
|
91
|
-
*/
|
|
92
|
-
function dloCoreSupportsFlags(manifest) {
|
|
93
|
-
const requiredVersion = getIncludedDloCoreVersion(manifest);
|
|
94
|
-
if (requiredVersion === null) {
|
|
95
|
-
return false;
|
|
96
|
-
}
|
|
97
|
-
const releaseVersion = semver.coerce(requiredVersion);
|
|
98
|
-
return semver.gte(releaseVersion, '1.1.0');
|
|
99
|
-
}
|
|
100
|
-
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
101
|
-
function generateAutoIncFromMap(ddeMap, resolvedConfig, manifest) {
|
|
102
|
-
const _pwn = []; // sample code output for pawn
|
|
103
|
-
const pwn = _pwn.push.bind(_pwn);
|
|
104
|
-
function pwn_section(s) {
|
|
105
|
-
pwn(`\n// === ${s} ===\n`);
|
|
106
|
-
}
|
|
107
|
-
/**
|
|
108
|
-
* generate PROJECT META definitions
|
|
109
|
-
*/
|
|
110
|
-
pwn_section('PROJECT META');
|
|
111
|
-
function addDefinition(name, value, noString = false) {
|
|
112
|
-
let quotes = isNumeric(value) ? '' : '"';
|
|
113
|
-
if (noString) {
|
|
114
|
-
quotes = '';
|
|
115
|
-
}
|
|
116
|
-
pwn(`#define ${name} ${quotes}${value}${quotes}`);
|
|
117
|
-
}
|
|
118
|
-
const { dpid, registry } = manifest;
|
|
119
|
-
if (!dpid) {
|
|
120
|
-
throw new Error('Setting "dpid" is required to generate dlo files');
|
|
121
|
-
}
|
|
122
|
-
const { auto_inc } = DeviceProfiles_1.DeviceProfiles[dpid];
|
|
123
|
-
addDefinition(`APM_DPID`, `${dpid}`);
|
|
124
|
-
addDefinition(`APM_DPID_${dpid}`, `1`);
|
|
125
|
-
addDefinition(`APM_DPID_${dpid.toUpperCase()}`, `1`);
|
|
126
|
-
addDefinition(`APM_ID`, registry?.id || ''); //
|
|
127
|
-
const currVersion = getApmVersion(manifest);
|
|
128
|
-
addDefinition(`APM_VERSION`, `${currVersion}`); // 1,
|
|
129
|
-
addDefinition(`APM_NAME`, `${manifest.name}`); // "project X",
|
|
130
|
-
addDefinition(`APM_AUTHOR`, `${manifest.publisher}`);
|
|
131
|
-
for (const [name, value] of Object.entries(auto_inc)) {
|
|
132
|
-
// quote all non-numeric values
|
|
133
|
-
if (!isNumeric(value)) {
|
|
134
|
-
addDefinition(name, `"${value}"`);
|
|
135
|
-
}
|
|
136
|
-
else {
|
|
137
|
-
addDefinition(name, `${value}`);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
/**
|
|
141
|
-
* generate global dlo defines if there are any
|
|
142
|
-
*/
|
|
143
|
-
const globalDefines = resolvedConfig.flat;
|
|
144
|
-
const { definesWithSource } = resolvedConfig;
|
|
145
|
-
pwn_section('GLOBAL DEFINES');
|
|
146
|
-
for (const [define, value] of Object.entries(globalDefines)) {
|
|
147
|
-
const comment = definesWithSource[define]?.comment;
|
|
148
|
-
if (comment) {
|
|
149
|
-
const lines = comment.split('\n');
|
|
150
|
-
if (lines.length === 1) {
|
|
151
|
-
pwn(`/** ${lines[0]} */`);
|
|
152
|
-
}
|
|
153
|
-
else {
|
|
154
|
-
pwn('/**');
|
|
155
|
-
for (const line of lines) {
|
|
156
|
-
pwn(` * ${line}`);
|
|
157
|
-
}
|
|
158
|
-
pwn(' */');
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
const valueIsDefine = Object.hasOwn(globalDefines, value);
|
|
162
|
-
addDefinition(define, `${value}`, valueIsDefine);
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* generate DDE-CORE definitions
|
|
166
|
-
*/
|
|
167
|
-
let sz_max = 0; // maximum byte size over all configX and histdataX
|
|
168
|
-
const cx_szs = Array(10).fill(0); // configX byte size
|
|
169
|
-
let cx_isupm = 0; // configX upward - bitmask
|
|
170
|
-
let cx_isvolatilem = 0; // configX dlo-volatile - bitmask
|
|
171
|
-
let cx_isdnm = 0; // configX downward - bitmask
|
|
172
|
-
let cx_isvlm = 0; // configX variable length - bitmask
|
|
173
|
-
const cx_isrdef = 0; // configX variable length - bitmask
|
|
174
|
-
const hx_szs = Array(10).fill(0); // histdataX byte size
|
|
175
|
-
let hx_isvlm = 0; // histdataX variable length - bitmask
|
|
176
|
-
let aloha_varlen = undefined;
|
|
177
|
-
for (const [containerName, containerDefinition] of Object.entries(ddeMap.containers)) {
|
|
178
|
-
if (containerDefinition.containerType === ContainerType.cx &&
|
|
179
|
-
containerDefinition.transferDirection !== TransferDirection.backendOnly) {
|
|
180
|
-
const cx = parseInt(containerName.substring(6));
|
|
181
|
-
const cmsk = 1 << cx;
|
|
182
|
-
cx_szs[cx] = containerDefinition.size;
|
|
183
|
-
cx_isupm |= [
|
|
184
|
-
TransferDirection.both,
|
|
185
|
-
TransferDirection.none,
|
|
186
|
-
TransferDirection.deviceOnly,
|
|
187
|
-
TransferDirection.up,
|
|
188
|
-
TransferDirection.upPlus
|
|
189
|
-
].includes(containerDefinition.transferDirection)
|
|
190
|
-
? cmsk
|
|
191
|
-
: 0;
|
|
192
|
-
cx_isvolatilem |= containerDefinition.volatile ? cmsk : 0;
|
|
193
|
-
cx_isdnm |= [
|
|
194
|
-
TransferDirection.both,
|
|
195
|
-
TransferDirection.none,
|
|
196
|
-
TransferDirection.deviceOnly,
|
|
197
|
-
TransferDirection.down,
|
|
198
|
-
TransferDirection.downPlus
|
|
199
|
-
].includes(containerDefinition.transferDirection)
|
|
200
|
-
? cmsk
|
|
201
|
-
: 0;
|
|
202
|
-
cx_isvlm |= [TransferDirection.bothPlus, TransferDirection.upPlus, TransferDirection.downPlus].includes(containerDefinition.transferDirection)
|
|
203
|
-
? cmsk
|
|
204
|
-
: 0;
|
|
205
|
-
// cx_isrdef |= cont.rdef ? 1 << cx : 0; //validation for down/down+ is don in the dde
|
|
206
|
-
sz_max = Math.max(sz_max, containerDefinition.size);
|
|
207
|
-
}
|
|
208
|
-
else if (containerDefinition.containerType === ContainerType.hx) {
|
|
209
|
-
const hx = parseInt(containerName.substring(8));
|
|
210
|
-
hx_szs[hx] = containerDefinition.size;
|
|
211
|
-
hx_isvlm |= [TransferDirection.upPlus].includes(containerDefinition.transferDirection) ? 1 << hx : 0;
|
|
212
|
-
sz_max = Math.max(sz_max, containerDefinition.size);
|
|
213
|
-
}
|
|
214
|
-
else if (containerDefinition.containerType === ContainerType.aloha) {
|
|
215
|
-
aloha_varlen = [TransferDirection.upPlus].includes(containerDefinition.transferDirection);
|
|
216
|
-
sz_max = Math.max(sz_max, containerDefinition.size);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
pwn_section('DDE CORE');
|
|
220
|
-
pwn(`#define _DDE_BUF_BYTES (${sz_max}+10)`); // todo rem +10 ??? round to next multiple of 4 ???
|
|
221
|
-
pwn('');
|
|
222
|
-
pwn('// c0\tc1\tc2\tc3\tc4\tc5\tc6\tc7\tc8\tc9');
|
|
223
|
-
pwn(`stock _DDE_CONFIGS_size[] =[ ${cx_szs.join(',\t')}];`);
|
|
224
|
-
pwn(`#define _DDE_CONFIGS_upm 0b${cx_isupm.toString(2)} // ..is tolerant when reading back container with under-length`);
|
|
225
|
-
pwn(`#define _DDE_CONFIGS_volatilem 0b${cx_isvolatilem.toString(2)} // inits container as volatile`);
|
|
226
|
-
pwn(`#define _DDE_CONFIGS_downm 0b${cx_isdnm.toString(2)} // reading the container expects strict length`);
|
|
227
|
-
pwn(`#define _DDE_CONFIGS_varlenm 0b${cx_isvlm.toString(2)} // allow partial write (dde_wxxx)`);
|
|
228
|
-
pwn(`#define _DDE_CONFIGS_rdef 0b${cx_isrdef.toString(2)} // ..apply defaults reading a container with under-length`);
|
|
229
|
-
pwn('');
|
|
230
|
-
pwn('// h0\th1\th2\th3\th4\th5\th6\th7\th8\th9');
|
|
231
|
-
pwn(`stock _DDE_HISTS_size[] =[ ${hx_szs.join(',\t')}];`);
|
|
232
|
-
pwn(`#define _DDE_HISTS_varlenm 0b${hx_isvlm.toString(2)} // allow partial write (dde_wxxx)`);
|
|
233
|
-
//see #RS-279 for more information about the _DDE_HISTS_maxsize
|
|
234
|
-
const szs = [...hx_szs];
|
|
235
|
-
if (Object.hasOwn(ddeMap, 'applog')) {
|
|
236
|
-
szs.push(125);
|
|
237
|
-
}
|
|
238
|
-
if (Object.hasOwn(ddeMap, 'alerts')) {
|
|
239
|
-
szs.push(13);
|
|
240
|
-
}
|
|
241
|
-
pwn(`#define _DDE_HISTS_maxsize ${Math.max(...szs)}`);
|
|
242
|
-
pwn('');
|
|
243
|
-
if (aloha_varlen !== undefined) {
|
|
244
|
-
pwn(`#define _DDE_ALOHA_varlen ${aloha_varlen ? 1 : 0}`);
|
|
245
|
-
pwn('');
|
|
246
|
-
}
|
|
247
|
-
// generate
|
|
248
|
-
// #define DDE_xxx_id
|
|
249
|
-
// #define DDE_xxx_sz
|
|
250
|
-
// #define DDE_xxx_idx
|
|
251
|
-
for (const [containerName, containerDefinition] of Object.entries(ddeMap.containers)) {
|
|
252
|
-
//special handling for applog container is handled afterwards
|
|
253
|
-
if (containerDefinition.containerType === 'applog') {
|
|
254
|
-
continue;
|
|
255
|
-
}
|
|
256
|
-
pwn_section(`${containerDefinition.title.toUpperCase()} - ${containerDefinition.transferDirection} via #${containerName}`);
|
|
257
|
-
const cid_base = CONTAINER_DEF_DLO_CID_BASE(containerDefinition.containerType, containerDefinition.transferDirection);
|
|
258
|
-
if (!cid_base) {
|
|
259
|
-
pwn(`// ... container not available in DLO`);
|
|
260
|
-
continue;
|
|
261
|
-
}
|
|
262
|
-
const preAlias = `DDE_${containerDefinition.containerType === ContainerType.aloha ? ContainerType.aloha : containerDefinition.title}`;
|
|
263
|
-
const CDEF = CONTAINER_DEFS[containerName];
|
|
264
|
-
pwn(`// ${preAlias}_id - container identifier required for ${preAlias}_read/_write operations`);
|
|
265
|
-
pwn(`#define ${preAlias}_id (${cid_base}+${CDEF.cnum || 0})`);
|
|
266
|
-
pwn(`// ${preAlias}_sz - [byte] container total size`);
|
|
267
|
-
pwn(`#define ${preAlias}_sz ${containerDefinition.size}`);
|
|
268
|
-
if (CDEF.cnum !== undefined) {
|
|
269
|
-
pwn(`// ${preAlias}_idx - 0+ container index number`);
|
|
270
|
-
pwn(`#define ${preAlias}_idx ${CDEF.cnum}`);
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
// setup results
|
|
274
|
-
return _pwn.join('\n');
|
|
275
|
-
}
|
|
276
|
-
class AutoDDEGenerator {
|
|
277
|
-
manifest;
|
|
278
|
-
ddeMap;
|
|
279
|
-
context;
|
|
280
|
-
globalVariables = [];
|
|
281
|
-
pawnGlobalSource = [];
|
|
282
|
-
pawnHelperSource = [];
|
|
283
|
-
timeSeriesSource = [];
|
|
284
|
-
readWriteSource = [];
|
|
285
|
-
definesSource = [];
|
|
286
|
-
defaultDefinesSource = [];
|
|
287
|
-
knownDefines = [];
|
|
288
|
-
pawnIndent = 0;
|
|
289
|
-
sourceType;
|
|
290
|
-
constructor(manifest, ddeMap, context) {
|
|
291
|
-
this.manifest = manifest;
|
|
292
|
-
this.ddeMap = ddeMap;
|
|
293
|
-
this.context = context;
|
|
294
|
-
this.sourceType = 'pawnSource';
|
|
295
|
-
}
|
|
296
|
-
pawn(a, b) {
|
|
297
|
-
if (b && a === '<') {
|
|
298
|
-
this.pawnIndent--;
|
|
299
|
-
}
|
|
300
|
-
const sourceToPush = {
|
|
301
|
-
pawnSource: this.pawnGlobalSource,
|
|
302
|
-
globalVariables: this.globalVariables,
|
|
303
|
-
timeseries: this.timeSeriesSource,
|
|
304
|
-
readWrite: this.readWriteSource,
|
|
305
|
-
defines: this.definesSource,
|
|
306
|
-
defaultDefines: this.defaultDefinesSource
|
|
307
|
-
}[this.sourceType];
|
|
308
|
-
sourceToPush.push('\t'.repeat(this.pawnIndent) + (b || a));
|
|
309
|
-
if (b && a === '>') {
|
|
310
|
-
this.pawnIndent++;
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
generate() {
|
|
314
|
-
for (const [containerName, containerDefinition] of Object.entries(this.ddeMap.containers)) {
|
|
315
|
-
// check if the given library uses this container
|
|
316
|
-
if (this.context && !containerDefinition.libraries.includes(this.context)) {
|
|
317
|
-
continue;
|
|
318
|
-
}
|
|
319
|
-
const containerIdBase = CONTAINER_DEF_DLO_CID_BASE(containerDefinition.containerType, containerDefinition.transferDirection);
|
|
320
|
-
//container is not available in dlo or has any fields
|
|
321
|
-
if (!containerIdBase || !containerDefinition.fields) {
|
|
322
|
-
continue;
|
|
323
|
-
}
|
|
324
|
-
// only generate the apps rw functions if the app has defined fields
|
|
325
|
-
if (!this.context && !coreDefinitions_1.DDE_Core.hasContainerAppFields(containerDefinition)) {
|
|
326
|
-
continue;
|
|
327
|
-
}
|
|
328
|
-
const CONTDEF = CONTAINER_DEFS[containerName];
|
|
329
|
-
if (CONTDEF.ctype !== ContainerType.cx && this.context) {
|
|
330
|
-
continue;
|
|
331
|
-
}
|
|
332
|
-
this.generateGlobalVarsForContainer(containerDefinition);
|
|
333
|
-
this.generateReadWriteFunctions(containerDefinition);
|
|
334
|
-
}
|
|
335
|
-
this.mergeSourceTypes();
|
|
336
|
-
return { globals: this.pawnGlobalSource, helper: this.pawnHelperSource };
|
|
337
|
-
}
|
|
338
|
-
createGlobalVar(variableName, field) {
|
|
339
|
-
this.sourceType = 'globalVariables';
|
|
340
|
-
const varName = field ? this.variableNameForPawnDefinition(variableName, field) : variableName;
|
|
341
|
-
if (field) {
|
|
342
|
-
const comment = this.generateCommentForField(field);
|
|
343
|
-
if (comment) {
|
|
344
|
-
if (Array.isArray(comment)) {
|
|
345
|
-
this.pawn('/**');
|
|
346
|
-
comment.forEach(line => {
|
|
347
|
-
this.pawn(` * ${line}`);
|
|
348
|
-
});
|
|
349
|
-
this.pawn(' */');
|
|
350
|
-
}
|
|
351
|
-
else {
|
|
352
|
-
this.pawn(`// ${comment}`);
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
this.pawn(`stock ${varName};`);
|
|
357
|
-
}
|
|
358
|
-
insertSection(title) {
|
|
359
|
-
this.pawn('');
|
|
360
|
-
this.pawn('// =============================================================================');
|
|
361
|
-
this.pawn(`// ${title}`);
|
|
362
|
-
this.pawn('// =============================================================================');
|
|
363
|
-
this.pawn('');
|
|
364
|
-
}
|
|
365
|
-
mergeSourceTypes() {
|
|
366
|
-
this.sourceType = 'pawnSource';
|
|
367
|
-
if (this.definesSource.length) {
|
|
368
|
-
this.insertSection('Defines');
|
|
369
|
-
this.pawnGlobalSource.push(...this.definesSource);
|
|
370
|
-
}
|
|
371
|
-
if (this.defaultDefinesSource.length) {
|
|
372
|
-
this.insertSection('Field defaults');
|
|
373
|
-
this.pawnGlobalSource.push(...this.defaultDefinesSource);
|
|
374
|
-
}
|
|
375
|
-
if (this.globalVariables.length) {
|
|
376
|
-
this.insertSection('Global Variables');
|
|
377
|
-
this.pawnGlobalSource.push(...this.globalVariables);
|
|
378
|
-
}
|
|
379
|
-
if (this.readWriteSource.length) {
|
|
380
|
-
this.insertSection('Internal read/write calls');
|
|
381
|
-
this.pawnHelperSource.push(...this.readWriteSource);
|
|
382
|
-
}
|
|
383
|
-
this.pawn('');
|
|
384
|
-
}
|
|
385
|
-
generateGlobalVarsForContainer(containerDefinition) {
|
|
386
|
-
// this.globalVariables.push('// === Global variables ===');
|
|
387
|
-
this.sourceType = 'globalVariables';
|
|
388
|
-
this.pawn('');
|
|
389
|
-
this.pawn(`// Container '${containerDefinition.title.replace('_', ' ')}'`);
|
|
390
|
-
this.pawn('');
|
|
391
|
-
const pre = `DDE_${containerDefinition.title}`;
|
|
392
|
-
// defines for arrays
|
|
393
|
-
for (const arrayInfo of Object.values(containerDefinition.arrays)) {
|
|
394
|
-
if (this.context !== arrayInfo.library) {
|
|
395
|
-
continue;
|
|
396
|
-
}
|
|
397
|
-
const arrayDimension = `${pre}_${arrayInfo.name}_dim`;
|
|
398
|
-
this.sourceType = 'defines';
|
|
399
|
-
this.pawn(`#define ${arrayDimension} ${arrayInfo.length}`);
|
|
400
|
-
if (arrayInfo.fields) {
|
|
401
|
-
const fakeDDEContainer = {
|
|
402
|
-
...containerDefinition
|
|
403
|
-
};
|
|
404
|
-
fakeDDEContainer.fields = [];
|
|
405
|
-
arrayInfo.fields.forEach(field => {
|
|
406
|
-
fakeDDEContainer.fields.push({
|
|
407
|
-
arrayRef: null,
|
|
408
|
-
shadowRef: null,
|
|
409
|
-
byteOffset: 0,
|
|
410
|
-
byteSize: field.byteSize,
|
|
411
|
-
id: field.name,
|
|
412
|
-
library: arrayInfo.library,
|
|
413
|
-
name: field.name,
|
|
414
|
-
type: field.type,
|
|
415
|
-
title: null,
|
|
416
|
-
index: 0
|
|
417
|
-
});
|
|
418
|
-
});
|
|
419
|
-
const arrayStructure = `${pre}_${arrayInfo.name}_def`;
|
|
420
|
-
this.generateTypeDefinitions(fakeDDEContainer, arrayStructure);
|
|
421
|
-
this.createGlobalVar(`${pre}_${arrayInfo.name}[${arrayDimension}][${arrayStructure}]`);
|
|
422
|
-
}
|
|
423
|
-
else {
|
|
424
|
-
this.createGlobalVar(`${pre}_${arrayInfo.name}[${arrayDimension}]`);
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
for (const field of containerDefinition.fields) {
|
|
428
|
-
if (field.type === 'shadow' || field.shadowRef || field.library !== this.context) {
|
|
429
|
-
continue;
|
|
430
|
-
}
|
|
431
|
-
// generate defines for array fields
|
|
432
|
-
if (field.arrayRef !== null) {
|
|
433
|
-
const ref = containerDefinition.arrays[field.arrayRef.name];
|
|
434
|
-
let defineName = `${pre}_${field.arrayRef.name}`;
|
|
435
|
-
// this is a structured array, add the field name to the define
|
|
436
|
-
if (ref.fields?.length) {
|
|
437
|
-
defineName += `_${field.name.split('.')[1]}`;
|
|
438
|
-
}
|
|
439
|
-
this.createDefaultDefineForField(defineName, field);
|
|
440
|
-
continue;
|
|
441
|
-
}
|
|
442
|
-
const variableName = this.generateFieldVariableName(pre, field);
|
|
443
|
-
this.createDefaultDefineForField(variableName, field);
|
|
444
|
-
this.createGlobalVar(`${variableName}`, field);
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
generateCommentForField(field) {
|
|
448
|
-
const fieldComment = [`@type ${field.type}`];
|
|
449
|
-
if (field.description) {
|
|
450
|
-
fieldComment.unshift(field.description);
|
|
451
|
-
}
|
|
452
|
-
if (field.defaultValue !== undefined) {
|
|
453
|
-
const { value, reason } = this.parseFieldDefault(field);
|
|
454
|
-
fieldComment.push(`@default ${value} ${reason || ''}`);
|
|
455
|
-
}
|
|
456
|
-
return fieldComment;
|
|
457
|
-
}
|
|
458
|
-
generateFieldVariableName(pre, field) {
|
|
459
|
-
const fieldVariableName = `${pre}_${field.name}`;
|
|
460
|
-
const isBlob = Object.hasOwn(fieldTypeDefinitions, field.type) && fieldTypeDefinitions[field.type].isBlob;
|
|
461
|
-
const dim = field.byteSize;
|
|
462
|
-
if (dim && isBlob) {
|
|
463
|
-
const loopVar = 'i';
|
|
464
|
-
this.sourceType = 'defines';
|
|
465
|
-
this.pawn(`#define ${pre}_${field.name}_dim ${dim}`);
|
|
466
|
-
this.pawn(`#define ${pre}_${field.name}_iter() for(new ${loopVar}=0;${loopVar}<${dim};${loopVar}++)`);
|
|
467
|
-
}
|
|
468
|
-
this.sourceType = 'globalVariables';
|
|
469
|
-
return fieldVariableName;
|
|
470
|
-
}
|
|
471
|
-
// generate type declarations
|
|
472
|
-
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
473
|
-
generateTypeDefinitions(containerDefinition, base) {
|
|
474
|
-
this.sourceType = 'defines';
|
|
475
|
-
const xfields = containerDefinition.fields;
|
|
476
|
-
if (!xfields) {
|
|
477
|
-
return;
|
|
478
|
-
}
|
|
479
|
-
const knownArrays = [];
|
|
480
|
-
this.pawn('>', `#define ${base} [`);
|
|
481
|
-
for (const field of xfields) {
|
|
482
|
-
if (field.type === 'shadow' || field.shadowRef) {
|
|
483
|
-
continue;
|
|
484
|
-
}
|
|
485
|
-
// validate context of field
|
|
486
|
-
if (field.library !== this.context) {
|
|
487
|
-
continue;
|
|
488
|
-
}
|
|
489
|
-
// avoid creating multiple definitions if the field is part of an array
|
|
490
|
-
const arrayRef = field.arrayRef;
|
|
491
|
-
if (arrayRef) {
|
|
492
|
-
const arrayInfo = containerDefinition.arrays[arrayRef.name];
|
|
493
|
-
if (!knownArrays.includes(arrayRef.name) && !arrayInfo.fields) {
|
|
494
|
-
knownArrays.push(arrayRef.name);
|
|
495
|
-
}
|
|
496
|
-
else {
|
|
497
|
-
continue;
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
const fieldName = field.arrayRef ? field.arrayRef.name : field.name;
|
|
501
|
-
const fld_dim = field.arrayRef ? `[${base}_${fieldName}_dim]` : '';
|
|
502
|
-
// let comment = fld.xfields ? `${base}_${fld.name}` : fld.type; // original DDE field type as comment
|
|
503
|
-
let fld_def = '';
|
|
504
|
-
if (field.type === 'struct') {
|
|
505
|
-
fld_def = '// .' + fieldName + fld_dim; // comment out if it's a struct field
|
|
506
|
-
}
|
|
507
|
-
else {
|
|
508
|
-
const tdef_pwn = getPawnTypeDefinition(field);
|
|
509
|
-
if (!tdef_pwn) {
|
|
510
|
-
continue;
|
|
511
|
-
} // error - do nothing
|
|
512
|
-
if (tdef_pwn === 'skip') {
|
|
513
|
-
fld_def = `// skipped - .${fieldName}${fld_dim}`; // '.xyz[5]'
|
|
514
|
-
}
|
|
515
|
-
else {
|
|
516
|
-
fld_def += tdef_pwn.rwp.replace('%n', `.${fieldName}${fld_dim}`).replace('%l', field.byteSize);
|
|
517
|
-
}
|
|
518
|
-
}
|
|
519
|
-
fld_def += ',';
|
|
520
|
-
// add library comment if the field comes from an library
|
|
521
|
-
if (field.library) {
|
|
522
|
-
fld_def += `\t // declared by ${field.library} library`;
|
|
523
|
-
}
|
|
524
|
-
this.pawn(fld_def);
|
|
525
|
-
}
|
|
526
|
-
this.pawn('<', ']');
|
|
527
|
-
}
|
|
528
|
-
variableNameForPawnDefinition(variableName, field) {
|
|
529
|
-
// variable name based on the pawn definitions
|
|
530
|
-
const pawnTypeDefinition = getPawnTypeDefinition(field);
|
|
531
|
-
if (pawnTypeDefinition && pawnTypeDefinition !== 'skip') {
|
|
532
|
-
return pawnTypeDefinition.rwp.replace('%n', `${variableName}`).replace('%l', field.byteSize);
|
|
533
|
-
}
|
|
534
|
-
return variableName;
|
|
535
|
-
}
|
|
536
|
-
createDefaultDefineForField(variableName, field) {
|
|
537
|
-
this.sourceType = 'defaultDefines';
|
|
538
|
-
if (field.scale !== undefined) {
|
|
539
|
-
this.addDefine(`${variableName}_scale`, field.scale);
|
|
540
|
-
}
|
|
541
|
-
if (field.offset !== undefined) {
|
|
542
|
-
this.addDefine(`${variableName}_offset`, field.offset);
|
|
543
|
-
}
|
|
544
|
-
if (field.defaultValue !== undefined) {
|
|
545
|
-
const { value, reason } = this.parseFieldDefault(field);
|
|
546
|
-
const defineName = `${variableName}_default`;
|
|
547
|
-
field.defaultDloDefine = defineName;
|
|
548
|
-
this.addDefine(defineName, value, reason);
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
/**
|
|
552
|
-
* Add given variable as define to the dlo source
|
|
553
|
-
* @param name of define
|
|
554
|
-
* @param value of define
|
|
555
|
-
* @param reason comment for define
|
|
556
|
-
* @private
|
|
557
|
-
*/
|
|
558
|
-
addDefine(name, value, reason) {
|
|
559
|
-
const containerRelation = regexRelation.exec(`${value}`);
|
|
560
|
-
if (containerRelation) {
|
|
561
|
-
return;
|
|
562
|
-
}
|
|
563
|
-
if (!this.knownDefines.includes(name)) {
|
|
564
|
-
if (reason) {
|
|
565
|
-
this.pawn(`// ${reason}`);
|
|
566
|
-
}
|
|
567
|
-
this.pawn(`#define ${name} ${value}`);
|
|
568
|
-
this.knownDefines.push(name);
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
generateReadWriteFunctions(containerDefinition) {
|
|
572
|
-
const containerName = containerDefinition.name;
|
|
573
|
-
const CONTDEF = CONTAINER_DEFS[containerName];
|
|
574
|
-
const pre = `DDE_${containerDefinition.containerType === ContainerType.aloha ? ContainerType.aloha : containerDefinition.title}`;
|
|
575
|
-
// ---
|
|
576
|
-
// add write method - but for UP_ward containers only
|
|
577
|
-
// ---
|
|
578
|
-
if ([
|
|
579
|
-
TransferDirection.both,
|
|
580
|
-
TransferDirection.bothPlus,
|
|
581
|
-
TransferDirection.none,
|
|
582
|
-
TransferDirection.deviceOnly,
|
|
583
|
-
TransferDirection.up,
|
|
584
|
-
TransferDirection.upPlus
|
|
585
|
-
].includes(containerDefinition.transferDirection)) {
|
|
586
|
-
this.generateWriteMethod(pre, containerDefinition);
|
|
587
|
-
}
|
|
588
|
-
// ---
|
|
589
|
-
// add read method - but for CONFIG0-9 containers only
|
|
590
|
-
// ---
|
|
591
|
-
if (CONTDEF.ctype === ContainerType.cx) {
|
|
592
|
-
this.generateReadMethod(pre, containerDefinition);
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
generateWriteMethod(pre, containerDefinition) {
|
|
596
|
-
this.sourceType = 'readWrite';
|
|
597
|
-
const containerID = `DDE_${containerDefinition.title}_id`;
|
|
598
|
-
const isTimeseriesOrAloha = [ContainerType.hx, ContainerType.aloha].includes(containerDefinition.containerType);
|
|
599
|
-
const isTimeseriesContainer = containerDefinition.containerType === ContainerType.hx;
|
|
600
|
-
const isAlohaContainer = containerDefinition.containerType === ContainerType.aloha;
|
|
601
|
-
const funcWrite = `_${pre}_write`;
|
|
602
|
-
const timeseriesFlags = dloCoreSupportsFlags(this.manifest) ? ', flags' : '';
|
|
603
|
-
const timeseriesOrAlohaArguments = isTimeseriesContainer ? `stamp${timeseriesFlags}` : '';
|
|
604
|
-
const funcWriteFlags = dloCoreSupportsFlags(this.manifest) ? 'const stamp=0, const flags=0' : 'const stamp=0';
|
|
605
|
-
this.pawn('>', `stock ${funcWrite}(${isTimeseriesContainer ? funcWriteFlags : ''}) {`);
|
|
606
|
-
// only aloha and time series write directly to the container
|
|
607
|
-
if (isTimeseriesOrAloha) {
|
|
608
|
-
this.pawn(`dde_wbegin(DDE_${isAlohaContainer ? ContainerType.aloha : containerDefinition.title}_id);`); // " dde_wbegin( DDE_status_id);"
|
|
609
|
-
}
|
|
610
|
-
this.generateRWFunctionBody(pre, containerDefinition, 'dde_w');
|
|
611
|
-
// only aloha and time series write directly to the container
|
|
612
|
-
if (isTimeseriesOrAloha) {
|
|
613
|
-
this.pawn(`return dde_wend(${timeseriesOrAlohaArguments});`); // " dde_wend();"
|
|
614
|
-
}
|
|
615
|
-
this.pawn('<', '}');
|
|
616
|
-
this.pawn('');
|
|
617
|
-
// flush function
|
|
618
|
-
this.sourceType = 'globalVariables';
|
|
619
|
-
const funcFlush = `${pre}_transfer`;
|
|
620
|
-
const funcPersist = `${pre}_persist`;
|
|
621
|
-
const funcArgs = this.functionArgumentsForDdeWrite(isTimeseriesContainer, isTimeseriesOrAloha);
|
|
622
|
-
this.pawn('>', `${this.context ? 'stock ' : ''}${funcFlush}(${funcArgs}) {`);
|
|
623
|
-
if (isTimeseriesOrAloha) {
|
|
624
|
-
this.pawn(`${funcWrite}(${timeseriesOrAlohaArguments});`);
|
|
625
|
-
}
|
|
626
|
-
else {
|
|
627
|
-
const containerNumber = containerDefinition.name.slice(-1);
|
|
628
|
-
this.pawn(`dde_flush(${containerNumber}, immediate);`);
|
|
629
|
-
}
|
|
630
|
-
this.pawn('<', '}');
|
|
631
|
-
this.pawn('');
|
|
632
|
-
if (containerDefinition.volatile) {
|
|
633
|
-
// generate persist function declaration
|
|
634
|
-
this.pawn('>', `stock ${funcPersist}() {`);
|
|
635
|
-
this.pawn(`return rM2M_CfgFlush(${containerID});`);
|
|
636
|
-
this.pawn('<', '}');
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
/**
|
|
640
|
-
* if it's a timeseries container the argument is `const stamp=0`
|
|
641
|
-
* if it's a configuration container the argument is `bool:immediate=false`
|
|
642
|
-
* @param isTimeseriesContainer
|
|
643
|
-
* @param isTimeseriesOrAloha
|
|
644
|
-
* @private
|
|
645
|
-
*/
|
|
646
|
-
functionArgumentsForDdeWrite(isTimeseriesContainer, isTimeseriesOrAloha) {
|
|
647
|
-
const timeseriesFlags = dloCoreSupportsFlags(this.manifest) ? ', const flags=0' : '';
|
|
648
|
-
return isTimeseriesContainer
|
|
649
|
-
? `const stamp=0${timeseriesFlags}`
|
|
650
|
-
: isTimeseriesOrAloha
|
|
651
|
-
? ''
|
|
652
|
-
: 'bool:immediate=false';
|
|
653
|
-
}
|
|
654
|
-
generateReadMethod(pre, containerDefinition) {
|
|
655
|
-
this.sourceType = 'readWrite';
|
|
656
|
-
// const containerID = `${pre}_id`;
|
|
657
|
-
// todo implement as "hidden" function
|
|
658
|
-
const funcRead = `_${pre}_read`;
|
|
659
|
-
this.pawn('>', `stock ${funcRead}() {`);
|
|
660
|
-
this.generateRWFunctionBody(pre, containerDefinition, 'dde_r');
|
|
661
|
-
this.pawn('<', '}');
|
|
662
|
-
this.pawn('');
|
|
663
|
-
}
|
|
664
|
-
generateRWFunctionBody(pre, containerDefinition, ddeFunc) {
|
|
665
|
-
const xfields = containerDefinition.fields;
|
|
666
|
-
for (const fld of xfields) {
|
|
667
|
-
// validate context of field
|
|
668
|
-
if (fld.type === 'shadow' || fld.shadowRef || fld.library !== this.context) {
|
|
669
|
-
continue;
|
|
670
|
-
}
|
|
671
|
-
// assert(!fld.xfields);
|
|
672
|
-
const tdef_pwn = getPawnTypeDefinition(fld); // pawn access methods to use
|
|
673
|
-
if (!tdef_pwn || tdef_pwn === 'skip') {
|
|
674
|
-
continue;
|
|
675
|
-
}
|
|
676
|
-
// set the byte offset for the next field
|
|
677
|
-
this.pawn(`_dde_idx = ${fld.byteOffset};`);
|
|
678
|
-
let s = ''; // resulting pawn line e.g. " dde_wu32( o.live_trg);"
|
|
679
|
-
s += ddeFunc;
|
|
680
|
-
s += tdef_pwn.rwfunc;
|
|
681
|
-
const fieldName = `${pre}_${fld.name}`;
|
|
682
|
-
s += `(${fieldName}`;
|
|
683
|
-
if (tdef_pwn.rwlen) {
|
|
684
|
-
s += `, ${fld.byteSize}`;
|
|
685
|
-
} // add byte/cellcount on strings & buffers
|
|
686
|
-
// add the default field value to the read function only
|
|
687
|
-
if (fld.defaultDloDefine !== undefined && ddeFunc === 'dde_r') {
|
|
688
|
-
s += `, ${fld.defaultDloDefine}`;
|
|
689
|
-
}
|
|
690
|
-
this.pawn(s + `);`);
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
parseFieldDefault(field) {
|
|
694
|
-
const typeDefinitions = getPawnTypeDefinition(field);
|
|
695
|
-
let defaultValue = field.defaultValue;
|
|
696
|
-
function buildReturnObject(value, reason) {
|
|
697
|
-
return { value, reason };
|
|
698
|
-
}
|
|
699
|
-
//modify the default value based on the string type. Either " or '';
|
|
700
|
-
switch (field.type) {
|
|
701
|
-
case 'astring':
|
|
702
|
-
case 'nstring':
|
|
703
|
-
case 'cstring': {
|
|
704
|
-
return buildReturnObject(`"${defaultValue}"`);
|
|
705
|
-
}
|
|
706
|
-
case 'wstring': {
|
|
707
|
-
return buildReturnObject(`''${defaultValue}''`);
|
|
708
|
-
}
|
|
709
|
-
case 'ustring': {
|
|
710
|
-
return buildReturnObject(`/* default not supported: ${defaultValue} */`);
|
|
711
|
-
}
|
|
712
|
-
case 'binary': {
|
|
713
|
-
// convert hex value to byte array equivalent...
|
|
714
|
-
const splitted = defaultValue.substring(2).match(/.{1,2}/g) || [];
|
|
715
|
-
const byteArray = `{ 0x${splitted.join(', 0x')} }`;
|
|
716
|
-
return buildReturnObject(byteArray);
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
if (defaultValue === 'NaN') {
|
|
720
|
-
const dataType = typeDefinitions.rwfunc;
|
|
721
|
-
return buildReturnObject(`${dataType}_NaN`.toUpperCase());
|
|
722
|
-
}
|
|
723
|
-
const scaledDefault = this.parseFieldScaleOffset(field);
|
|
724
|
-
if (scaledDefault) {
|
|
725
|
-
return buildReturnObject(scaledDefault.calculated, scaledDefault.reason);
|
|
726
|
-
}
|
|
727
|
-
// add missing fractionDigits to float types
|
|
728
|
-
if (defaultValue !== undefined &&
|
|
729
|
-
!regexRelation.exec(`${defaultValue}`) &&
|
|
730
|
-
field.type.startsWith('float') &&
|
|
731
|
-
defaultValue % 1 === 0) {
|
|
732
|
-
defaultValue = defaultValue.toFixed(field.decimalPlaces || 1);
|
|
733
|
-
}
|
|
734
|
-
return buildReturnObject(`${defaultValue}`);
|
|
735
|
-
}
|
|
736
|
-
/**
|
|
737
|
-
* Try to calculate the default value based on scale and offset
|
|
738
|
-
* @param field
|
|
739
|
-
* @private
|
|
740
|
-
*/
|
|
741
|
-
parseFieldScaleOffset(field) {
|
|
742
|
-
const defaultValue = field.defaultValue;
|
|
743
|
-
// validate if any of the given fields has a relation to another container
|
|
744
|
-
const isAnyRelation = !!regexRelation.exec(`${field.offset}`) ||
|
|
745
|
-
!!regexRelation.exec(`${field.scale}`) ||
|
|
746
|
-
!!regexRelation.exec(`${field.defaultValue}`);
|
|
747
|
-
// scale || offset is set
|
|
748
|
-
if (!isAnyRelation && (field.offset !== undefined || field.scale !== undefined)) {
|
|
749
|
-
const offset = field.offset !== undefined ? Number(field.offset) : 0;
|
|
750
|
-
const scale = field.scale !== undefined ? Number(field.scale) : 1;
|
|
751
|
-
// calculate the original value without scale and offset
|
|
752
|
-
let calculated = (Number(defaultValue) - offset) / scale;
|
|
753
|
-
let reason = `(defaultValue - offset) / scale -> (${defaultValue} - ${offset}) / ${scale}`;
|
|
754
|
-
// field type is no float - round to integer
|
|
755
|
-
if (!field.type.startsWith('float')) {
|
|
756
|
-
calculated = Math.round(calculated);
|
|
757
|
-
reason = `Rounded value of: ${reason}`;
|
|
758
|
-
}
|
|
759
|
-
else if (calculated % 1 === 0) {
|
|
760
|
-
calculated = calculated.toFixed(1);
|
|
761
|
-
}
|
|
762
|
-
return { calculated, reason };
|
|
763
|
-
}
|
|
764
|
-
return null;
|
|
765
|
-
}
|
|
766
|
-
}
|
|
767
|
-
exports.AutoDDEGenerator = AutoDDEGenerator;
|
|
768
|
-
// eslint-disable-next-line sonarjs/cognitive-complexity
|
|
769
|
-
function generateAutoUplinkIncFromMap(ddeMap,
|
|
770
|
-
/**
|
|
771
|
-
* The names of the included libraries
|
|
772
|
-
*/
|
|
773
|
-
includedLibNames) {
|
|
774
|
-
const _pwn = [];
|
|
775
|
-
const pwn = _pwn.push.bind(_pwn);
|
|
776
|
-
// collect containers to apply/restore23
|
|
777
|
-
const containerApply = [];
|
|
778
|
-
const containerRestore = [];
|
|
779
|
-
function buildUplinkApplyCall(applyName) {
|
|
780
|
-
const funcName = `onUplinkApply_${applyName}()`;
|
|
781
|
-
return `${funcName};`;
|
|
782
|
-
}
|
|
783
|
-
function buildLibraryRestoreApplyCall(cont, restoreApply) {
|
|
784
|
-
cont.libraries.forEach(libraryName => {
|
|
785
|
-
const hashedLib = helper_1.Helper.generateHashForLibraryName(libraryName);
|
|
786
|
-
pwn(`\t#ifdef _${hashedLib}${restoreApply}_${cont.title}`);
|
|
787
|
-
pwn(`\t\t_${hashedLib}${restoreApply}_${cont.title}();\t// ${libraryName}`);
|
|
788
|
-
pwn('\t#endif');
|
|
789
|
-
});
|
|
790
|
-
}
|
|
791
|
-
//generate onUplinkEvent dispatcher
|
|
792
|
-
pwn(`stock _onUplinkEvent(ev, param) {`);
|
|
793
|
-
// insert library calls...
|
|
794
|
-
includedLibNames.forEach(libraryName => {
|
|
795
|
-
const hashedName = helper_1.Helper.generateHashForLibraryName(libraryName);
|
|
796
|
-
const funcName = `_${hashedName}UplinkEvent`;
|
|
797
|
-
pwn(`\t#ifdef ${funcName}`);
|
|
798
|
-
pwn(`\t\t${funcName}(ev, param);`);
|
|
799
|
-
pwn(`\t#endif`);
|
|
800
|
-
});
|
|
801
|
-
pwn(`\tonUplinkEvent(ev, param);`);
|
|
802
|
-
pwn(`}`);
|
|
803
|
-
for (const [containerName, containerDefinition] of Object.entries(ddeMap.containers)) {
|
|
804
|
-
const CONTDEF = CONTAINER_DEFS[containerName];
|
|
805
|
-
if (CONTDEF.ctype !== ContainerType.cx) {
|
|
806
|
-
continue;
|
|
807
|
-
}
|
|
808
|
-
if ([TransferDirection.up, TransferDirection.upPlus, TransferDirection.deviceOnly].includes(containerDefinition.transferDirection)) {
|
|
809
|
-
containerRestore.push(containerDefinition);
|
|
810
|
-
}
|
|
811
|
-
if ([TransferDirection.bothPlus, TransferDirection.both, TransferDirection.downPlus, TransferDirection.down].includes(containerDefinition.transferDirection)) {
|
|
812
|
-
containerApply.push(containerDefinition);
|
|
813
|
-
}
|
|
814
|
-
}
|
|
815
|
-
if (containerRestore.length) {
|
|
816
|
-
pwn('');
|
|
817
|
-
}
|
|
818
|
-
// generate restore code
|
|
819
|
-
for (const cont of containerRestore) {
|
|
820
|
-
cont.knownNames.forEach((libAlias) => {
|
|
821
|
-
pwn(`forward onUplinkRestore_${libAlias}();`);
|
|
822
|
-
});
|
|
823
|
-
pwn('');
|
|
824
|
-
pwn(`stock restoreUplink${cont.name}() {`);
|
|
825
|
-
pwn(`\t_DDE_${cont.name}_read();`);
|
|
826
|
-
buildLibraryRestoreApplyCall(cont, 'Restore');
|
|
827
|
-
if (coreDefinitions_1.DDE_Core.hasContainerAppFields(cont)) {
|
|
828
|
-
pwn(`\tonUplinkRestore_${cont.title}();`);
|
|
829
|
-
}
|
|
830
|
-
pwn(`}`);
|
|
831
|
-
}
|
|
832
|
-
pwn(`#pragma warning push`);
|
|
833
|
-
pwn(`stock _onUplinkRestore(cfgId) {`);
|
|
834
|
-
if (containerRestore.length) {
|
|
835
|
-
pwn(`\tswitch(cfgId) {`);
|
|
836
|
-
for (const cont of containerRestore) {
|
|
837
|
-
pwn(`\t\tcase DDE_${cont.title}_id: restoreUplink${cont.name}(); // ${cont.name}`);
|
|
838
|
-
}
|
|
839
|
-
pwn(`\t}`);
|
|
840
|
-
}
|
|
841
|
-
else {
|
|
842
|
-
pwn(`\t#pragma warning disable 203`);
|
|
843
|
-
pwn(`\t// no containers to restore`);
|
|
844
|
-
}
|
|
845
|
-
pwn(`}`);
|
|
846
|
-
pwn(`#pragma warning pop`);
|
|
847
|
-
if (containerApply.length) {
|
|
848
|
-
pwn('');
|
|
849
|
-
}
|
|
850
|
-
// generate apply code
|
|
851
|
-
for (const cont of containerApply) {
|
|
852
|
-
cont.knownNames.forEach((libAlias) => {
|
|
853
|
-
pwn(`forward onUplinkApply_${libAlias}();`);
|
|
854
|
-
});
|
|
855
|
-
pwn('');
|
|
856
|
-
pwn(`stock applyUplink${cont.name}() {`);
|
|
857
|
-
pwn(`\t_DDE_${cont.name}_read();`);
|
|
858
|
-
buildLibraryRestoreApplyCall(cont, 'Apply');
|
|
859
|
-
if (coreDefinitions_1.DDE_Core.hasContainerAppFields(cont)) {
|
|
860
|
-
pwn(`\t${buildUplinkApplyCall(cont.title)}`);
|
|
861
|
-
}
|
|
862
|
-
pwn(`\treturn(OK);`);
|
|
863
|
-
pwn(`}`);
|
|
864
|
-
}
|
|
865
|
-
pwn(`#pragma warning push`);
|
|
866
|
-
pwn(`stock _onUplinkApply(cfgId) {`);
|
|
867
|
-
if (containerApply.length) {
|
|
868
|
-
pwn(`\tswitch(cfgId) {`);
|
|
869
|
-
for (const cont of containerApply) {
|
|
870
|
-
pwn(`\t\tcase DDE_${cont.title}_id: return applyUplink${cont.name}(); // ${cont.name}`);
|
|
871
|
-
}
|
|
872
|
-
pwn(`\t}`);
|
|
873
|
-
pwn(`\treturn ERROR;`);
|
|
874
|
-
}
|
|
875
|
-
else {
|
|
876
|
-
pwn(`\t#pragma warning disable 203`);
|
|
877
|
-
pwn(`\t// no containers to apply`);
|
|
878
|
-
pwn(`\treturn OK;`);
|
|
879
|
-
}
|
|
880
|
-
pwn(`}`);
|
|
881
|
-
pwn(`#pragma warning pop`);
|
|
882
|
-
return _pwn.join('\n');
|
|
883
|
-
}
|
|
884
|
-
const ALL_CONFIG_WRITE_NAMES = CONFIG_CONTAINER.map(containerName => `_DDE_${containerName}_write`);
|
|
885
|
-
function generateMainDDEIncFromMap(ddeMap) {
|
|
886
|
-
const _pawnSource = [];
|
|
887
|
-
const pawnSource = _pawnSource.push.bind(_pawnSource);
|
|
888
|
-
const dummyWriteFunctions = [...ALL_CONFIG_WRITE_NAMES];
|
|
889
|
-
for (const [containerName, containerDefinition] of Object.entries(ddeMap.containers)) {
|
|
890
|
-
const cid_base = CONTAINER_DEF_DLO_CID_BASE(containerDefinition.containerType, containerDefinition.transferDirection);
|
|
891
|
-
const CONTDEF = CONTAINER_DEFS[containerName];
|
|
892
|
-
if (!cid_base || !containerDefinition.fields || CONTDEF.ctype !== ContainerType.cx) {
|
|
893
|
-
//container is not available in dlo
|
|
894
|
-
continue;
|
|
895
|
-
}
|
|
896
|
-
const pre = `DDE_${containerDefinition.name}`;
|
|
897
|
-
const containerID = `DDE_${containerDefinition.title}_id`;
|
|
898
|
-
// ---
|
|
899
|
-
// add write method - but for configuration UP_ward containers only
|
|
900
|
-
// ---
|
|
901
|
-
if ([
|
|
902
|
-
TransferDirection.both,
|
|
903
|
-
TransferDirection.bothPlus,
|
|
904
|
-
TransferDirection.none,
|
|
905
|
-
TransferDirection.deviceOnly,
|
|
906
|
-
TransferDirection.up,
|
|
907
|
-
TransferDirection.upPlus
|
|
908
|
-
].includes(containerDefinition.transferDirection)) {
|
|
909
|
-
const funcWrite = `_${pre}_write`;
|
|
910
|
-
// pawnSource(`#define ${funcWrite}_def 01`);
|
|
911
|
-
pawnSource(`stock ${funcWrite}() {`);
|
|
912
|
-
pawnSource(`\tdde_wbegin(${containerID});`);
|
|
913
|
-
generateMainDDEFunctionBody(pawnSource, containerDefinition, 'write');
|
|
914
|
-
pawnSource(`\treturn dde_wend();`);
|
|
915
|
-
pawnSource(`}`);
|
|
916
|
-
// remove from dummy array
|
|
917
|
-
dummyWriteFunctions.splice(dummyWriteFunctions.indexOf(funcWrite), 1);
|
|
918
|
-
}
|
|
919
|
-
// ---
|
|
920
|
-
// add read method - but for CONFIG0-9 containers only
|
|
921
|
-
// ---
|
|
922
|
-
if (CONTDEF.ctype === ContainerType.cx) {
|
|
923
|
-
const funcRead = `_${pre}_read`;
|
|
924
|
-
pawnSource(`stock ${funcRead}() {`);
|
|
925
|
-
pawnSource(`\tif (dde_rbegin(${containerID})) return ERROR;`);
|
|
926
|
-
generateMainDDEFunctionBody(pawnSource, containerDefinition, 'read');
|
|
927
|
-
pawnSource(`\tdde_rend();`);
|
|
928
|
-
pawnSource('\treturn OK;');
|
|
929
|
-
pawnSource(`}`);
|
|
930
|
-
}
|
|
931
|
-
}
|
|
932
|
-
if (dummyWriteFunctions.length) {
|
|
933
|
-
pawnSource('');
|
|
934
|
-
pawnSource(`// Dummy functions needed by the dde library`);
|
|
935
|
-
for (const dummyFunc of dummyWriteFunctions) {
|
|
936
|
-
pawnSource(`stock ${dummyFunc}() { return OK; }`);
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
return _pawnSource.join('\n');
|
|
940
|
-
}
|
|
941
|
-
function generateMainDDEFunctionBody(pawnSource, containerDefinition, readWrite) {
|
|
942
|
-
containerDefinition.libraries.forEach(libraryName => {
|
|
943
|
-
const libraryHash = helper_1.Helper.generateHashForLibraryName(libraryName);
|
|
944
|
-
pawnSource(`\t#ifdef __${libraryHash}${containerDefinition.title}_${readWrite}`);
|
|
945
|
-
pawnSource(`\t\t__${libraryHash}${containerDefinition.title}_${readWrite}();`);
|
|
946
|
-
pawnSource(`\t#endif`);
|
|
947
|
-
});
|
|
948
|
-
if (coreDefinitions_1.DDE_Core.hasContainerAppFields(containerDefinition)) {
|
|
949
|
-
pawnSource(`\t#ifdef _DDE_${containerDefinition.title}_${readWrite}`);
|
|
950
|
-
pawnSource(`\t\t_DDE_${containerDefinition.title}_${readWrite}();`);
|
|
951
|
-
pawnSource(`\t#endif`);
|
|
952
|
-
}
|
|
953
|
-
}
|
|
954
|
-
/**
|
|
955
|
-
* Default INC handling
|
|
956
|
-
*/
|
|
957
|
-
/**
|
|
958
|
-
* Generate the default.inc file
|
|
959
|
-
* @param cwd
|
|
960
|
-
* @param fs
|
|
961
|
-
*/
|
|
962
|
-
async function buildDefaultInc(cwd, fs) {
|
|
963
|
-
const fileContent = [];
|
|
964
|
-
const dloLibs = await dependencies_1.Dependencies.getApmPartDependencies(cwd, fs, apm_1.APM.Part.dlo);
|
|
965
|
-
await addInclude(cwd, fs, fileContent, defaultFiles_1.DefaultFiles.fileNames.autoInc);
|
|
966
|
-
const autoDdeIncs = await getAutoDDEIncludes(cwd, fs, dloLibs);
|
|
967
|
-
for (const dloLib of dloLibs) {
|
|
968
|
-
// todo use relative path as include?
|
|
969
|
-
if (dloLib.name === 'local-data-interface') {
|
|
970
|
-
await addInclude(cwd, fs, fileContent, defaultFiles_1.DefaultFiles.fileNames.autoLocalDataInc);
|
|
971
|
-
}
|
|
972
|
-
fileContent.push(`#include <${dloLib.name}>`);
|
|
973
|
-
if (dloLib.name === 'dlo-core') {
|
|
974
|
-
fileContent.push(...autoDdeIncs);
|
|
975
|
-
await addInclude(cwd, fs, fileContent, defaultFiles_1.DefaultFiles.fileNames.autoDdeInc.replace('X', 'app'));
|
|
976
|
-
await addInclude(cwd, fs, fileContent, defaultFiles_1.DefaultFiles.fileNames.autoDdeInc.replace('X', 'main'));
|
|
977
|
-
await addInclude(cwd, fs, fileContent, defaultFiles_1.DefaultFiles.fileNames.autoUplinkInc);
|
|
978
|
-
}
|
|
979
|
-
}
|
|
980
|
-
return fileContent.join('\n');
|
|
981
|
-
}
|
|
982
|
-
/**
|
|
983
|
-
* Get all <library-name>-dde.inc files
|
|
984
|
-
* @param cwd
|
|
985
|
-
* @param fs
|
|
986
|
-
* @param dependencies
|
|
987
|
-
*/
|
|
988
|
-
async function getAutoDDEIncludes(cwd, fs, dependencies) {
|
|
989
|
-
const includes = [];
|
|
990
|
-
for (const dependency of dependencies) {
|
|
991
|
-
const includePath = defaultFiles_1.DefaultFiles.filePaths.studio.auto.dlo.autoDdeInc.replace('X', dependency.name);
|
|
992
|
-
if (await fs.stat(vscode_uri_1.Utils.joinPath(cwd, includePath))) {
|
|
993
|
-
includes.push(`#include "${defaultFiles_1.DefaultFiles.fileNames.autoDdeInc.replace('X', dependency.name)}"`);
|
|
994
|
-
}
|
|
995
|
-
}
|
|
996
|
-
return includes;
|
|
997
|
-
}
|
|
998
|
-
/**
|
|
999
|
-
* Validate if the given file exist within the .studio/auto/dlo directory
|
|
1000
|
-
*/
|
|
1001
|
-
async function addInclude(cwd, fs, fileContent, fileName) {
|
|
1002
|
-
const basePath = vscode_uri_1.Utils.joinPath(cwd, defaultFiles_1.DefaultFiles.filePaths.studio.auto.dlo.path, fileName);
|
|
1003
|
-
if (await fs.stat(basePath)) {
|
|
1004
|
-
fileContent.push(`#include "${fileName}"`);
|
|
1005
|
-
}
|
|
1006
|
-
}
|
|
1007
|
-
//# sourceMappingURL=dlo.js.map
|