添加遥控业务代码
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
const assert = require('node:assert/strict');
|
||||
const root = path.resolve(__dirname, '../..');
|
||||
const files = [
|
||||
'104/business/IEC104_Command.c',
|
||||
'104/business/IEC104_Command.h',
|
||||
'examples/iec104_slave_example.c',
|
||||
'test/iec104_command_test.c',
|
||||
];
|
||||
|
||||
// Preserve literals and token boundaries while ignoring only comments/whitespace.
|
||||
function tokens(source) {
|
||||
const input = source.replace(/\\\r?\n/g, '');
|
||||
const result = [];
|
||||
let offset = 0;
|
||||
while (offset < input.length) {
|
||||
if (/\s/.test(input[offset])) { offset++; continue; }
|
||||
if (input.startsWith('//', offset)) {
|
||||
const end = input.indexOf('\n', offset + 2);
|
||||
offset = end < 0 ? input.length : end + 1;
|
||||
continue;
|
||||
}
|
||||
if (input.startsWith('/*', offset)) {
|
||||
const end = input.indexOf('*/', offset + 2);
|
||||
assert(end >= 0, 'unterminated comment');
|
||||
offset = end + 2;
|
||||
continue;
|
||||
}
|
||||
const tail = input.slice(offset);
|
||||
const literal = /^(?:u8|u|U|L)?(?:"(?:\\[\s\S]|[^"\\])*"|'(?:\\[\s\S]|[^'\\])*')/.exec(tail);
|
||||
const word = literal || /^(?:[A-Za-z_][A-Za-z_0-9]*|(?:[0-9]|\.[0-9])(?:[eEpP][+-]|[A-Za-z_0-9.])*)/.exec(tail);
|
||||
const token = word || /^(?:>>=|<<=|\.\.\.|->|\+\+|--|<<|>>|<=|>=|==|!=|&&|\|\||\*=|\/=|%=|\+=|-=|&=|\^=|\|=|##|.)/.exec(tail);
|
||||
assert(token, `cannot tokenize at ${offset}`);
|
||||
result.push(token[0]);
|
||||
offset += token[0].length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
for (const file of files) {
|
||||
const originalBytes = fs.readFileSync(path.join(__dirname, `${path.basename(file)}.before`));
|
||||
const currentBytes = fs.readFileSync(path.join(root, file));
|
||||
const decoder = new TextDecoder('utf-8', { fatal: true });
|
||||
const original = decoder.decode(originalBytes);
|
||||
const current = decoder.decode(currentBytes);
|
||||
assert.deepEqual(tokens(current), tokens(original), `${file}: code tokens changed`);
|
||||
assert.equal(currentBytes.subarray(0, 3).equals(Buffer.from([0xef, 0xbb, 0xbf])),
|
||||
originalBytes.subarray(0, 3).equals(Buffer.from([0xef, 0xbb, 0xbf])), `${file}: BOM changed`);
|
||||
assert(!current.includes('\r'), `${file}: CR line endings`);
|
||||
assert(!current.includes('\ufffd'), `${file}: replacement character`);
|
||||
assert(!/[\t ]+$/m.test(current), `${file}: trailing whitespace`);
|
||||
assert(current.endsWith('\n'), `${file}: missing terminal newline`);
|
||||
console.log(`${file}: ${tokens(current).length} unchanged tokens, UTF-8/LF OK`);
|
||||
}
|
||||
|
||||
// The loopback update only adds standalone line comments; compare all other bytes.
|
||||
const loopbackPath = 'test/slave_example_loopback_test.cjs';
|
||||
const loopbackBefore = fs.readFileSync(path.join(__dirname, 'slave_example_loopback_test.cjs.before'), 'utf8');
|
||||
const loopbackAfter = fs.readFileSync(path.join(root, loopbackPath), 'utf8');
|
||||
const withoutCommentLines = (source) => source.split('\n').filter(line => !/^\s*\/\//.test(line)).join('\n');
|
||||
assert.equal(withoutCommentLines(loopbackAfter), withoutCommentLines(loopbackBefore));
|
||||
assert(!loopbackAfter.includes('\r') && !loopbackAfter.includes('\ufffd'));
|
||||
assert(!/[\t ]+$/m.test(loopbackAfter) && loopbackAfter.endsWith('\n'));
|
||||
new TextDecoder('utf-8', { fatal: true }).decode(fs.readFileSync(path.join(root, loopbackPath)));
|
||||
console.log(`${loopbackPath}: only standalone comments changed, UTF-8/LF OK`);
|
||||
Reference in New Issue
Block a user