From 980292b128a6e4c54e9cb12fe8e491fea4892574 Mon Sep 17 00:00:00 2001 From: Daniel Stein Date: Sat, 26 Sep 2026 00:04:02 +0200 Subject: [PATCH] Keep split GDB/MI result tokens in stdout buffer --- src/backend/mi2/mi2.ts | 5 +++++ test/suite/mi2_stream.test.ts | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 test/suite/mi2_stream.test.ts diff --git a/src/backend/mi2/mi2.ts b/src/backend/mi2/mi2.ts index e750f9ad..5b857855 100644 --- a/src/backend/mi2/mi2.ts +++ b/src/backend/mi2/mi2.ts @@ -264,6 +264,11 @@ export class MI2 extends EventEmitter implements IBackend { } private onOutputPartial(line) { + // A chunk may end after the digits of an MI result token, before '^done'. + // Keep those digits until we have the rest of the record or a newline. + if (/^\d+$/.test(line)) { + return false; + } if (couldBeOutput(line)) { this.logNoNewLine('stdout', line); return true; diff --git a/test/suite/mi2_stream.test.ts b/test/suite/mi2_stream.test.ts new file mode 100644 index 00000000..816ff197 --- /dev/null +++ b/test/suite/mi2_stream.test.ts @@ -0,0 +1,34 @@ +import * as assert from 'assert'; +import { MI2 } from '../../src/backend/mi2/mi2'; +import { MINode } from '../../src/backend/mi_parse'; + +suite('GDB/MI output stream', () => { + test('keeps a result token split from its record marker', () => { + const gdb = new MI2('gdb', []); + const messages: Array<[string, string]> = []; + let response: MINode = undefined; + gdb.on('msg', (type: string, message: string) => messages.push([type, message])); + (gdb as any).handlers[787] = (result: MINode) => { + response = result; + }; + + (gdb as any).stdout(Buffer.from('787')); + assert.strictEqual((gdb as any).buffer, '787'); + assert.deepStrictEqual(messages, []); + + (gdb as any).stdout(Buffer.from('^done,changelist=[]\n')); + assert.strictEqual(response.token, 787); + assert.strictEqual(response.resultRecords.resultClass, 'done'); + assert.strictEqual((gdb as any).handlers[787], undefined); + assert.strictEqual((gdb as any).buffer, ''); + }); + + test('still forwards a complete numeric output line', () => { + const gdb = new MI2('gdb', []); + const messages: Array<[string, string]> = []; + gdb.on('msg', (type: string, message: string) => messages.push([type, message])); + + (gdb as any).stdout(Buffer.from('787\n')); + assert.deepStrictEqual(messages, [['stdout', '787\n']]); + }); +});