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

📄 quincy.cpp

📁 一个完全使用MFC框架开发的C++编译器的代码。功能十分强大可以编译大型程序。
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	m_pCompiler = 0;

	// ---- set paths to find the compiler executables
	int nIndex = m_strQuincyBinPath.ReverseFind('\\');
	ASSERT(nIndex > 0);
	m_strQuincyInstallPath = m_strQuincyBinPath.Left(nIndex);

	// poor man's constructor

	m_bCompilerIsInstalled = false;

	m_strToolsPath.Empty();
	m_strIncludePath.Empty();
	m_strRIncludePath.Empty();
	m_strStartupCode.Empty();
	m_strLibPath.Empty();
	m_strVersion.Empty();

	m_strLCCPath = m_strQuincyInstallPath + "\\lcc\\bin\\";

	for (;;)	{

		// loops in case Quincy expects compiler on cd-rom and cd is not in drive
		// only comes back here if programmed compiler path cd and can't find compiler
		// and user does not Cancel the retry

		CString strCompilerBin;
		CString strMingw32LibPath = "lib\\gcc-lib\\";
		CString strCompiler;

		// looking for the mingw32 compiler
		//
		//	This code depends on gcc-Mingw32 compiler's subdirectory structure
		//  If they change it, this code will need to be changed.
		//
		// start from the programmed compiler location
		strCompiler = m_strCompiler;
		if (strCompiler.IsEmpty())
			// no programmed location, look for mingw off the quincy install directory
			strCompiler = m_strQuincyInstallPath + "\\mingw\\";
		// --- scanning for one of the mingw32 compilers
		CString CompilerPath(strCompiler + strMingw32LibPath);
		CString strSpec = CompilerPath + "*.*";
		struct _finddata_t file;
		long hFile;
		
		// --- gcc-mingw32 uses its version number as the only subdirectory
		//     under the "lib\\gcc-lib\\mingw32\\"
		//     By scanning for it, don't need a Quincy 2002 recompile 
		//     whenever they release a new version (I hope)

		if ((hFile = _findfirst(strSpec.GetBuffer(0), &file)) != -1)	{
			while (*file.name == '.' || (file.attrib & _A_SUBDIR) == 0)
				if (_findnext(hFile, &file) != 0)
					break;
			if (*file.name != '.' && (file.attrib & _A_SUBDIR) != 0)	{
				// --- now we're at mingw32, i386-mingw32, or i386-mingw32msvc, I hope
				_findclose(hFile);
				strSpec = CompilerPath+file.name + "\\*.*";
				if ((hFile = _findfirst(strSpec.GetBuffer(0), &file)) != -1)	{
					while (*file.name == '.' || (file.attrib & _A_SUBDIR) == 0)
						if (_findnext(hFile, &file) != 0)
							break;
					if (*file.name != '.' && (file.attrib & _A_SUBDIR) != 0)
						m_strVersion = file.name;
				}
			}
			_findclose(hFile);
		}
		if (!m_strVersion.IsEmpty())	{
			// ---- found a version of mingw32
			strCompilerBin = strCompiler + "bin\\";
			m_strToolsPath = strCompilerBin;
			m_strRIncludePath = strCompiler + "include\\";

			// --- make sure that at least gcc is in the directory
			CString strGcc = m_strToolsPath + "gcc.exe";
			m_bCompilerIsInstalled = _access(strGcc, 0) == 0;

			if (m_bCompilerIsInstalled)	{
				m_strCompiler = strCompiler;	// update the programmed compiler path
				m_pCompiler = new GCCCompiler();
			}
		}

		// --- set flags to disable compiler and tools menu items if executables are not installed
		CMenu* pMenu = ((CMainFrame*)m_pMainWnd)->GetMenu();
		ASSERT(pMenu != 0);

		CString strGrep = m_strQuincyBinPath + "\\grep.exe";
		m_bGrepIsInstalled = _access(strGrep, 0) == 0;

		CString strAStyle = m_strQuincyBinPath + "\\astyle.exe";
		m_bAStyleIsInstalled = _access(strAStyle, 0) == 0;

		CString strWEditRes(m_strLCCPath + "weditres.exe ");
		m_bWEditResIsInstalled = _access(strWEditRes, 0) == 0;

		if (!m_bCompilerIsInstalled)	{
			if (IsOnCDROM(m_strToolsPath))	{
				CString msg("Compiler files not found. Insert CD-ROM in ");
				char dr[3] = "x:";
				*dr = m_strToolsPath[0];
				msg += dr;
				if (AfxMessageBox(msg, MB_RETRYCANCEL) == IDRETRY)
					continue;	// start all over again at the for (;;) loop
			}
			else	{
				AfxMessageBox(	"Install MinGW "
					"and set the compiler's installation path in the "
					"Tools/Options dialog's Build tab.", MB_ICONSTOP);
			}
		}
		else	{
			// --- set path so compiler can find its own tools
			char* penv = 0;
			penv = getenv("PATH");
			CString path("Path=" + strCompilerBin + ";" + penv);
			_putenv(path.GetBuffer(0));
			// --- program debugger path if one is not already programmed
//			TestDebuggerPath();
			m_strDebugger = m_strToolsPath;
		}
		break;
	}
}

CWnd* CQuincyApp::MaximizeDocument(const CString& strDocument)
{
	CTextView* pView = GetTextView(strDocument);
	ASSERT(pView != 0);
	CWnd* pWnd = pView->GetParent();
	ASSERT(pWnd != 0);
	WINDOWPLACEMENT wndpl = { sizeof(WINDOWPLACEMENT) };
	if (pWnd->GetWindowPlacement(&wndpl))	{
		wndpl.showCmd = SW_SHOWMAXIMIZED;
		pWnd->SetWindowPlacement(&wndpl);
	}
	return pView;
}

CDocument* CQuincyApp::OpenDocumentFile(LPCTSTR lpszFileName) 
{
	CString strDocument(lpszFileName);
	if (strDocument.Right(4).CompareNoCase(".prj") == 0)	{
		// ----- change to the subdirectory where project file is located
		int offset = strDocument.ReverseFind('\\');
		if (offset != -1)	{
			CString strPath = strDocument.Left(offset);
			_chdir(strPath);
		}
	}
	return CWinApp::OpenDocumentFile(lpszFileName);
}

void CQuincyApp::ChangeToRuntimeDirectory(CString& strCmd)
{
	// --- determine where the target program should write its file output (if any)
	// --- if a project, see if the project has a working directory programmed
	CString strWk = GetProjectRuntimeDirectory();
	if (strWk.IsEmpty())	{
		// either not a project or no working directory programmed
		// see if the options have a working directory programmed
		strWk = GetRuntimeDirectory();
		if (strWk.IsEmpty())	{
			// no options working directory programmed
			if (IsOnCDROM(strCmd))
				// use the TEMP directory, if TEMP is set. (If not, you're on your own)
				strWk = GetTemporaryDirectory();
			else	{
				// ----- change to the subdirectory where 
				//       executable file is located
				int offset = strCmd.ReverseFind('\\');
				if (offset != -1)	{
					strWk = strCmd.Left(offset);
				}
			}
		}
	}
	if (!strWk.IsEmpty())
		_chdir(strWk);
}

void CQuincyApp::StartProgram(CString& strCmd)
{
	// make true if any breakpoints are programmed.
	bool breakpointsset = breakpoints.size() > 0 || !steptobreakpoint.m_strFile.IsEmpty();

//	CString strCmd = Enquote(cmd);
	ChangeToRuntimeDirectory(strCmd);
	CStab stabs(strCmd.GetBuffer(0));
	if (stabs.TestStabs() && breakpointsset)
		DebugProgram(strCmd);
	else	{
		CString strCmdline;
		GetCommandLine(strCmdline);

		delete m_pExecutor;
		m_pExecutor = new Executor(strCmd);
		m_pExecutor->Run(strCmdline.GetBuffer(0));
	}
}

void CQuincyApp::DebugProgram(CString strCmd, bool bStepping)
{
//	CString strCmd = Enquote(cmd);
	CStab stabs(strCmd.GetBuffer(0));
	if (stabs.TestStabs())	{
		ChangeToRuntimeDirectory(strCmd);

		ASSERT(m_pDebugger == 0);
		m_pDebugger = new Debugger;

		CString strCmdline;
		GetCommandLine(strCmdline);
		if (!strCmdline.IsEmpty())	{
			strCmd += " ";
			strCmd += strCmdline;
		}
		m_pDebugger->LoadDebugger(strCmd.GetBuffer(0));
		PostWatchList();
		std::set<Breakpoint>::iterator iter;
		for (iter=breakpoints.begin(); iter != breakpoints.end(); iter++)
			m_pDebugger->SetBreakpoint(*iter);

		if (bStepping)
			m_pDebugger->StepIntoProgram();
		else
			m_pDebugger->StartProgram();
	}
	else if (AfxMessageBox("No debug information. Run anyway?", MB_YESNO | MB_ICONQUESTION) == IDYES)
		StartProgram(strCmd);
}

// --- called from the debugger to stop itself. Don't call this from anywhere else
void CQuincyApp::StopDebugger()
{
	delete m_pDebugger;
	m_pDebugger = 0;
}

