/** * 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; }