⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.cpp

📁 非常好用的可移植的多平台C/C++源代码编辑器
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	opts.wantPreprocessor = m_Options.wantPreprocessor;
	opts.useBuffer = false;
	opts.bufferSkipBlocks = false;
	ParserThread* thread = new ParserThread(this,&this->m_abort_flag,
											wxEmptyString,
											false,
											opts,
											&m_Tokens);
	return thread->ParseBufferForFunctions(buffer);
}

bool Parser::RemoveFile(const wxString& filename)
{
	wxMutexLocker lock(s_mutexListProtection);
	wxMutexLocker lock1(s_mutexProtection);

	wxString file = UnixFilename(filename);
	if (m_ParsedFiles.Index(file) != wxNOT_FOUND)
	{
		// only if it has been parsed before...
		// delete any entries that belong to the file in question
		// FIXME: what happens with entries *linked* to this entry?
		unsigned int i = 0;
		while (i < m_Tokens.GetCount())
		{
			if (m_Tokens[i]->m_Filename.Matches(file))
				m_Tokens.RemoveAt(i);
			else
				++i;
		}
		m_ParsedFiles.Remove(file);
	}
	else
		return false;
	return true;
}

bool Parser::Reparse(const wxString& filename, bool isLocal)
{
	if (!Done())
		return false; // if still parsing, exit with error

	wxString file = UnixFilename(filename);
//	Manager::Get()->GetMessageManager()->DebugLog(_("Reparsing %s"), file.c_str());
	RemoveFile(file);
	ClearTemporaries();
	wxMutexLocker* lock = new wxMutexLocker(s_mutexListProtection);
	m_ReparsedFiles.Add(file);
	delete lock;

	return Parse(file, isLocal);
}

void Parser::Clear()
{
//    Manager::Get()->GetMessageManager()->DebugLog(_("Parser::Clear: Disconnecting events..."));
    DisconnectEvents();
//    Manager::Get()->GetMessageManager()->DebugLog(_("Parser::Clear: Terminating all threads..."));
	TerminateAllThreads();
    wxSafeYield();
	wxSleep(0);

	wxMutexLocker* lockl = new wxMutexLocker(s_mutexListProtection);
//    Manager::Get()->GetMessageManager()->DebugLog(_("Parser::Clear: Clearing 'm_ParsedFiles'..."));
	m_ParsedFiles.Clear();
//    Manager::Get()->GetMessageManager()->DebugLog(_("Parser::Clear: Clearing 'm_ReparsedFiles'..."));
	m_ReparsedFiles.Clear();
//    Manager::Get()->GetMessageManager()->DebugLog(_("Parser::Clear: Clearing 'm_IncludeDirs'..."));
	m_IncludeDirs.Clear();
	delete lockl;

//    Manager::Get()->GetMessageManager()->DebugLog(_("Parser::Clear: Locking s_mutexProtection and clearing m_Tokens..."));
	wxMutexLocker lock(s_mutexProtection);
	WX_CLEAR_ARRAY(m_Tokens);
	m_Tokens.Clear();

//    Manager::Get()->GetMessageManager()->DebugLog(_("Parser::Clear: wxSafeYield..."));
	wxSafeYield();
//    Manager::Get()->GetMessageManager()->DebugLog(_("Parser::Clear: Connecting Events..."));
	ConnectEvents();

	m_UsingCache = false;
	m_CacheFilesCount = 0;
	m_CacheTokensCount = 0;
	m_abort_flag = false;
//    Manager::Get()->GetMessageManager()->DebugLog(_("Parser::Clear: Done."));
}

void Parser::ClearTemporaries()
{
	if (!Done())
		return;

	unsigned int i = 0;
	while (i < m_Tokens.GetCount())
	{
		Token* token = m_Tokens[i];
		if (token->m_IsTemporary)
			m_Tokens.RemoveAt(i);
		else
			++i;
	}
}

void Parser::TerminateAllThreads()
{
    Manager::Get()->GetMessageManager()->DebugLog(_("Parser::TerminateAllThreads: Aborting all tasks..."));
    m_Pool.AbortAllTasks();
}

void Parser::PauseAllThreads()
{
//    wxLogNull ln; // no other logging
//	wxMutexLocker lock(s_mutexListProtection);
//	for (unsigned int i = 0; i < m_Threads.GetCount(); ++i)
//		m_Threads[i]->Pause();
}

void Parser::ResumeAllThreads()
{
//    wxLogNull ln; // no other logging
//	wxMutexLocker lock(s_mutexListProtection);
//	for (unsigned int i = 0; i < m_Threads.GetCount(); ++i)
//		m_Threads[i]->Resume();
}

void Parser::OnStartThread(CodeBlocksEvent& event)
{
    event.Skip();
}

void Parser::OnEndThread(CodeBlocksEvent& event)
{
    event.Skip();
}

void Parser::OnAllThreadsDone(CodeBlocksEvent& event)
{
    LinkInheritance(false);
    wxCommandEvent evt(wxEVT_COMMAND_MENU_SELECTED, PARSER_END);
    evt.SetClientData(this);
	wxPostEvent(m_pParent, evt);
}

void Parser::OnNewToken(wxCommandEvent& event)
{
#ifndef STANDALONE
	Manager::Get()->GetMessageManager()->DebugLog(event.GetString());
#endif
}

void Parser::OnParseFile(wxCommandEvent& event)
{
//    LOGSTREAM << "Parser::OnParseFile: " << event.GetString() << "\n";
	// a ParserThread ran into an #include directive
	// it's up to us to decide to parse this file...

	if ((event.GetInt() == 0 && !m_Options.followLocalIncludes) ||
		(event.GetInt() == 1 && !m_Options.followGlobalIncludes))
		return;

	// the string is thread's_filename+included_filename
	wxString filename = event.GetString();
	int idx = filename.First('+');
	wxFileName fname;
	wxFileName source;
	wxString base;

	if (idx == -1)
		return;
	fname.Assign(filename.Mid(idx + 1));
	source.Assign(filename.Left(idx - 1));

	if (event.GetInt() == 0)
		base = source.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR);
	else
	{
		// loop through all known include dirs
		// and locate the file...
		for (unsigned int i = 0; i < m_IncludeDirs.GetCount(); ++i)
		{
			base = m_IncludeDirs[i];
			wxFileName tmp = fname;
			tmp.Normalize(wxPATH_NORM_ALL & ~wxPATH_NORM_CASE, base);
			if (wxFileExists(tmp.GetFullPath()))
				break;
		}
	}

	fname.Normalize(wxPATH_NORM_ALL & ~wxPATH_NORM_CASE, base);
	filename = fname.GetFullPath();

	/*wxMutexLocker* lock = new wxMutexLocker(s_mutexListProtection);
	bool abort = m_ReparsedFiles.Index(filename) != wxNOT_FOUND;
	delete lock;
	if (abort)
		return; // the file is being re-parsed; don't follow includes
	*/

	if (m_ParsedFiles.Index(filename) != wxNOT_FOUND) // parsed file
        return;
//	Manager::Get()->GetMessageManager()->DebugLog("Adding in parse queue: %s", filename.c_str());

	bool res = false;
	if (m_ReparsedFiles.Index(source.GetFullPath()) != wxNOT_FOUND) // reparsing file
		res = Reparse(filename, event.GetInt() == 0);
	else
		res = Parse(filename, event.GetInt() == 0);
	if (res)
	{
#if 0
#ifndef STANDALONE
	Manager::Get()->GetMessageManager()->DebugLog("Adding in parse queue: %s", filename.c_str());
#endif
#endif
	}
}

void Parser::BuildTree(wxTreeCtrl& tree)
{
	if (!Done())
		return;

	tree.Freeze();
    tree.DeleteAllItems();

#ifndef STANDALONE
	tree.SetImageList(m_pImageList);
#endif
	m_RootNode = tree.AddRoot(_("Symbols"), PARSER_IMG_SYMBOLS_FOLDER);
	if (m_BrowserOptions.viewFlat)
	{
		for (unsigned int x = 0; x < m_Tokens.GetCount(); ++x)
		{
			Token* token = m_Tokens[x];
			if (!token->m_pParent && // base (no parent)
				token->m_IsLocal) // local symbols only
				AddTreeNode(tree, m_RootNode, token);
		}
		tree.Expand(m_RootNode);
		tree.Thaw();
		return;
	}

	wxTreeItemId globalNS = tree.AppendItem(m_RootNode, _("Global namespace"), PARSER_IMG_NAMESPACE);
    AddTreeNamespace(tree, globalNS, 0L);
    BuildTreeNamespace(tree, m_RootNode, 0L);
	tree.Expand(m_RootNode);
	tree.Thaw();
}

