?? esc_seq.cpp
字號:
head 2.1;access;symbols;locks; strict;comment @// @;2.1date 95.10.24.15.52.51; author tsurace; state Release;branches;next 1.4;1.4date 95.10.11.21.00.39; author tsurace; state Beta;branches;next 1.3;1.3date 95.10.08.23.27.53; author tsurace; state Exp;branches;next 1.2;1.2date 95.10.07.00.34.18; author tsurace; state Exp;branches;next 1.1;1.1date 95.10.05.18.33.42; author tsurace; state Exp;branches;next ;desc@EscapeSequence methods.@2.1log@Roll.@text@// 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 //
@1.4log@Changed from assert to ASSERT.@text@@1.3log@Rearranged parsing algorithm to allow variable numbers of parametersto better support ANSI color/attribute sequences.@text@a2 1#include <assert.h>d6 1d31 1a31 1 assert(NULL != buf); // Null pointer forbiddend152 2a153 2 assert(NULL != buf); // Invalid pointer? assert(NULL != *buf); // Invalid string?@1.2log@Fixed ClearScreen lockup bug.@text@d28 2a29 1 _isEscapeSequence(1)d79 6a84 2 if (*buf == '\[') {d86 51a136 8 if (_EndOfString(buf)) return 1; return (_ClearScreen(buf) || _ClearEOL(buf) || _BoldOn(buf) || _BoldOff(buf) || _TwoParameters(buf));d138 1a138 1 return 0; // No matchd142 9a150 2// Not implementedint EscapeSequence::_ClearScreen(char * buf)d152 4a155 24 // ClearScreen ends with 2J if (*buf == '2') { ++ buf; if (_EndOfString(buf)) return 1; // Valid/incomplete else if (*buf == 'J') // Clrscr? { _SetType(CLRSCR); // Complete escape sequence return 1; // Valid escape sequence }; }; return 0; // Not a clear screen}int EscapeSequence::_ClearEOL(char * buf){ if (*buf == 'K') // CLREOL ends with a K { _SetType(CLREOL); // Complete return 1; // Valid escape sequence }; return 0; // Not clreol}d157 4a160 4int EscapeSequence::_BoldOn(char * buf){ // ClearScreen ends with 2J if (*buf == '1') d162 6a167 4 ++ buf; if (_EndOfString(buf)) return 1; else if (*buf == 'm')d169 9a177 2 _SetType(BOLD_ON); // Complete escape sequence return 1; // Valid escape sequencea178 3 }; return 0; // Not a bold on}d180 7a186 69int EscapeSequence::_BoldOff(char * buf){ if (*buf == 'm') // May also be 0m, I think { _SetType(BOLD_OFF); // Complete return 1; // Valid escape sequence }; return 0; // Not clreol}// ------------------------------------------------------------------------// TwoParameters - all types that take two parameters fall into this// categoryint EscapeSequence::_TwoParameters(char * buf){ int chars_read1, chars_read2; // Number of characters scanned from string int n_scanned = sscanf(buf, "%d%n;%d%n", &_parameters[0], &chars_read1, &_parameters[1], &chars_read2); char * new_buf; // Extra char pointer if (n_scanned == 2) { new_buf = buf + chars_read2; if (_EndOfString(new_buf)) // Not complete, but valid? return 1; else // More data! { return (_CursorMove(new_buf) || _Scroll(new_buf)); }; } else if (n_scanned == 1) { // Note: chars_read is invalid here new_buf = buf + chars_read1; if (_EndOfString(new_buf) // Is there more to come? || *new_buf == ';') { return 1; }; } else assert(0); // Internal error return 0; // Not a 2-parameter}// ------------------------------------------------------------------------// _CursorMove takes two parameters, then the terminator.int EscapeSequence::_CursorMove(char * buf){ if (*buf == 'H') { _SetType(CMOVE); // Complete return 1; // Valid escape sequence }; return 0; // Not this one}int EscapeSequence::_Scroll(char * buf){ if (*buf == 'r') { _SetType(SCROLL); // Complete return 1; // Valid escape sequenced188 1a188 1 return 0; // Not this oned191 1a191 32#ifdef QQQ // comment out - obsolete// Consider a train of newlines to be one "escape sequence"//int EscapeSequence::_ParseNewlineSequence(char * buf){ int count = 0; while(1) { if (_EndOfString(buf)) break; else if (*buf == '\n') { ++ buf; ++ count; } else if (count > 0) { _parameters[0] = count; _parameters[1] = *buf; _SetType(NEWLINE); // Complete sequence! break; } else // Not a newline sequence break; }; if (count > 0) // Newline sequence! return 1; return 0; // Not a newline sequence}#endif // QQQ@1.1log@Initial revision@text@a38 8// _EndOfString - returns nonzero at the NULL at the end of a string//int EscapeSequence::_EndOfString(char * buf){ return (*buf == '\0');}// ------------------------------------------------------------------------d61 1a61 1// _ScrollReverse, for some reason, is not prefixed by a "["d67 1a67 1 _SetType(SCR_REV);d101 3a103 2 if (! _EndOfString(buf) && *buf == 'J')d106 1a107 1 return 1; // Valid escape sequence@
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -