URL
https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk
Subversion Repositories openrisc_me
[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [tools/] [src/] [tools/] [configtool/] [common/] [win32/] [CTCommonDoc.cpp] - Rev 26
Go to most recent revision | Compare with Previous | Blame | View Log
//####COPYRIGHTBEGIN#### // // ---------------------------------------------------------------------------- // Copyright (C) 1998, 1999, 2000 Red Hat, Inc. // // This program is part of the eCos host tools. // // This program is free software; you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by the Free // Software Foundation; either version 2 of the License, or (at your option) // any later version. // // This program is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for // more details. // // You should have received a copy of the GNU General Public License along with // this program; if not, write to the Free Software Foundation, Inc., // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // // ---------------------------------------------------------------------------- // //####COPYRIGHTEND#### #include "stdafx.h" #include "ConfigToolDoc.h" #ifdef PLUGIN #include "CTMain.h" #include "Project.h" #include "ProjectManager.h" #else #include "MainFrm.h" #endif #include "CTUtils.h" #include "CdlPackagesDialog.h" #include "ConfigItem.h" #include "ConfigTool.h" #include "ControlView.h" #include "FailingRulesDialog.h" #include "FolderDialog.h" #include "IdleMessage.h" #include "MLTView.h" #include "NotePage.h" #include "RegionGeneralPage.h" #include "RegKeyEx.h" #include "RulesView.h" #include "SectionGeneralPage.h" #include "SectionRelocationPage.h" #include <htmlhelp.h> #include <shlobj.h> #define INCLUDEFILE <string> #include "IncludeSTL.h" #define INCLUDEFILE "build.hxx" #include "IncludeSTL.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif const CFileName &CConfigToolDoc::DefaultExternalBrowser() { static bool bFirstTime=true; if(bFirstTime){ const CFileName strFile(CFileName::GetTempPath()+_T("index.html")); CFile f; if(f.Open(strFile,CFile::modeCreate|CFile::modeWrite)){ f.Close(); bool rc=((int)FindExecutable(strFile,_T("."),m_strDefaultExternalBrowser.GetBuffer(MAX_PATH))>32); m_strDefaultExternalBrowser.ReleaseBuffer(); if(!rc){ m_strDefaultExternalBrowser=_T(""); } ::DeleteFile(strFile); } bFirstTime=false; } return m_strDefaultExternalBrowser; } CFileName CConfigToolDoc::m_strDefaultExternalBrowser; void CConfigToolDoc::CheckRadios() { for(int nItem=0;nItem<ItemCount();nItem++){ CConfigItem *pItem=Item(nItem); if(pItem->HasRadio () && pItem==pItem->FirstRadio()){ CString strMsg; CConfigItem *pFirstSet=NULL; for(CConfigItem *pSibItem=pItem;pSibItem;pSibItem=pSibItem->NextRadio()){ if(pSibItem->IsEnabled ()){ if(pFirstSet){ strMsg+=_T(" "); strMsg+=pSibItem->Macro (); } else { pFirstSet=pSibItem; } } } if(!strMsg.IsEmpty()){ CConfigTool::Log(_T("%s, multiple radio buttons are set: %s%s"), pItem->Macro(),pFirstSet->Macro(),strMsg); } else if(!pFirstSet){ CConfigTool::Log(_T("%s, no radio buttons are set"),pItem->Macro()); } } } } // Find the ConfigItem referencing the given CdlValuable CConfigItem * CConfigToolDoc::Find (CdlValuable v) { for(int nItem=0;nItem<ItemCount();nItem++){ CConfigItem *pItem=Item(nItem); if(v==pItem->GetCdlValuable()){ return pItem; } } return NULL; } CConfigItem * CConfigToolDoc::Find(const CString & strWhat,WhereType where) { for(int nItem=0;nItem<ItemCount();nItem++){ CConfigItem *pItem=Item(nItem); if(0==pItem->StringValue(where).Compare(strWhat)){ return pItem; } } return NULL; } void CConfigToolDoc::OnMLTNewRegion() { // create the property sheet CPropertySheet prsRegionSheet (IDS_NEW_REGION_SHEET_TITLE, CConfigTool::GetMLTView()); // add the property pages CRegionGeneralPage prpGeneral; CNotePage prpNote; prsRegionSheet.AddPage (&prpGeneral); prsRegionSheet.AddPage (&prpNote); // setup initial values prpGeneral.m_strRegionName = _T(""); prpGeneral.m_dwRegionStartAddress = 0; prpGeneral.m_dwRegionSize = 0; // show property sheet if (prsRegionSheet.DoModal () == IDOK) { if (int nErrorCode = MemoryMap.create_memory_region (CUtils::UnicodeToStdStr(prpGeneral.m_strRegionName), prpGeneral.m_dwRegionStartAddress, prpGeneral.m_dwRegionSize, (prpGeneral.m_bRegionReadOnly ? read_only : read_write), CUtils::UnicodeToStdStr(prpNote.m_strNote))) ErrorBox (IDS_ERR_MEMMAP_REGION_CREATE, IDS_ERR_MEMMAP_BASE + nErrorCode); else // no errors { SetModifiedFlag (); UpdateAllViews (NULL, MemLayoutChanged); } } } void CConfigToolDoc::ErrorBox (UINT uIDSIntro, UINT uIDSError) { CString strIntro, strError; strIntro.LoadString (uIDSIntro); strError.LoadString (uIDSError); AfxMessageBox (strIntro + _T("\n\n") + strError); } void CConfigToolDoc::OnMLTNewSection() { // create the property sheet CPropertySheet prsSectionSheet (IDS_NEW_SECTION_SHEET_TITLE, CConfigTool::GetMLTView()); // add the property pages CSectionGeneralPage prpGeneral; CSectionRelocationPage prpRelocation; CNotePage prpNote; prsSectionSheet.AddPage (&prpGeneral); prsSectionSheet.AddPage (&prpRelocation); prsSectionSheet.AddPage (&prpNote); // initialise for a new section prpGeneral.m_bNameLinkerDefined = TRUE; prpGeneral.m_strNameLinker = _T(""); prpRelocation.m_bRelocates = FALSE; prpRelocation.m_bNewSection = TRUE; // show property sheet if (prsSectionSheet.DoModal () == IDOK) { mem_anchor initial_anchor, final_anchor; mem_address initial_address; CString strInitialRelativeName = _T(""); if (prpGeneral.m_bFinalAbsolute) // final location is an absolute location final_anchor = absolute; else // final location is a relative location final_anchor = relative; if (prpRelocation.m_bRelocates) // if the section relocates { if (prpRelocation.m_bInitialAbsolute) // initial location is an absolute location { initial_anchor = absolute; } else // initial location is a relative location { strInitialRelativeName = prpRelocation.m_strInitialRelativeName; initial_anchor = relative; } initial_address = prpRelocation.m_dwInitialAddress; } else { strInitialRelativeName = prpGeneral.m_strFinalRelativeName; initial_anchor = final_anchor; initial_address = prpGeneral.m_dwFinalAddress; } if (int nErrorCode = MemoryMap.create_memory_section (CUtils::UnicodeToStdStr(prpGeneral.m_bNameLinkerDefined ? prpGeneral.m_strNameLinker : prpGeneral.m_strNameUser), prpGeneral.m_dwSectionSize, prpGeneral.m_dwAlignment, initial_anchor, CUtils::UnicodeToStdStr(strInitialRelativeName), initial_address, final_anchor, CUtils::UnicodeToStdStr(prpGeneral.m_strFinalRelativeName), prpGeneral.m_dwFinalAddress, prpRelocation.m_bRelocates, false, prpGeneral.m_bNameLinkerDefined, CUtils::UnicodeToStdStr(prpNote.m_strNote))) ErrorBox (IDS_ERR_MEMMAP_SECTION_CREATE, IDS_ERR_MEMMAP_BASE + nErrorCode); else // no errors { SetModifiedFlag (); UpdateAllViews (NULL, MemLayoutChanged); } } } void CConfigToolDoc::OnMLTDelete() { if (strSelectedSection != _T("")) // a section is selected { if (MemoryMap.delete_memory_section (CUtils::UnicodeToStdStr(strSelectedSection))) { strSelectedSection = _T(""); SetModifiedFlag (); UpdateAllViews (NULL, MemLayoutChanged); } else AfxMessageBox (_T("Could not delete memory section.\n\nMake sure there are no other sections defined relative to this one.")); } else if (strSelectedRegion != _T("")) // a region is selected { if (MemoryMap.delete_memory_region (CUtils::UnicodeToStdStr(strSelectedRegion))) { strSelectedRegion = _T(""); SetModifiedFlag (); UpdateAllViews (NULL, MemLayoutChanged); } else AfxMessageBox (_T("Could not delete memory region.\n\nMake sure it is not in use.")); // FIXME } } void CConfigToolDoc::ShowRegionProperties() { // create the property sheet CString strTitle; strTitle.LoadString (IDS_REGION_PROPERTIES_SHEET_TITLE); CPropertySheet prsRegionSheet (strSelectedRegion + _T(" - ") + strTitle, CConfigTool::GetMLTView()); // add the property pages CRegionGeneralPage prpGeneral; CNotePage prpNote; prsRegionSheet.AddPage (&prpGeneral); prsRegionSheet.AddPage (&prpNote); // set up property sheet values mem_type type; std::string note; MemoryMap.get_memory_region (CUtils::UnicodeToStdStr(strSelectedRegion), &prpGeneral.m_dwRegionStartAddress, &prpGeneral.m_dwRegionSize, &type, ¬e); prpGeneral.m_strRegionName = strSelectedRegion; prpGeneral.m_bRegionReadOnly = (type == read_only); prpNote.m_strNote = note.c_str (); // show property sheet if (prsRegionSheet.DoModal () == IDOK) { if (int nErrorCode = MemoryMap.edit_memory_region (CUtils::UnicodeToStdStr(strSelectedRegion), CUtils::UnicodeToStdStr(prpGeneral.m_strRegionName), prpGeneral.m_dwRegionStartAddress, prpGeneral.m_dwRegionSize, (prpGeneral.m_bRegionReadOnly ? read_only : read_write), CUtils::UnicodeToStdStr(prpNote.m_strNote))) ErrorBox (IDS_ERR_MEMMAP_REGION_MODIFY, IDS_ERR_MEMMAP_BASE + nErrorCode); else // no errors { SetModifiedFlag (); UpdateAllViews (NULL, MemLayoutChanged); } } } void CConfigToolDoc::ShowSectionProperties() { // create the property sheet CString strTitle; strTitle.LoadString (IDS_SECTION_PROPERTIES_SHEET_TITLE); CPropertySheet prsSectionSheet (strSelectedSection + _T(" - ") + strTitle, CConfigTool::GetMLTView()); // add the property pages CSectionGeneralPage prpGeneral; CSectionRelocationPage prpRelocation; CNotePage prpNote; prsSectionSheet.AddPage (&prpGeneral); prsSectionSheet.AddPage (&prpRelocation); prsSectionSheet.AddPage (&prpNote); // setup initial values std::list <mem_section>::iterator section = MemoryMap.find_memory_section (CUtils::UnicodeToStdStr(strSelectedSection)); prpGeneral.m_bNameLinkerDefined = (section->linker_defined); if (prpGeneral.m_bNameLinkerDefined) prpGeneral.m_strNameLinker = section->name.c_str (); else { prpGeneral.m_strNameUser = section->name.c_str (); prpGeneral.m_dwSectionSize = section->size; } prpGeneral.m_bFinalAbsolute = (section->final_location->anchor == absolute); if (prpGeneral.m_bFinalAbsolute) prpGeneral.m_dwFinalAddress = section->final_location->address; else { prpGeneral.m_strFinalRelativeName = MemoryMap.find_preceding_section (section, false)->name.c_str (); prpGeneral.m_dwAlignment = section->alignment; } prpRelocation.m_bRelocates = section->relocates; if (prpRelocation.m_bRelocates) { prpRelocation.m_bInitialAbsolute = (section->initial_location->anchor == absolute); if (prpRelocation.m_bInitialAbsolute) prpRelocation.m_dwInitialAddress = section->initial_location->address; else prpRelocation.m_strInitialRelativeName = MemoryMap.find_preceding_section (section, true)->name.c_str (); } prpNote.m_strNote = section->note.c_str (); // show property sheet if (prsSectionSheet.DoModal () == IDOK) { mem_anchor initial_anchor, final_anchor; mem_address initial_address; CString strInitialRelativeName = _T(""); if (prpGeneral.m_bFinalAbsolute) // final location is an absolute location final_anchor = absolute; else // final location is a relative location final_anchor = relative; if (prpRelocation.m_bRelocates) // if the section relocates { if (prpRelocation.m_bInitialAbsolute) // initial location is an absolute location { initial_anchor = absolute; } else // initial location is a relative location { strInitialRelativeName = prpRelocation.m_strInitialRelativeName; initial_anchor = relative; } initial_address = prpRelocation.m_dwInitialAddress; } else { strInitialRelativeName = prpGeneral.m_strFinalRelativeName; initial_anchor = final_anchor; initial_address = prpGeneral.m_dwFinalAddress; } if (int nErrorCode = MemoryMap.edit_memory_section (CUtils::UnicodeToStdStr(strSelectedSection), CUtils::UnicodeToStdStr(prpGeneral.m_bNameLinkerDefined ? prpGeneral.m_strNameLinker : prpGeneral.m_strNameUser), prpGeneral.m_dwSectionSize, prpGeneral.m_dwAlignment, initial_anchor, CUtils::UnicodeToStdStr(strInitialRelativeName), initial_address, final_anchor, CUtils::UnicodeToStdStr(prpGeneral.m_strFinalRelativeName), prpGeneral.m_dwFinalAddress, prpRelocation.m_bRelocates, false, prpGeneral.m_bNameLinkerDefined, CUtils::UnicodeToStdStr(prpNote.m_strNote))) ErrorBox (IDS_ERR_MEMMAP_SECTION_MODIFY, IDS_ERR_MEMMAP_BASE + nErrorCode); else // no errors { SetModifiedFlag (); UpdateAllViews (NULL, MemLayoutChanged); } } } void CConfigToolDoc::OnMLTProperties() { if (strSelectedRegion != _T("")) ShowRegionProperties (); else if (strSelectedSection != _T("")) ShowSectionProperties (); } // Choose a default Hal. Do this using clues the installer may have helpfully left behind (PR 18050) // or else if there is only one possible choice, by choosing that one :-). /* void CConfigToolDoc::ChooseDefaultHal() { bool bFound=false; // Has the installer told us? LPCTSTR pszRegPath=_T("SOFTWARE\\Red Hat\\eCos\\1.2.8"); HKEY hKey; if(ERROR_SUCCESS==RegOpenKeyEx (HKEY_LOCAL_MACHINE, pszRegPath, 0L, KEY_READ, &hKey)){ DWORD dwSizePath=MAX_PATH; CString str; PTCHAR psz=str.GetBuffer(dwSizePath); if(ERROR_SUCCESS==RegQueryValueEx(hKey, _T("Default Architecture"), NULL, NULL, (LPBYTE)psz, &dwSizePath)){ str.MakeLower(); for(int nItem=0;nItem<ItemCount();nItem++){ CConfigItem *pItem=Item(nItem); if(pItem->m_pTarget){ CString strTarget(pItem->m_pTarget->Name()); strTarget.MakeLower(); if(-1!=str.Find(strTarget)){ bFound=true; dwSizePath=MAX_PATH; if(ERROR_SUCCESS==::RegQueryValueEx(hKey, _T("Default Build Tools Path"), NULL, NULL, (LPBYTE)psz, &dwSizePath)){ pItem->m_pTarget->SetBinDir(psz); for(CConfigItem *pSib=pItem->FirstRadio();pSib;pSib=pSib->NextRadio()){ pSib->SetValue((ItemIntegerType) (pSib==pItem)); } // pItem->EnableAncestors(); } break; } } } } RegCloseKey(hKey); } if(!bFound){ // No - choose the Hal according to toolchain for(int nItem=0;nItem<ItemCount();nItem++){ CConfigItem *pItem=Item(nItem); if(pItem->m_pTarget){ CString strTarget(pItem->m_pTarget->Name()); strTarget.MakeLower(); for(int j=0;j<m_arstrToolChainPaths.GetSize();j++){ CString strTools(m_arstrToolChainPaths[j]); strTools.MakeLower(); if(-1!=strTools.Find(strTarget)){ for(CConfigItem *pSib=pItem->FirstRadio();pSib;pSib=pSib->NextRadio()){ pSib->SetValue((ItemIntegerType) (pSib==pItem)); } return; } } } } } } */ bool CConfigToolDoc::SetValue (CConfigItem &ti, double dValue, CdlTransaction transaction/*=NULL*/) { ASSERT (ti.Type () == CConfigItem::Double); // test if the new double value is in range const CdlValuable valuable = ti.GetCdlValuable(); CdlListValue list_value; CdlEvalContext context (NULL, ti.GetCdlItem (), ti.GetCdlItem ()->get_property (CdlPropertyId_LegalValues)); valuable->get_legal_values ()->eval (context, list_value); if (! list_value.is_member (dValue)) { if (dValue==valuable->get_double_value(CdlValueSource_Current) || IDNO == CUtils::MessageBoxFT (MB_YESNO, _T("%s is not a legal value for %s.\n\nDo you want to use this value anyway?"), CUtils::DoubleToStr (dValue), ti.Macro ())) return false; } if (! ti.SetValue (dValue,transaction)) return false; SetModifiedFlag (); return true; } bool CConfigToolDoc::SetValue(CConfigItem &ti,const CString &strValue, CdlTransaction transaction/*=NULL*/) { // warn the user if a modified memory layout is about to be discarded if (MemoryMap.map_modified () && (ti.Macro () == _T("CYG_HAL_STARTUP")) && (IDCANCEL == CUtils::MessageBoxFT (MB_OKCANCEL, _T("Changes to the current memory layout will be lost.")))) return false; bool rc=false; switch(ti.Type()){ case CConfigItem::None: break; case CConfigItem::Enum: case CConfigItem::String: rc=ti.SetValue(strValue,transaction); break; case CConfigItem::Integer: { ItemIntegerType n; rc=CUtils::StrToItemIntegerType(strValue,n) && SetValue(ti,n,transaction); } break; case CConfigItem::Double: { double dValue; rc = CUtils::StrToDouble (strValue, dValue) && SetValue (ti, dValue,transaction); } break; default: ASSERT(FALSE); break; } if(rc){ SetModifiedFlag(); UpdateAllViews (NULL, CConfigToolDoc::ValueChanged, (CObject *)&ti); } return rc; } // Look in registry to match prefixes CYGPKG_HAL_ and CYGHWR_HAL_: // bool CConfigToolDoc::GetRunPlatform(CString &strTarget) { CRegKeyEx k1(HKEY_CURRENT_USER,_T("Software\\Red Hat\\eCos\\Platforms"), KEY_READ); CString strKey; for(int i=0;k1.QueryKey(i,strKey);i++){ CRegKeyEx k2((HKEY)k1,strKey,KEY_READ); // Subkeys' names are the target image names [one of which we aim to return] // Subkeys's values of interest are: // Prefix String // Sim DWORD [optional] // Macro String DWORD dwSim=0; CString strPrefix,strMacro; k2.QueryValue(_T("Sim"),dwSim); k2.QueryValue(_T("Prefix"),strPrefix); k2.QueryValue(_T("Macro"),strMacro); CConfigItem *pItem=Find(_T("CYGPKG_HAL_")+strMacro); if(pItem && pItem->IsEnabled()){ // We have found what we are looking for - probably pItem=Find(_T("CYGHWR_HAL_")+strMacro+_T("_STARTUP")); if(pItem){ // Two platforms apply - choose this one only if the ram startup attribute fits if( (dwSim==0) == (0==pItem->StringValue().CompareNoCase(_T("ram"))) ) { strTarget=strKey; } } else { // Only one platform applies strTarget=strKey; } } } return !strTarget.IsEmpty(); } bool CConfigToolDoc::SetEnabled(CConfigItem &ti, bool bEnabled, CdlTransaction transaction/*=NULL*/) { const bool bStatus = ti.SetEnabled (bEnabled,transaction); if (bStatus) { SetModifiedFlag(); UpdateAllViews (NULL, CConfigToolDoc::ValueChanged, (CObject *) &ti); } return bStatus; } void CConfigToolDoc::AddContents (const CdlContainer container, CConfigItem *pParent) { // determine the container contents const std::vector<CdlNode>& contents = container->get_contents (); std::vector<CdlNode>::const_iterator node_i; for (node_i = contents.begin (); node_i != contents.end (); node_i++) { const CdlNode node = * node_i; const CdlPackage pkg = dynamic_cast<CdlPackage> (node); const CdlComponent comp = dynamic_cast<CdlComponent> (node); const CdlOption opt = dynamic_cast<CdlOption> (node); const CdlContainer contnr = dynamic_cast<CdlContainer> (node); // if the node in the container is a package, component or option // then it is visible and should be added to the tree if (0 != pkg) // the node is a package { CConfigItem * pItem = AddItem (pkg, pParent); // add the package AddContents (pkg, pItem); // add the package contents } else if (0 != comp) // the node is a component { CConfigItem * pItem = AddItem (comp, pParent); // add the component AddContents (comp, pItem); // add the component contents } else if (0 != opt) // the node is an option AddItem (opt, pParent); // add the option else if (0 != contnr) // if the node is a container AddContents (contnr, pParent); // add the container contents // ignore nodes of any other class } } // Three hack functions. const CString CConfigToolDoc::CurrentPlatform() { /* for(int nItem=0;nItem<ItemCount();nItem++){ CConfigItem *pItem=Item(nItem); if(pItem->IsEnabled() && !pItem->Platform().IsEmpty()){ return pItem->Platform(); } } */ return _T(""); } // a trivial CDL parse error handler void CConfigToolDoc::CdlParseErrorHandler (std::string message) { CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc(); pDoc->m_strCdlErrorMessage = message.c_str (); TRACE (_T("CdlParseError: %s\n"), pDoc->m_strCdlErrorMessage); CConfigTool::Log (CUtils::StripExtraWhitespace (pDoc->m_strCdlErrorMessage)); // display the message in the output window }; // a trivial CDL parse warning handler void CConfigToolDoc::CdlParseWarningHandler (std::string message) { CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc(); pDoc->m_strCdlErrorMessage = message.c_str (); TRACE (_T("CdlParseWarning: %s\n"), pDoc->m_strCdlErrorMessage); CConfigTool::Log (CUtils::StripExtraWhitespace (pDoc->m_strCdlErrorMessage)); // display the message in the output window }; // a trivial CDL load error handler void CConfigToolDoc::CdlLoadErrorHandler (std::string message) { CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc(); pDoc->m_strCdlErrorMessage = message.c_str (); TRACE (_T("CdlLoadError: %s\n"), pDoc->m_strCdlErrorMessage); CConfigTool::Log (CUtils::StripExtraWhitespace (pDoc->m_strCdlErrorMessage)); // display the message in the output window }; // a trivial CDL load warning handler void CConfigToolDoc::CdlLoadWarningHandler (std::string message) { CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc(); pDoc->m_strCdlErrorMessage = message.c_str (); TRACE (_T("CdlLoadWarning: %s\n"), pDoc->m_strCdlErrorMessage); CConfigTool::Log (CUtils::StripExtraWhitespace (pDoc->m_strCdlErrorMessage)); // display the message in the output window }; CdlInferenceCallbackResult CConfigToolDoc::CdlGlobalInferenceHandler(CdlTransaction transaction) { CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc(); pDoc->m_ConflictsOutcome=NotDone; // prepare for the case that there are no solutions CdlInferenceCallbackResult rc=CdlInferenceCallbackResult_Continue; /* std::list<CdlConflict>conflicts1(transaction->get_global_conflicts_with_solutions()); const std::vector<CdlConflict>&conflicts2=transaction->get_resolved_conflicts(); for (unsigned int i = 0; i < conflicts2.size (); i++) { conflicts1.push_back(conflicts2 [i]); } if(conflicts1.size()>0){ CFailingRulesDialog dlg(conflicts1,transaction,&pDoc->m_arConflictsOfInterest); rc=(IDOK==dlg.DoModal())?CdlInferenceCallbackResult_Continue:CdlInferenceCallbackResult_Cancel; pDoc->m_ConflictsOutcome=(CdlInferenceCallbackResult_Continue==rc)?OK:Cancel; } */ const std::list<CdlConflict>& conflicts=pDoc->GetCdlConfig()->get_all_conflicts(); CFailingRulesDialog dlg(conflicts,transaction,&pDoc->m_arConflictsOfInterest); rc=(IDOK==dlg.DoModal())?CdlInferenceCallbackResult_Continue:CdlInferenceCallbackResult_Cancel; pDoc->m_ConflictsOutcome=(CdlInferenceCallbackResult_Continue==rc)?OK:Cancel; return rc; } CdlInferenceCallbackResult CConfigToolDoc::CdlInferenceHandler (CdlTransaction transaction) { CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc(); CdlInferenceCallbackResult rc=CdlInferenceCallbackResult_Continue; const std::list<CdlConflict>&conflicts=transaction->get_new_conflicts(); if((pDoc->m_nRuleChecking&Immediate) && conflicts.size()>0){ if(pDoc->m_nRuleChecking&SuggestFixes){ std::list<CdlConflict> s_conflicts; for (std::list<CdlConflict>::const_iterator conf_i= conflicts.begin (); conf_i != conflicts.end (); conf_i++) { // for each conflict if((*conf_i)->has_known_solution()){ s_conflicts.push_back(*conf_i); } } if(s_conflicts.size()>0){ CFailingRulesDialog dlg(s_conflicts,transaction); return(IDOK==dlg.DoModal()?CdlInferenceCallbackResult_Continue:CdlInferenceCallbackResult_Cancel); } } CString strMsg; if(1==conflicts.size()){ strMsg=(_T("There is 1 unresolved conflict.")); } else { strMsg.Format(_T("There are %d unresolved conflict%s."),conflicts.size(),1==conflicts.size()?_T(""):_T("s")); } rc=(IDYES==CUtils::MessageBoxFT(MB_YESNO|MB_DEFBUTTON2,_T("%s Make the change anyway?"),strMsg))?CdlInferenceCallbackResult_Continue:CdlInferenceCallbackResult_Cancel; } return rc; } // a CDL transaction handler to refresh the configuration tree void CConfigToolDoc::CdlTransactionHandler (const CdlTransactionCallback & data) { static int nNesting=0; TRACE(_T("Transaction handler: nesting level=%d\n"),nNesting++); CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc(); std::vector<CdlValuable>::const_iterator val_i; std::vector<CdlNode>::const_iterator node_i; std::list<CdlConflict>::const_iterator conf_i; CControlView *pControlView=CConfigTool::GetControlView(); for (val_i = data.value_changes.begin(); val_i != data.value_changes.end(); val_i++) { const CString strName((*val_i)->get_name().c_str()); TRACE(_T("%s %s : value change\n"), CString ((*val_i)->get_class_name().c_str()), strName); pControlView->Refresh(strName); if (strName==_T("CYGHWR_MEMORY_LAYOUT")){ // the memory layout has changed... pDoc->SwitchMemoryLayout (false); // ...so display a new one } } for (node_i = data.active_changes.begin(); node_i != data.active_changes.end(); node_i++) { const CString strName((*node_i)->get_name().c_str()); TRACE(_T("%s %s : this has become active or inactive\n"), CString ((*node_i)->get_class_name().c_str()), CString ((*node_i)->get_name().c_str())); if (! dynamic_cast<CdlInterface> (*node_i)){ // if not an interface node pControlView->Refresh(strName); } } for (val_i = data.legal_values_changes.begin(); val_i != data.legal_values_changes.end(); val_i++) { const CString strName((*node_i)->get_class_name().c_str()); TRACE(_T("%s %s : the legal_values list has changed, a new widget may be needed.\n"), CString ((*val_i)->get_class_name().c_str()), strName); } for (val_i = data.value_source_changes.begin(); val_i != data.value_source_changes.end(); val_i++) { const CString strName((*val_i)->get_name().c_str()); CdlValueSource source = (*val_i)->get_source(); TRACE(_T("%s %s : the value source has changed to %s\n"), CString ((*val_i)->get_class_name().c_str()), strName, CString ((CdlValueSource_Default == source) ? "default" : (CdlValueSource_Inferred == source) ? "inferred" : (CdlValueSource_Wizard == source) ? "wizard" : "user")); pControlView->Refresh (strName); } pDoc->UpdateFailingRuleCount(); nNesting--; } // Three hack functions. const CString CConfigToolDoc::CurrentMemoryLayout () { const CConfigItem * pItem = Find (_T("CYGHWR_MEMORY_LAYOUT")); #ifdef _DEBUG if(NULL==pItem){ TRACE(_T("Warning - CurrentMemoryLayout() returning NULL\n")); } #endif return pItem ? pItem->StringValue () : _T(""); } const CString CConfigToolDoc::CurrentTestingIdentifier () { // use the CDL target as the default testing identifier // override in the forthcoming testing identifier dialog as necessary return GetCdlConfig()->get_hardware ().c_str (); // const CConfigItem * pItem = Find (_T("CYGTST_TESTING_IDENTIFIER")); //#ifdef _DEBUG // if(NULL==pItem){ // TRACE(_T("Warning - CurrentTestingIdentifier() returning NULL\n")); // } //#endif // return pItem ? pItem->StringValue () : _T(""); } const CString CConfigToolDoc::CurrentStartup() { const CConfigItem * pItem = Find (_T("CYG_HAL_STARTUP")); #ifdef _DEBUG if(NULL==pItem){ TRACE(_T("Warning - CurrentStartup() returning NULL\n")); } #endif return pItem ? pItem->StringValue () : _T(""); /* for(int nItem=0;nItem<ItemCount();nItem++){ CConfigItem *pItem=Item(nItem); const CString strName(pItem->Name()); if(0==strName.Compare(_T("Startup type")) && pItem->IsEnabled()){ return pItem->StringValue(); } } return _T("ram"); // FIXME - assume ram startup for now if no startup item */ } void CConfigToolDoc::UpdateFailingRuleCount() { int nCount=0; if (GetCdlConfig ()){ // if configuration information // calculate the number of conflicts nCount = // GetCdlConfig ()->get_structural_conflicts ().size () + ignore for now GetCdlConfig ()->get_all_conflicts ().size (); // update the conflicts view if (CConfigTool::GetRulesView ()) { CConfigTool::GetRulesView ()->FillRules (); } } if(CConfigTool::GetMain()){ CConfigTool::GetMain()->SetFailRulePane(nCount); } } void CConfigToolDoc::LogConflicts (const std::list<CdlConflict> & conflicts) { std::list<CdlConflict>::const_iterator conf_i; for (conf_i = conflicts.begin (); conf_i != conflicts.end (); conf_i++) // for each conflict { CString strExplain = (* conf_i)->get_explanation ().c_str (); // get the conflict explanation CConfigTool::Log (CUtils::StripExtraWhitespace (strExplain)); // display the message in the output window } } CString CConfigToolDoc::GetPackageName (const CString & strAlias) { const std::vector<std::string> & packages = m_CdlPkgData->get_packages (); std::vector<std::string>::const_iterator package_i; for (package_i = packages.begin (); package_i != packages.end (); package_i++) { const std::vector<std::string> & aliases = m_CdlPkgData->get_package_aliases (* package_i); CString strPackageAlias = aliases [0].c_str (); if (aliases.size () && (0 == strAlias.Compare (strPackageAlias))) return package_i->c_str (); } return _T(""); } void CConfigToolDoc::DeleteContents() { TRACE(_T("###DeleteContents()\n")); #ifndef PLUGIN CDocument::DeleteContents(); #endif RemoveAllItems(); TRACE(_T("###DeleteContents done\n")); } void CConfigToolDoc::SelectPackages () { CCdlPackagesDialog dlg; // This map holds the CConfigItem pointers for the packages loaded before the dialog is invoked. // We cannot use Find(), which traverses all items - potentially those that have been removed CMapStringToPtr arLoadedPackages; // generate the contents of the add/remove list boxes const std::vector<std::string> & packages = m_CdlPkgData->get_packages (); std::vector<std::string>::const_iterator package_i; for (package_i = packages.begin (); package_i != packages.end (); package_i++) { // if (! m_CdlPkgData->is_hardware_package (* package_i)) // do not list hardware packages { const std::vector<std::string> & aliases = m_CdlPkgData->get_package_aliases (* package_i); CString strMacroName = package_i->c_str (); // use the first alias (if any) as the package identifier CString strPackageName = aliases.size () ? aliases [0].c_str () : strMacroName; CConfigItem * pItem = Find (strMacroName); if (pItem) // if the package is loaded { arLoadedPackages.SetAt(strMacroName,pItem); // pass the currently selected package version string to the dialog box const CdlValuable valuable = pItem->GetCdlValuable(); dlg.Insert (strPackageName, TRUE, NULL, valuable ? (LPCTSTR) CString (valuable->get_value ().c_str ()) : NULL); } else { // pass version string of the most latest version to the dialog box dlg.Insert (strPackageName, FALSE, NULL, (LPCTSTR) CString (m_CdlPkgData->get_package_versions (* package_i) [0].c_str ())); } } } if (IDOK == dlg.DoModal ()) { bool bChanged = false; // until proved otherwise // determine whether each package has changed loaded/unloaded state for (package_i = packages.begin (); package_i != packages.end (); package_i++) // if (! m_CdlPkgData->is_hardware_package (* package_i)) // do not check hardware packages { const std::vector<std::string> & aliases = m_CdlPkgData->get_package_aliases (* package_i); CString strMacroName = package_i->c_str (); // use the first alias (if any) as the package identifier CString strPackageName = aliases.size () ? aliases [0].c_str () : strMacroName; CConfigItem *pItem=NULL; bool bPreviouslyLoaded=arLoadedPackages.Lookup(strMacroName,(void *&)pItem); bool bNowLoaded=dlg.IsAdded (strPackageName); // unload packages which are no longer required before // loading new ones to avoid potential duplicate macro definitions if (! bNowLoaded && bPreviouslyLoaded){ // The package was loaded but should now be unloaded: bChanged|=pItem->Unload(); } else if (bNowLoaded) {// if the package should be loaded const CString strVersion(dlg.GetVersion (strPackageName)); if (bPreviouslyLoaded) { // if the package is already loaded CdlTransactionCallback::set_callback_fn (NULL); // avoid value refresh attempts during load/unload bChanged|=pItem->ChangeVersion(strVersion); CdlTransactionCallback::set_callback_fn (CdlTransactionHandler); // restore value refresh } else { // the package was not loaded but should now be loaded TRACE (_T("Loading package %s\n"), strMacroName); try { GetCdlConfig()->load_package (CUtils::UnicodeToStdStr(strMacroName), CUtils::UnicodeToStdStr (strVersion), CConfigToolDoc::CdlParseErrorHandler, CConfigToolDoc::CdlParseWarningHandler); bChanged=true; } catch (CdlStringException exception) { CUtils::MessageBoxF(_T("Error loading package %s:\n\n%s"), strMacroName, CString (exception.get_message ().c_str ())); } catch (...) { CUtils::MessageBoxF(_T("Error loading package %s."), strMacroName); } } } } if (bChanged) {// at least one package was loaded, unloaded or changed version SetModifiedFlag(); RegenerateData(); } } } bool CConfigToolDoc::SetValue(CConfigItem &ti,ItemIntegerType nValue, CdlTransaction transaction/*=NULL*/) { switch(ti.Type()){ case CConfigItem::Enum: case CConfigItem::Integer: // case CConfigItem::Boolean: // case CConfigItem::Radio: break; case CConfigItem::None: case CConfigItem::String: default: ASSERT(FALSE); break; } bool rc=false; bool bChangingMemmap=MemoryMap.map_modified () && ((ti.Macro ().Compare (_T ("CYG_HAL_STARTUP")) == 0)); if(nValue==ti.Value()){ return true; } // test if the new integer value is in range if (CConfigItem::Integer == ti.Type ()) { const CdlValuable valuable = ti.GetCdlValuable(); CdlListValue list_value; CdlEvalContext context (NULL, ti.GetCdlItem (), ti.GetCdlItem ()->get_property (CdlPropertyId_LegalValues)); valuable->get_legal_values ()->eval (context, list_value); if (! list_value.is_member ((cdl_int) nValue)) { if (nValue==(ItemIntegerType) valuable->get_integer_value (CdlValueSource_Current) || IDNO == CUtils::MessageBoxFT (MB_YESNO, _T("%s is not a legal value for %s.\n\nDo you want to use this value anyway?"), CUtils::IntToStr (nValue, CConfigTool::GetConfigToolDoc ()->m_bHex), ti.Macro ())) goto Exit; }; } // if(!ti.CanSetValue(nValue)) // { // if(bInteractive){ // CString strExplanation; // if(CConfigItem::Integer==ti.Type()){ // strExplanation.Format(_T(" [value must lie in the range %d..%d]"), // CUtils::IntToStr(ti.Min(),m_bHex), // CUtils::IntToStr(ti.Max()),m_bHex); // } // CUtils::MessageBoxF( // _T("Cannot set '%s' to %s%s"), // ti.ItemNameOrMacro(), CUtils::IntToStr(nValue,m_bHex), strExplanation); // } // goto Exit; // } // warn the user if the current memory layout has been changed and will be lost // this will happen when the layout has been modified and the target-platform-startup is changed if (bChangingMemmap && IDCANCEL==CUtils::MessageBoxFT(MB_OKCANCEL,_T("Changes to the current memory layout will be lost."))){ goto Exit; } // Save state if(!ti.SetValue(nValue,transaction)){ // CanSetValue above should have caught this CUtils::MessageBoxF(_T("Cannot set '%s' to %d"),ti.ItemNameOrMacro(), nValue); goto Exit; } rc=true; Exit: if(rc){ SetModifiedFlag(); UpdateFailingRuleCount (); UpdateAllViews (NULL, CConfigToolDoc::ValueChanged, (CObject *)&ti); // switch to new memory layout when target, platform or startup changes // but ignore cases where a target or platform is being deactivated (PR 19363) // if (((CurrentTarget () != pOldTarget) || (CurrentPlatform () != strOldPlatform) || (ti.Name ().Compare (_T ("Startup type")) == 0)) && // ((ti.Type () != CConfigItem::Radio) || (nValue))) // SwitchMemoryLayout ((CurrentTarget () != pOldTarget) || (CurrentPlatform () != strOldPlatform)); } return rc; } bool CConfigToolDoc::OpenRepository(LPCTSTR pszRepository/*=NULL*/,bool bPromptInitially/*=false*/) { if(!m_bRepositoryOpen){ CWaitCursor wait; CIdleMessage IM(_T("Opening repository")); UpdateFailingRuleCount(); CFileName strNewRepository; while(!m_bRepositoryOpen){ if(bPromptInitially){ CFolderDialog dlg(/*BOOL bAllowCreation=*/false); dlg.m_strDesc=_T("Please specify the root of the eCos repository tree."); dlg.m_strTitle=_T("Choose folder for eCos repository"); dlg.m_strFolder=strNewRepository; CConfigTool::DismissSplash(); if(IDCANCEL==dlg.DoModal()){ return false; } strNewRepository=dlg.m_strFolder; } else { // Use what came in as parameter or what was found in registry strNewRepository=pszRepository?pszRepository:m_strRepository; bPromptInitially=true; } IM.Set (_T("Opening repository ") + (CString) strNewRepository); CdlPackagesDatabase NewCdlPkgData = NULL; CdlInterpreter NewCdlInterp = NULL; CdlConfiguration NewCdlConfig = NULL; CFileName strNewPackagesDir; EnableCallbacks(false); // disable transaction callbacks until the config tree is regenerated if(OpenRepository(strNewRepository,NewCdlPkgData,NewCdlInterp,NewCdlConfig,strNewPackagesDir)){ // Success // select the "default" template if it exists // otherwise select the first available template std::string default_template = "default"; if (! NewCdlPkgData->is_known_template (default_template)) { const std::vector<std::string>& templates = NewCdlPkgData->get_templates (); if (templates.size () != 0) default_template = templates [0]; } m_template_version = ""; try { const std::vector<std::string>& template_versions = NewCdlPkgData->get_template_versions (default_template); NewCdlConfig->set_template (default_template, template_versions [0], &CdlParseErrorHandler, &CdlParseWarningHandler); m_template_version = template_versions [0]; } catch (CdlStringException exception) { CUtils::MessageBoxF(_T("Error loading package template '%s':\n\n%s"), CString (default_template.c_str ()), CString (exception.get_message ().c_str ())); } catch (...) { CUtils::MessageBoxF(_T("Error loading package template '%s'."), CString (default_template.c_str ())); } // check the configuration ASSERT (NewCdlConfig->check_this (cyg_extreme)); // use the new package database, interpreter and configuration deleteZ(m_CdlConfig); // delete the previous configuration deleteZ(m_CdlInterp); // delete the previous interpreter deleteZ(m_CdlPkgData); // delete the previous package database m_CdlPkgData = NewCdlPkgData; m_CdlInterp = NewCdlInterp; m_CdlConfig = NewCdlConfig; // save the repository location SetRepository(strNewRepository); m_strPackagesDir = strNewPackagesDir; #ifndef PLUGIN // clear the previously specified document file name (if any), // OnNewDocument() calls DeleteContents() so must be called // before AddAllItems() CDocument::OnNewDocument (); #endif // generate the CConfigItems from their CDL descriptions AddAllItems (); m_bRepositoryOpen=true; } else { // failure deleteZ(NewCdlConfig); deleteZ(NewCdlInterp); deleteZ(NewCdlPkgData); } // install a transaction handler callback function now that the tree exists EnableCallbacks(true); } } return m_bRepositoryOpen; } // Helper fn for namesake above bool CConfigToolDoc::OpenRepository (const CFileName strNewRepository,CdlPackagesDatabase &NewCdlPkgData,CdlInterpreter &NewCdlInterp,CdlConfiguration &NewCdlConfig,CFileName &strNewPackagesDir) { bool rc=false; TRACE(_T("###Open repository %s\n"),strNewRepository); if(!strNewRepository.IsEmpty()){ // Now strNewRepository is guaranteed non-empty, but does it exist? if(!strNewRepository.IsDir()) { CUtils::MessageBoxF(_T("Cannot open repository - the folder %s does not exist"), strNewRepository); } else { // Ok so it exists, but does it look right? strNewPackagesDir=strNewRepository+_T("ecc"); if(!strNewPackagesDir.IsDir()){ strNewPackagesDir=strNewRepository+_T("packages"); } if(!strNewPackagesDir.IsDir()){ // Don't mention the ecc\ attempt CUtils::MessageBoxF(_T("%s does not seem to be a source repository: the folder %s does not exist"), strNewRepository,strNewPackagesDir); } else { const CFileName strDatabase = strNewPackagesDir + _T("ecos.db"); if(!strDatabase.Exists()) { CUtils::MessageBoxF(_T("%s does not seem to be a source repository: %s does not exist"), strNewRepository, strDatabase); } else { // create a CDL repository, interpreter and configuration try {// create a new package database, interpreter and configuration NewCdlPkgData = CdlPackagesDatabaseBody::make (CUtils::UnicodeToStdStr(strNewPackagesDir), &CdlParseErrorHandler, &CdlParseWarningHandler); NewCdlInterp = CdlInterpreterBody::make (); NewCdlConfig = CdlConfigurationBody::make ("eCos", NewCdlPkgData, NewCdlInterp); } catch (CdlStringException exception) { CUtils::MessageBoxF(_T("Error opening eCos repository:\n\n%s"), CString (exception.get_message ().c_str ())); return false; } catch (...) { CUtils::MessageBoxF(_T("Error opening eCos repository.")); return false; } // select the default target if specified in the registry // otherwise select the first available target std::string default_hardware = CUtils::UnicodeToStdStr (GetDefaultHardware ()); if (! NewCdlPkgData->is_known_target (default_hardware)) { const std::vector<std::string>& targets = NewCdlPkgData->get_targets (); if (targets.size () == 0){ CUtils::MessageBoxF (_T("Error opening eCos repository:\n\nno hardware templates")); return false; } else { default_hardware = targets [0]; } } try { m_strCdlErrorMessage = _T(""); NewCdlConfig->set_hardware (default_hardware, &CdlParseErrorHandler, &CdlParseWarningHandler); } catch (CdlStringException exception) { if (m_strCdlErrorMessage.IsEmpty ()) { CUtils::MessageBoxF (_T("Error loading the default hardware template '%s':\n\n%s"), CString (default_hardware.c_str ()), CString (exception.get_message ().c_str ())); } else // report the most recent parser message in the message box since there may be no output pane in which to view it { CUtils::MessageBoxF (_T("Error loading the default hardware template '%s':\n\n%s\n\nParser message:\n\n%s"), CString (default_hardware.c_str ()), CString (exception.get_message ().c_str ()), m_strCdlErrorMessage); } return false; } catch (...) { CUtils::MessageBoxF (_T("Error loading the default hardware template '%s':\n\n%s"), CString (default_hardware.c_str ()), m_strCdlErrorMessage); return false; } rc=true; } } } } return rc; } void CConfigToolDoc::CloseRepository() { if(m_bRepositoryOpen){ // delete the libCDL objects with the document EnableCallbacks(false); // first disable the transaction handler deleteZ(m_CdlConfig); deleteZ(m_CdlInterp); deleteZ(m_CdlPkgData); m_bRepositoryOpen=false; } } void CConfigToolDoc::SelectTemplate (std::string NewTemplate, std::string NewTemplateVersion) { if ((NewTemplate != m_CdlConfig->get_template()) || (NewTemplateVersion != m_template_version)){ CWaitCursor wait; // this may take a little while RemoveAllItems(); m_template_version = ""; try { m_CdlConfig->set_template (NewTemplate, NewTemplateVersion, CdlParseErrorHandler, CdlParseWarningHandler); m_template_version = NewTemplateVersion; } catch (CdlStringException exception) { CUtils::MessageBoxF(_T("Error loading package template '%s':\n\n%s"), CString (NewTemplate.c_str ()), CString (exception.get_message ().c_str ())); } catch (...) { CUtils::MessageBoxF(_T("Error loading package template '%s'."), CString (NewTemplate.c_str ())); } RegenerateData(); if (!GetPathName().IsEmpty()){ // not a new document CopyMLTFiles (); // copy new MLT files to the build tree as necessary } SetModifiedFlag(); } } void CConfigToolDoc::RegenerateData() { CWaitCursor wait; // This may take a little while AddAllItems (); // regenerate all the config items since the topology may have changed if (m_strLinkerScriptFolder.IsEmpty ()) { CUtils::MessageBoxF(_T("The eCos linker script macro CYGBLD_LINKER_SCRIPT is not defined.")); } if (m_strMemoryLayoutFolder.IsEmpty ()) { CUtils::MessageBoxF(_T("The eCos memory layout macro CYGHWR_MEMORY_LAYOUT is not defined.")); } SwitchMemoryLayout (true); // the hardware template may have changed UpdateBuildInfo(); CConfigTool::GetControlView()->SelectItem(Item(0)); } void CConfigToolDoc::SelectHardware (std::string NewTemplate) { const std::string OldTemplate=m_CdlConfig->get_hardware(); if (NewTemplate != OldTemplate){ RemoveAllItems(); try { m_CdlConfig->set_hardware (NewTemplate, CdlParseErrorHandler, CdlParseWarningHandler); } catch (CdlStringException exception) { CUtils::MessageBoxF(_T("Error loading hardware template '%s':\n\n%s"), CString (NewTemplate.c_str ()), CString (exception.get_message ().c_str ())); m_CdlConfig->set_hardware (OldTemplate, CdlParseErrorHandler, CdlParseWarningHandler); } catch (...) { CUtils::MessageBoxF(_T("Error loading hardware template '%s'."), CString (NewTemplate.c_str ())); m_CdlConfig->set_hardware (OldTemplate, CdlParseErrorHandler, CdlParseWarningHandler); } RegenerateData(); //EnableCallbacks(true); // re-enable the transaction handler if (!GetPathName().IsEmpty()){ CopyMLTFiles (); // copy new MLT files to the build tree as necessary } SetModifiedFlag(); } } bool CConfigToolDoc::SaveMemoryMap() { const CString strSuffix(_T("mlt_") + CurrentMemoryLayout ()); const CFileName strMLTInstallPkgconfDir(InstallTree() + _T("include\\pkgconf")); bool rc=false; if(strMLTInstallPkgconfDir.CreateDirectory(true)){ const CString strMLTInstallBase(strMLTInstallPkgconfDir+CFileName(strSuffix)); const CFileName strMLTDir (MLTDir()); if(strMLTDir.CreateDirectory (true)){ const CString strMLTBase (strMLTDir + CFileName (strSuffix)); TRACE(_T("Saving memory layout to %s\n"), strMLTBase + _T(".mlt")); if(MemoryMap.save_memory_layout (strMLTBase + _T(".mlt"))){ TRACE(_T("Exporting memory layout to %s\n"), strMLTInstallPkgconfDir); rc=MemoryMap.export_files (strMLTInstallBase + _T(".ldi"), strMLTInstallBase + _T(".h")); } } } return rc; } bool CConfigToolDoc::CopyMLTFiles() { // copy default MLT files for the selected target/platform from the repository if they do not already exist TRACE (_T("Looking for MLT files at %s\n"), PackagesDir() + m_strMemoryLayoutFolder + _T("include\\pkgconf\\mlt_*.*")); const CFileName strInstallDestination(InstallTree () + _T("include\\pkgconf")); const CFileName strMLTDestination (MLTDir ()); TRACE (_T("Copying .ldi and .h files to %s\n"), strInstallDestination); TRACE (_T("Copying .mlt files to %s\n"), strMLTDestination); bool rc=strInstallDestination.CreateDirectory (true) && strMLTDestination.CreateDirectory (true); if(rc){ CFileFind ffFileFind; BOOL bLastFile = ffFileFind.FindFile (PackagesDir() + m_strMemoryLayoutFolder + _T("\\include\\pkgconf\\mlt_*.*")); while (bLastFile) { bLastFile = ffFileFind.FindNextFile (); if (_T(".mlt") == ffFileFind.GetFileName ().Right (4)) // if a .mlt file { if (! CFileName (strMLTDestination, CFileName (ffFileFind.GetFileName ())).Exists ()) { if(!CUtils::CopyFile (ffFileFind.GetFilePath (), strMLTDestination + CFileName (ffFileFind.GetFileName ()))){ return false; // message already emitted } } } else // a .h or .ldi file { if (! CFileName (strInstallDestination, CFileName (ffFileFind.GetFileName ())).Exists () && !CUtils::CopyFile (ffFileFind.GetFilePath (), strInstallDestination + CFileName (ffFileFind.GetFileName ()))){ return false; // message already emitted } } } } return rc; //FIXME } CString CConfigToolDoc::GetDefaultHardware () { CString strKey = _T("SOFTWARE\\Red Hat\\eCos"); CString strVersionKey = _T(""); CString rc = _T(""); TCHAR pszBuffer [MAX_PATH + 1]; HKEY hKey; LONG lStatus; // get the greatest eCos version subkey if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE, strKey, 0L, KEY_READ, &hKey)) { DWORD dwIndex = 0; while (ERROR_SUCCESS == RegEnumKey (hKey, dwIndex++, (LPTSTR) pszBuffer, sizeof (pszBuffer))) { if (strVersionKey.Compare (pszBuffer) < 0) strVersionKey = pszBuffer; } RegCloseKey (hKey); if (! strVersionKey.IsEmpty ()) { TRACE (_T("CConfigToolDoc::GetDefaultHardware(): version subkey = '%s'\n"), strVersionKey); // get the default hardware value strKey += _T("\\") + strVersionKey; if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE, strKey, 0L, KEY_READ, &hKey)) { DWORD dwBufferSize = sizeof (pszBuffer); lStatus = RegQueryValueEx (hKey, _T("Default Hardware"), NULL, NULL, (LPBYTE) pszBuffer, &dwBufferSize); RegCloseKey (hKey); if (ERROR_SUCCESS == lStatus) { TRACE (_T("CConfigToolDoc::GetDefaultHardware(): default hardware = '%s'\n"), pszBuffer); rc=pszBuffer; } } } } return rc; } CConfigItem * CConfigToolDoc::AddItem (const CdlUserVisible vitem, CConfigItem * pParent) { CConfigItem * pItem = new CConfigItem (pParent, vitem); m_arItem.Add(pItem); pItem->m_strDesc = CUtils::StripExtraWhitespace (CString (vitem->get_description ().c_str ())); if (vitem->get_name () == "CYGHWR_MEMORY_LAYOUT") { ASSERT (m_strMemoryLayoutFolder.IsEmpty ()); m_strMemoryLayoutFolder = vitem->get_owner ()->get_directory().c_str (); m_strMemoryLayoutFolder.Replace(_TCHAR('/'),_TCHAR('\\')); TRACE (_T("Found memory layout folder: %s\n"), m_strMemoryLayoutFolder); } if (vitem->get_name () == "CYGBLD_LINKER_SCRIPT") { ASSERT (m_strLinkerScriptFolder.IsEmpty ()); m_strLinkerScriptFolder = vitem->get_owner ()->get_directory().c_str (); m_strLinkerScriptFolder.Replace(_TCHAR('/'),_TCHAR('\\')); TRACE (_T("Found linker script folder: %s\n"), m_strLinkerScriptFolder); // the CDL hardware template name will eventually become the target name, // but for now we must deduce the target name from the linker script file name const CdlValuable valuable = dynamic_cast<CdlValuable> (vitem); CFileName strLinkerScript (m_strPackagesDir, m_strLinkerScriptFolder, CString (valuable->get_value ().c_str ())); strLinkerScript.Replace (_TCHAR('/'), _TCHAR('\\')); if(!strLinkerScript.Exists ()){ CConfigTool::Log(_T("%s does not exist\n"),strLinkerScript); } TRACE (_T("Target '%s' selected\n"), strLinkerScript.Tail ().Root (), pItem->Macro()); //CFileName strBinDir = AfxGetApp () -> GetProfileString (CUtils::LoadString (IDS_KEY_TOOLS_DIR), pTarget->Name (), _T("")); //if (! strBinDir.IsEmpty () && strBinDir.IsDir ()) //{ // pTarget->SetBinDir (strBinDir); //} } //TRACE(_T("Created new item from cdl: ")); //pItem->DumpItem(); return pItem; } void CConfigToolDoc::AddAllItems () { // remove any old items and packages DeleteContents (); if(NULL!=CConfigTool::GetControlView()){ // may not be the case for plugin // add the root item CConfigItem * pItem = new CConfigItem (NULL, NULL); m_arItem.Add(pItem); pItem->m_strDesc = _T("The root node for all configurable items"); // add the remaining items using their CDL descriptions m_strMemoryLayoutFolder = _T(""); m_strLinkerScriptFolder = _T(""); AddContents (m_CdlConfig, FirstItem ()); // check that exactly one radio button in each group is enabled CheckRadios (); // update the rules (conflicts) view UpdateFailingRuleCount (); if(NULL==CConfigTool::GetRulesView() || !CConfigTool::GetRulesView()->IsWindowVisible()){ // log all conflicts // LogConflicts (m_CdlConfig->get_structural_conflicts ()); // relating to package availability - ignore for now LogConflicts (m_CdlConfig->get_all_conflicts ()); } CConfigTool::GetControlView()->SelectItem(Item(0)); UpdateAllViews (NULL, SelChanged, (CObject *)Item(0)); // refresh the display if(ItemCount()>0){ CConfigTool::GetControlView()->GetTreeCtrl().Expand(Item(0)->HItem(),TVE_EXPAND); } CConfigTool::GetControlView()->SetFocus(); } } const CFileName CConfigToolDoc::CurrentLinkerScript() { const CConfigItem * pItem = Find (_T("CYGBLD_LINKER_SCRIPT")); return pItem ? CFileName (m_strPackagesDir, m_strLinkerScriptFolder, pItem->StringValue ()) : _T(""); } bool CConfigToolDoc::GenerateHeaders() { // Copy non-config header files from the repository to the // install tree for plugin only. The make system used by // the standalone config tool does this for us. #ifdef PLUGIN typedef std::vector<CdlBuildInfo_Loadable> EntriesArray; const EntriesArray &arEntries=BuildInfo().entries; typedef std::vector<CdlBuildInfo_Header> HeaderArray; for(EntriesArray::size_type j=0;j<arEntries.size();j++){ const CdlBuildInfo_Loadable &e=arEntries[j]; const CFileName strDir(CUtils::WPath(e.directory)); const HeaderArray &arHeaders=e.headers; for(HeaderArray::size_type i=0;i<arHeaders.size();i++){ const CdlBuildInfo_Header &h=arHeaders[i]; const CFileName strSource(PackagesDir()+strDir+CUtils::WPath(h.source)); const CFileName strDest(HeadersDir()/*+CUtils::WPath(e.directory)*/+CUtils::WPath(h.destination)); if(!strDest.Head().CreateDirectory(true)){ CUtils::MessageBoxF(_T("Failed to create %s - %s"),strDest.Head(),CUtils::GetLastErrorMessageString()); return false; } if(!CUtils::CopyFile(strSource,strDest)){ return false; // message already emitted } } } #endif // Generate headers try { CFileName strPkfConfDir(InstallTree()+_T("include\\pkgconf")); if(!strPkfConfDir.CreateDirectory()){ CUtils::MessageBoxF(_T("Failed to create %s - %s"),strPkfConfDir,CUtils::GetLastErrorMessageString()); return false; } GetCdlConfig()->generate_config_headers(CUtils::UnicodeToStdStr(strPkfConfDir.ShortName())); } catch (CdlInputOutputException e) { const CString strMsg(e.get_message().c_str()); TRACE(_T("!!! Exception thrown calling generate_config_headers - %s"),strMsg); CUtils::MessageBoxF(_T("Failed to generate header files - %s"),strMsg); return false; } return true; } const CFileName CConfigToolDoc::MLTDir () { CString strPathName (GetPathName ()); ASSERT (! strPathName.IsEmpty ()); return strPathName.Left (strPathName.ReverseFind (_TCHAR('.'))) + _T("_mlt"); } bool CConfigToolDoc::UpdateBuildInfo(bool bFirstTime) { try { GetCdlConfig()->get_build_info(m_BuildInfo); #ifdef PLUGIN // FIXME: this means anything not mentioned by AddFile in our scan below will be removed - including user-added items m_peCosProject->ClearItemFlags(); m_peCosProject->UpdateeCosProject(bFirstTime); m_peCosProject->RemoveAllUnflaggedItems(); #else UNUSED_ALWAYS(bFirstTime); generate_build_tree (GetCdlConfig(), CUtils::UnicodeToStdStr(BuildTree()), CUtils::UnicodeToStdStr(InstallTree())); #endif return true; } catch(...){ return false; } } void CConfigToolDoc::RemoveAllItems() { for(int nItem=0;nItem<ItemCount();nItem++){ CConfigItem *pItem=Item(nItem); deleteZ(pItem); } m_arItem.RemoveAll(); UpdateAllViews(NULL,Clear,0); } void CConfigToolDoc::EnableCallbacks (bool bEnable/*=true*/) { CdlTransactionCallback::set_callback_fn(bEnable?&CdlTransactionHandler:0); CdlTransactionBody::set_inference_callback_fn(bEnable?&CdlInferenceHandler:0); CdlTransactionBody::set_inference_override(CdlValueSource_Invalid); } int CConfigToolDoc::GetTestExeNames (CFileNameArray &arTestExes,CFileNameArray &arMissing) { arTestExes.RemoveAll(); arMissing.RemoveAll(); typedef std::vector<CdlBuildInfo_Loadable> EntriesArray; const EntriesArray &arEntries=BuildInfo().entries; for(EntriesArray::size_type j=0;j<arEntries.size();j++){ const CdlBuildInfo_Loadable &e=arEntries[j]; CStringArray ar; int n=CUtils::Chop(CString(get_tests(GetCdlConfig(),e).c_str()),ar); for(int i=0;i<n;i++){ CFileName strFile; strFile.Format(_T("%s\\tests\\%s\\%s.exe"),InstallTree(),CString(e.directory.c_str()),ar[i]); strFile.Replace(_TCHAR('/'),_TCHAR('\\')); if(strFile.Exists()){ arTestExes.Add(strFile); } else { arMissing.Add(strFile); } } } return arTestExes.GetSize(); } CConfigToolDoc::GlobalConflictOutcome CConfigToolDoc::ResolveGlobalConflicts(CPtrArray *parConflictsOfInterest) { m_ConflictsOutcome=NotDone; m_arConflictsOfInterest.RemoveAll(); if(parConflictsOfInterest){ m_arConflictsOfInterest.Copy(*parConflictsOfInterest); } CdlInferenceCallback fn=CdlTransactionBody::get_inference_callback_fn(); CdlTransactionBody::set_inference_callback_fn(CdlGlobalInferenceHandler); GetCdlInterpreter()->get_toplevel()->resolve_all_conflicts(); CdlTransactionBody::set_inference_callback_fn(fn); if(NotDone==m_ConflictsOutcome){ // No solutions were available, but we'll run the dialog anyway const std::list<CdlConflict>& conflicts=GetCdlConfig()->get_all_conflicts(); CFailingRulesDialog dlg(conflicts,NULL,&m_arConflictsOfInterest); m_ConflictsOutcome=(IDOK==dlg.DoModal())?OK:Cancel; } return m_ConflictsOutcome; } bool CConfigToolDoc::CheckConflictsBeforeSave() { if(GetCdlInterpreter()->get_toplevel()->get_all_conflicts().size()>0){ if(Deferred&m_nRuleChecking){ if((SuggestFixes&m_nRuleChecking)&&(Cancel==ResolveGlobalConflicts())){ return false; } int nConflicts=GetCdlInterpreter()->get_toplevel()->get_all_conflicts().size(); switch(nConflicts){ case 0: break; case 1: if(IDNO==CUtils::MessageBoxFT(MB_YESNO|MB_DEFBUTTON2,_T("There is 1 unresolved conflict. Save anyway?"))){ return false; } default: if(IDNO==CUtils::MessageBoxFT(MB_YESNO|MB_DEFBUTTON2,_T("There are %d unresolved conflicts. Save anyway?"),nConflicts)){ return false; } } } } return true; } BOOL CConfigToolDoc::IsModified() { return m_bModified || MemoryMap.map_modified(); } void CConfigToolDoc::OnFileExport() { CFileDialog dlg (FALSE, _T("ecm"), NULL, OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY, _T("eCos Minimal Configuration (*.ecm)|*.ecm||"), AfxGetMainWnd ()); TCHAR szBuffer [MAX_PATH * 16] = _T(""); dlg.m_ofn.lpstrFile = szBuffer; dlg.m_ofn.nMaxFile = MAX_PATH * 16; dlg.m_ofn.lpstrTitle = _T("Export eCos Minimal Configuration"); if (IDOK == dlg.DoModal ()) { try { TRACE (_T("Exporting eCos minimal configuration '%s'\n"), dlg.GetPathName ()); m_CdlConfig->save (CUtils::UnicodeToStdStr (dlg.GetPathName ()), /* minimal = */ true); } catch (CdlStringException exception) { CUtils::MessageBoxF (_T("Error exporting eCos minimal configuration:\n\n%s"), CString (exception.get_message ().c_str ())); } catch (...) { CUtils::MessageBoxF (_T("Error exporting eCos minimal configuration.")); } } } void CConfigToolDoc::OnFileImport() { CFileDialog dlg (TRUE, _T("ecm"), NULL, OFN_PATHMUSTEXIST | OFN_HIDEREADONLY, _T("eCos Minimal Configurations (*.ecm)|*.ecm||"), AfxGetMainWnd ()); TCHAR szBuffer [MAX_PATH * 16] = _T(""); dlg.m_ofn.lpstrFile = szBuffer; dlg.m_ofn.nMaxFile = MAX_PATH * 16; dlg.m_ofn.lpstrTitle = _T("Import eCos Minimal Configuration"); if (IDOK == dlg.DoModal ()) { try { TRACE (_T("Importing eCos minimal configuration '%s'\n"), dlg.GetPathName ()); m_CdlConfig->add (CUtils::UnicodeToStdStr (dlg.GetPathName ()), CConfigToolDoc::CdlParseErrorHandler, CConfigToolDoc::CdlParseWarningHandler); } catch (CdlStringException exception) { CUtils::MessageBoxF (_T("Error importing eCos minimal configuration:\n\n%s"), CString (exception.get_message ().c_str ())); } catch (...) { CUtils::MessageBoxF (_T("Error importing eCos minimal configuration.")); } CWaitCursor wait; AddAllItems (); // regenerate all the config items since the topology may have changed if (m_strLinkerScriptFolder.IsEmpty ()) { CUtils::MessageBoxF (_T("The eCos linker script macro CYGBLD_LINKER_SCRIPT is not defined.")); } if (m_strMemoryLayoutFolder.IsEmpty ()) { CUtils::MessageBoxF (_T("The eCos memory layout macro CYGHWR_MEMORY_LAYOUT is not defined.")); } SwitchMemoryLayout (true); // the hardware template may have changed UpdateBuildInfo (); CConfigTool::GetControlView()->SelectItem (Item (0)); SetModifiedFlag (); } } bool CConfigToolDoc::QualifyDocURL(CString &strURL) { if(-1==strURL.Find(_T("://"))){ strURL.Replace(_TCHAR('/'),_TCHAR('\\')); if (! CFileName (strURL).IsFile ()) { // if not an absolute filepath strURL = DocBase () + CFileName (strURL); // prepend the doc directory path } strURL=_T("file://")+strURL; } if(0==strURL.Find(_T("file://"))){ CFileName strFile(strURL.Right(strURL.GetLength()-7)); int nIndex=strFile.ReverseFind(_TCHAR('#')); if(-1!=nIndex){ strFile=strFile.Left(nIndex); } strFile.Replace(_TCHAR('/'),_TCHAR('\\')); if(!strFile.Exists()){ CUtils::MessageBoxF(_T("Cannot locate the file %s"),strFile); return false; } } return true; } bool CConfigToolDoc::NewMemoryLayout (const CString &strPrefix) { CFileName strFileName = CurrentLinkerScript (); TRACE(_T("Reading linker-defined memory sections from %s\n"), strFileName); MemoryMap.new_memory_layout (); // delete the old memory layout regardless if (! strFileName.IsEmpty ()) MemoryMap.import_linker_defined_sections (strFileName); // read the linker-defined section names from the repository (failure is silent) CString strMemoryLayoutFileName = strPrefix + _T("\\mlt_") + CurrentMemoryLayout () + _T(".mlt"); TRACE(_T("Reading memory layout from %s\n"), strMemoryLayoutFileName); MemoryMap.load_memory_layout (strMemoryLayoutFileName); // load the new memory layout (failure is silent) strSelectedSection = _T(""); strSelectedRegion = _T(""); UpdateAllViews (NULL, MemLayoutChanged); return true; // FIXME } void CConfigToolDoc::SetPathName( LPCTSTR pszPath, BOOL bAddToMRU /*= TRUE*/ ) { if(_TCHAR('\0')==*pszPath){ // called like this after failed saves to put things back as they were // CDocument::SetPathName would assert given an empty string m_strPathName = _T(""); #ifndef PLUGIN SetTitle(_T("Untitled")); #endif m_strBuildTree = _T(""); m_strInstallTree = _T(""); } else { #ifdef PLUGIN m_strPathName = CFileName (pszPath); #else CDocument::SetPathName (pszPath, bAddToMRU); #endif CString strFolder (pszPath); strFolder = strFolder.Left (strFolder.ReverseFind (_TCHAR('.'))); // extract folder from file path m_strBuildTree = CFileName(strFolder + _T("_build")); m_strInstallTree = CFileName(strFolder + _T("_install")); } } bool CConfigToolDoc::ShowHtmlHelp (LPCTSTR pszURL) { HWND hwndCaller=AfxGetMainWnd()->CWnd::GetDesktopWindow()->GetSafeHwnd(); bool rc=false; const CFileName strFile(HTMLHelpLinkFileName()); CStdioFile f; if(!CFileName(CConfigTool::strHelpFile).Exists()) { CUtils::MessageBoxF(_T("Cannot display help - %s does not exist\n"),CConfigTool::strHelpFile); } else if(!f.Open(strFile,CFile::typeText|CFile::modeCreate|CFile::modeWrite)){ CUtils::MessageBoxF(_T("Cannot display help - error creating %s\n"),strFile); } else { CString str; str.Format(_T("<meta HTTP-EQUIV=\"refresh\" CONTENT=\"0;URL=%s\">"),pszURL); f.WriteString(str); f.Close(); if(0==HtmlHelp(hwndCaller, CConfigTool::strHelpFile, HH_DISPLAY_TOPIC, 0)){ CUtils::MessageBoxF(_T("Cannot display %s"),pszURL); } else { // FIXME: Do this the first time only? HH_WINTYPE WinType; HWND wnd; HH_WINTYPE *pWinType=NULL; wnd = HtmlHelp(hwndCaller, CConfigTool::strHelpFile+_T(">mainwin"), HH_GET_WIN_TYPE, (DWORD) &pWinType); WinType=*pWinType; WinType.hwndCaller=hwndCaller; WinType.fsWinProperties|=HHWIN_PROP_TRACKING; WinType.idNotify = ID_HHNOTIFICATION; wnd = HtmlHelp(hwndCaller, CConfigTool::strHelpFile, HH_SET_WIN_TYPE, (DWORD) &WinType); rc=true; } //::DeleteFile(strFile); } return rc; } const CString CConfigToolDoc::HTMLHelpLinkFileName() { return CFileName(CConfigTool::strHelpFile).Head()+"link2.htm"; }
Go to most recent revision | Compare with Previous | Blame | View Log