void Parser::BuildTreeNamespace(wxTreeCtrl& tree, const wxTreeItemId& parentNode, Token* parent)
{
	for (unsigned int x = 0; x < m_Tokens.GetCount(); ++x)
	{
		Token* token = m_Tokens[x];
		if (token->m_pParent == parent &&
			token->m_IsLocal && // local symbols only
			token->m_TokenKind == tkNamespace) // namespaces
        {
            ClassTreeData* ctd = new ClassTreeData(token);
            wxTreeItemId newNS = tree.AppendItem(parentNode, token->m_Name, PARSER_IMG_NAMESPACE, -1, ctd);
            BuildTreeNamespace(tree, newNS, token);
            AddTreeNamespace(tree, newNS, token);
        }
	}
}

void Parser::AddTreeNamespace(wxTreeCtrl& tree, const wxTreeItemId& parentNode, Token* parent)
{
	wxTreeItemId node = tree.AppendItem(parentNode, _("Classes"), PARSER_IMG_CLASS_FOLDER);
	for (unsigned int x = 0; x < m_Tokens.GetCount(); ++x)
	{
		Token* token = m_Tokens[x];
		if (token->m_pParent == parent && // parent matches
			token->m_IsLocal && // local symbols only
			token->m_TokenKind == tkClass) // classes
        {
			AddTreeNode(tree, node, token);
        }
	}
	node = tree.AppendItem(parentNode, _("Enums"), PARSER_IMG_ENUMS_FOLDER);
	for (unsigned int x = 0; x < m_Tokens.GetCount(); ++x)
	{
		Token* token = m_Tokens[x];
		if (token->m_pParent == parent && // parent matches
			token->m_IsLocal && // local symbols only
			token->m_TokenKind == tkEnum) // enums
        {
			AddTreeNode(tree, node, token);
        }
	}
	node = tree.AppendItem(parentNode, _("Preprocessor"), PARSER_IMG_PREPROC_FOLDER);
	for (unsigned int x = 0; x < m_Tokens.GetCount(); ++x)
	{
		Token* token = m_Tokens[x];
		if (token->m_pParent == parent && // parent matches
			token->m_IsLocal && // local symbols only
			token->m_TokenKind == tkPreprocessor) // preprocessor
        {
			AddTreeNode(tree, node, token);
        }
	}
	node = tree.AppendItem(parentNode, _("Others"), PARSER_IMG_OTHERS_FOLDER);
	for (unsigned int x = 0; x < m_Tokens.GetCount(); ++x)
	{
		Token* token = m_Tokens[x];
		if (token->m_pParent == parent && // parent matches
			token->m_IsLocal && // local symbols only
			(token->m_TokenKind == tkEnumerator || // enumerators
			token->m_TokenKind == tkFunction || // functions
			token->m_TokenKind == tkVariable || // variables
			token->m_TokenKind == tkUndefined)) // others
        {
			AddTreeNode(tree, node, token);
        }
	}
}

void Parser::AddTreeNode(wxTreeCtrl& tree, const wxTreeItemId& parentNode, Token* token, bool childrenOnly)
{
    if (!token)
        return;
	ClassTreeData* ctd = new ClassTreeData(token);
	int image = -1;
#ifndef STANDALONE
	image = GetTokenKindImage(token);
#endif
	wxString str = token->m_Name + token->m_Args;
	if (!token->m_ActualType.IsEmpty())
		 str = str + _T(" : ") + token->m_ActualType;
	wxTreeItemId node = childrenOnly ? parentNode : tree.AppendItem(parentNode, str, image, -1, ctd);

	// add children
	for (unsigned int i = 0; i < token->m_Children.GetCount(); ++i)
	{
		Token* childToken = token->m_Children[i];
		AddTreeNode(tree, node, childToken);
	}

	if (!m_BrowserOptions.showInheritance || (token->m_TokenKind != tkClass && token->m_TokenKind != tkNamespace))
		return;
	// add ancestor's children
	for (unsigned int x = 0; x < token->m_Ancestors.GetCount(); ++x)
	{
		Token* ancestor = token->m_Ancestors[x];
		AddTreeNode(tree, node, ancestor, true);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -