实例介绍
【实例简介】
一款简易的C/C 开发环境源码,支持格式化、代码分色显示。必须与MinGW环境搭配使用,实现debug功能。 Dr.Dobb的作品,适合C/C 开发人员参考、定制自己的IDE.
【实例截图】Quincy2005ProjectV1.3.zip
【核心代码】
// ---------- build.cpp #include "stdafx.h" #include "Quincy.h" #include "QuincyView.h" #include "QuincyDoc.h" #include "TextDocument.h" #include "compiler.h" #include ".\quincyview.h" // --- recursive function to make subdirectories that don't exist void CQuincyView::MakeSubdirectories(const CString& strPath) { if (!strPath.IsEmpty()) { int ndx = strPath.ReverseFind('\\'); if (ndx != -1) MakeSubdirectories(strPath.Left(ndx)); struct _stat sbf; if (_stat(strPath, &sbf) != 0 || (sbf.st_mode & _S_IFDIR) == 0) _mkdir(strPath); } } // ----- project Build command void CQuincyView::BuildProject(bool bDoExecute, bool bDoStep) { int ndx = m_strTargetFile.ReverseFind('\\'); if (ndx != -1) { CString strPath = m_strTargetFile.Left(ndx); struct _stat sbf; // see if the target path exists and is a directory if (_stat(strPath, &sbf) != 0 || (sbf.st_mode & _S_IFDIR) == 0) { if (AfxMessageBox("Path " strPath "\\ does not exist. Make it?", MB_YESNO) == IDNO) return; MakeSubdirectories(strPath); } } CDocument* pDoc = GetDocument(); ASSERT(pDoc != 0); const CString& strPath = pDoc->GetPathName(); if (!strPath.IsEmpty()) pDoc->OnSaveDocument(strPath); theApp.GetCompiler().BuildTarget(m_strTargetFile, bDoExecute ? (bDoStep ? Compiler::step : Compiler::run) : Compiler::none); } bool CQuincyView::TargetIsCurrent(bool bForceRebuild) { CListCtrl& rlist = GetListCtrl(); int count = rlist.GetItemCount(); if (count == 0) return true; bool bIsCurrent = !bForceRebuild; theApp.SetBuildingCPP(false); theApp.GetCompiler().ClearArrays(); theApp.GetCompiler().ClearErrorLog(); theApp.GetCompiler().AddLogEntry("Checking dependencies"); // ---- iterate through the source files in the project for (int nItem = 0; nItem < count; nItem ) { CString strSrcFile = rlist.GetItemText(nItem, 0); bool bCpp = strSrcFile.Right(4).CompareNoCase(".cpp") == 0; if (bCpp) theApp.SetBuildingCPP(true); bool bLib = (strSrcFile.Right(2).CompareNoCase(".a") == 0); bool bRc = strSrcFile.Right(3).CompareNoCase(".rc") == 0; bool bRes = strSrcFile.Right(4).CompareNoCase(".res") == 0; bool bDef = strSrcFile.Right(4).CompareNoCase(".def") == 0; if (!bLib && !bRes) // ---- if the source file is in memory and modified, save it bIsCurrent &= !UpdateSourceFile(strSrcFile); if (bLib) { // --- object library, add to compiler's list of files to include in link theApp.GetCompiler().AddLibraryFile(strSrcFile); if (!bForceRebuild && bIsCurrent) { CString strLibPathFile; const CStringArray& rstrLibs = theApp.GetLibraryArray(); int nSize = rstrLibs.GetSize(); int i; bool isLib = (strSrcFile.Left(3).CompareNoCase("lib") == 0 && strSrcFile.Right(2).CompareNoCase(".a") == 0); // ---- test to see if the library file exists for (i = 0; i < nSize; i ) { if (isLib) strLibPathFile = rstrLibs[i] "\\" strSrcFile; else strLibPathFile = strSrcFile; if (_access(strLibPathFile, 0) == 0) break; } // ---- test to see if the library file exists and is newer than the executable if (i < nSize && theApp.CompareFileTimes(m_strTargetFile, strLibPathFile) < 0) bIsCurrent = false; } continue; } if (bDef && bIsCurrent) { bool bCompileDef = false; if (!bForceRebuild && bIsCurrent) { // if target older than def, compile bCompileDef = theApp.CompareFileTimes(m_strTargetFile, strSrcFile) < 0; if (!bCompileDef) { const Compiler& rc = theApp.GetCompiler(); const CString& strTg = rc.GetTargetName(); CString ext("a"); CString strImportLib = theApp.GetFileName(strTg.Left(strTg.GetLength() - 3) ext); // if import lib older than def, compile bCompileDef = theApp.CompareFileTimes(strImportLib, strSrcFile) < 0; } } if (bForceRebuild || bCompileDef) { theApp.GetCompiler().AddSourceFile(strSrcFile); bIsCurrent = false; } continue; } // ---- make a copy of the source file name without the path or file extension CString strSrcName = theApp.GetFileName(strSrcFile.Left(strSrcFile.ReverseFind('.'))); // ================================================== CString strObjFile = theApp.GetCompiler().MakeObjectFileName(strSrcName); if (bRc) { // --- compiling .rc into .o theApp.GetCompiler().AddObjectFile(strObjFile); if (bForceRebuild || theApp.CompareFileTimes(strObjFile, strSrcFile) < 0) { theApp.GetCompiler().AddSourceFile(strSrcFile); bIsCurrent = false; } else if (theApp.CompareFileTimes(m_strTargetFile, strObjFile) < 0) bIsCurrent = false; continue; } if (bRes) { // --- linking .res into .exe (bcc) or compiling res or rc into .o (gcc) CString strResFile(strSrcName ".res"); // --- compiling .res into .o theApp.GetCompiler().AddObjectFile(strObjFile); if (bForceRebuild || theApp.CompareFileTimes(strObjFile, strSrcFile) < 0) { theApp.GetCompiler().AddSourceFile(strResFile); bIsCurrent = false; } if (theApp.CompareFileTimes(m_strTargetFile, strObjFile) < 0) bIsCurrent = false; continue; } // --- c or cpp source file // ---- make a copy of the source file's object file specification strObjFile = theApp.GetCompiler().MakeObjectFileName(strSrcName); // ---- add the object file to the compiler's link list theApp.GetCompiler().AddObjectFile(strObjFile); // ---- if the object file has no path info, add it from the target spec if (strObjFile.Find("\\") == -1) { // --- extract path info from target spec int ndx = m_strTargetFile.ReverseFind('\\'); strObjFile = m_strTargetFile.Left(ndx 1) strObjFile; } // ---- test for rebuild all or if the source file is newer than the object or // an included file is newer than the object file. if ( IncludesAreNewer(strSrcFile, strObjFile) || bForceRebuild || theApp.CompareFileTimes(strObjFile, strSrcFile) < 0 ) { // ---- queue the source file to be compiled theApp.GetCompiler().AddSourceFile(strSrcFile); bIsCurrent = false; m_IncludesChecked.RemoveAll(); } // ---- test to see if the object file is newer than the executable else if (theApp.CompareFileTimes(m_strTargetFile, strObjFile) < 0) bIsCurrent = false; } if (bIsCurrent) { theApp.GetCompiler().ClearArrays(); if (!bForceRebuild) { CString msg = theApp.GetFileName(m_strTargetFile); msg = " is up to date"; theApp.GetCompiler().AddLogEntry(msg); } } return bIsCurrent; } // ---- if the named source file is in memory and modified, save it bool CQuincyView::UpdateSourceFile(CString& strSrcFile) { CTextDocument* pDoc = theApp.GetTextDocument(strSrcFile); bool bUd = pDoc != 0 && pDoc->IsModified(); if (bUd) pDoc->OnSaveDocument(strSrcFile); return bUd; } bool CQuincyView::IncludesAreNewer(CString& strSrcFile, CString& strObjFile) { CStdioFile ifile(strSrcFile, CFile::modeRead); char buf[81]; while (ifile.ReadString(buf, 80) != 0) { // ---- parse the line for an #include statement with "" delimiters char *cp = buf; while (isspace(*cp)) cp ; if (*cp != '#') continue; while (isspace(*cp)) cp ; if (strncmp(cp, "include", 7) != 0) continue; cp = 7; while (isspace(*cp)) cp ; if (*cp != '"') continue; cp ; // ---- extract the filename of the included file while (isspace(*cp)) cp ; char ifilename[81]; char *cp2 = ifilename; while (*cp != '"' && !isspace(*cp) && cp2 < ifilename 80) *cp2 = *cp ; *cp2 = '\0'; CString strInclFile(ifilename); // ---- see if this file has already been checked int nSize = m_IncludesChecked.GetSize(); int i; for (i = 0; i < nSize; i ) if (strInclFile == m_IncludesChecked[i]) break; if (i < nSize) continue; m_IncludesChecked.Add(strInclFile); // ---- if the included source file is in memory and modified, save it if (UpdateSourceFile(strInclFile)) return true; // ---- see if the included file is in one of the -I specifications const CStringArray& rstrIncludes = theApp.GetIncludeArray(); nSize = rstrIncludes.GetSize(); i = 0; if (nSize && (_access(strInclFile, 0) != 0)) { // --- not a local header for (; i < nSize; i ) { strInclFile = rstrIncludes[i] "\\" theApp.GetFileName(strInclFile); if (_access(strInclFile, 0) == 0) break; } } if (i == nSize) // not in -I, must be system header continue; // ---- compare the times of the two files if (theApp.CompareFileTimes(strInclFile, strObjFile) > 0) return true; // ---- now check nested includes if (IncludesAreNewer(strInclFile, strObjFile)) return true; } return false; } void CQuincyView::MakeTargetName() { CQuincyDoc* pDoc = static_cast<CQuincyDoc*>(GetDocument()); ASSERT(pDoc != 0); m_strTargetFile = pDoc->TargetName(); if (m_strTargetFile.Find('\\') == -1 || m_strTargetFile[1] != ':') { // --- incomplete or no path information in the target, prefix with the path of the project CString strProjPath = pDoc->GetPathName(); // strip the file name int nIndex = strProjPath.ReverseFind('\\'); if (nIndex == -1) nIndex = strProjPath.ReverseFind(':'); if (nIndex != -1) strProjPath = strProjPath.Left(nIndex 1); // ----- build the target file specification m_strTargetFile = strProjPath pDoc->TargetName(); } } bool CQuincyView::CanExecuteProgram(bool bDoStep) { MakeTargetName(); CString msg = theApp.GetFileName(m_strTargetFile); bool bExeExists = _access(m_strTargetFile, 0) == 0; bool bIsCurrent = TargetIsCurrent(); if (bExeExists) { // ---- exe file exists if (bIsCurrent) return true; msg = " is out of date. Rebuild?"; } else // ---- exe file does not exist msg = " does not exist. Build?"; int rtn = AfxMessageBox(msg, MB_YESNOCANCEL | MB_ICONQUESTION); if (rtn == IDYES) BuildProject(true, bDoStep); // ??????? else if (rtn != IDCANCEL && bExeExists) return true; return false; } void CQuincyView::OnRun() { if (!theApp.ExecuteRunningProgram()) if (CanExecuteProgram(false)) theApp.StartProgram(m_strTargetFile); } void CQuincyView::OnDebugStep() { if (!theApp.StepProgram()) if (CanExecuteProgram(true)) theApp.DebugProgram(m_strTargetFile, true); } void CQuincyView::OnBuild() { MakeTargetName(); if (!TargetIsCurrent()) BuildProject(false, false); } void CQuincyView::OnBuildAll() { MakeTargetName(); TargetIsCurrent(true); BuildProject(false, false); }
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论