Example #1
0
/**
 * Initialises the CscopeFrontend class with the current project arguments,
 * and creates an object used for rebuilding the symbol database.
 */
void KScope::initCscope()
{
	ProjectBase* pProj;
	
	// Delete the current object, if one exists
	if (m_pCscopeBuild)
		delete m_pCscopeBuild;

	// Initialise CscopeFrontend
	pProj = m_pProjMgr->curProject();
	CscopeFrontend::init(pProj->getPath(), pProj->getArgs());

	// Create a persistent Cscope process
	m_pCscopeBuild = new CscopeFrontend();

	// Show build progress information in the main status bar
	connect(m_pCscopeBuild, SIGNAL(progress(int, int)), this,
		SLOT(slotBuildProgress(int, int)));
	connect(m_pCscopeBuild, SIGNAL(buildInvIndex()), this,
		SLOT(slotBuildInvIndex()));
	connect(m_pCscopeBuild, SIGNAL(finished(uint)), this,
		SLOT(slotBuildFinished(uint)));
	connect(m_pCscopeBuild, SIGNAL(aborted()), this,
		SLOT(slotBuildAborted()));

	// Show errors in a modeless dialogue
	connect(m_pCscopeBuild, SIGNAL(error(const QString&)), this,
		SLOT(slotCscopeError(const QString&)));
}
/**
 * Parses the output of a Cscope process.
 * Implements a state machine, where states correspond to the output of the
 * controlled Cscope process.
 * @param	sToken	The current token read (the token delimiter is determined
 *					by the current state)
 * @return	A value indicating the way this token should be treated: dropped,
 *			added to the token queue, or finishes a new record
 */
Frontend::ParseResult GrepFrontend::parseStdout(QString& sToken,
	ParserDelim /* ignored */)
{

	qDebug() << "Frontend::ParseResult \n";

	int nFiles, nTotal, nRecords;
	ParseResult result = DiscardToken;
	ParserState stPrev;
	
#if 0
	// Remember previous state
	stPrev = m_state;
	
	// Handle the token according to the current state
	switch (m_state) {
	case BuildStart:
		if (sToken == "Building cross-reference...") {
			m_state = BuildSymbol;
			m_delim = WSpace;
		}
		else if (sToken == "Building inverted index...") {
			emit buildInvIndex();
		}
		
		result = DiscardToken;
		break;

	case BuildSymbol:
		// A single angle bracket is the prefix of a progress indication,
		// while double brackets is Cscope's prompt for a new query
		if (sToken == ">") {
			m_state = Building;
			m_delim = Newline;
		}

		result = DiscardToken;
		break;

	case Building:
		// Try to get building progress
		if (sscanf(sToken.latin1(), BUILD_STR, &nFiles, &nTotal) == 2) {
			emit progress(nFiles, nTotal);
			
			// Check for last progress message
			if (nFiles == nTotal) {
				m_state = BuildStart;
				m_delim = Newline;
				
				result = DiscardToken;
				break;
			}
		}

		// Wait for another progress line or the "ready" symbol
		m_state = BuildSymbol;
		m_delim = WSpace;

		result = DiscardToken;
		break;

	case SearchSymbol:
		// Check for more search progress, or the end of the search,
		// designated by a line in the format of "cscope: X lines"
		if (sToken == ">") {
			m_state = Searching;
			m_delim = Newline;
			result = DiscardToken;
			break;
		}
		else if (sToken == "cscope:") {
			m_state = SearchEnd;
			m_delim = Newline;
			result = DiscardToken;
			break;
		}

	case File:
		// Is this the first entry? If so, signal that the query is complete
		if (stPrev != LineText)
			emit progress(1, 1);

		// Treat the token as the name of the file in this record
		m_state = Func;
		result = AcceptToken;
		break;

	case Searching:
		// Try to get the search progress value (ignore other messages)
		if ((sscanf(sToken.latin1(), SEARCH_STR, &nFiles, &nTotal) == 2) ||
			(sscanf(sToken.latin1(), INV_STR, &nFiles, &nTotal) == 2) ||
			(sscanf(sToken.latin1(), REGEXP_STR, &nFiles, &nTotal) == 2)) {
			emit progress(nFiles, nTotal);
		}

		m_state = SearchSymbol;
		m_delim = WSpace;
		result = DiscardToken;
		break;

	case SearchEnd:
		// Get the number of results found in this search
		if ((sscanf(sToken.latin1(), SEARCHEND_STR, &nRecords) == 1) &&
			(m_nMaxRecords > 0) &&
			(nRecords > m_nMaxRecords)) {
			result = Abort;
		}
		else {
			m_state = File;
			m_delim = WSpace;
			result = DiscardToken;
		}
		
		break;
		
	case Func:
		// Treat the token as the name of the function in this record
		if (sToken.toInt()) {
			// In case of a global definition, there is no function name, and
			// instead the line number is given immediately
			m_state = LineText;
			m_delim = Newline;
		}
		else {
			// Not a number, it is the name of the function
			m_state = Line;
		}
		
		result = AcceptToken;
		break;

	case Line:
		// Treat the token as the line number in this record
		m_state = LineText;
		m_delim = Newline;
		result = AcceptToken;
		break;

	case LineText:
		// Treat the token as the text of this record, and report a new
		// record
		m_state = File;
		m_delim = WSpace;
		result = RecordReady;
		break;

	default:
		// Do nothing (prevents a compilation warning for unused enum values)
		break;
	}

#endif
	return result;
}