void CQuincyApp::GetCommandLine(CString& strCmdLine)
{
	if (m_CommandLinePromptOption == 0)
		strCmdLine = "";
	else	{
		strCmdLine = m_strCommandLine;
		if (m_CommandLinePromptOption == 1)	{
			CCommandLineDialog dlgCmdLine;
			if (dlgCmdLine.DoModal() == IDOK)
				strCmdLine = dlgCmdLine.m_strCommandLine;
		}
	}
}

// ----  extract the path from a file specification
CString CQuincyApp::GetFilePath(const CString& rstrPath)
{
	int offset = rstrPath.ReverseFind('\\');
	if (offset == -1)
		offset = rstrPath.ReverseFind('/');
	return offset == -1 ? CString() : rstrPath.Left(offset);
}
// ----  extract the filename from a file specification
CString CQuincyApp::GetFileName(const CString& rstrPath)
{
	int offset = rstrPath.ReverseFind('\\');
	if (offset == -1)
		offset = rstrPath.ReverseFind('/');
	return offset == -1 ? rstrPath : rstrPath.Right(rstrPath.GetLength() - offset - 1);
}

// ----- compare the date/time stamps on two files
int CQuincyApp::CompareFileTimes(CString& strFile1, CString& strFile2)
{
	struct _stat buf1;
	char* path1 = strFile1.GetBuffer(0);
	int rtn1 = _stat(path1, &buf1);

	struct _stat buf2;
	char* path2 = strFile2.GetBuffer(0);
	int rtn2 = _stat(path2, &buf2);

	// --- a non-existing file is always older than one that exists
	if (rtn1 == -1 && rtn2 == -1)
		return 0;
	if (rtn1 == 0 && rtn2 == -1)
		return 1;
	if (rtn1 == -1 && rtn2 == 0)
		return -1;

	// ---- a zero-length file is always older than one with data
	if (buf1.st_size == 0 && buf2.st_size != 0)
		return -1;
	if (buf1.st_size != 0 && buf2.st_size == 0)
		return 1;

	return buf1.st_mtime - buf2.st_mtime;
}

CString CQuincyApp::GetProjectRuntimeDirectory()
{
	CString strWk;
	CQuincyDoc* pDoc = CQuincyDoc::CurrentProject();
	if (pDoc != 0)
		strWk = pDoc->WorkingDirectory();
	return strWk;
}

CQuincyDoc* CQuincyApp::GetProjectDocument(CString* pstrPath)
{
	CQuincyDoc* pDoc = CQuincyDoc::CurrentProject();
	if (pDoc != 0)	{
		CString strPath = pDoc->GetPathName();
		if (pstrPath != 0)
			*pstrPath = strPath;
	}
	return pDoc;
}

bool CQuincyApp::IsLibraryTarget()
{
	CQuincyDoc* pDoc = GetProjectDocument();
	if (pDoc != 0)
		return pDoc->IsLibraryTarget();
	return false;
}

bool CQuincyApp::IsGUITarget()
{
	CQuincyDoc* pDoc = GetProjectDocument();
	if (pDoc != 0)
		return pDoc->IsGUITarget();
	return false;
}

bool CQuincyApp::IsDLLTarget()
{
	CQuincyDoc* pDoc = GetProjectDocument();
	if (pDoc != 0)
		return pDoc->IsDLLTarget();
	return false;
}

bool CQuincyApp::IsConsoleApplication()
{
	CQuincyDoc* pDoc = GetProjectDocument();
	if (pDoc != 0)
		return pDoc->IsConsoleApplication();
	return true;
}

void CQuincyApp::ParseFileSpec(CString& strFileSpec, CString& strCmdLine, int nIndex)
{
	int ndx = nIndex + 1;
	CString cmdLine(strCmdLine.Left(nIndex) + " ");

	strFileSpec.Empty();

	while (isspace(strCmdLine[ndx]))
		ndx++;
	while (ndx < strCmdLine.GetLength() && !isspace(strCmdLine[ndx]) 
				&& strCmdLine[ndx] != '<' && strCmdLine[ndx] != '>')
		strFileSpec += strCmdLine[ndx++];

	while (++ndx < strCmdLine.GetLength())
		cmdLine += strCmdLine[ndx];
	
	strCmdLine = cmdLine;
}

CQuincyView* CQuincyApp::GetProjectView()
{
	CQuincyDoc* pDoc = GetProjectDocument();
	if (pDoc != 0)	{
		POSITION vpos = pDoc->GetFirstViewPosition();
		ASSERT(vpos != 0);
		CQuincyView* pView = static_cast<CQuincyView*>(pDoc->GetNextView(vpos));
		ASSERT(pView != 0);
		return pView;
	}
	return 0;
}

