📄 esc_seq.cpp
字号:
// esc_seq.cpp - escape sequence parser methods
#include <stdio.h>
#include <string.h>
#include "debug.hpp"
#include "esc_seq.hpp"
// These will need some adjustment to parse out the position code
static const char ESCAPE = 27; // VT102 command prefix - escape
// ------------------------------------------------------------------------
// constructor
//
// buf - null-terminated string
//
// The sense of the parser is that a function returns nonzero if it
// successfully parsed part of an escape sequence.
// - Functions internally set the _isComplete to true if they
// complete a sequence, and set _type appropriately.
// - Functions that increment the buffer pointer are responsible for
// checking for end of string.
EscapeSequence::EscapeSequence(char * buf)
: _type(NONE),
_isComplete(0),
_isEscapeSequence(1),
_nParameters(0)
{
ASSERT(NULL != buf, "Null pointer forbidden");
if (_EndOfString(buf)) // Empty string?
_isEscapeSequence = 0;
else if (0 == _ParseEscapeSequence(buf))
_isEscapeSequence = 0;
}
// ------------------------------------------------------------------------
// _SetType - sets the type for this, and assumes that it is now complete!
void EscapeSequence::_SetType(_Type type)
{
_type = type;
_isComplete = 1;
}
int EscapeSequence::_ParseEscapeSequence(char * buf)
{
if (*buf == ESCAPE)
{
++ buf; // Great! Parsed a character
if (_EndOfString(buf))
return 1; // Valid, but end of string
return (_ScrollReverse(buf)
|| _LeftSquareBracket(buf));
};
return 0; // Not escape sequence
}
// ------------------------------------------------------------------------
// _ScrollReverse -- This is actually the reverse-newline sequence
//
int EscapeSequence::_ScrollReverse(char * buf)
{
if (*buf == 'M') // Reverse scroll code?
{
_SetType(REV_NEWLINE);
return 1;
};
return 0;
}
// ------------------------------------------------------------------------
// Most escape sequences are prefixed by "Esc-["
//
int EscapeSequence::_LeftSquareBracket(char * buf)
{
int ret_val = 0; // Default is to assume that this is invalid
if (*buf != '\[')
ret_val = 0;
else
{
++ buf;
if (_EndOfString(buf)) // No more string
ret_val = 1;
else if (0 == _GetParameters(&buf)) // Not a valid sequence?
ret_val = 0;
else if (_EndOfString(buf)) // No terminator, not finished
ret_val = 1;
else
{
switch (*buf) // Get type from terminator
{
case 'J': // Might be a clear screen if parameter = 2
if (1 == ParameterCount() && Parameter(0) == 2)
{
_SetType(CLRSCR);
ret_val = 1;
};
break;
case 'K': // CLREOL
if (0 == _nParameters) // Must have no parameters
{
_SetType(CLREOL);
ret_val = 1;
};
break;
case 'H': // Cursor move
if (2 == ParameterCount()) // Exactly two parameters?
{
_SetType(CMOVE);
ret_val = 1;
};
break;
case 'r': // Set scroll region
if (2 == ParameterCount()) // Exactly two parameters?
{
_SetType(SCROLL);
ret_val = 1;
};
break;
case 'm': // Ansi screen color/attribute sequence
_SetType(ANSI_COLOR);
ret_val = 1;
break;
default: // Not escape sequence
break;
};
};
};
return ret_val; // No match
}
// ------------------------------------------------------------------------
// _GetParameters - Count the parameters.
//
// Leaves the pointer buf pointing at the first character after the
// parameters, which may be end-of-string.
//
// Returns:
// zero if for some reason this can't be an escape sequence
//
int EscapeSequence::_GetParameters(char ** buf)
{
ASSERT(NULL != buf, "Invalid pointer?");
ASSERT(NULL != *buf, "Invalid string?");
int ret_val = 1; // So far, this is an escape sequence
int value; // Scanned numeric value
int chars_read; // Number of characters scanned from string
int fields_scanned; // Number of fields matched
while (1) // Loop forever
{
// Check for integer value first
fields_scanned = sscanf(*buf, "%d%n", &value, &chars_read);
if (0 == fields_scanned) // Nothing scanned
break;
else if (1 == fields_scanned)
{
if (_nParameters >= 20)
{
// Give up on this escape sequence--too many parameters.
ret_val = 0;
break;
};
_parameters[_nParameters] = value;
++ _nParameters;
*buf += chars_read; // Move to next parameter
};
// Check for semicolon or terminator
if (_EndOfString(*buf)) // End of string, not finished
break;
else if (**buf == ';') // Another parameter?
++ *buf; // Keep going
else
break; // No more parameters, exit
};
return ret_val;
}
// EOF //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -