⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 esc_seq.cpp

📁 使用BorlandC++4.5编译的一个MUD客户端程序
💻 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 + -