Add ApcParser
This commit is contained in:
@@ -3,13 +3,14 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { IParsingState, IDcsHandler, IEscapeSequenceParser, IParams, IOscHandler, IHandlerCollection, CsiHandlerType, OscFallbackHandlerType, IOscParser, EscHandlerType, IDcsParser, DcsFallbackHandlerType, IFunctionIdentifier, ExecuteFallbackHandlerType, CsiFallbackHandlerType, EscFallbackHandlerType, PrintHandlerType, PrintFallbackHandlerType, ExecuteHandlerType, IParserStackState, ParserStackType, ResumableHandlersType } from 'common/parser/Types';
|
||||
import { IParsingState, IDcsHandler, IEscapeSequenceParser, IParams, IOscHandler, IHandlerCollection, CsiHandlerType, OscFallbackHandlerType, IOscParser, EscHandlerType, IDcsParser, DcsFallbackHandlerType, IFunctionIdentifier, ExecuteFallbackHandlerType, CsiFallbackHandlerType, EscFallbackHandlerType, PrintHandlerType, PrintFallbackHandlerType, ExecuteHandlerType, IParserStackState, ParserStackType, ResumableHandlersType, IApcHandler, IApcParser, ApcFallbackHandlerType } from 'common/parser/Types';
|
||||
import { ParserState, ParserAction } from 'common/parser/Constants';
|
||||
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IDisposable } from 'common/Types';
|
||||
import { Params } from 'common/parser/Params';
|
||||
import { OscParser } from 'common/parser/OscParser';
|
||||
import { DcsParser } from 'common/parser/DcsParser';
|
||||
import { ApcParser } from 'common/parser/ApcParser';
|
||||
|
||||
/**
|
||||
* Table values are generated like this:
|
||||
@@ -75,7 +76,7 @@ const NON_ASCII_PRINTABLE = 0xA0;
|
||||
* VT500 compatible transition table.
|
||||
* Taken from https://vt100.net/emu/dec_ansi_parser.
|
||||
*/
|
||||
export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
|
||||
export const VT500_TRANSITION_TABLE = (function(): TransitionTable {
|
||||
const table: TransitionTable = new TransitionTable(4095);
|
||||
|
||||
// range macro for byte
|
||||
@@ -104,7 +105,8 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
|
||||
table.add(0x9c, state, ParserAction.IGNORE, ParserState.GROUND); // ST as terminator
|
||||
table.add(0x1b, state, ParserAction.CLEAR, ParserState.ESCAPE); // ESC
|
||||
table.add(0x9d, state, ParserAction.OSC_START, ParserState.OSC_STRING); // OSC
|
||||
table.addMany([0x98, 0x9e, 0x9f], state, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING);
|
||||
table.addMany([0x98, 0x9e], state, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING); // SOS, PM
|
||||
table.add(0x9f, state, ParserAction.APC_START, ParserState.APC_STRING); // APC
|
||||
table.add(0x9b, state, ParserAction.CLEAR, ParserState.CSI_ENTRY); // CSI
|
||||
table.add(0x90, state, ParserAction.CLEAR, ParserState.DCS_ENTRY); // DCS
|
||||
}
|
||||
@@ -128,8 +130,9 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
|
||||
table.add(0x7f, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);
|
||||
table.addMany([0x9c, 0x1b, 0x18, 0x1a, 0x07], ParserState.OSC_STRING, ParserAction.OSC_END, ParserState.GROUND);
|
||||
table.addMany(r(0x1c, 0x20), ParserState.OSC_STRING, ParserAction.IGNORE, ParserState.OSC_STRING);
|
||||
// sos/pm/apc does nothing
|
||||
table.addMany([0x58, 0x5e, 0x5f], ParserState.ESCAPE, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING);
|
||||
// sos/pm/apc - sos/pm does nothing, apc gets separate handling
|
||||
table.addMany([0x58, 0x5e], ParserState.ESCAPE, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING); // SOS, PM
|
||||
table.add(0x5f, ParserState.ESCAPE, ParserAction.APC_START, ParserState.APC_STRING); // APC ('_')
|
||||
table.addMany(PRINTABLES, ParserState.SOS_PM_APC_STRING, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING);
|
||||
table.addMany(EXECUTABLES, ParserState.SOS_PM_APC_STRING, ParserAction.IGNORE, ParserState.SOS_PM_APC_STRING);
|
||||
table.add(0x9c, ParserState.SOS_PM_APC_STRING, ParserAction.IGNORE, ParserState.GROUND);
|
||||
@@ -187,12 +190,18 @@ export const VT500_TRANSITION_TABLE = (function (): TransitionTable {
|
||||
table.addMany(PRINTABLES, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);
|
||||
table.add(0x7f, ParserState.DCS_PASSTHROUGH, ParserAction.IGNORE, ParserState.DCS_PASSTHROUGH);
|
||||
table.addMany([0x1b, 0x9c, 0x18, 0x1a], ParserState.DCS_PASSTHROUGH, ParserAction.DCS_UNHOOK, ParserState.GROUND);
|
||||
// apc passthrough - similar to DCS passthrough
|
||||
table.addMany(PRINTABLES, ParserState.APC_STRING, ParserAction.APC_PUT, ParserState.APC_STRING);
|
||||
table.addMany(EXECUTABLES, ParserState.APC_STRING, ParserAction.IGNORE, ParserState.APC_STRING);
|
||||
table.add(0x7f, ParserState.APC_STRING, ParserAction.IGNORE, ParserState.APC_STRING);
|
||||
table.addMany([0x1b, 0x9c, 0x18, 0x1a], ParserState.APC_STRING, ParserAction.APC_END, ParserState.GROUND);
|
||||
// special handling of unicode chars
|
||||
table.add(NON_ASCII_PRINTABLE, ParserState.GROUND, ParserAction.PRINT, ParserState.GROUND);
|
||||
table.add(NON_ASCII_PRINTABLE, ParserState.OSC_STRING, ParserAction.OSC_PUT, ParserState.OSC_STRING);
|
||||
table.add(NON_ASCII_PRINTABLE, ParserState.CSI_IGNORE, ParserAction.IGNORE, ParserState.CSI_IGNORE);
|
||||
table.add(NON_ASCII_PRINTABLE, ParserState.DCS_IGNORE, ParserAction.IGNORE, ParserState.DCS_IGNORE);
|
||||
table.add(NON_ASCII_PRINTABLE, ParserState.DCS_PASSTHROUGH, ParserAction.DCS_PUT, ParserState.DCS_PASSTHROUGH);
|
||||
table.add(NON_ASCII_PRINTABLE, ParserState.APC_STRING, ParserAction.APC_PUT, ParserState.APC_STRING);
|
||||
return table;
|
||||
})();
|
||||
|
||||
@@ -243,6 +252,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
||||
protected _escHandlers: IHandlerCollection<EscHandlerType>;
|
||||
protected readonly _oscParser: IOscParser;
|
||||
protected readonly _dcsParser: IDcsParser;
|
||||
protected readonly _apcParser: IApcParser;
|
||||
protected _errorHandler: (state: IParsingState) => IParsingState;
|
||||
|
||||
// fallback handlers
|
||||
@@ -290,6 +300,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
||||
}));
|
||||
this._oscParser = this._register(new OscParser());
|
||||
this._dcsParser = this._register(new DcsParser());
|
||||
this._apcParser = this._register(new ApcParser());
|
||||
this._errorHandler = this._errorHandlerFb;
|
||||
|
||||
// swallow 7bit ST (ESC+\)
|
||||
@@ -425,6 +436,16 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
||||
this._oscParser.setHandlerFallback(handler);
|
||||
}
|
||||
|
||||
public registerApcHandler(ident: number, handler: IApcHandler): IDisposable {
|
||||
return this._apcParser.registerHandler(ident, handler);
|
||||
}
|
||||
public clearApcHandler(ident: number): void {
|
||||
this._apcParser.clearHandler(ident);
|
||||
}
|
||||
public setApcHandlerFallback(handler: ApcFallbackHandlerType): void {
|
||||
this._apcParser.setHandlerFallback(handler);
|
||||
}
|
||||
|
||||
public setErrorHandler(callback: (state: IParsingState) => IParsingState): void {
|
||||
this._errorHandler = callback;
|
||||
}
|
||||
@@ -445,6 +466,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
||||
this.currentState = this.initialState;
|
||||
this._oscParser.reset();
|
||||
this._dcsParser.reset();
|
||||
this._apcParser.reset();
|
||||
this._params.reset();
|
||||
this._params.addParam(0); // ZDM
|
||||
this._collect = 0;
|
||||
@@ -606,6 +628,17 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
||||
this._params.addParam(0); // ZDM
|
||||
this._collect = 0;
|
||||
break;
|
||||
case ParserStackType.APC:
|
||||
code = data[this._parseStack.chunkPos];
|
||||
handlerResult = this._apcParser.end(code !== 0x18 && code !== 0x1a, promiseResult);
|
||||
if (handlerResult) {
|
||||
return handlerResult;
|
||||
}
|
||||
if (code === 0x1b) this._parseStack.transition |= ParserState.ESCAPE;
|
||||
this._params.reset();
|
||||
this._params.addParam(0); // ZDM
|
||||
this._collect = 0;
|
||||
break;
|
||||
}
|
||||
// cleanup before continuing with the main sync loop
|
||||
this._parseStack.state = ParserStackType.NONE;
|
||||
@@ -785,6 +818,31 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
|
||||
this._collect = 0;
|
||||
this.precedingJoinState = 0;
|
||||
break;
|
||||
case ParserAction.APC_START:
|
||||
this._apcParser.start();
|
||||
break;
|
||||
case ParserAction.APC_PUT:
|
||||
// inner loop - exit APC_PUT: 0x18, 0x1a, 0x1b, 0x9c
|
||||
for (let j = i + 1; ; ++j) {
|
||||
if (j >= length || (code = data[j]) === 0x18 || code === 0x1a || code === 0x1b || code === 0x9c || (code > 0x7f && code < NON_ASCII_PRINTABLE)) {
|
||||
this._apcParser.put(data, i, j);
|
||||
i = j - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ParserAction.APC_END:
|
||||
handlerResult = this._apcParser.end(code !== 0x18 && code !== 0x1a);
|
||||
if (handlerResult) {
|
||||
this._preserveStack(ParserStackType.APC, [], 0, transition, i);
|
||||
return handlerResult;
|
||||
}
|
||||
if (code === 0x1b) transition |= ParserState.ESCAPE;
|
||||
this._params.reset();
|
||||
this._params.addParam(0); // ZDM
|
||||
this._collect = 0;
|
||||
this.precedingJoinState = 0;
|
||||
break;
|
||||
}
|
||||
this.currentState = transition & TableAccess.TRANSITION_STATE_MASK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user