From 46ccdb146476f8ac140af75ab2decccbce800db2 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Fri, 6 Jan 2012 01:08:53 -0700 Subject: smlToConsole is now non-recursive. It's a lot better this way overall, it's one self-contained function, it doesn't require as much setup, and it works wonderfully overall. --- src/options.cpp | 233 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 140 insertions(+), 93 deletions(-) diff --git a/src/options.cpp b/src/options.cpp index 0f84e1c..319532e 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -118,129 +118,176 @@ void smlToHtml( const SmlNode *pNode ) } } -void appendToken( Bu::String &sCurLine, Bu::String &sNextToken, int &iLineLen ) +void appendToken( Bu::String &sCurLine, Bu::String &sNextToken, int &iLineLen, + int &iNextLen ) { - if( iLineLen + sNextToken.getSize() + 1 >= 78 ) + if( iLineLen + iNextLen + 1 >= 78 ) { sio << sCurLine << sio.nl; iLineLen = 0; sCurLine = sNextToken; - } else { sCurLine += sNextToken; } - iLineLen += sNextToken.getSize() + 1; + iLineLen += iNextLen + 1; sCurLine += " "; + iNextLen = 0; sNextToken.clear(); } -void smlToConsole( const SmlNode *pNode, Bu::String &sCurLine, - Bu::String &sNextToken, int &iLineLen, int &iState ) +void smlToConsole( const SmlNode *pNode ) { -// sio << "Begin: iState = " << iState << sio.nl; - switch( pNode->getType() ) + Bu::String sCurLine; + Bu::String sNextToken; + int iLineLen = 0; + int iNextLen = 0; + int iState = 0; + typedef Bu::List NodeStack; + NodeStack sNode; + + sNode.push( pNode->getChildren().begin() ); + + for(;;) { - case SmlNode::typeRoot: - for( SmlNode::SmlNodeList::const_iterator i = - pNode->getChildren().begin(); i; i++ ) + if( !sNode.peek() ) + { + sNode.pop(); + if( sNode.isEmpty() ) + break; + if( sNode.peek() ) { - smlToConsole( *i, sCurLine, sNextToken, iLineLen, iState ); + // sio << "Pop'd: " << (*sNode.peek())->getText() << sio.nl; + Bu::String sTag = (*sNode.peek())->getText(); + if( sTag == "green" || sTag == "red" ) + { + sNextToken += "\x1B[0m"; + } + sNode.peek()++; + continue; } + } + if( sNode.isEmpty() ) + { break; - - case SmlNode::typeText: - { - Bu::String::const_iterator iBgn = pNode->getText().begin(); - Bu::String::const_iterator iEnd = iBgn; - for(;iBgn;) + } + const SmlNode *pNode = (*sNode.peek()); + switch( pNode->getType() ) + { + case SmlNode::typeRoot: + throw Bu::ExceptionBase("Invalid root."); + + case SmlNode::typeText: { -// sio << iState << ": [" << (iBgn?*iBgn:'-') << ":" -// << (iEnd?*iEnd:'-') << "]" -// << sio.nl; + // sio << "Process text node: " << pNode->getText() << + // sio.nl; + Bu::String::const_iterator iBgn = pNode->getText().begin(); + Bu::String::const_iterator iEnd = iBgn; int iTmpLen = 0; - switch( iState ) + for(;iBgn;) { - case 0: // begining of paragraph - if( iBgn && ( *iBgn == ' ' || *iBgn == '\n' || - *iBgn == '\r' || *iBgn == '\t' ) ) - { - iBgn++; - } - else - { - // Here is where you would indent paragraphs - iEnd = iBgn; - iState = 1; - } - break; - - case 1: // non-whitespace - if( !iEnd ) - { - sNextToken.append( iBgn, iEnd ); - iBgn = iEnd; - } - else if( *iEnd == ' ' || *iEnd == '\n' || - *iEnd == '\r' || *iEnd == '\t' ) - { - sNextToken.append( iBgn, iEnd ); - iState = 2; - iBgn = iEnd; - } - else - { - iEnd++; - iTmpLen++; - } - break; - - case 2: // Whitespace - if( iBgn && (*iBgn == ' ' || *iBgn == '\n' || - *iBgn == '\r' || *iBgn == '\t') ) - { - iBgn++; - } - else - { - iEnd = iBgn; - iState = 1; - appendToken( sCurLine, sNextToken, iLineLen ); - } - break; + switch( iState ) + { + case 0: // begining of paragraph + if( iBgn && ( *iBgn == ' ' || *iBgn == '\n' || + *iBgn == '\r' || *iBgn == '\t' ) ) + { + iBgn++; + } + else + { + // Here is where you would indent paragraphs + iEnd = iBgn; + iState = 1; + } + break; + + case 1: // non-whitespace + if( !iEnd ) + { + sNextToken.append( iBgn, iEnd ); + iBgn = iEnd; + } + else if( *iEnd == ' ' || *iEnd == '\n' || + *iEnd == '\r' || *iEnd == '\t' ) + { + sNextToken.append( iBgn, iEnd ); + iNextLen += iTmpLen; + iTmpLen = 0; + iState = 2; + iBgn = iEnd; + } + else + { + iEnd++; + iTmpLen++; + } + break; + + case 2: // Whitespace + if( iBgn && (*iBgn == ' ' || *iBgn == '\n' || + *iBgn == '\r' || *iBgn == '\t') ) + { + iBgn++; + } + else + { + iEnd = iBgn; + iState = 1; + appendToken( sCurLine, sNextToken, + iLineLen, iNextLen ); + } + break; + } } } - } - break; + break; - case SmlNode::typeTag: - if( pNode->getChildren().isEmpty() ) - { - if( pNode->getText() == "break" ) + case SmlNode::typeTag: + if( pNode->getChildren().isEmpty() ) { - appendToken( sCurLine, sNextToken, iLineLen ); - if( !sCurLine.isEmpty() ) - sio << sCurLine << sio.nl; - sCurLine.clear(); - iLineLen = 0; - iState = 0; + if( pNode->getText() == "break" ) + { + appendToken( sCurLine, sNextToken, iLineLen, iNextLen ); + if( !sCurLine.isEmpty() ) + sio << sCurLine << sio.nl; + sCurLine.clear(); + iLineLen = 0; + iState = 0; + } } - } - else - { - for( SmlNode::SmlNodeList::const_iterator i = - pNode->getChildren().begin(); i; i++ ) + else { - smlToConsole( *i, sCurLine, sNextToken, iLineLen, iState ); +// sio << "Push'd: " << pNode->getText() << sio.nl; + Bu::String sTag = pNode->getText(); + if( sTag == "green" ) + { + sNextToken += "\x1B[1;32m"; + } + else if( sTag == "red" ) + { + sNextToken += "\x1B[1;31m"; + } + sNode.push( pNode->getChildren().begin() ); + continue; +/* for( SmlNode::SmlNodeList::const_iterator i = + pNode->getChildren().begin(); i; i++ ) + { + s + smlToConsole( *i, sCurLine, sNextToken, iLineLen, iState ); + } +*/ } - } - break; + break; + } + sNode.peek()++; } - -// sio << "Green? \x1b[1mhello\x1b[0m huh" << sio.nl; + if( !sNextToken.isEmpty() ) + appendToken( sCurLine, sNextToken, iLineLen, iNextLen ); + sio << sCurLine << sio.nl; } - +/* void smlToConsole( const SmlNode *pNode ) { Bu::String sBuf, sBuf2; @@ -248,7 +295,7 @@ void smlToConsole( const SmlNode *pNode ) smlToConsole( pNode, sBuf, sBuf2, i1, i2 ); appendToken( sBuf, sBuf2, i1 ); sio << sBuf << sBuf2 << sio.nl; -} +}*/ int Options::smlTest( Bu::Array aArgs ) { -- cgit v1.2.3