int ParseLine( LPCLASSDATA lpcd, int nInBlock, TCHAR *pcText, int nLength, SYNTAX_COLOR *scColors, int *lpnBlocks, int nNumBlocks, int nLine ) { LPPARSER lpp = Parser; LPKEYHASH lpHash; LPBLOCK lpBlock; COLORREF crText = Parser->crColors[ CARR_TEXT ]; int nIndex = 0, nBlock = 0, nSize, i, nMatchX1 = 0, nMatchX2 = 0; BOOL bContinue = FALSE, bStartOfLine = TRUE, bHasInit = FALSE; int nHyperLength; // Modified by Stephan (2005-06-12) // To allow unquoted paths with space like c:\program files /* * Compute match columns. */ if ( lpcd->ptBracket1.y >= 0 ) nMatchX1 = CaretOffsetLine( lpcd, lpcd->ptBracket1.y, lpcd->ptBracket1.x ); if ( lpcd->ptBracket2.y >= 0 ) nMatchX2 = CaretOffsetLine( lpcd, lpcd->ptBracket2.y, lpcd->ptBracket2.x ); /* * Any text to parse? */ if ( nLength == 0 ) /* * Return the block we are in. */ return nInBlock; /* * Start with a normal text * color block... */ if ( scColors ) { /* * Enough text blocks? */ CHECK_BLOCKS; scColors[ nBlock ].nColumn = nLength; scColors[ nBlock ].crColor = crText; scColors[ nBlock ].crBgColor = CLR_DEFAULT; scColors[ nBlock ].pHash = NULL; scColors[ nBlock ].wFlags = 0; } /* * Parser active? */ if ( lpp == NULL ) { /* * A single text color block. */ *lpnBlocks = 1; return -1; } /* * Are we in a block? */ if ( nInBlock != -1 ) { /* * Get the block. */ lpBlock = ArrayGetAt( lpp->lpaBlocks, nInBlock ); /* * Setup the color. */ if ( scColors ) { /* * Enough text blocks? */ CHECK_BLOCKS; scColors[ nBlock ].nColumn = nLength; scColors[ nBlock ].crColor = lpBlock->crColor; scColors[ nBlock ].crBgColor = lpBlock->crBgColor; scColors[ nBlock ].pHash = NULL; scColors[ nBlock ].wFlags = 0; } /* * End the block with a string? */ if ( lpBlock->nEnd ) { /* * See if the terminator string occures * on the line. */ LPCTSTR pszStr = ( lpp->bCaseOn ? StrStr : StrStrI )( pcText, lpBlock->pszEnd ); /* * Terminator found? */ if( pszStr == NULL ) { /* * Are we parsing hyperlinks? */ if ( Parser->bParseHyperLinks && scColors && lpnBlocks ) { /* * Find all hyperlinks in the line starting * at offset 'nIndex'. */ *lpnBlocks = FindHyperlinksInBlock( lpcd, pcText, nIndex, nLength, 0, nNumBlocks, lpnBlocks, scColors ) + 1; scColors[ *lpnBlocks - 1 ].nColumn = nLength; } else if ( lpnBlocks ) /* * Uses a single block. */ *lpnBlocks = 1; /* * Remain in the text block. */ return nInBlock; } else if ( Parser->bParseHyperLinks && scColors && lpnBlocks ) /* * Find all hyperlinks from offset 'nIndex' * up to the block end marker. */ nBlock = FindHyperlinksInBlock( lpcd, pcText, nIndex, ( int )( pszStr - pcText ), 0, nNumBlocks, lpnBlocks, scColors ); /* * Skip to the index at which * the terminator was found. */ nIndex = ( int )( pszStr - pcText ); } } else { /* * If we are not yet inside a block we determine * if any of the block initiators occure in this * line and, if so, at which offset. */ for ( i = 0; ; i++ ) { /* * Get the block. */ lpBlock = ArrayGetAt( lpp->lpaBlocks, i ); /* * Done? */ if ( lpBlock == NULL ) break; /* * By default this block initiator is not on * this line. */ lpBlock->bInLine = FALSE; /* * Will the initiator fit at all? */ if ( lpBlock->nStart && lpBlock->nStart <= nLength ) { /* * Look up the block initiator on the line. */ LPCTSTR pszStr = ( lpp->bCaseOn ? StrStr : StrStrI )( pcText, lpBlock->pszStart ); /* * Found? */ if ( pszStr != NULL ) { /* * We have a block initializer. */ bHasInit = TRUE; /* * This block initiator is located * on this line. */ lpBlock->bInLine = TRUE; } } } } /* * First we skip the leading blanks... */ while ( _istspace( pcText[ nIndex ] ) && nIndex <= nLength ) nIndex++; /* * Iterate text. */ for ( /*nIndex = 0*/; nIndex <= nLength; nIndex++ ) { /* * Clear continue flag. */ bContinue = FALSE; /* * In a block? */ if ( nInBlock != -1 ) { /* * Get block. */ lpBlock = ArrayGetAt( lpp->lpaBlocks, nInBlock ); /* * Does the block terminate with a string? */ if ( lpBlock->nEnd ) { /* * Does the terminator occure in the text? */ LPCTSTR pszStr = ( lpp->bCaseOn ? StrStr : StrStrI )( &pcText[ nIndex ], lpBlock->pszEnd ); /* * No. Return the block number. */ if ( pszStr == NULL ) { /* * Are we parsing hyperlinks? */ if ( Parser->bParseHyperLinks && scColors && lpnBlocks ) { /* * Find the hyperlinks starting at offset 'nIndex'. */ *lpnBlocks = FindHyperlinksInBlock( lpcd, pcText, nIndex, nLength, nBlock, nNumBlocks, lpnBlocks, scColors ) + 1; scColors[ *lpnBlocks - 1 ].nColumn = nLength; } else if ( lpnBlocks ) /* * Store the block number. */ *lpnBlocks = nBlock + 1; return nInBlock; } else if ( Parser->bParseHyperLinks && scColors && lpnBlocks ) /* * Find all hyperlinks from offset 'nIndex' * up to the block end marker. */ nBlock = FindHyperlinksInBlock( lpcd, pcText, nIndex, ( int )( pszStr - pcText ), nBlock, nNumBlocks, lpnBlocks, scColors ); /* * Skip through to the index at which the * terminator was found. */ nIndex = ( int )( pszStr - pcText ); } /* * Will the terminator fit? */ if ( nLength - nIndex >= lpBlock->nEnd || lpBlock->pszEnd == END_OF_LINE ) { /* * End a block? */ if ( BlockEnd( lpcd, lpBlock, pcText, nIndex, nLength )) { /* * Color array present? */ if ( scColors ) { /* * Enough room? */ CHECK_BLOCKS; /* * Yes. Terminate current color. */ scColors[ nBlock++ ].nColumn = nIndex + lpBlock->nEnd; /* * Start a new color. */ scColors[ nBlock ].nColumn = nLength; scColors[ nBlock ].crColor = crText; scColors[ nBlock ].crBgColor = CLR_DEFAULT; scColors[ nBlock ].pHash = NULL; scColors[ nBlock ].wFlags = 0; } /* * Skip the block terminator. */ if ( lpBlock->pszEnd != END_OF_LINE ) nIndex += lpBlock->nEnd - 1; else nIndex = nLength; /* * No longer in the block. */ nInBlock = -1; /* * Continue parse... */ continue; } } } /* * Keep looking for the terminator if * we are still inside a block. */ if ( nInBlock != -1 ) { if ( scColors && nIndex >= nLength ) scColors[ nBlock ].nColumn = nIndex; continue; } /* * Do we have an initiator? */ if ( bHasInit ) { /* * Look up the block * initiators. */ for ( i = 0; ; i++ ) { /* * Valid block? */ if (( lpBlock = ArrayGetAt( lpp->lpaBlocks, i )) == NULL ) break; /* * Block initiator in this * line? */ if ( ! lpBlock->bInLine ) continue; /* * Block found? */ if ( ! BlockStart( lpcd, lpBlock, pcText, nIndex, nLength, bStartOfLine )) continue; /* * Colors present? */ if ( scColors ) { /* * Enough room? */ CHECK_BLOCKS; /* * Yes. Terminate current color. */ scColors[ nBlock++ ].nColumn = nIndex; /* * Start a new color. */ scColors[ nBlock ].nColumn = nLength; scColors[ nBlock ].crColor = lpBlock->crColor; scColors[ nBlock ].crBgColor = lpBlock->crBgColor; scColors[ nBlock ].pHash = NULL; scColors[ nBlock ].wFlags = 0; } /* * Mark us as being in the block. */ nInBlock = i; /* * Does this block terminate at eol? */ if ( lpBlock->pszEnd == END_OF_LINE ) { /* * Look at the rest of the line * for hyperlinks. */ if ( Parser->bParseHyperLinks && scColors && lpnBlocks ) nBlock = FindHyperlinksInBlock( lpcd, pcText, nIndex, nLength, nBlock, nNumBlocks, lpnBlocks, scColors ); /* * Skip everything except * the last terminator length * plus the escape character. */ nIndex = max( 0, nLength - 2 ); } else /* * Skip the block initiator. */ nIndex += lpBlock->nStart - 1; /* * Break the loop and * continue parsing. */ bContinue = TRUE; break; } } /* * No longer at the start * of the line... */ bStartOfLine = FALSE; /* * Continue? */ if ( bContinue || scColors == NULL ) continue; /* * Skip spaces. */ if ( _istspace( pcText[ nIndex ] )) { /* * Make a new block. */ if ( scColors[ nBlock ].crBgColor != CLR_DEFAULT || scColors[ nBlock ].crColor != crText || scColors[ nBlock ].wFlags ) { /* * Enough room? */ CHECK_BLOCKS; /* * Terminate current color. */ scColors[ nBlock++ ].nColumn = nIndex; /* * Setup new color. */ scColors[ nBlock ].crColor = crText; scColors[ nBlock ].crBgColor = CLR_DEFAULT; scColors[ nBlock ].nColumn = nLength; scColors[ nBlock ].pHash = NULL; scColors[ nBlock ].wFlags = 0; } continue; } if ( Parser->bParseHyperLinks && scColors ) { nHyperLength = IsHyperlink( pcText, nIndex, nLength ); // Modified by Stephan (2005-06-12) if (nHyperLength) { /* * Enough room? */ CHECK_BLOCKS; /* * Yes. Terminate current color. */ scColors[ nBlock++ ].nColumn = nIndex; /* * Start a new color. */ scColors[ nBlock ].nColumn = nLength; scColors[ nBlock ].crColor = Parser->crColors[ CARR_HYPERLINK ]; scColors[ nBlock ].crBgColor = Parser->crColors[ CARR_BACKGROUND_HYPERLINK ]; scColors[ nBlock ].pHash = NULL; scColors[ nBlock ].wFlags = SCF_HYPERLINK; /* * Is it a quoted hyperlink? */ if ( nIndex && (pcText[ nIndex - 1 ] == _T( '"' ) || pcText[ nIndex - 1 ] == _T( '\'' ))) // Modified by Stephan (2005-05-30) { /* * Look up the next quote. */ while ( nIndex < nLength && pcText[ nIndex ] != _T( '"' ) && pcText[ nIndex ] != _T( '\'' )) // Modified by Stephan (2005-05-30) nIndex++; if ( pcText[ nIndex ] == _T( '"' ) || pcText[ nIndex ] == _T( '\'' )) // Modified by Stephan (2005-05-30) nIndex--; } else { /* * Look up the next white space. */ nIndex += nHyperLength; // Modified by Stephan while ( nIndex < nLength && ! _istspace( pcText[ nIndex ] ) && pcText[ nIndex ] != _T('(') && pcText[ nIndex ] != _T(',') && pcText[ nIndex ] != _T(';') && pcText[ nIndex ] != _T(')') && pcText[ nIndex ] != _T('\'')) // Modified by Stephan (2005-05-28) nIndex++; if ( _istspace( pcText[ nIndex ] ) || pcText[ nIndex ] == _T('(') || pcText[ nIndex ] == _T(',') || pcText[ nIndex ] == _T(';') || pcText[ nIndex ] == _T(')') || pcText[ nIndex ] == _T('\'')) // Modified by Stephan (2005-05-28) nIndex--; } continue; } } /* * Delimiter? */ if ( IsDelimiter( lpcd, pcText[ nIndex ] )) { /* * Any change in color? */ if (( scColors[ nBlock ].crColor != Parser->crColors[ CARR_DELIMITER ] ) || ( scColors[ nBlock ].crBgColor != Parser->crColors[ CARR_BACKGROUND_DELIMITER ] ) || ( scColors[ nBlock ].wFlags )) { /* * Enough room? */ CHECK_BLOCKS; /* * Terminate current color. */ scColors[ nBlock++ ].nColumn = nIndex; /* * Setup delimiter color. */ scColors[ nBlock ].crColor = Parser->crColors[ CARR_DELIMITER ]; scColors[ nBlock ].crBgColor = Parser->crColors[ CARR_BACKGROUND_DELIMITER ]; scColors[ nBlock ].nColumn = nLength; scColors[ nBlock ].pHash = NULL; scColors[ nBlock ].wFlags = 0; } /* * Do we have matched brackets? */ if (( nLine == lpcd->ptBracket1.y && nIndex == nMatchX1 ) || ( nLine == lpcd->ptBracket2.y && nIndex == nMatchX2 )) { /* * Enough room? */ CHECK_BLOCKS; /* * Terminate current color. */ scColors[ nBlock++ ].nColumn = nIndex; /* * Setup match color. */ scColors[ nBlock ].crColor = scColors[ nBlock - 1 ].crColor; scColors[ nBlock ].crBgColor = lpp->crColors[ CARR_BRACKET_MATCH ]; scColors[ nBlock ].nColumn = nLength; scColors[ nBlock ].pHash = NULL; scColors[ nBlock ].wFlags = 0; } /* * Continue parsing. */ continue; } else /* * Is it a number? This check is a bit * to simple but it should not pose * any problems... */ if ( _istdigit( pcText[ nIndex ] )) { /* * Color changes? */ if (( scColors[ nBlock ].crColor != Parser->crColors[ CARR_NUMBER ] ) || ( scColors[ nBlock ].crBgColor != Parser->crColors[ CARR_BACKGROUND_NUMBER ] ) || ( scColors[ nBlock ].wFlags )) { /* * Enough room? */ CHECK_BLOCKS; /* * Terminate the current color. */ scColors[ nBlock++ ].nColumn = nIndex; /* * Setup the number colors. */ scColors[ nBlock ].nColumn = nLength; scColors[ nBlock ].crColor = Parser->crColors[ CARR_NUMBER ]; scColors[ nBlock ].crBgColor = Parser->crColors[ CARR_BACKGROUND_NUMBER ]; scColors[ nBlock ].pHash = NULL; scColors[ nBlock ].wFlags = 0; } } else { /* * Do we have bracket matches? */ if (( nLine == lpcd->ptBracket1.y && nIndex == nMatchX1 ) || ( nLine == lpcd->ptBracket2.y && nIndex == nMatchX2 )) { /* * Enough room? */ CHECK_BLOCKS; /* * Terminate current color. */ scColors[ nBlock++ ].nColumn = nIndex; /* * Setup match color. */ scColors[ nBlock ].crColor = crText; scColors[ nBlock ].crBgColor = lpp->crColors[ CARR_BRACKET_MATCH ]; scColors[ nBlock ].nColumn = nLength; scColors[ nBlock ].pHash = NULL; scColors[ nBlock ].wFlags = 0; /* * Continue parsing. */ continue; } else if ( scColors[ nBlock ].crColor != crText || scColors[ nBlock ].crBgColor != CLR_DEFAULT || scColors[ nBlock ].wFlags ) { /* * Enough room? */ CHECK_BLOCKS; /* * Terminate current color. */ scColors[ nBlock++ ].nColumn = nIndex; /* * Setup text color. */ scColors[ nBlock ].crColor = crText; scColors[ nBlock ].crBgColor = CLR_DEFAULT; scColors[ nBlock ].nColumn = nLength; scColors[ nBlock ].pHash = NULL; scColors[ nBlock ].wFlags = 0; } } /* * Count the characters up until * the next space or delimiter. */ nSize = nIndex; while ( nSize < nLength && ! _istspace( pcText[ nSize ] ) && ! IsDelimiter( lpcd, pcText[ nSize ] )) { /* * Do we have bracket matches? */ if (( nLine == lpcd->ptBracket1.y && nSize == nMatchX1 ) || ( nLine == lpcd->ptBracket2.y && nSize == nMatchX2 )) { /* * Enough room? */ CHECK_BLOCKS; /* * Terminate current color. */ scColors[ nBlock++ ].nColumn = nSize; /* * Setup match colors. */ scColors[ nBlock ].crColor = crText; scColors[ nBlock ].crBgColor = lpp->crColors[ CARR_BRACKET_MATCH ]; scColors[ nBlock ].nColumn = nLength; scColors[ nBlock ].pHash = NULL; scColors[ nBlock ].wFlags = 0; /* * Continue parsing. */ break; } nSize++; } /* * Is the previous character a space/delimiter or are * we at the start of the line? */ if ( nIndex == 0 || _istspace( pcText[ nIndex - 1 ] ) || IsDelimiter( lpcd, pcText[ nIndex - 1 ] )) { /* * Is it a keyword */ if (( lpHash = IsKeyword( lpcd, &pcText[ nIndex ], nSize - nIndex )) != NULL ) { /* * Color changes? * NOTE: Removed to accomodate case-fixing. */ /*if ( scColors[ nBlock ].crColor != lpHash->crColor )*/ { /* * Enough room? */ CHECK_BLOCKS; /* * Terminate the current color. */ scColors[ nBlock++ ].nColumn = nIndex; /* * Setup the keyword color and the hash. We use the hash * when a text line is edited to fix the casing when * case-fixing is turned on. */ scColors[ nBlock ].nColumn = nLength; scColors[ nBlock ].crColor = lpHash->crColor; scColors[ nBlock ].crBgColor = lpHash->crBkColor; scColors[ nBlock ].pHash = lpHash; scColors[ nBlock ].wFlags = 0; } } } /* * Are we at the end? */ if ( nSize >= nLength ) break; /* * Adjust the index. */ nIndex = nSize - 1; } /* * Store the number of syntax * color block that are valid. */ if ( lpnBlocks ) *lpnBlocks = nBlock + 1; return nInBlock; }
bool ConfigParser::Parse(void) { if(!f_) { logger_.msg(Arc::ERROR, "Configuration file can not be read"); return false; }; while(f_.good()) { if(!f_) { logger_.msg(Arc::ERROR, "Configuration file can not be read"); return false; }; std::string line; getline(f_,line); line = Arc::trim(line); if(line.empty()) continue; if(line[0] == '#') continue; if(line[0] == '[') { if(line.length() < 2) { logger_.msg(Arc::ERROR, "Configuration file is broken - block name is too short: %s",line); return false; }; if(!block_id_.empty()) { if(!BlockEnd(block_id_,block_name_)) { return false; }; }; line = line.substr(1,line.length()-2); block_id_ = ""; block_name_ = ""; std::string::size_type ps = line.find('/'); if(ps != std::string::npos) { block_name_ = Arc::trim(line.substr(ps+1)); line.resize(ps); }; line = Arc::trim(line); block_id_ = line; if(!BlockStart(block_id_,block_name_)) { return false; }; continue; }; std::string cmd; std::string::size_type p = line.find('='); if(p == std::string::npos) { cmd = Arc::trim(line); line = ""; } else { cmd = Arc::trim(line.substr(0,p)); line = Arc::trim(line.substr(p+1)); if(is_nested(line)) line=line.substr(1,line.length()-2); }; if(cmd == "name") { if(p != std::string::npos) { block_name_ = Arc::trim(Arc::trim(line),"\""); }; continue; }; if(!ConfigLine(block_id_,block_name_,cmd,line)) { return false; }; }; if(!block_id_.empty()) { if(!BlockEnd(block_id_,block_name_)) return false; }; return true; }