📄 quincy.cpp
字号:
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 + -