There is something inefficient going on with memory management.
Code: Select all
/**
* @brief Creates tokens from a single GDB output row.
*/
QList<Token *> GdbCom::tokenize( QString str )
{
enum { IDLE, END_CODE, STRING, VAR} state = IDLE;
QList<Token *> list;
Token *cur = nullptr;
bool prevCharIsEscCode = false;
QDateTime now = QDateTime::currentDateTime();
qDebug() << "***** tokenize() called at " << now.toString( "yyyyMMdd-hhmmss.zzz" ) << " for '"
<< str << "'\n";
if ( str.isEmpty() )
{
return list;
}
for ( int i = 0; i < str.size(); i++ )
{
QChar c = str[i];
bool isEscaped = false;
if ( c == '\\' && prevCharIsEscCode )
{
prevCharIsEscCode = false;
}
else if ( prevCharIsEscCode )
{
isEscaped = true;
prevCharIsEscCode = false;
}
else if ( c == '\\' )
{
prevCharIsEscCode = true;
continue;
}
switch ( state )
{
case IDLE:
{
if ( c == '"' )
{
cur = new Token( Token::C_STRING );
list.push_back( cur );
state = STRING;
}
else if ( c == '(' )
{
cur = new Token( Token::END_CODE );
list.push_back( cur );
cur->m_text += c;
state = END_CODE;
}
else if ( c == '=' || c == '{' || c == '}' || c == ',' ||
c == '[' || c == ']' || c == '+' || c == '^' ||
c == '~' || c == '@' || c == '&' || c == '*' )
{
Token::Type type = Token::UNKNOWN;
if ( c == '=' )
{
type = Token::KEY_EQUAL;
}
if ( c == '{' )
{
type = Token::KEY_LEFT_BRACE;
}
if ( c == '}' )
{
type = Token::KEY_RIGHT_BRACE;
}
if ( c == '[' )
{
type = Token::KEY_LEFT_BAR;
}
if ( c == ']' )
{
type = Token::KEY_RIGHT_BAR;
}
if ( c == ',' )
{
type = Token::KEY_COMMA;
}
if ( c == '^' )
{
type = Token::KEY_UP;
}
if ( c == '+' )
{
type = Token::KEY_PLUS;
}
if ( c == '~' )
{
type = Token::KEY_TILDE;
}
if ( c == '@' )
{
type = Token::KEY_SNABEL;
}
if ( c == '&' )
{
type = Token::KEY_AND;
}
if ( c == '*' )
{
type = Token::KEY_STAR;
}
cur = new Token( type );
list.push_back( cur );
cur->m_text += c;
state = IDLE;
}
else if ( c != ' ' )
{
cur = new Token( Token::VAR );
list.push_back( cur );
cur->m_text = c;
state = VAR;
}
};
break;
case END_CODE:
{
QString codeEndStr = "(gdb)";
cur->m_text += c;
if ( cur->m_text.length() == codeEndStr.length() )
{
state = IDLE;
}
else if ( cur->m_text.compare( codeEndStr.left( cur->m_text.length() ) ) != 0 )
{
cur->setType( Token::VAR );
state = IDLE;
}
};
break;
case STRING:
{
if ( c == '"' && isEscaped == false )
{
state = IDLE;
}
else if ( isEscaped )
{
if ( c == 'n' )
{
cur->m_text += '\n';
}
else if ( c == 't' )
{
cur->m_text += '\t';
}
else
{
cur->m_text += c;
}
}
else
{
cur->m_text += c;
}
};
break;
case VAR:
{
if ( c == '=' || c == ',' || c == '{' || c == '}' )
{
i--;
cur->m_text = cur->m_text.trimmed();
state = IDLE;
}
else
{
cur->m_text += c;
}
};
break;
}
}
if ( cur )
{
if ( cur->getType() == Token::VAR )
{
cur->m_text = cur->m_text.trimmed();
}
}
now = QDateTime::currentDateTime();
qDebug() << "**** tokenize() completed at " << now.toString( "yyyyMMdd-hhmmss.zzz" ) << "\n";
return list;
}
You probably want to see Token too though it isn't much.
Code: Select all
class Token
{
public:
enum Type
{
UNKNOWN,
C_STRING, // "string"
C_CHAR, // 'c'
KEY_EQUAL, // '='
KEY_LEFT_BRACE, // '{'
KEY_RIGHT_BRACE, // '}'
KEY_LEFT_BAR, // '['
KEY_RIGHT_BAR, // ']'
KEY_UP, // '^'
KEY_PLUS, // '-'
KEY_COMMA, // ','
KEY_TILDE, // '~'
KEY_SNABEL, // '@'
KEY_STAR, // '*'
KEY_AND, // '&'
END_CODE,
VAR
};
public:
Token( Type type ) : m_type( type ) {};
static const QString &typeToString( Type type );
Type getType() const
{
return m_type;
};
void setType( Type type )
{
m_type = type;
};
QString getString() const
{
return m_text;
};
const QString toString();
private:
Type m_type;
public:
QString m_text;
};
Well under a second
When run in RedBug (my port) compiled in CopperSpice
Takes way too long
[ Edited for content and clarity ]