CTextDocument* CQuincyApp::GetTextDocument(CString pstrPath)
{
	POSITION tpos = GetFirstDocTemplatePosition();
	CString strArgFile = GetFileName(pstrPath);
	while (tpos != 0)	{
		CDocTemplate* pTem = GetNextDocTemplate(tpos);
		ASSERT(pTem != 0);
		POSITION dpos = pTem->GetFirstDocPosition();
		while (dpos != 0)	{
			CTextDocument* pDoc = static_cast<CTextDocument*>(pTem->GetNextDoc(dpos));
			ASSERT(pDoc != 0);
			CString strDocFile = GetFileName(pDoc->GetPathName());
			if (strArgFile.CompareNoCase(strDocFile) == 0)
				return pDoc;
		}
	}
	return 0;
}

CTextView* CQuincyApp::GetTextView(CString pstrPath)
{
	CTextDocument* pDoc = GetTextDocument(pstrPath);
	if (pDoc != 0)	{
		POSITION vpos = pDoc->GetFirstViewPosition();
		ASSERT(vpos != 0);
		CTextView* pView = static_cast<CTextView*>(pDoc->GetNextView(vpos));
		ASSERT(pView != 0);
		return pView;
	}
	return 0;
}

void CQuincyApp::RunResourceEditor(const CString& strItem)
{
	CString strCmd(m_strLCCPath + "weditres.exe " + strItem);
	STARTUPINFO suinfo = { sizeof(STARTUPINFO) };
	PROCESS_INFORMATION pi;
	CreateProcess(0, strCmd.GetBuffer(0), 0,0,0,0,0,0, &suinfo, &pi);
}

void CQuincyApp::ShowLineColumn(int nLine, int nColumn)
{
	CMainFrame* pMainFrame = static_cast<CMainFrame*>(m_pMainWnd);
	pMainFrame->SetRowColumn(nLine, nColumn);
}


BOOL CQuincyApp::OnIdle(LONG lCount)
{
	if (stepping)	{
		stepping = false;
		if (m_pDebugger)
			m_pDebugger->SelectSteppingSourceLine();
	}
	CWinApp::OnIdle(lCount);

#ifdef TYCPP
	if (m_bReadTutorial)
		ReadTutorial();
#endif

	return false;
}

void CQuincyApp::EditorScreenFont(CFont* font, int ht, int wd, int wt)
{
	font->CreateFont(
		ht,						// height
		wd,						// width
		0,						// nEscapement
		0,						// nOrientation
		wt,						// nWeight
		0,						// bItalic
		0,						// bUnderline
		0,						// cStrikeOut
		ANSI_CHARSET,
		OUT_DEFAULT_PRECIS,
		CLIP_CHARACTER_PRECIS,
		DEFAULT_QUALITY,
		FIXED_PITCH | FF_MODERN,
		"Courier");
}

void CQuincyApp::RetabAllTextDocuments(int newtabstops)
{
	POSITION tpos = GetFirstDocTemplatePosition();
	while (tpos != 0)	{
		CDocTemplate* pTem = GetNextDocTemplate(tpos);
		ASSERT(pTem != 0);
		POSITION dpos = pTem->GetFirstDocPosition();
		while (dpos != 0)	{
			CTextDocument* pDoc = static_cast<CTextDocument*>(pTem->GetNextDoc(dpos));
			ASSERT(pDoc != 0);
			CString strDocFile = GetFileName(pDoc->GetPathName());
			if (strDocFile.Right(4).CompareNoCase(".prj") != 0)
				pDoc->Retab(newtabstops);
		}
	}
}

void CQuincyApp::InvalidateAllViews(bool rebuildfont)
{
	POSITION tpos = GetFirstDocTemplatePosition();
	while (tpos != 0)	{
		CDocTemplate* pTem = GetNextDocTemplate(tpos);
		ASSERT(pTem != 0);
		POSITION dpos = pTem->GetFirstDocPosition();
		while (dpos != 0)	{
			CTextDocument* pDoc = dynamic_cast<CTextDocument*>(pTem->GetNextDoc(dpos)); // could be project file
			if (pDoc != 0)	{
				POSITION vpos = pDoc->GetFirstViewPosition();
				ASSERT(vpos != 0);
				CTextView* pView = static_cast<CTextView*>(pDoc->GetNextView(vpos));
				ASSERT(pView != 0);
				if (rebuildfont)
					pView->RebuildFont();
				pView->Invalidate(false);
				pView->BuildContextHighlightTable();
			}
		}
	}
}

bool CQuincyApp::TestProgramChanged()

⌨️ 快捷键说明

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