comparison host/tools/configtool/common/win32/CTCommonDoc.cpp @ 76:435cced73e2f ecos-v1_3_1-release

eCos v1.3.1 merged from eCos master repository on 2000-03-27-23:22:51-BST
author jlarmour
date Tue, 28 Mar 2000 14:10:45 +0000
parents
children 59d97b6ba612
comparison
equal deleted inserted replaced
75:41bf073c0c32 76:435cced73e2f
1 //####COPYRIGHTBEGIN####
2 //
3 // ----------------------------------------------------------------------------
4 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
5 //
6 // This program is part of the eCos host tools.
7 //
8 // This program is free software; you can redistribute it and/or modify it
9 // under the terms of the GNU General Public License as published by the Free
10 // Software Foundation; either version 2 of the License, or (at your option)
11 // any later version.
12 //
13 // This program is distributed in the hope that it will be useful, but WITHOUT
14 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 // more details.
17 //
18 // You should have received a copy of the GNU General Public License along with
19 // this program; if not, write to the Free Software Foundation, Inc.,
20 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 //
22 // ----------------------------------------------------------------------------
23 //
24 //####COPYRIGHTEND####
25 #include "stdafx.h"
26
27 #include "ConfigToolDoc.h"
28
29 #ifdef PLUGIN
30 #include "CTMain.h"
31 #include "Project.h"
32 #include "ProjectManager.h"
33 #else
34 #include "MainFrm.h"
35 #endif
36
37 #include "CTUtils.h"
38 #include "CdlPackagesDialog.h"
39 #include "ConfigItem.h"
40 #include "ConfigTool.h"
41 #include "ControlView.h"
42 #include "FailingRulesDialog.h"
43 #include "FolderDialog.h"
44 #include "IdleMessage.h"
45 #include "MLTView.h"
46 #include "NotePage.h"
47 #include "RegionGeneralPage.h"
48 #include "RegKeyEx.h"
49 #include "RulesView.h"
50 #include "SectionGeneralPage.h"
51 #include "SectionRelocationPage.h"
52
53 #include <htmlhelp.h>
54 #include <shlobj.h>
55
56 #define INCLUDEFILE <string>
57 #include "IncludeSTL.h"
58 #define INCLUDEFILE "build.hxx"
59 #include "IncludeSTL.h"
60
61 #ifdef _DEBUG
62 #define new DEBUG_NEW
63 #undef THIS_FILE
64 static char THIS_FILE[] = __FILE__;
65 #endif
66
67 const CFileName &CConfigToolDoc::DefaultExternalBrowser()
68 {
69 static bool bFirstTime=true;
70 if(bFirstTime){
71 const CFileName strFile(CFileName::GetTempPath()+_T("index.html"));
72 CFile f;
73 if(f.Open(strFile,CFile::modeCreate|CFile::modeWrite)){
74 f.Close();
75 bool rc=((int)FindExecutable(strFile,_T("."),m_strDefaultExternalBrowser.GetBuffer(MAX_PATH))>32);
76 m_strDefaultExternalBrowser.ReleaseBuffer();
77 if(!rc){
78 m_strDefaultExternalBrowser=_T("");
79 }
80 ::DeleteFile(strFile);
81 }
82 bFirstTime=false;
83 }
84 return m_strDefaultExternalBrowser;
85 }
86
87 CFileName CConfigToolDoc::m_strDefaultExternalBrowser;
88
89 void CConfigToolDoc::CheckRadios()
90 {
91 for(int nItem=0;nItem<ItemCount();nItem++){
92 CConfigItem *pItem=Item(nItem);
93 if(pItem->HasRadio () && pItem==pItem->FirstRadio()){
94 CString strMsg;
95 CConfigItem *pFirstSet=NULL;
96 for(CConfigItem *pSibItem=pItem;pSibItem;pSibItem=pSibItem->NextRadio()){
97 if(pSibItem->IsEnabled ()){
98 if(pFirstSet){
99 strMsg+=_T(" ");
100 strMsg+=pSibItem->Macro ();
101 } else {
102 pFirstSet=pSibItem;
103 }
104 }
105 }
106 if(!strMsg.IsEmpty()){
107 CConfigTool::Log(_T("%s, multiple radio buttons are set: %s%s"),
108 pItem->Macro(),pFirstSet->Macro(),strMsg);
109 } else if(!pFirstSet){
110 CConfigTool::Log(_T("%s, no radio buttons are set"),pItem->Macro());
111 }
112 }
113 }
114 }
115
116 // Find the ConfigItem referencing the given CdlValuable
117 CConfigItem * CConfigToolDoc::Find (CdlValuable v)
118 {
119 for(int nItem=0;nItem<ItemCount();nItem++){
120 CConfigItem *pItem=Item(nItem);
121 if(v==pItem->GetCdlValuable()){
122 return pItem;
123 }
124 }
125 return NULL;
126 }
127
128 CConfigItem * CConfigToolDoc::Find(const CString & strWhat,WhereType where)
129 {
130 for(int nItem=0;nItem<ItemCount();nItem++){
131 CConfigItem *pItem=Item(nItem);
132 if(0==pItem->StringValue(where).Compare(strWhat)){
133 return pItem;
134 }
135 }
136 return NULL;
137 }
138
139 void CConfigToolDoc::OnMLTNewRegion()
140 {
141 // create the property sheet
142
143 CPropertySheet prsRegionSheet (IDS_NEW_REGION_SHEET_TITLE, CConfigTool::GetMLTView());
144
145 // add the property pages
146
147 CRegionGeneralPage prpGeneral;
148 CNotePage prpNote;
149
150 prsRegionSheet.AddPage (&prpGeneral);
151 prsRegionSheet.AddPage (&prpNote);
152
153 // setup initial values
154
155 prpGeneral.m_strRegionName = _T("");
156 prpGeneral.m_dwRegionStartAddress = 0;
157 prpGeneral.m_dwRegionSize = 0;
158
159 // show property sheet
160
161 if (prsRegionSheet.DoModal () == IDOK)
162 {
163 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)))
164 ErrorBox (IDS_ERR_MEMMAP_REGION_CREATE, IDS_ERR_MEMMAP_BASE + nErrorCode);
165 else // no errors
166 {
167 SetModifiedFlag ();
168 UpdateAllViews (NULL, MemLayoutChanged);
169 }
170 }
171 }
172
173 void CConfigToolDoc::ErrorBox (UINT uIDSIntro, UINT uIDSError)
174 {
175 CString strIntro, strError;
176 strIntro.LoadString (uIDSIntro);
177 strError.LoadString (uIDSError);
178 AfxMessageBox (strIntro + _T("\n\n") + strError);
179 }
180
181 void CConfigToolDoc::OnMLTNewSection()
182 {
183 // create the property sheet
184
185 CPropertySheet prsSectionSheet (IDS_NEW_SECTION_SHEET_TITLE, CConfigTool::GetMLTView());
186
187 // add the property pages
188
189 CSectionGeneralPage prpGeneral;
190 CSectionRelocationPage prpRelocation;
191 CNotePage prpNote;
192
193 prsSectionSheet.AddPage (&prpGeneral);
194 prsSectionSheet.AddPage (&prpRelocation);
195 prsSectionSheet.AddPage (&prpNote);
196
197 // initialise for a new section
198
199 prpGeneral.m_bNameLinkerDefined = TRUE;
200 prpGeneral.m_strNameLinker = _T("");
201 prpRelocation.m_bRelocates = FALSE;
202 prpRelocation.m_bNewSection = TRUE;
203
204 // show property sheet
205
206 if (prsSectionSheet.DoModal () == IDOK)
207 {
208 mem_anchor initial_anchor, final_anchor;
209 mem_address initial_address;
210 CString strInitialRelativeName = _T("");
211
212 if (prpGeneral.m_bFinalAbsolute) // final location is an absolute location
213 final_anchor = absolute;
214 else // final location is a relative location
215 final_anchor = relative;
216
217 if (prpRelocation.m_bRelocates) // if the section relocates
218 {
219 if (prpRelocation.m_bInitialAbsolute) // initial location is an absolute location
220 {
221 initial_anchor = absolute;
222 }
223 else // initial location is a relative location
224 {
225 strInitialRelativeName = prpRelocation.m_strInitialRelativeName;
226 initial_anchor = relative;
227 }
228 initial_address = prpRelocation.m_dwInitialAddress;
229 }
230 else
231 {
232 strInitialRelativeName = prpGeneral.m_strFinalRelativeName;
233 initial_anchor = final_anchor;
234 initial_address = prpGeneral.m_dwFinalAddress;
235 }
236
237
238 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)))
239 ErrorBox (IDS_ERR_MEMMAP_SECTION_CREATE, IDS_ERR_MEMMAP_BASE + nErrorCode);
240 else // no errors
241 {
242 SetModifiedFlag ();
243 UpdateAllViews (NULL, MemLayoutChanged);
244 }
245 }
246 }
247
248 void CConfigToolDoc::OnMLTDelete()
249 {
250 if (strSelectedSection != _T("")) // a section is selected
251 {
252 if (MemoryMap.delete_memory_section (CUtils::UnicodeToStdStr(strSelectedSection)))
253 {
254 strSelectedSection = _T("");
255 SetModifiedFlag ();
256 UpdateAllViews (NULL, MemLayoutChanged);
257 }
258 else
259 AfxMessageBox (_T("Could not delete memory section.\n\nMake sure there are no other sections defined relative to this one."));
260 }
261 else if (strSelectedRegion != _T("")) // a region is selected
262 {
263 if (MemoryMap.delete_memory_region (CUtils::UnicodeToStdStr(strSelectedRegion)))
264 {
265 strSelectedRegion = _T("");
266 SetModifiedFlag ();
267 UpdateAllViews (NULL, MemLayoutChanged);
268 }
269 else
270 AfxMessageBox (_T("Could not delete memory region.\n\nMake sure it is not in use.")); // FIXME
271 }
272 }
273
274 void CConfigToolDoc::ShowRegionProperties()
275 {
276 // create the property sheet
277
278 CString strTitle;
279 strTitle.LoadString (IDS_REGION_PROPERTIES_SHEET_TITLE);
280 CPropertySheet prsRegionSheet (strSelectedRegion + _T(" - ") + strTitle, CConfigTool::GetMLTView());
281
282 // add the property pages
283
284 CRegionGeneralPage prpGeneral;
285 CNotePage prpNote;
286
287 prsRegionSheet.AddPage (&prpGeneral);
288 prsRegionSheet.AddPage (&prpNote);
289
290 // set up property sheet values
291
292 mem_type type;
293 std::string note;
294 MemoryMap.get_memory_region (CUtils::UnicodeToStdStr(strSelectedRegion), &prpGeneral.m_dwRegionStartAddress, &prpGeneral.m_dwRegionSize, &type, &note);
295 prpGeneral.m_strRegionName = strSelectedRegion;
296 prpGeneral.m_bRegionReadOnly = (type == read_only);
297 prpNote.m_strNote = note.c_str ();
298
299 // show property sheet
300
301 if (prsRegionSheet.DoModal () == IDOK)
302 {
303 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)))
304 ErrorBox (IDS_ERR_MEMMAP_REGION_MODIFY, IDS_ERR_MEMMAP_BASE + nErrorCode);
305 else // no errors
306 {
307 SetModifiedFlag ();
308 UpdateAllViews (NULL, MemLayoutChanged);
309 }
310 }
311 }
312
313 void CConfigToolDoc::ShowSectionProperties()
314 {
315 // create the property sheet
316
317 CString strTitle;
318 strTitle.LoadString (IDS_SECTION_PROPERTIES_SHEET_TITLE);
319 CPropertySheet prsSectionSheet (strSelectedSection + _T(" - ") + strTitle, CConfigTool::GetMLTView());
320
321 // add the property pages
322
323 CSectionGeneralPage prpGeneral;
324 CSectionRelocationPage prpRelocation;
325 CNotePage prpNote;
326
327 prsSectionSheet.AddPage (&prpGeneral);
328 prsSectionSheet.AddPage (&prpRelocation);
329 prsSectionSheet.AddPage (&prpNote);
330
331 // setup initial values
332
333 std::list <mem_section>::iterator section = MemoryMap.find_memory_section (CUtils::UnicodeToStdStr(strSelectedSection));
334 prpGeneral.m_bNameLinkerDefined = (section->linker_defined);
335 if (prpGeneral.m_bNameLinkerDefined)
336 prpGeneral.m_strNameLinker = section->name.c_str ();
337 else
338 {
339 prpGeneral.m_strNameUser = section->name.c_str ();
340 prpGeneral.m_dwSectionSize = section->size;
341 }
342
343 prpGeneral.m_bFinalAbsolute = (section->final_location->anchor == absolute);
344 if (prpGeneral.m_bFinalAbsolute)
345 prpGeneral.m_dwFinalAddress = section->final_location->address;
346 else
347 {
348 prpGeneral.m_strFinalRelativeName = MemoryMap.find_preceding_section (section, false)->name.c_str ();
349 prpGeneral.m_dwAlignment = section->alignment;
350 }
351
352 prpRelocation.m_bRelocates = section->relocates;
353 if (prpRelocation.m_bRelocates)
354 {
355 prpRelocation.m_bInitialAbsolute = (section->initial_location->anchor == absolute);
356 if (prpRelocation.m_bInitialAbsolute)
357 prpRelocation.m_dwInitialAddress = section->initial_location->address;
358 else
359 prpRelocation.m_strInitialRelativeName = MemoryMap.find_preceding_section (section, true)->name.c_str ();
360 }
361
362 prpNote.m_strNote = section->note.c_str ();
363
364 // show property sheet
365
366 if (prsSectionSheet.DoModal () == IDOK)
367 {
368 mem_anchor initial_anchor, final_anchor;
369 mem_address initial_address;
370 CString strInitialRelativeName = _T("");
371
372 if (prpGeneral.m_bFinalAbsolute) // final location is an absolute location
373 final_anchor = absolute;
374 else // final location is a relative location
375 final_anchor = relative;
376
377 if (prpRelocation.m_bRelocates) // if the section relocates
378 {
379 if (prpRelocation.m_bInitialAbsolute) // initial location is an absolute location
380 {
381 initial_anchor = absolute;
382 }
383 else // initial location is a relative location
384 {
385 strInitialRelativeName = prpRelocation.m_strInitialRelativeName;
386 initial_anchor = relative;
387 }
388 initial_address = prpRelocation.m_dwInitialAddress;
389 }
390 else
391 {
392 strInitialRelativeName = prpGeneral.m_strFinalRelativeName;
393 initial_anchor = final_anchor;
394 initial_address = prpGeneral.m_dwFinalAddress;
395 }
396
397
398 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)))
399 ErrorBox (IDS_ERR_MEMMAP_SECTION_MODIFY, IDS_ERR_MEMMAP_BASE + nErrorCode);
400 else // no errors
401 {
402 SetModifiedFlag ();
403 UpdateAllViews (NULL, MemLayoutChanged);
404 }
405 }
406 }
407
408 void CConfigToolDoc::OnMLTProperties()
409 {
410 if (strSelectedRegion != _T(""))
411 ShowRegionProperties ();
412 else if (strSelectedSection != _T(""))
413 ShowSectionProperties ();
414 }
415
416 // Choose a default Hal. Do this using clues the installer may have helpfully left behind (PR 18050)
417 // or else if there is only one possible choice, by choosing that one :-).
418 /*
419 void CConfigToolDoc::ChooseDefaultHal()
420 {
421 bool bFound=false;
422 // Has the installer told us?
423 LPCTSTR pszRegPath=_T("SOFTWARE\\Red Hat\\eCos\\1.2.8");
424 HKEY hKey;
425 if(ERROR_SUCCESS==RegOpenKeyEx (HKEY_LOCAL_MACHINE, pszRegPath, 0L, KEY_READ, &hKey)){
426 DWORD dwSizePath=MAX_PATH;
427 CString str;
428 PTCHAR psz=str.GetBuffer(dwSizePath);
429 if(ERROR_SUCCESS==RegQueryValueEx(hKey, _T("Default Architecture"), NULL, NULL, (LPBYTE)psz, &dwSizePath)){
430 str.MakeLower();
431 for(int nItem=0;nItem<ItemCount();nItem++){
432 CConfigItem *pItem=Item(nItem);
433 if(pItem->m_pTarget){
434 CString strTarget(pItem->m_pTarget->Name());
435 strTarget.MakeLower();
436 if(-1!=str.Find(strTarget)){
437 bFound=true;
438 dwSizePath=MAX_PATH;
439 if(ERROR_SUCCESS==::RegQueryValueEx(hKey, _T("Default Build Tools Path"), NULL, NULL, (LPBYTE)psz, &dwSizePath)){
440 pItem->m_pTarget->SetBinDir(psz);
441 for(CConfigItem *pSib=pItem->FirstRadio();pSib;pSib=pSib->NextRadio()){
442 pSib->SetValue((ItemIntegerType) (pSib==pItem));
443 }
444 // pItem->EnableAncestors();
445 }
446 break;
447 }
448 }
449 }
450 }
451 RegCloseKey(hKey);
452 }
453
454 if(!bFound){
455 // No - choose the Hal according to toolchain
456 for(int nItem=0;nItem<ItemCount();nItem++){
457 CConfigItem *pItem=Item(nItem);
458 if(pItem->m_pTarget){
459 CString strTarget(pItem->m_pTarget->Name());
460 strTarget.MakeLower();
461 for(int j=0;j<m_arstrToolChainPaths.GetSize();j++){
462 CString strTools(m_arstrToolChainPaths[j]);
463 strTools.MakeLower();
464 if(-1!=strTools.Find(strTarget)){
465 for(CConfigItem *pSib=pItem->FirstRadio();pSib;pSib=pSib->NextRadio()){
466 pSib->SetValue((ItemIntegerType) (pSib==pItem));
467 }
468 return;
469 }
470 }
471 }
472 }
473 }
474 }
475 */
476
477 bool CConfigToolDoc::SetValue (CConfigItem &ti, double dValue, CdlTransaction transaction/*=NULL*/)
478 {
479 ASSERT (ti.Type () == CConfigItem::Double);
480
481 // test if the new double value is in range
482 const CdlValuable valuable = ti.GetCdlValuable();
483 CdlListValue list_value;
484 CdlEvalContext context (NULL, ti.GetCdlItem (), ti.GetCdlItem ()->get_property (CdlPropertyId_LegalValues));
485 valuable->get_legal_values ()->eval (context, list_value);
486 if (! list_value.is_member (dValue))
487 {
488 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?"),
489 CUtils::DoubleToStr (dValue), ti.Macro ()))
490 return false;
491 }
492
493 if (! ti.SetValue (dValue,transaction))
494 return false;
495
496 SetModifiedFlag ();
497 return true;
498 }
499 bool CConfigToolDoc::SetValue(CConfigItem &ti,const CString &strValue, CdlTransaction transaction/*=NULL*/)
500 {
501 // warn the user if a modified memory layout is about to be discarded
502 if (MemoryMap.map_modified () && (ti.Macro () == _T("CYG_HAL_STARTUP")) &&
503 (IDCANCEL == CUtils::MessageBoxFT (MB_OKCANCEL, _T("Changes to the current memory layout will be lost."))))
504 return false;
505
506 bool rc=false;
507 switch(ti.Type()){
508 case CConfigItem::None:
509 break;
510 case CConfigItem::Enum:
511 case CConfigItem::String:
512 rc=ti.SetValue(strValue,transaction);
513 break;
514 case CConfigItem::Integer:
515 {
516 ItemIntegerType n;
517 rc=CUtils::StrToItemIntegerType(strValue,n) && SetValue(ti,n,transaction);
518 }
519 break;
520 case CConfigItem::Double:
521 {
522 double dValue;
523 rc = CUtils::StrToDouble (strValue, dValue) && SetValue (ti, dValue,transaction);
524 }
525 break;
526 default:
527 ASSERT(FALSE);
528 break;
529
530 }
531 if(rc){
532 SetModifiedFlag();
533 UpdateAllViews (NULL, CConfigToolDoc::ValueChanged, (CObject *)&ti);
534 }
535 return rc;
536 }
537
538 // Look in registry to match prefixes CYGPKG_HAL_ and CYGHWR_HAL_:
539 //
540 bool CConfigToolDoc::GetRunPlatform(CString &strTarget)
541 {
542 CRegKeyEx k1(HKEY_CURRENT_USER,_T("Software\\Red Hat\\eCos\\Platforms"), KEY_READ);
543 CString strKey;
544 for(int i=0;k1.QueryKey(i,strKey);i++){
545 CRegKeyEx k2((HKEY)k1,strKey,KEY_READ);
546 // Subkeys' names are the target image names [one of which we aim to return]
547 // Subkeys's values of interest are:
548 // Prefix String
549 // Sim DWORD [optional]
550 // Macro String
551 DWORD dwSim=0;
552 CString strPrefix,strMacro;
553 k2.QueryValue(_T("Sim"),dwSim);
554 k2.QueryValue(_T("Prefix"),strPrefix);
555 k2.QueryValue(_T("Macro"),strMacro);
556
557 CConfigItem *pItem=Find(_T("CYGPKG_HAL_")+strMacro);
558 if(pItem && pItem->IsEnabled()){
559 // We have found what we are looking for - probably
560 pItem=Find(_T("CYGHWR_HAL_")+strMacro+_T("_STARTUP"));
561 if(pItem){
562 // Two platforms apply - choose this one only if the ram startup attribute fits
563 if( (dwSim==0) == (0==pItem->StringValue().CompareNoCase(_T("ram"))) ) {
564 strTarget=strKey;
565 }
566 } else {
567 // Only one platform applies
568 strTarget=strKey;
569 }
570
571 }
572 }
573 return !strTarget.IsEmpty();
574 }
575
576 bool CConfigToolDoc::SetEnabled(CConfigItem &ti, bool bEnabled, CdlTransaction transaction/*=NULL*/)
577 {
578 const bool bStatus = ti.SetEnabled (bEnabled,transaction);
579
580 if (bStatus) {
581 SetModifiedFlag();
582 UpdateAllViews (NULL, CConfigToolDoc::ValueChanged, (CObject *) &ti);
583 }
584 return bStatus;
585 }
586
587 void CConfigToolDoc::AddContents (const CdlContainer container, CConfigItem *pParent)
588 {
589
590 // determine the container contents
591
592 const std::vector<CdlNode>& contents = container->get_contents ();
593 std::vector<CdlNode>::const_iterator node_i;
594 for (node_i = contents.begin (); node_i != contents.end (); node_i++)
595 {
596 const CdlNode node = * node_i;
597 const CdlPackage pkg = dynamic_cast<CdlPackage> (node);
598 const CdlComponent comp = dynamic_cast<CdlComponent> (node);
599 const CdlOption opt = dynamic_cast<CdlOption> (node);
600 const CdlContainer contnr = dynamic_cast<CdlContainer> (node);
601
602 // if the node in the container is a package, component or option
603 // then it is visible and should be added to the tree
604 if (0 != pkg) // the node is a package
605 {
606 CConfigItem * pItem = AddItem (pkg, pParent); // add the package
607 AddContents (pkg, pItem); // add the package contents
608 }
609 else if (0 != comp) // the node is a component
610 {
611 CConfigItem * pItem = AddItem (comp, pParent); // add the component
612 AddContents (comp, pItem); // add the component contents
613 }
614 else if (0 != opt) // the node is an option
615 AddItem (opt, pParent); // add the option
616
617 else if (0 != contnr) // if the node is a container
618 AddContents (contnr, pParent); // add the container contents
619
620 // ignore nodes of any other class
621 }
622 }
623
624 // Three hack functions.
625
626 const CString CConfigToolDoc::CurrentPlatform()
627 {
628 /*
629 for(int nItem=0;nItem<ItemCount();nItem++){
630 CConfigItem *pItem=Item(nItem);
631 if(pItem->IsEnabled() && !pItem->Platform().IsEmpty()){
632 return pItem->Platform();
633 }
634 }
635 */
636 return _T("");
637 }
638
639 // a trivial CDL parse error handler
640 void CConfigToolDoc::CdlParseErrorHandler (std::string message)
641 {
642 CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc();
643 pDoc->m_strCdlErrorMessage = message.c_str ();
644 TRACE (_T("CdlParseError: %s\n"), pDoc->m_strCdlErrorMessage);
645 CConfigTool::Log (CUtils::StripExtraWhitespace (pDoc->m_strCdlErrorMessage)); // display the message in the output window
646 };
647
648 // a trivial CDL parse warning handler
649 void CConfigToolDoc::CdlParseWarningHandler (std::string message)
650 {
651 CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc();
652 pDoc->m_strCdlErrorMessage = message.c_str ();
653 TRACE (_T("CdlParseWarning: %s\n"), pDoc->m_strCdlErrorMessage);
654 CConfigTool::Log (CUtils::StripExtraWhitespace (pDoc->m_strCdlErrorMessage)); // display the message in the output window
655 };
656
657 // a trivial CDL load error handler
658 void CConfigToolDoc::CdlLoadErrorHandler (std::string message)
659 {
660 CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc();
661 pDoc->m_strCdlErrorMessage = message.c_str ();
662 TRACE (_T("CdlLoadError: %s\n"), pDoc->m_strCdlErrorMessage);
663 CConfigTool::Log (CUtils::StripExtraWhitespace (pDoc->m_strCdlErrorMessage)); // display the message in the output window
664 };
665
666 // a trivial CDL load warning handler
667 void CConfigToolDoc::CdlLoadWarningHandler (std::string message)
668 {
669 CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc();
670 pDoc->m_strCdlErrorMessage = message.c_str ();
671 TRACE (_T("CdlLoadWarning: %s\n"), pDoc->m_strCdlErrorMessage);
672 CConfigTool::Log (CUtils::StripExtraWhitespace (pDoc->m_strCdlErrorMessage)); // display the message in the output window
673 };
674
675 CdlInferenceCallbackResult CConfigToolDoc::CdlGlobalInferenceHandler(CdlTransaction transaction)
676 {
677 CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc();
678 pDoc->m_ConflictsOutcome=NotDone; // prepare for the case that there are no solutions
679 CdlInferenceCallbackResult rc=CdlInferenceCallbackResult_Continue;
680 /*
681 std::list<CdlConflict>conflicts1(transaction->get_global_conflicts_with_solutions());
682 const std::vector<CdlConflict>&conflicts2=transaction->get_resolved_conflicts();
683 for (unsigned int i = 0; i < conflicts2.size (); i++) {
684 conflicts1.push_back(conflicts2 [i]);
685 }
686 if(conflicts1.size()>0){
687 CFailingRulesDialog dlg(conflicts1,transaction,&pDoc->m_arConflictsOfInterest);
688 rc=(IDOK==dlg.DoModal())?CdlInferenceCallbackResult_Continue:CdlInferenceCallbackResult_Cancel;
689 pDoc->m_ConflictsOutcome=(CdlInferenceCallbackResult_Continue==rc)?OK:Cancel;
690 }
691 */
692 const std::list<CdlConflict>& conflicts=pDoc->GetCdlConfig()->get_all_conflicts();
693 CFailingRulesDialog dlg(conflicts,transaction,&pDoc->m_arConflictsOfInterest);
694 rc=(IDOK==dlg.DoModal())?CdlInferenceCallbackResult_Continue:CdlInferenceCallbackResult_Cancel;
695 pDoc->m_ConflictsOutcome=(CdlInferenceCallbackResult_Continue==rc)?OK:Cancel;
696
697 return rc;
698 }
699
700 CdlInferenceCallbackResult CConfigToolDoc::CdlInferenceHandler (CdlTransaction transaction)
701 {
702 CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc();
703 CdlInferenceCallbackResult rc=CdlInferenceCallbackResult_Continue;
704 const std::list<CdlConflict>&conflicts=transaction->get_new_conflicts();
705 if((pDoc->m_nRuleChecking&Immediate) && conflicts.size()>0){
706 if(pDoc->m_nRuleChecking&SuggestFixes){
707 std::list<CdlConflict> s_conflicts;
708 for (std::list<CdlConflict>::const_iterator conf_i= conflicts.begin (); conf_i != conflicts.end (); conf_i++) { // for each conflict
709 if((*conf_i)->has_known_solution()){
710 s_conflicts.push_back(*conf_i);
711 }
712 }
713 if(s_conflicts.size()>0){
714 CFailingRulesDialog dlg(s_conflicts,transaction);
715 return(IDOK==dlg.DoModal()?CdlInferenceCallbackResult_Continue:CdlInferenceCallbackResult_Cancel);
716 }
717 }
718 CString strMsg;
719 if(1==conflicts.size()){
720 strMsg=(_T("There is 1 unresolved conflict."));
721 } else {
722 strMsg.Format(_T("There are %d unresolved conflict%s."),conflicts.size(),1==conflicts.size()?_T(""):_T("s"));
723 }
724 rc=(IDYES==CUtils::MessageBoxFT(MB_YESNO|MB_DEFBUTTON2,_T("%s Make the change anyway?"),strMsg))?CdlInferenceCallbackResult_Continue:CdlInferenceCallbackResult_Cancel;
725 }
726 return rc;
727 }
728
729
730 // a CDL transaction handler to refresh the configuration tree
731 void CConfigToolDoc::CdlTransactionHandler (const CdlTransactionCallback & data)
732 {
733 static int nNesting=0;
734 TRACE(_T("Transaction handler: nesting level=%d\n"),nNesting++);
735 CConfigToolDoc *pDoc=CConfigTool::GetConfigToolDoc();
736 std::vector<CdlValuable>::const_iterator val_i;
737 std::vector<CdlNode>::const_iterator node_i;
738 std::list<CdlConflict>::const_iterator conf_i;
739 CControlView *pControlView=CConfigTool::GetControlView();
740 for (val_i = data.value_changes.begin(); val_i != data.value_changes.end(); val_i++)
741 {
742 const CString strName((*val_i)->get_name().c_str());
743 TRACE(_T("%s %s : value change\n"), CString ((*val_i)->get_class_name().c_str()), strName);
744 pControlView->Refresh(strName);
745 if (strName==_T("CYGHWR_MEMORY_LAYOUT")){ // the memory layout has changed...
746 pDoc->SwitchMemoryLayout (false); // ...so display a new one
747 }
748 }
749 for (node_i = data.active_changes.begin(); node_i != data.active_changes.end(); node_i++)
750 {
751 const CString strName((*node_i)->get_name().c_str());
752 TRACE(_T("%s %s : this has become active or inactive\n"), CString ((*node_i)->get_class_name().c_str()),
753 CString ((*node_i)->get_name().c_str()));
754 if (! dynamic_cast<CdlInterface> (*node_i)){ // if not an interface node
755 pControlView->Refresh(strName);
756 }
757 }
758 for (val_i = data.legal_values_changes.begin(); val_i != data.legal_values_changes.end(); val_i++)
759 {
760 const CString strName((*node_i)->get_class_name().c_str());
761 TRACE(_T("%s %s : the legal_values list has changed, a new widget may be needed.\n"),
762 CString ((*val_i)->get_class_name().c_str()), strName);
763 }
764
765 for (val_i = data.value_source_changes.begin(); val_i != data.value_source_changes.end(); val_i++)
766 {
767 const CString strName((*val_i)->get_name().c_str());
768 CdlValueSource source = (*val_i)->get_source();
769 TRACE(_T("%s %s : the value source has changed to %s\n"),
770 CString ((*val_i)->get_class_name().c_str()), strName,
771 CString ((CdlValueSource_Default == source) ? "default" :
772 (CdlValueSource_Inferred == source) ? "inferred" :
773 (CdlValueSource_Wizard == source) ? "wizard" : "user"));
774 pControlView->Refresh (strName);
775 }
776
777 pDoc->UpdateFailingRuleCount();
778 nNesting--;
779 }
780
781 // Three hack functions.
782
783 const CString CConfigToolDoc::CurrentMemoryLayout ()
784 {
785 const CConfigItem * pItem = Find (_T("CYGHWR_MEMORY_LAYOUT"));
786 #ifdef _DEBUG
787 if(NULL==pItem){
788 TRACE(_T("Warning - CurrentMemoryLayout() returning NULL\n"));
789 }
790 #endif
791 return pItem ? pItem->StringValue () : _T("");
792 }
793
794 const CString CConfigToolDoc::CurrentTestingIdentifier ()
795 {
796 // use the CDL target as the default testing identifier
797 // override in the forthcoming testing identifier dialog as necessary
798 return GetCdlConfig()->get_hardware ().c_str ();
799
800 // const CConfigItem * pItem = Find (_T("CYGTST_TESTING_IDENTIFIER"));
801 //#ifdef _DEBUG
802 // if(NULL==pItem){
803 // TRACE(_T("Warning - CurrentTestingIdentifier() returning NULL\n"));
804 // }
805 //#endif
806 // return pItem ? pItem->StringValue () : _T("");
807 }
808
809 const CString CConfigToolDoc::CurrentStartup()
810 {
811 const CConfigItem * pItem = Find (_T("CYG_HAL_STARTUP"));
812 #ifdef _DEBUG
813 if(NULL==pItem){
814 TRACE(_T("Warning - CurrentStartup() returning NULL\n"));
815 }
816 #endif
817 return pItem ? pItem->StringValue () : _T("");
818
819 /*
820 for(int nItem=0;nItem<ItemCount();nItem++){
821 CConfigItem *pItem=Item(nItem);
822 const CString strName(pItem->Name());
823 if(0==strName.Compare(_T("Startup type")) && pItem->IsEnabled()){
824 return pItem->StringValue();
825 }
826 }
827 return _T("ram"); // FIXME - assume ram startup for now if no startup item
828 */
829 }
830
831 void CConfigToolDoc::UpdateFailingRuleCount()
832 {
833 int nCount=0;
834 if (GetCdlConfig ()){
835 // if configuration information
836
837 // calculate the number of conflicts
838 nCount =
839 // GetCdlConfig ()->get_structural_conflicts ().size () + ignore for now
840 GetCdlConfig ()->get_all_conflicts ().size ();
841
842 // update the conflicts view
843 if (CConfigTool::GetRulesView ()) {
844 CConfigTool::GetRulesView ()->FillRules ();
845 }
846 }
847 if(CConfigTool::GetMain()){
848 CConfigTool::GetMain()->SetFailRulePane(nCount);
849 }
850 }
851
852 void CConfigToolDoc::LogConflicts (const std::list<CdlConflict> & conflicts)
853 {
854 std::list<CdlConflict>::const_iterator conf_i;
855 for (conf_i = conflicts.begin (); conf_i != conflicts.end (); conf_i++) // for each conflict
856 {
857 CString strExplain = (* conf_i)->get_explanation ().c_str (); // get the conflict explanation
858 CConfigTool::Log (CUtils::StripExtraWhitespace (strExplain)); // display the message in the output window
859 }
860 }
861
862 CString CConfigToolDoc::GetPackageName (const CString & strAlias)
863 {
864 const std::vector<std::string> & packages = m_CdlPkgData->get_packages ();
865 std::vector<std::string>::const_iterator package_i;
866 for (package_i = packages.begin (); package_i != packages.end (); package_i++)
867 {
868 const std::vector<std::string> & aliases = m_CdlPkgData->get_package_aliases (* package_i);
869 CString strPackageAlias = aliases [0].c_str ();
870 if (aliases.size () && (0 == strAlias.Compare (strPackageAlias)))
871 return package_i->c_str ();
872 }
873 return _T("");
874 }
875
876 void CConfigToolDoc::DeleteContents()
877 {
878 TRACE(_T("###DeleteContents()\n"));
879 #ifndef PLUGIN
880 CDocument::DeleteContents();
881 #endif
882
883 RemoveAllItems();
884 TRACE(_T("###DeleteContents done\n"));
885 }
886
887 void CConfigToolDoc::SelectPackages ()
888 {
889 CCdlPackagesDialog dlg;
890 // This map holds the CConfigItem pointers for the packages loaded before the dialog is invoked.
891 // We cannot use Find(), which traverses all items - potentially those that have been removed
892 CMapStringToPtr arLoadedPackages;
893
894 // generate the contents of the add/remove list boxes
895 const std::vector<std::string> & packages = m_CdlPkgData->get_packages ();
896 std::vector<std::string>::const_iterator package_i;
897 for (package_i = packages.begin (); package_i != packages.end (); package_i++)
898 {
899 // if (! m_CdlPkgData->is_hardware_package (* package_i)) // do not list hardware packages
900 {
901 const std::vector<std::string> & aliases = m_CdlPkgData->get_package_aliases (* package_i);
902 CString strMacroName = package_i->c_str ();
903
904 // use the first alias (if any) as the package identifier
905 CString strPackageName = aliases.size () ? aliases [0].c_str () : strMacroName;
906 CConfigItem * pItem = Find (strMacroName);
907 if (pItem) // if the package is loaded
908 {
909 arLoadedPackages.SetAt(strMacroName,pItem);
910 // pass the currently selected package version string to the dialog box
911 const CdlValuable valuable = pItem->GetCdlValuable();
912 dlg.Insert (strPackageName, TRUE, NULL, valuable ? (LPCTSTR) CString (valuable->get_value ().c_str ()) : NULL);
913 }
914 else
915 {
916 // pass version string of the most latest version to the dialog box
917 dlg.Insert (strPackageName, FALSE, NULL, (LPCTSTR) CString (m_CdlPkgData->get_package_versions (* package_i) [0].c_str ()));
918 }
919 }
920 }
921
922 if (IDOK == dlg.DoModal ())
923 {
924 bool bChanged = false; // until proved otherwise
925
926 // determine whether each package has changed loaded/unloaded state
927 for (package_i = packages.begin (); package_i != packages.end (); package_i++)
928 // if (! m_CdlPkgData->is_hardware_package (* package_i)) // do not check hardware packages
929 {
930 const std::vector<std::string> & aliases = m_CdlPkgData->get_package_aliases (* package_i);
931 CString strMacroName = package_i->c_str ();
932
933 // use the first alias (if any) as the package identifier
934 CString strPackageName = aliases.size () ? aliases [0].c_str () : strMacroName;
935
936 CConfigItem *pItem=NULL;
937 bool bPreviouslyLoaded=arLoadedPackages.Lookup(strMacroName,(void *&)pItem);
938 bool bNowLoaded=dlg.IsAdded (strPackageName);
939
940 // unload packages which are no longer required before
941 // loading new ones to avoid potential duplicate macro definitions
942 if (! bNowLoaded && bPreviouslyLoaded){
943 // The package was loaded but should now be unloaded:
944 bChanged|=pItem->Unload();
945 } else if (bNowLoaded) {// if the package should be loaded
946 const CString strVersion(dlg.GetVersion (strPackageName));
947 if (bPreviouslyLoaded) { // if the package is not already loaded
948 bChanged|=pItem->ChangeVersion(strVersion);
949 } else {
950 // the package was not loaded but should now be loaded
951 TRACE (_T("Loading package %s\n"), strMacroName);
952 try
953 {
954 GetCdlConfig()->load_package (CUtils::UnicodeToStdStr(strMacroName), CUtils::UnicodeToStdStr (strVersion), CConfigToolDoc::CdlParseErrorHandler, CConfigToolDoc::CdlParseWarningHandler);
955 bChanged=true;
956 }
957 catch (CdlStringException exception)
958 {
959 CUtils::MessageBoxF(_T("Error loading package %s:\n\n%s"), strMacroName, CString (exception.get_message ().c_str ()));
960 }
961 catch (...)
962 {
963 CUtils::MessageBoxF(_T("Error loading package %s."), strMacroName);
964 }
965 }
966 }
967 }
968
969 if (bChanged) {// at least one package was loaded, unloaded or changed version
970 SetModifiedFlag();
971 RegenerateData();
972 }
973 }
974 }
975
976 bool CConfigToolDoc::SetValue(CConfigItem &ti,ItemIntegerType nValue, CdlTransaction transaction/*=NULL*/)
977 {
978 switch(ti.Type()){
979 case CConfigItem::Enum:
980 case CConfigItem::Integer:
981 // case CConfigItem::Boolean:
982 // case CConfigItem::Radio:
983 break;
984 case CConfigItem::None:
985 case CConfigItem::String:
986 default:
987 ASSERT(FALSE);
988 break;
989 }
990
991 bool rc=false;
992 bool bChangingMemmap=MemoryMap.map_modified () && ((ti.Macro ().Compare (_T ("CYG_HAL_STARTUP")) == 0));
993
994 if(nValue==ti.Value()){
995 return true;
996 }
997
998 // test if the new integer value is in range
999 if (CConfigItem::Integer == ti.Type ())
1000 {
1001 const CdlValuable valuable = ti.GetCdlValuable();
1002 CdlListValue list_value;
1003 CdlEvalContext context (NULL, ti.GetCdlItem (), ti.GetCdlItem ()->get_property (CdlPropertyId_LegalValues));
1004 valuable->get_legal_values ()->eval (context, list_value);
1005 if (! list_value.is_member ((cdl_int) nValue))
1006 {
1007 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?"),
1008 CUtils::IntToStr (nValue, CConfigTool::GetConfigToolDoc ()->m_bHex), ti.Macro ()))
1009 goto Exit;
1010 };
1011 }
1012
1013 // if(!ti.CanSetValue(nValue))
1014 // {
1015 // if(bInteractive){
1016 // CString strExplanation;
1017 // if(CConfigItem::Integer==ti.Type()){
1018 // strExplanation.Format(_T(" [value must lie in the range %d..%d]"),
1019 // CUtils::IntToStr(ti.Min(),m_bHex),
1020 // CUtils::IntToStr(ti.Max()),m_bHex);
1021 // }
1022 // CUtils::MessageBoxF(
1023 // _T("Cannot set '%s' to %s%s"),
1024 // ti.ItemNameOrMacro(), CUtils::IntToStr(nValue,m_bHex), strExplanation);
1025 // }
1026 // goto Exit;
1027 // }
1028
1029 // warn the user if the current memory layout has been changed and will be lost
1030 // this will happen when the layout has been modified and the target-platform-startup is changed
1031
1032 if (bChangingMemmap && IDCANCEL==CUtils::MessageBoxFT(MB_OKCANCEL,_T("Changes to the current memory layout will be lost."))){
1033 goto Exit;
1034 }
1035
1036 // Save state
1037 if(!ti.SetValue(nValue,transaction)){
1038 // CanSetValue above should have caught this
1039 CUtils::MessageBoxF(_T("Cannot set '%s' to %d"),ti.ItemNameOrMacro(), nValue);
1040 goto Exit;
1041 }
1042
1043 rc=true;
1044 Exit:
1045 if(rc){
1046 SetModifiedFlag();
1047 UpdateFailingRuleCount ();
1048 UpdateAllViews (NULL, CConfigToolDoc::ValueChanged, (CObject *)&ti);
1049 // switch to new memory layout when target, platform or startup changes
1050 // but ignore cases where a target or platform is being deactivated (PR 19363)
1051
1052 // if (((CurrentTarget () != pOldTarget) || (CurrentPlatform () != strOldPlatform) || (ti.Name ().Compare (_T ("Startup type")) == 0)) &&
1053 // ((ti.Type () != CConfigItem::Radio) || (nValue)))
1054 // SwitchMemoryLayout ((CurrentTarget () != pOldTarget) || (CurrentPlatform () != strOldPlatform));
1055 }
1056 return rc;
1057 }
1058
1059 bool CConfigToolDoc::OpenRepository(LPCTSTR pszRepository/*=NULL*/,bool bPromptInitially/*=false*/)
1060 {
1061 if(!m_bRepositoryOpen){
1062 CWaitCursor wait;
1063 CIdleMessage IM(_T("Opening repository"));
1064 UpdateFailingRuleCount();
1065
1066 CFileName strNewRepository;
1067 while(!m_bRepositoryOpen){
1068
1069 if(bPromptInitially){
1070 CFolderDialog dlg(/*BOOL bAllowCreation=*/false);
1071 dlg.m_strDesc=_T("Please specify the root of the eCos repository tree.");
1072 dlg.m_strTitle=_T("Choose folder for eCos repository");
1073 dlg.m_strFolder=strNewRepository;
1074 CConfigTool::DismissSplash();
1075 if(IDCANCEL==dlg.DoModal()){
1076 return false;
1077 }
1078 strNewRepository=dlg.m_strFolder;
1079 } else {
1080 // Use what came in as parameter or what was found in registry
1081 strNewRepository=pszRepository?pszRepository:m_strRepository;
1082 bPromptInitially=true;
1083 }
1084
1085 IM.Set (_T("Opening repository ") + (CString) strNewRepository);
1086
1087 CdlPackagesDatabase NewCdlPkgData = NULL;
1088 CdlInterpreter NewCdlInterp = NULL;
1089 CdlConfiguration NewCdlConfig = NULL;
1090 CFileName strNewPackagesDir;
1091
1092 EnableCallbacks(false); // disable transaction callbacks until the config tree is regenerated
1093
1094 if(OpenRepository(strNewRepository,NewCdlPkgData,NewCdlInterp,NewCdlConfig,strNewPackagesDir)){
1095 // Success
1096
1097 // select the "default" template if it exists
1098 // otherwise select the first available template
1099 std::string default_template = "default";
1100 if (! NewCdlPkgData->is_known_template (default_template))
1101 {
1102 const std::vector<std::string>& templates = NewCdlPkgData->get_templates ();
1103 if (templates.size () != 0)
1104 default_template = templates [0];
1105 }
1106
1107 m_template_version = "";
1108 try
1109 {
1110 const std::vector<std::string>& template_versions = NewCdlPkgData->get_template_versions (default_template);
1111 NewCdlConfig->set_template (default_template, template_versions [0], &CdlParseErrorHandler, &CdlParseWarningHandler);
1112 m_template_version = template_versions [0];
1113 }
1114 catch (CdlStringException exception) {
1115 CUtils::MessageBoxF(_T("Error loading package template '%s':\n\n%s"), CString (default_template.c_str ()), CString (exception.get_message ().c_str ()));
1116 }
1117 catch (...) {
1118 CUtils::MessageBoxF(_T("Error loading package template '%s'."), CString (default_template.c_str ()));
1119 }
1120
1121 // check the configuration
1122 ASSERT (NewCdlConfig->check_this (cyg_extreme));
1123
1124 // use the new package database, interpreter and configuration
1125 deleteZ(m_CdlConfig); // delete the previous configuration
1126 deleteZ(m_CdlInterp); // delete the previous interpreter
1127 deleteZ(m_CdlPkgData); // delete the previous package database
1128
1129 m_CdlPkgData = NewCdlPkgData;
1130 m_CdlInterp = NewCdlInterp;
1131 m_CdlConfig = NewCdlConfig;
1132
1133 // save the repository location
1134
1135 SetRepository(strNewRepository);
1136 m_strPackagesDir = strNewPackagesDir;
1137
1138 #ifndef PLUGIN
1139 // clear the previously specified document file name (if any),
1140 // OnNewDocument() calls DeleteContents() so must be called
1141 // before AddAllItems()
1142 CDocument::OnNewDocument ();
1143 #endif
1144
1145 // generate the CConfigItems from their CDL descriptions
1146 AddAllItems ();
1147
1148 m_bRepositoryOpen=true;
1149 } else {
1150 // failure
1151 deleteZ(NewCdlConfig);
1152 deleteZ(NewCdlInterp);
1153 deleteZ(NewCdlPkgData);
1154
1155 }
1156
1157 // install a transaction handler callback function now that the tree exists
1158 EnableCallbacks(true);
1159 }
1160
1161 }
1162 return m_bRepositoryOpen;
1163 }
1164
1165 // Helper fn for namesake above
1166 bool CConfigToolDoc::OpenRepository (const CFileName strNewRepository,CdlPackagesDatabase &NewCdlPkgData,CdlInterpreter &NewCdlInterp,CdlConfiguration &NewCdlConfig,CFileName &strNewPackagesDir)
1167 {
1168 bool rc=false;
1169 TRACE(_T("###Open repository %s\n"),strNewRepository);
1170 if(!strNewRepository.IsEmpty()){
1171 // Now strNewRepository is guaranteed non-empty, but does it exist?
1172 if(!strNewRepository.IsDir()) {
1173 CUtils::MessageBoxF(_T("Cannot open repository - the folder %s does not exist"), strNewRepository);
1174 } else {
1175
1176 // Ok so it exists, but does it look right?
1177 strNewPackagesDir=strNewRepository+_T("ecc");
1178 if(!strNewPackagesDir.IsDir()){
1179 strNewPackagesDir=strNewRepository+_T("packages");
1180 }
1181
1182 if(!strNewPackagesDir.IsDir()){
1183 // Don't mention the ecc\ attempt
1184 CUtils::MessageBoxF(_T("%s does not seem to be a source repository: the folder %s does not exist"),
1185 strNewRepository,strNewPackagesDir);
1186 } else {
1187
1188 const CFileName strDatabase = strNewPackagesDir + _T("ecos.db");
1189 if(!strDatabase.Exists()) {
1190 CUtils::MessageBoxF(_T("%s does not seem to be a source repository: %s does not exist"), strNewRepository, strDatabase);
1191 } else {
1192
1193 // create a CDL repository, interpreter and configuration
1194
1195 try {// create a new package database, interpreter and configuration
1196 NewCdlPkgData = CdlPackagesDatabaseBody::make (CUtils::UnicodeToStdStr(strNewPackagesDir));
1197 NewCdlInterp = CdlInterpreterBody::make ();
1198 NewCdlConfig = CdlConfigurationBody::make ("eCos", NewCdlPkgData, NewCdlInterp);
1199 }
1200 catch (CdlStringException exception) {
1201 CUtils::MessageBoxF(_T("Error opening eCos repository:\n\n%s"), CString (exception.get_message ().c_str ()));
1202 return false;
1203 }
1204 catch (...) {
1205 CUtils::MessageBoxF(_T("Error opening eCos repository."));
1206 return false;
1207 }
1208
1209 // select the default target if specified in the registry
1210 // otherwise select the first available target
1211 std::string default_hardware = CUtils::UnicodeToStdStr (GetDefaultHardware ());
1212 if (! NewCdlPkgData->is_known_target (default_hardware)) {
1213 const std::vector<std::string>& targets = NewCdlPkgData->get_targets ();
1214 if (targets.size () == 0){
1215 CUtils::MessageBoxF (_T("Error opening eCos repository:\n\nno hardware templates"));
1216 return false;
1217 } else {
1218 default_hardware = targets [0];
1219 }
1220 }
1221
1222 try {
1223 m_strCdlErrorMessage = _T("");
1224 NewCdlConfig->set_hardware (default_hardware, &CdlParseErrorHandler, &CdlParseWarningHandler);
1225 }
1226 catch (CdlStringException exception) {
1227 if (m_strCdlErrorMessage.IsEmpty ())
1228 {
1229 CUtils::MessageBoxF (_T("Error loading the default hardware template '%s':\n\n%s"), CString (default_hardware.c_str ()), CString (exception.get_message ().c_str ()));
1230 }
1231 else // report the most recent parser message in the message box since there may be no output pane in which to view it
1232 {
1233 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);
1234 }
1235 return false;
1236 }
1237 catch (...) {
1238 CUtils::MessageBoxF (_T("Error loading the default hardware template '%s':\n\n%s"), CString (default_hardware.c_str ()), m_strCdlErrorMessage);
1239 return false;
1240 }
1241 rc=true;
1242 }
1243 }
1244 }
1245 }
1246 return rc;
1247 }
1248
1249 void CConfigToolDoc::CloseRepository()
1250 {
1251 if(m_bRepositoryOpen){
1252 // delete the libCDL objects with the document
1253 EnableCallbacks(false); // first disable the transaction handler
1254 deleteZ(m_CdlConfig);
1255 deleteZ(m_CdlInterp);
1256 deleteZ(m_CdlPkgData);
1257 m_bRepositoryOpen=false;
1258 }
1259 }
1260
1261 void CConfigToolDoc::SelectTemplate (std::string NewTemplate, std::string NewTemplateVersion)
1262 {
1263 if ((NewTemplate != m_CdlConfig->get_template()) || (NewTemplateVersion != m_template_version)){
1264
1265 CWaitCursor wait; // this may take a little while
1266 RemoveAllItems();
1267 m_template_version = "";
1268 try
1269 {
1270 m_CdlConfig->set_template (NewTemplate, NewTemplateVersion, CdlParseErrorHandler, CdlParseWarningHandler);
1271 m_template_version = NewTemplateVersion;
1272 }
1273 catch (CdlStringException exception)
1274 {
1275 CUtils::MessageBoxF(_T("Error loading package template '%s':\n\n%s"), CString (NewTemplate.c_str ()), CString (exception.get_message ().c_str ()));
1276 }
1277 catch (...)
1278 {
1279 CUtils::MessageBoxF(_T("Error loading package template '%s'."), CString (NewTemplate.c_str ()));
1280 }
1281 RegenerateData();
1282
1283 if (!GetPathName().IsEmpty()){ // not a new document
1284 CopyMLTFiles (); // copy new MLT files to the build tree as necessary
1285 }
1286 SetModifiedFlag();
1287 }
1288 }
1289
1290 void CConfigToolDoc::RegenerateData()
1291 {
1292 CWaitCursor wait; // This may take a little while
1293 AddAllItems (); // regenerate all the config items since the topology may have changed
1294 if (m_strLinkerScriptFolder.IsEmpty ())
1295 {
1296 CUtils::MessageBoxF(_T("The eCos linker script macro CYGBLD_LINKER_SCRIPT is not defined."));
1297 }
1298 if (m_strMemoryLayoutFolder.IsEmpty ())
1299 {
1300 CUtils::MessageBoxF(_T("The eCos memory layout macro CYGHWR_MEMORY_LAYOUT is not defined."));
1301 }
1302 SwitchMemoryLayout (true); // the hardware template may have changed
1303 UpdateBuildInfo();
1304 CConfigTool::GetControlView()->SelectItem(Item(0));
1305 }
1306
1307 void CConfigToolDoc::SelectHardware (std::string NewTemplate)
1308 {
1309 const std::string OldTemplate=m_CdlConfig->get_hardware();
1310 if (NewTemplate != OldTemplate){
1311 RemoveAllItems();
1312
1313 try
1314 {
1315 m_CdlConfig->set_hardware (NewTemplate, CdlParseErrorHandler, CdlParseWarningHandler);
1316 }
1317 catch (CdlStringException exception)
1318 {
1319 CUtils::MessageBoxF(_T("Error loading hardware template '%s':\n\n%s"), CString (NewTemplate.c_str ()), CString (exception.get_message ().c_str ()));
1320 m_CdlConfig->set_hardware (OldTemplate, CdlParseErrorHandler, CdlParseWarningHandler);
1321 }
1322 catch (...)
1323 {
1324 CUtils::MessageBoxF(_T("Error loading hardware template '%s'."), CString (NewTemplate.c_str ()));
1325 m_CdlConfig->set_hardware (OldTemplate, CdlParseErrorHandler, CdlParseWarningHandler);
1326 }
1327
1328 RegenerateData();
1329 //EnableCallbacks(true); // re-enable the transaction handler
1330 if (!GetPathName().IsEmpty()){
1331 CopyMLTFiles (); // copy new MLT files to the build tree as necessary
1332 }
1333 SetModifiedFlag();
1334 }
1335 }
1336
1337 bool CConfigToolDoc::SaveMemoryMap()
1338 {
1339 const CString strSuffix(_T("mlt_") + CurrentMemoryLayout ());
1340 const CFileName strMLTInstallPkgconfDir(InstallTree() + _T("include\\pkgconf"));
1341 bool rc=false;
1342 if(strMLTInstallPkgconfDir.CreateDirectory(true)){
1343 const CString strMLTInstallBase(strMLTInstallPkgconfDir+CFileName(strSuffix));
1344 const CFileName strMLTDir (MLTDir());
1345 if(strMLTDir.CreateDirectory (true)){
1346 const CString strMLTBase (strMLTDir + CFileName (strSuffix));
1347 TRACE(_T("Saving memory layout to %s\n"), strMLTBase + _T(".mlt"));
1348 if(MemoryMap.save_memory_layout (strMLTBase + _T(".mlt"))){
1349 TRACE(_T("Exporting memory layout to %s\n"), strMLTInstallPkgconfDir);
1350 rc=MemoryMap.export_files (strMLTInstallBase + _T(".ldi"), strMLTInstallBase + _T(".h"));
1351 }
1352 }
1353 }
1354 return rc;
1355 }
1356
1357 bool CConfigToolDoc::CopyMLTFiles()
1358 {
1359 // copy default MLT files for the selected target/platform from the repository if they do not already exist
1360
1361 TRACE (_T("Looking for MLT files at %s\n"), PackagesDir() + m_strMemoryLayoutFolder + _T("include\\pkgconf\\mlt_*.*"));
1362 const CFileName strInstallDestination(InstallTree () + _T("include\\pkgconf"));
1363 const CFileName strMLTDestination (MLTDir ());
1364 TRACE (_T("Copying .ldi and .h files to %s\n"), strInstallDestination);
1365 TRACE (_T("Copying .mlt files to %s\n"), strMLTDestination);
1366 bool rc=strInstallDestination.CreateDirectory (true) && strMLTDestination.CreateDirectory (true);
1367 if(rc){
1368 CFileFind ffFileFind;
1369 BOOL bLastFile = ffFileFind.FindFile (PackagesDir() + m_strMemoryLayoutFolder + _T("\\include\\pkgconf\\mlt_*.*"));
1370 while (bLastFile)
1371 {
1372 bLastFile = ffFileFind.FindNextFile ();
1373 if (_T(".mlt") == ffFileFind.GetFileName ().Right (4)) // if a .mlt file
1374 {
1375 if (! CFileName (strMLTDestination, CFileName (ffFileFind.GetFileName ())).Exists ())
1376 {
1377 if(!CUtils::CopyFile (ffFileFind.GetFilePath (), strMLTDestination + CFileName (ffFileFind.GetFileName ()))){
1378 return false; // message already emitted
1379 }
1380 }
1381 }
1382 else // a .h or .ldi file
1383 {
1384 if (! CFileName (strInstallDestination, CFileName (ffFileFind.GetFileName ())).Exists () &&
1385 !CUtils::CopyFile (ffFileFind.GetFilePath (), strInstallDestination + CFileName (ffFileFind.GetFileName ()))){
1386 return false; // message already emitted
1387 }
1388 }
1389 }
1390 }
1391 return rc; //FIXME
1392 }
1393
1394 CString CConfigToolDoc::GetDefaultHardware ()
1395 {
1396 CString strKey = _T("SOFTWARE\\Red Hat\\eCos");
1397 CString strVersionKey = _T("");
1398 CString rc = _T("");
1399 TCHAR pszBuffer [MAX_PATH + 1];
1400 HKEY hKey;
1401 LONG lStatus;
1402
1403 // get the greatest eCos version subkey
1404 if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE, strKey, 0L, KEY_READ, &hKey))
1405 {
1406 DWORD dwIndex = 0;
1407 while (ERROR_SUCCESS == RegEnumKey (hKey, dwIndex++, (LPTSTR) pszBuffer, sizeof (pszBuffer)))
1408 {
1409 if (strVersionKey.Compare (pszBuffer) < 0)
1410 strVersionKey = pszBuffer;
1411 }
1412 RegCloseKey (hKey);
1413 if (! strVersionKey.IsEmpty ())
1414 {
1415 TRACE (_T("CConfigToolDoc::GetDefaultHardware(): version subkey = '%s'\n"), strVersionKey);
1416
1417 // get the default hardware value
1418 strKey += _T("\\") + strVersionKey;
1419 if (ERROR_SUCCESS == RegOpenKeyEx (HKEY_LOCAL_MACHINE, strKey, 0L, KEY_READ, &hKey))
1420 {
1421 DWORD dwBufferSize = sizeof (pszBuffer);
1422 lStatus = RegQueryValueEx (hKey, _T("Default Hardware"), NULL, NULL, (LPBYTE) pszBuffer, &dwBufferSize);
1423 RegCloseKey (hKey);
1424 if (ERROR_SUCCESS == lStatus)
1425 {
1426 TRACE (_T("CConfigToolDoc::GetDefaultHardware(): default hardware = '%s'\n"), pszBuffer);
1427 rc=pszBuffer;
1428 }
1429 }
1430 }
1431 }
1432 return rc;
1433 }
1434
1435 CConfigItem * CConfigToolDoc::AddItem (const CdlUserVisible vitem, CConfigItem * pParent)
1436 {
1437 CConfigItem * pItem = new CConfigItem (pParent, vitem);
1438
1439 m_arItem.Add(pItem);
1440 pItem->m_strDesc = CUtils::StripExtraWhitespace (CString (vitem->get_description ().c_str ()));
1441
1442 if (vitem->get_name () == "CYGHWR_MEMORY_LAYOUT")
1443 {
1444 ASSERT (m_strMemoryLayoutFolder.IsEmpty ());
1445 m_strMemoryLayoutFolder = vitem->get_owner ()->get_directory().c_str ();
1446 m_strMemoryLayoutFolder.Replace(_TCHAR('/'),_TCHAR('\\'));
1447 TRACE (_T("Found memory layout folder: %s\n"), m_strMemoryLayoutFolder);
1448 }
1449
1450 if (vitem->get_name () == "CYGBLD_LINKER_SCRIPT")
1451 {
1452 ASSERT (m_strLinkerScriptFolder.IsEmpty ());
1453 m_strLinkerScriptFolder = vitem->get_owner ()->get_directory().c_str ();
1454 m_strLinkerScriptFolder.Replace(_TCHAR('/'),_TCHAR('\\'));
1455 TRACE (_T("Found linker script folder: %s\n"), m_strLinkerScriptFolder);
1456
1457 // the CDL hardware template name will eventually become the target name,
1458 // but for now we must deduce the target name from the linker script file name
1459
1460 const CdlValuable valuable = dynamic_cast<CdlValuable> (vitem);
1461 CFileName strLinkerScript (m_strPackagesDir, m_strLinkerScriptFolder, CString (valuable->get_value ().c_str ()));
1462 strLinkerScript.Replace (_TCHAR('/'), _TCHAR('\\'));
1463 if(!strLinkerScript.Exists ()){
1464 CConfigTool::Log(_T("%s does not exist\n"),strLinkerScript);
1465 }
1466 TRACE (_T("Target '%s' selected\n"), strLinkerScript.Tail ().Root (), pItem->Macro());
1467 //CFileName strBinDir = AfxGetApp () -> GetProfileString (CUtils::LoadString (IDS_KEY_TOOLS_DIR), pTarget->Name (), _T(""));
1468 //if (! strBinDir.IsEmpty () && strBinDir.IsDir ())
1469 //{
1470 // pTarget->SetBinDir (strBinDir);
1471 //}
1472 }
1473
1474 //TRACE(_T("Created new item from cdl: "));
1475 //pItem->DumpItem();
1476 return pItem;
1477 }
1478
1479 void CConfigToolDoc::AddAllItems ()
1480 {
1481 // remove any old items and packages
1482 DeleteContents ();
1483 if(NULL!=CConfigTool::GetControlView()){ // may not be the case for plugin
1484
1485 // add the root item
1486 CConfigItem * pItem = new CConfigItem (NULL, NULL);
1487 m_arItem.Add(pItem);
1488 pItem->m_strDesc = _T("The root node for all configurable items");
1489
1490 // add the remaining items using their CDL descriptions
1491 m_strMemoryLayoutFolder = _T("");
1492 m_strLinkerScriptFolder = _T("");
1493 AddContents (m_CdlConfig, FirstItem ());
1494
1495 // check that exactly one radio button in each group is enabled
1496 CheckRadios ();
1497
1498 // update the rules (conflicts) view
1499 UpdateFailingRuleCount ();
1500
1501 if(NULL==CConfigTool::GetRulesView() || !CConfigTool::GetRulesView()->IsWindowVisible()){
1502 // log all conflicts
1503 // LogConflicts (m_CdlConfig->get_structural_conflicts ()); // relating to package availability - ignore for now
1504 LogConflicts (m_CdlConfig->get_all_conflicts ());
1505 }
1506
1507 CConfigTool::GetControlView()->SelectItem(Item(0));
1508 UpdateAllViews (NULL, SelChanged, (CObject *)Item(0)); // refresh the display
1509 if(ItemCount()>0){
1510 CConfigTool::GetControlView()->GetTreeCtrl().Expand(Item(0)->HItem(),TVE_EXPAND);
1511 }
1512 CConfigTool::GetControlView()->SetFocus();
1513 }
1514 }
1515
1516 const CFileName CConfigToolDoc::CurrentLinkerScript()
1517 {
1518 const CConfigItem * pItem = Find (_T("CYGBLD_LINKER_SCRIPT"));
1519 return pItem ? CFileName (m_strPackagesDir, m_strLinkerScriptFolder, pItem->StringValue ()) : _T("");
1520 }
1521
1522 bool CConfigToolDoc::GenerateHeaders()
1523 {
1524 // Copy non-config header files from the repository to the
1525 // install tree for plugin only. The make system used by
1526 // the standalone config tool does this for us.
1527 #ifdef PLUGIN
1528 typedef std::vector<CdlBuildInfo_Loadable> EntriesArray;
1529 const EntriesArray &arEntries=BuildInfo().entries;
1530 typedef std::vector<CdlBuildInfo_Header> HeaderArray;
1531 for(EntriesArray::size_type j=0;j<arEntries.size();j++){
1532 const CdlBuildInfo_Loadable &e=arEntries[j];
1533 const CFileName strDir(CUtils::WPath(e.directory));
1534 const HeaderArray &arHeaders=e.headers;
1535 for(HeaderArray::size_type i=0;i<arHeaders.size();i++){
1536 const CdlBuildInfo_Header &h=arHeaders[i];
1537 const CFileName strSource(PackagesDir()+strDir+CUtils::WPath(h.source));
1538 const CFileName strDest(HeadersDir()/*+CUtils::WPath(e.directory)*/+CUtils::WPath(h.destination));
1539
1540 if(!strDest.Head().CreateDirectory(true)){
1541 CUtils::MessageBoxF(_T("Failed to create %s - %s"),strDest.Head(),CUtils::GetLastErrorMessageString());
1542 return false;
1543 }
1544 if(!CUtils::CopyFile(strSource,strDest)){
1545 return false; // message already emitted
1546 }
1547 }
1548 }
1549 #endif
1550
1551 // Generate headers
1552 try {
1553 CFileName strPkfConfDir(InstallTree()+_T("include\\pkgconf"));
1554 if(!strPkfConfDir.CreateDirectory()){
1555 CUtils::MessageBoxF(_T("Failed to create %s - %s"),strPkfConfDir,CUtils::GetLastErrorMessageString());
1556 return false;
1557 }
1558 GetCdlConfig()->generate_config_headers(CUtils::UnicodeToStdStr(strPkfConfDir.ShortName()));
1559 }
1560 catch (CdlInputOutputException e) {
1561 const CString strMsg(e.get_message().c_str());
1562 TRACE(_T("!!! Exception thrown calling generate_config_headers - %s"),strMsg);
1563 CUtils::MessageBoxF(_T("Failed to generate header files - %s"),strMsg);
1564 return false;
1565 }
1566 return true;
1567 }
1568
1569 const CFileName CConfigToolDoc::MLTDir ()
1570 {
1571 CString strPathName (GetPathName ());
1572 ASSERT (! strPathName.IsEmpty ());
1573 return strPathName.Left (strPathName.ReverseFind (_TCHAR('.'))) + _T("_mlt");
1574 }
1575
1576 bool CConfigToolDoc::UpdateBuildInfo(bool bFirstTime)
1577 {
1578 try {
1579 GetCdlConfig()->get_build_info(m_BuildInfo);
1580 #ifdef PLUGIN
1581 // FIXME: this means anything not mentioned by AddFile in our scan below will be removed - including user-added items
1582 m_peCosProject->ClearItemFlags();
1583 m_peCosProject->UpdateeCosProject(bFirstTime);
1584 m_peCosProject->RemoveAllUnflaggedItems();
1585 #else
1586 UNUSED_ALWAYS(bFirstTime);
1587 generate_build_tree (GetCdlConfig(), CUtils::UnicodeToStdStr(BuildTree()), CUtils::UnicodeToStdStr(InstallTree()));
1588 #endif
1589 return true;
1590 }
1591 catch(...){
1592 return false;
1593 }
1594 }
1595
1596 void CConfigToolDoc::RemoveAllItems()
1597 {
1598 for(int nItem=0;nItem<ItemCount();nItem++){
1599 CConfigItem *pItem=Item(nItem);
1600 deleteZ(pItem);
1601 }
1602 m_arItem.RemoveAll();
1603
1604 UpdateAllViews(NULL,Clear,0);
1605 }
1606
1607 void CConfigToolDoc::EnableCallbacks (bool bEnable/*=true*/)
1608 {
1609 CdlTransactionCallback::set_callback_fn(bEnable?&CdlTransactionHandler:0);
1610 CdlTransactionBody::set_inference_callback_fn(bEnable?&CdlInferenceHandler:0);
1611 CdlTransactionBody::set_inference_override(CdlValueSource_Invalid);
1612 }
1613
1614 int CConfigToolDoc::GetTestExeNames (CFileNameArray &arTestExes,CFileNameArray &arMissing)
1615 {
1616 arTestExes.RemoveAll();
1617 arMissing.RemoveAll();
1618
1619 typedef std::vector<CdlBuildInfo_Loadable> EntriesArray;
1620 const EntriesArray &arEntries=BuildInfo().entries;
1621 for(EntriesArray::size_type j=0;j<arEntries.size();j++){
1622 const CdlBuildInfo_Loadable &e=arEntries[j];
1623 CStringArray ar;
1624 int n=CUtils::Chop(CString(get_tests(GetCdlConfig(),e).c_str()),ar);
1625 for(int i=0;i<n;i++){
1626 CFileName strFile;
1627 strFile.Format(_T("%s\\tests\\%s\\%s.exe"),InstallTree(),CString(e.directory.c_str()),ar[i]);
1628 strFile.Replace(_TCHAR('/'),_TCHAR('\\'));
1629 if(strFile.Exists()){
1630 arTestExes.Add(strFile);
1631 } else {
1632 arMissing.Add(strFile);
1633 }
1634 }
1635 }
1636 return arTestExes.GetSize();
1637 }
1638
1639 CConfigToolDoc::GlobalConflictOutcome CConfigToolDoc::ResolveGlobalConflicts(CPtrArray *parConflictsOfInterest)
1640 {
1641 m_ConflictsOutcome=NotDone;
1642 m_arConflictsOfInterest.RemoveAll();
1643 if(parConflictsOfInterest){
1644 m_arConflictsOfInterest.Copy(*parConflictsOfInterest);
1645 }
1646 CdlInferenceCallback fn=CdlTransactionBody::get_inference_callback_fn();
1647 CdlTransactionBody::set_inference_callback_fn(CdlGlobalInferenceHandler);
1648 GetCdlInterpreter()->get_toplevel()->resolve_all_conflicts();
1649 CdlTransactionBody::set_inference_callback_fn(fn);
1650 if(NotDone==m_ConflictsOutcome){
1651 // No solutions were available, but we'll run the dialog anyway
1652 const std::list<CdlConflict>& conflicts=GetCdlConfig()->get_all_conflicts();
1653 CFailingRulesDialog dlg(conflicts,NULL,&m_arConflictsOfInterest);
1654 m_ConflictsOutcome=(IDOK==dlg.DoModal())?OK:Cancel;
1655 }
1656 return m_ConflictsOutcome;
1657 }
1658
1659 bool CConfigToolDoc::CheckConflictsBeforeSave()
1660 {
1661 if(GetCdlInterpreter()->get_toplevel()->get_all_conflicts().size()>0){
1662 if(Deferred&m_nRuleChecking){
1663 if((SuggestFixes&m_nRuleChecking)&&(Cancel==ResolveGlobalConflicts())){
1664 return false;
1665 }
1666 int nConflicts=GetCdlInterpreter()->get_toplevel()->get_all_conflicts().size();
1667 switch(nConflicts){
1668 case 0:
1669 break;
1670 case 1:
1671 if(IDNO==CUtils::MessageBoxFT(MB_YESNO|MB_DEFBUTTON2,_T("There is 1 unresolved conflict. Save anyway?"))){
1672 return false;
1673 }
1674 default:
1675 if(IDNO==CUtils::MessageBoxFT(MB_YESNO|MB_DEFBUTTON2,_T("There are %d unresolved conflicts. Save anyway?"),nConflicts)){
1676 return false;
1677 }
1678 }
1679 }
1680 }
1681 return true;
1682 }
1683
1684 BOOL CConfigToolDoc::IsModified()
1685 {
1686 return m_bModified || MemoryMap.map_modified();
1687 }
1688
1689 void CConfigToolDoc::OnFileExport()
1690 {
1691 CFileDialog dlg (FALSE, _T("ecm"), NULL, OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY, _T("eCos Minimal Configuration (*.ecm)|*.ecm||"), AfxGetMainWnd ());
1692 TCHAR szBuffer [MAX_PATH * 16] = _T("");
1693 dlg.m_ofn.lpstrFile = szBuffer;
1694 dlg.m_ofn.nMaxFile = MAX_PATH * 16;
1695 dlg.m_ofn.lpstrTitle = _T("Export eCos Minimal Configuration");
1696 if (IDOK == dlg.DoModal ()) {
1697 try {
1698 TRACE (_T("Exporting eCos minimal configuration '%s'\n"), dlg.GetPathName ());
1699 m_CdlConfig->save (CUtils::UnicodeToStdStr (dlg.GetPathName ()), /* minimal = */ true);
1700 }
1701 catch (CdlStringException exception) {
1702 CUtils::MessageBoxF (_T("Error exporting eCos minimal configuration:\n\n%s"), CString (exception.get_message ().c_str ()));
1703 }
1704 catch (...) {
1705 CUtils::MessageBoxF (_T("Error exporting eCos minimal configuration."));
1706 }
1707 }
1708 }
1709
1710 void CConfigToolDoc::OnFileImport()
1711 {
1712 CFileDialog dlg (TRUE, NULL, NULL, OFN_PATHMUSTEXIST | OFN_HIDEREADONLY, _T("eCos Minimal Configurations (*.ecm)|*.ecm||"), AfxGetMainWnd ());
1713 TCHAR szBuffer [MAX_PATH * 16] = _T("");
1714 dlg.m_ofn.lpstrFile = szBuffer;
1715 dlg.m_ofn.nMaxFile = MAX_PATH * 16;
1716 dlg.m_ofn.lpstrTitle = _T("Import eCos Minimal Configuration");
1717 if (IDOK == dlg.DoModal ()) {
1718 try {
1719 TRACE (_T("Importing eCos minimal configuration '%s'\n"), dlg.GetPathName ());
1720 m_CdlConfig->add (CUtils::UnicodeToStdStr (dlg.GetPathName ()), CConfigToolDoc::CdlParseErrorHandler, CConfigToolDoc::CdlParseWarningHandler);
1721 }
1722 catch (CdlStringException exception) {
1723 CUtils::MessageBoxF (_T("Error importing eCos minimal configuration:\n\n%s"), CString (exception.get_message ().c_str ()));
1724 }
1725 catch (...) {
1726 CUtils::MessageBoxF (_T("Error importing eCos minimal configuration."));
1727 }
1728
1729 CWaitCursor wait;
1730 AddAllItems (); // regenerate all the config items since the topology may have changed
1731 if (m_strLinkerScriptFolder.IsEmpty ()) {
1732 CUtils::MessageBoxF (_T("The eCos linker script macro CYGBLD_LINKER_SCRIPT is not defined."));
1733 }
1734 if (m_strMemoryLayoutFolder.IsEmpty ()) {
1735 CUtils::MessageBoxF (_T("The eCos memory layout macro CYGHWR_MEMORY_LAYOUT is not defined."));
1736 }
1737 SwitchMemoryLayout (true); // the hardware template may have changed
1738 UpdateBuildInfo ();
1739 CConfigTool::GetControlView()->SelectItem (Item (0));
1740 SetModifiedFlag ();
1741 }
1742 }
1743
1744 bool CConfigToolDoc::QualifyDocURL(CString &strURL)
1745 {
1746 if(-1==strURL.Find(_T("://"))){
1747 // Relative URL - qualify it as a file URL
1748 strURL=DocBase()+CFileName(strURL);
1749 strURL.Replace(_TCHAR('/'),_TCHAR('\\'));
1750 strURL=_T("file://")+strURL;
1751 }
1752
1753 if(0==strURL.Find(_T("file://"))){
1754 CFileName strFile(strURL.Right(strURL.GetLength()-7));
1755 int nIndex=strFile.ReverseFind(_TCHAR('#'));
1756 if(-1!=nIndex){
1757 strFile=strFile.Left(nIndex);
1758 }
1759 strFile.Replace(_TCHAR('/'),_TCHAR('\\'));
1760 if(!strFile.Exists()){
1761 CUtils::MessageBoxF(_T("Cannot locate the file %s"),strFile);
1762 return false;
1763 }
1764 }
1765 return true;
1766 }
1767
1768 bool CConfigToolDoc::NewMemoryLayout (const CString &strPrefix)
1769 {
1770 CFileName strFileName = CurrentLinkerScript ();
1771 TRACE(_T("Reading linker-defined memory sections from %s\n"), strFileName);
1772 MemoryMap.new_memory_layout (); // delete the old memory layout regardless
1773 if (! strFileName.IsEmpty ())
1774 MemoryMap.import_linker_defined_sections (strFileName); // read the linker-defined section names from the repository (failure is silent)
1775
1776 CString strMemoryLayoutFileName = strPrefix + _T("\\mlt_") + CurrentMemoryLayout () + _T(".mlt");
1777 TRACE(_T("Reading memory layout from %s\n"), strMemoryLayoutFileName);
1778 MemoryMap.load_memory_layout (strMemoryLayoutFileName); // load the new memory layout (failure is silent)
1779 strSelectedSection = _T("");
1780 strSelectedRegion = _T("");
1781 UpdateAllViews (NULL, MemLayoutChanged);
1782 return true; // FIXME
1783 }
1784
1785 void CConfigToolDoc::SetPathName( LPCTSTR pszPath, BOOL bAddToMRU /*= TRUE*/ )
1786 {
1787 if(_TCHAR('\0')==*pszPath){ // called like this after failed saves to put things back as they were
1788 // CDocument::SetPathName would assert given an empty string
1789 m_strPathName = _T("");
1790 #ifndef PLUGIN
1791 SetTitle(_T("Untitled"));
1792 #endif
1793 m_strBuildTree = _T("");
1794 m_strInstallTree = _T("");
1795 } else {
1796 #ifdef PLUGIN
1797 m_strPathName = CFileName (pszPath);
1798 #else
1799 CDocument::SetPathName (pszPath, bAddToMRU);
1800 #endif
1801 CString strFolder (pszPath);
1802 strFolder = strFolder.Left (strFolder.ReverseFind (_TCHAR('.'))); // extract folder from file path
1803 m_strBuildTree = CFileName(strFolder + _T("_build"));
1804 m_strInstallTree = CFileName(strFolder + _T("_install"));
1805 }
1806 }
1807
1808 bool CConfigToolDoc::ShowHtmlHelp (LPCTSTR pszURL)
1809 {
1810
1811 HWND hwndCaller=AfxGetMainWnd()->CWnd::GetDesktopWindow()->GetSafeHwnd();
1812 bool rc=false;
1813 const CFileName strFile(HTMLHelpLinkFileName());
1814 CStdioFile f;
1815 if(!CFileName(CConfigTool::strHelpFile).Exists()) {
1816 CUtils::MessageBoxF(_T("Cannot display help - %s does not exist\n"),CConfigTool::strHelpFile);
1817 } else if(!f.Open(strFile,CFile::typeText|CFile::modeCreate|CFile::modeWrite)){
1818 CUtils::MessageBoxF(_T("Cannot display help - error creating %s\n"),strFile);
1819 } else {
1820 CString str;
1821 str.Format(_T("<meta HTTP-EQUIV=\"refresh\" CONTENT=\"0;URL=%s\">"),pszURL);
1822 f.WriteString(str);
1823 f.Close();
1824 if(0==HtmlHelp(hwndCaller, CConfigTool::strHelpFile, HH_DISPLAY_TOPIC, 0)){
1825 CUtils::MessageBoxF(_T("Cannot display %s"),pszURL);
1826 } else {
1827 // FIXME: Do this the first time only?
1828 HH_WINTYPE WinType;
1829 HWND wnd;
1830 HH_WINTYPE *pWinType=NULL;
1831 wnd = HtmlHelp(hwndCaller, CConfigTool::strHelpFile+_T(">mainwin"), HH_GET_WIN_TYPE, (DWORD) &pWinType);
1832 WinType=*pWinType;
1833 WinType.hwndCaller=hwndCaller;
1834 WinType.fsWinProperties|=HHWIN_PROP_TRACKING;
1835 WinType.idNotify = ID_HHNOTIFICATION;
1836 wnd = HtmlHelp(hwndCaller, CConfigTool::strHelpFile, HH_SET_WIN_TYPE, (DWORD) &WinType);
1837 rc=true;
1838 }
1839 //::DeleteFile(strFile);
1840 }
1841 return rc;
1842 }
1843
1844 const CString CConfigToolDoc::HTMLHelpLinkFileName()
1845 {
1846 return CFileName(CConfigTool::strHelpFile).Head()+"link2.htm";
1847 }