changeset 199:920b9b754b53

Merge from eCos master repository on 2001-12-15-12:00:33-GMT
author jlarmour
date Sat, 15 Dec 2001 13:42:19 +0000
parents ea3f0bd33a73
children 8147f1c99f15
files host/libcdl/ChangeLog host/tools/configtool/standalone/wxwin/CHANGES.txt host/tools/configtool/standalone/wxwin/TODO.txt host/tools/configtool/standalone/wxwin/appsettings.cpp host/tools/configtool/standalone/wxwin/appsettings.h host/tools/configtool/standalone/wxwin/configtool.cpp host/tools/configtool/standalone/wxwin/dialogs/configtool.wdr host/tools/configtool/standalone/wxwin/docsystem.cpp host/tools/configtool/standalone/wxwin/docsystem.h host/tools/configtool/standalone/wxwin/packagesdlg.cpp host/tools/configtool/standalone/wxwin/packagesdlg.h host/tools/configtool/standalone/wxwin/runtestsdlg.h host/tools/configtool/standalone/wxwin/setup/configtool.iss packages/compat/posix/current/ChangeLog packages/compat/posix/current/tests/mqueue2.c packages/devs/eth/amd/pcnet/current/src/if_pcnet.c packages/devs/eth/arm/flexanet/current/ChangeLog packages/devs/eth/arm/flexanet/current/cdl/flexanet_eth_drivers.cdl packages/devs/eth/ns/dp83902a/current/ChangeLog packages/devs/eth/ns/dp83902a/current/src/if_dp83902a.c packages/devs/eth/smsc/lan91cxx/current/ChangeLog packages/devs/eth/smsc/lan91cxx/current/src/if_lan91cxx.c packages/hal/common/current/ChangeLog packages/hal/common/current/include/hal_stub.h packages/hal/common/current/src/hal_misc.c packages/hal/i386/arch/current/ChangeLog packages/hal/i386/arch/current/src/i386.ld packages/hal/i386/pc/current/ChangeLog packages/hal/i386/pc/current/include/plf_intr.h packages/hal/synth/arch/current/ChangeLog packages/hal/synth/arch/current/include/hal_io.h packages/hal/synth/i386linux/current/ChangeLog packages/hal/synth/i386linux/current/src/syscall-i386-linux-1.0.S packages/io/eth/current/ChangeLog packages/io/eth/current/cdl/eth_drivers.cdl packages/io/eth/current/src/net/eth_drv.c packages/io/eth/current/src/stand_alone/eth_drv.c packages/kernel/current/ChangeLog packages/kernel/current/tests/kcache2.c packages/net/tcpip/current/ChangeLog packages/net/tcpip/current/cdl/net.cdl packages/net/tcpip/current/include/machine/param.h packages/net/tcpip/current/src/ecos/support.c packages/net/tcpip/current/src/sys/net/if_ethersubr.c packages/net/tcpip/current/tests/nc_test_master.c packages/net/tcpip/current/tests/nc_test_slave.c packages/net/tcpip/current/tests/tcp_echo.c packages/redboot/current/ChangeLog packages/redboot/current/cdl/redboot.cdl packages/redboot/current/src/net/cksum.c packages/redboot/current/src/net/net_io.c
diffstat 51 files changed, 1487 insertions(+), 519 deletions(-) [+]
line wrap: on
line diff
--- a/host/libcdl/ChangeLog
+++ b/host/libcdl/ChangeLog
@@ -1,3 +1,12 @@
+2001-12-07  Bart Veer  <bartv@redhat.com>
+
+	* doc/language.sgml, doc/*.html:
+	Add a footnote clarifying a particular Tcl expression
+	(bug 57097). Regenerate html.
+
+	* doc/fixhtml.tcl
+	Removed, the master copy now lives in pkgconf
+
 2001-12-06  Bart Veer  <bartv@redhat.com>
 
 	* cdlcore.hxx, build.cxx, interp.cxx:
--- a/host/tools/configtool/standalone/wxwin/CHANGES.txt
+++ b/host/tools/configtool/standalone/wxwin/CHANGES.txt
@@ -1,10 +1,24 @@
 Release History for eCos Configuration Tool 2
 =============================================
 
-*** Version 2.09, December 3rd 2001
+*** Version 2.09, December 11th 2001
 
 - Hardware is now sorted alphabetically on UNIX.
 
+- The documentation system will now work with HTML documentation
+  generated from SGML, which will be the case from eCos 2.0
+  on.
+
+- --compile-help command added, which will create .hhp and .hhc
+  files, and then exit.
+
+- Packages dialog improvements: added keyword search and 'Omit hardware'
+  checkbox; added more information to the description window.
+
+- added an "exact match" checkbox to the Packages dialog. That way if
+  you type 'flash', you get exactly what you'd get if you type
+  'ecosconfig add flash'.
+
 
 *** Version 2.08, October 25th 2001
 
--- a/host/tools/configtool/standalone/wxwin/TODO.txt
+++ b/host/tools/configtool/standalone/wxwin/TODO.txt
@@ -28,4 +28,10 @@ To-Do List for Configuration Tool 2.x
   menus.
 
 - Should look for a .ecc file in the current directory if no save file is
-  passed on the command line.
\ No newline at end of file
+  passed on the command line.
+
+- Packages dialog:
+
+  o optionally, the ability to hide inactive and/or calculated options
+    and/or interfaces. They add a lot to visual clutter, but we do require the
+    user to be _able_ to view them if need be.
--- a/host/tools/configtool/standalone/wxwin/appsettings.cpp
+++ b/host/tools/configtool/standalone/wxwin/appsettings.cpp
@@ -30,7 +30,7 @@
 // Author(s):   julians
 // Contact(s):  julians
 // Date:        2000/08/29
-// Version:     $Id: appsettings.cpp,v 1.25 2001/09/25 09:50:23 julians Exp $
+// Version:     $Id: appsettings.cpp,v 1.27 2001/12/14 17:34:03 julians Exp $
 // Purpose:
 // Description: Implementation file for the ecSettings
 // Requires:
@@ -130,6 +130,10 @@ ecSettings::ecSettings()
     m_findDialogPos = wxPoint(-1, -1);
 
     m_editSaveFileOnly = FALSE;
+
+    // Packages dialog settings
+    m_omitHardwarePackages = FALSE;
+    m_matchPackageNamesExactly = FALSE;
 }
 
 // Copy constructor
@@ -175,6 +179,10 @@ void ecSettings::Copy(const ecSettings& 
     m_buildToolsDir = settings.m_buildToolsDir;
 
     m_editSaveFileOnly = settings.m_editSaveFileOnly;
+
+    // Packages dialog settings
+    m_omitHardwarePackages = settings.m_omitHardwarePackages;
+    m_matchPackageNamesExactly = settings.m_matchPackageNamesExactly;
 }
 
 ecSettings::~ecSettings()
@@ -286,6 +294,10 @@ bool ecSettings::LoadConfig()
     config.Read(_("/Find/DialogX"), & m_findDialogPos.x);
     config.Read(_("/Find/DialogY"), & m_findDialogPos.y);
 
+    // Package dialog settings
+    config.Read(_("/Packages/OmitHardwarePackages"), & m_omitHardwarePackages);
+    config.Read(_("/Packages/MatchPackageNamesExactly"), & m_matchPackageNamesExactly);
+
     // Run tests settings
     m_runTestsSettings.LoadConfig(config);
 
@@ -631,6 +643,10 @@ bool ecSettings::SaveConfig()
     config.Write(_("/Find/DialogX"), (long) m_findDialogPos.x);
     config.Write(_("/Find/DialogY"), (long) m_findDialogPos.y);
     
+    // Package dialog settings
+    config.Write(_("/Packages/OmitHardwarePackages"), m_omitHardwarePackages);
+    config.Write(_("/Packages/MatchPackageNamesExactly"), m_matchPackageNamesExactly);
+
     // Save current repository to eCos/Common/Repository/Folder
     // UNLESS it was overridden by ECOS_REPOSITORY
     {
--- a/host/tools/configtool/standalone/wxwin/appsettings.h
+++ b/host/tools/configtool/standalone/wxwin/appsettings.h
@@ -30,7 +30,7 @@
 // Author(s):   julians
 // Contact(s):  julians
 // Date:        2000/08/29
-// Version:     $Id: appsettings.h,v 1.10 2001/08/22 16:50:32 julians Exp $
+// Version:     $Id: appsettings.h,v 1.12 2001/12/14 17:34:03 julians Exp $
 // Purpose:
 // Description: Header file for the ConfigTool application settings
 // Requires:
@@ -243,6 +243,10 @@ public:
 
     // Font settings
     wxWindowSettings        m_windowSettings;
+
+    // Packages dialog settings
+    bool                    m_omitHardwarePackages;
+    bool                    m_matchPackageNamesExactly;
 };
 
 #endif
--- a/host/tools/configtool/standalone/wxwin/configtool.cpp
+++ b/host/tools/configtool/standalone/wxwin/configtool.cpp
@@ -30,7 +30,7 @@
 // Author(s):   julians
 // Contact(s):  julians
 // Date:        2000/08/24
-// Version:     $Id: configtool.cpp,v 1.50 2001/10/15 15:33:02 julians Exp $
+// Version:     $Id: configtool.cpp,v 1.51 2001/12/11 15:59:51 julians Exp $
 // Purpose:
 // Description: Implementation file for the ConfigTool application class
 // Requires:
@@ -123,6 +123,7 @@ static const wxCmdLineEntryDesc sg_cmdLi
     { wxCMD_LINE_SWITCH, "h", "help",   "displays help on the command line parameters" },
     { wxCMD_LINE_SWITCH, "e", "edit-only",    "edit save file only" },
     { wxCMD_LINE_SWITCH, "v", "version",    "print version" },
+    { wxCMD_LINE_SWITCH, "c", "compile-help",    "compile online help only" },
 
     { wxCMD_LINE_PARAM,  NULL, NULL, "input file 1", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
     { wxCMD_LINE_PARAM,  NULL, NULL, "input file 2", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL },
@@ -230,7 +231,7 @@ bool ecApp::OnInit()
     if (res == -1 || res > 0 || parser.Found(wxT("h")))
     {
 #ifdef __WXGTK__
-	wxLog::SetActiveTarget(new wxLogStderr);
+        wxLog::SetActiveTarget(new wxLogStderr);
 #endif
         parser.Usage();
         return FALSE;
@@ -238,10 +239,10 @@ bool ecApp::OnInit()
     if (parser.Found(wxT("v")))
     {
 #ifdef __WXGTK__
-	wxLog::SetActiveTarget(new wxLogStderr);
+        wxLog::SetActiveTarget(new wxLogStderr);
 #endif
-	wxString msg;
-	msg.Printf(wxT("eCos Configuration Tool (c) Red Hat, 2001 Version %.2f, %s"), ecCONFIGURATION_TOOL_VERSION, __DATE__);
+        wxString msg;
+        msg.Printf(wxT("eCos Configuration Tool (c) Red Hat, 2001 Version %.2f, %s"), ecCONFIGURATION_TOOL_VERSION, __DATE__);
         wxLogMessage(msg);
         return FALSE;
     }
@@ -287,6 +288,9 @@ bool ecApp::OnInit()
     if (parser.Found(wxT("e")))
         GetSettings().m_editSaveFileOnly = TRUE;
 
+    // If in --compile-help (-c) mode, then exit immediately after recompiling help file
+    bool compileHelpOnly = parser.Found(wxT("c"));
+
     wxString filenameToOpen1, filenameToOpen2;
     if (parser.GetParamCount() > 0)
     {
@@ -462,6 +466,38 @@ bool ecApp::OnInit()
             // Create a new file
             m_docManager->CreateDocument(wxString(""), wxDOC_NEW);
         }
+
+        if (compileHelpOnly)
+        {
+            if (!gotRepository)
+            {
+                wxString msg;
+                msg.Printf(wxT("Please specify a repository when using the --compile-help option."));
+                wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK);
+                return FALSE;
+            }
+            ecConfigToolDoc* doc = wxGetApp().GetConfigToolDoc();
+            if (doc)
+            {
+                if (!doc->RebuildHelpIndex(TRUE))
+                {
+                    wxString msg;
+                    msg.Printf(wxT("Sorry, there was a problem compiling the help index."));
+                    wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK);
+                    return FALSE;                   
+                }
+            }
+            else
+            {
+                wxString msg;
+                msg.Printf(wxT("Sorry, there was no current document when compiling the help index."));
+                wxMessageBox(msg, wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK);
+                return FALSE;                   
+            }
+
+            // Return FALSE in order to quit the application
+            return FALSE;
+        }
     }
     else
     {
index 47d708c74f5c9063897ae4afc066cddcf7780e96..1e24f33463cbc2d79d5d907f0f3d1e945e7ed76c
GIT binary patch
literal 73440
zc%1D$O_Srsb=VI{)@<aJWm!p-#6cXJmOr$SR;v$hsT6}GI7AjCSOhqu)rEy6dq|W(
zfCYd%JE@#<@F{;Fw^YTa`~oMH<g8!dpO8~h<zvd1q+bIK0wl-*zy?Un5>+!KKG^8@
z+3&r6{rbGwzr}If9nL>)aq;5>|BaE`G<4IRxOeeccOc936P|bt{{^?-#a~~AQ%R7O
z)7PUvP5R}V_^*##+kB21wsm0|BhQ8Re+&QBl`mE4E3qHEUo_DSS>7M`XJ>W$g=+jQ
za%gMtE4X+0g5KfJ?xty}ouZ}o?EtL$K+}|Nyq(|-_uq4DGXS~1@I2e%f)3!O!gG4O
z5;Xb8<h~$Fr`=&g>}q0v*jD<|S4vkC<Ud@$c_#KXsUgU(l3TLa(q1Fq`qF7zdxd<}
zlwR;w1$VatZ~M(Xj)TU~NNNrnO1C9T4NZk_n$#VL{}&u@<44{Ocwm(eRu8xj(AEHQ
z!&;z9Bj|s=%W?O}H9(NiZHRInq;Nr}8@e?@<|-&}M0!iQ!>s$jyc&ApLH}+Cf2#+y
z(^C2(e%Uqx1!pbWLB@no1f(H2<r|(8f^{nbn%~{izH-hCrvJe7_#-ZfXZ>%KKEJ{J
zh;h!AgN-_Xd+=*j6EIww_@%ZDp>OzSs;7I#2#CamO~$XSGSRmqnDo)IRTi>i_pNp8
zcGOdf*WYtK-&0a=JFxU{J;$EgE*kTyZ7w{+w%o_?cC{xo#5jJw6<}npk5F_t00_uM
zhqg=KTb?5LegJi)wb{Sk^GUKo+^*8irRpgFwXSVdTh0GlGS>@oZfy_zTNBJRU0;Ag
zyopNw-;<TRs>lOPQo5m%A9LxI{3bG8hr1+elncPu49`RvEL%XQ@XTI#c+_YutPwk_
z_I43ereKyQi9l57A0~SM2_^NfFw{R!BYIq6TDmwx?Z3b4Q;*o0%9FfW2b{H<@+9e2
z8ctv3P6~TgE(Z&xWmseXiPU_a+UH^;F?X2usX)W;mEdo83EV1np`YV}k%tEX3ch93
ztTBH%)xF2?8bC)w>&x3va?d{lz^VE<@w*zi!g29or#yx9JuVoDT2i+;^o3w}-WD{9
zqi?wMHgOabj@zqMaA*=qTWYk$#uMCJ3YKY1(dcX3!jfg8SLi_{h$&b6X%bg-1g+7=
zyrIasOzL;=Uq|;wQ@(aNwN1od+Rm7_E%S=fs~WiZlg+qk2x>0W+*_h%q`PPpgz_{(
zTFL4QO-V^dslGlo>=>n@SM~!Y(C6JGGB%~Y*Z?a$D;441cl<XCL$xP1q}J0R)_Lmf
z$OB+pGz|xhAXGr?nZcYmnN9mLG|J$@ogFX{fj<jHD`6>=%OMPm256$DBHh8FZCH;<
zoV2Y-tI?rE+r2ThjS-^s0R>0T_lJ^1p;1MlkCmSk3eDeh=}m@LBADvvBgf_~eTH1(
zCwXY*pF#XWo!XAaW4w$UV@_giV2U>uj)M`%pXufTkt<Dfp)X8&CHfkWs;t<6-=-0v
z=zH$&K$2o@p465~r6XP&&Dt*3NqOge0P-3*etZ{Gq0;zaJn>U&nD)|UNhJWROp&A`
z&F|Koc-r->;Q$Drof+s7IT-^24BYs)f|mU8GO4|{xaD{nZx!h88*$fi@wd5%9T&2$
zA1_+DxXJ{%Sr!@re*7U9i1C>up5tE!g4`B`CO#8XRcT0qCN}e!Yk@IZA7bBhK;8%j
zoZ!0l$k07B=ARR~vN4Xz!8w~qN`xRus`dL@X`;0yHLo@S__V3v@--jzY$nsnRjw4~
zN{<jgJU*Gsb#Q9LfZBNpO$O7tV_&-H!Gi}$aOR5`<u#g^#_^(H6cGGMA%YPzr^jWF
z-W3c0Gz3E?KSlZ&>&6SiL@vK@4QsNEP8HS#?1yl8q9Q~123~C{jbVKt$(oco)<O@k
zy=wJ^VS4WyRxnzZGsZF%=D*mCp!^07J%D{8Ce1UVbB{L7#+dFp4R$eT0A$~w2@ucD
zqA46L1sXD?ko3=zNgCKMn6kSVFLkGuV7%;kx~pnd%r>DrY!e33cZdlywnqy<vJL^s
z>us2%BW;?_YLtP3m^ESnBSO<~=caz8_;J)d#4Oqw4W2e_wUCJ?rbGH8d?DoQrlj^{
z;ptH6k<_lCEYw9g*KiV@M}iK?`ZHv@z!(D;@wM49bpB3oEew@E$M?ydikr}fPy3JY
zg&%C9y@VS+#Z60^*x8u{z-*E%4^6Oe7#^Cr(3M&fjf|OYf=ISe?FDwP$axgrf;1vX
zEo2ZHlZE3e!=7%Te3KP<bwt5A>Xn>;By4eRSY!LL+Ov<J;0rvrL9|-<T|*x<ili4@
zdaHr10|S<bF);*${dvdca^4a8tt`Cx!mF@8t#o+u(`~%aXbas_k+4Kw3;#aw!Bn><
zc;IYdOhnB5f^*&BZ96H=%#kE&_*EnKY9rOvwsJm%OKLk0)xluHf_}*xmf>O3nXiF?
z>`r+s^#~=hdI1~&`ln;KBV?L*@U$0h5xzvS{ZApwlMdarJ@m}BzxJOx@U;JE{Dc7s
zp-Eu2<h*`Z!ZA)sJ9aU-O6zvEs|6~J3Wj+a@Vc76LbuW=0oY%sC~1pwFE2t!+GQJ=
z^XSE5*TEE>&=Oa}6v(U!okTYmhB@x(-jrcwg6)~~yQH#|;PMp|00o96)=W>(+A5h2
zYettN!~GVQE<Y{6k2dToLt&udaR|`-&-kinc^FmR6!E4#@_lprf}HEl?0sZj@XvtW
zyl2~{%b#4><`_9Y=P#$m2-`nXdx7tbFamYMqQ7{5G8#SLpV|w4q+9%ncQr>m+~wz(
zX?WY=7cL@i@aOpP3qWn)H}EHx{@j@89)c5{_h0sa&Da;3vP!3(GEUU6XV2nsqUaSk
z-sbk9<K9W)3<6iwv`FLM(qIvWtUhe^m0nXh@2)<;702gkv{&Vaq_ECNlwAHy(=M}2
z>nSn?DkP8yqWF0Y6hXOOXtnitSa-lD|3Jm9t*G(OQ;>bL8vjRbn;OT;)(NyXRo*9w
z+8h6j*R3&cx=ZCvb@xdM<sH}ECr9OdP40Pw9ge#DP<8jpP)n#)G1Uz(9DowIR&ysE
zX{a3c3Me>PeG3v-4a!Ueu_ty8#`czW8JMaQ9(|8nDJv4jM}?LaOg#nx@?05ZAS=QJ
zj6=G0Mdls(5s8zNAXjzp^p_j)R2LzHH&lf)se76SMX++ZjxKBm@iiBZm(~P^-{q82
zwGb8NCayCSHcr&R>8YsZnq~ns)r5s-&p_UE)4bx{#bkn9kH0WpEZ6N($O_V&&|QK|
zY&kiEP^1LT<05oug7%}(<x!+PQ}=MEXKoQ;cQ!U1C0wQLgQYbm3mR4q9d+1Ino{fO
zPUb<!9vc@|*gU8_e!|*fOZ*7U-1*8RP%VtdHvuyVoYNF#QQOV1Y$6kRsOtDRPV*Ez
z&9fg^_EN9!Hdm;P@ay}L%92Y_mZhcT^V?hL>$fExY0Za~F`wh|Pulwf5N)t5>*39S
zs3v-G>KNm-*6x$mVz=Q11&0Qio6QUo_oC$X(|6fd9E-xg6rAkff^H$w;TuMwkPN#*
zCmig4$7M_7e+g+0($TPIGl<dF<_^N1&|~H?QC36`bKF;n-s_7k>C4qv=XLOJjdd2x
z3wJ|QluU3KRs?54mXNr_1+ASn>lGAqp??~tv_tiue@Fp5-1qB!YvQmokTpq`x?&0B
zK19)nF<Y`OkYm`+;nF``Q@2WgsoN6!k`fjKpli0Wcs4H?#o<*w$DYj#C?(2@-dl9M
z(&??O(94p1wNu_aZDc>|kO~Xk7D6gj9pW)1uL-Im=Q(oTca1UPaWnK*bm79DCLY;@
zC@Wv=j6om;?jHjwv13ahrMd~CahIRMlxO|0>X$G*MHX^&v!_oGy8uG5>xbC{I4W3W
zBpe@9zrgMARP2g<K^|hG`$_gnPH-<+SQ{yzMk=z%hV?ZbGRD|_wb1zSVV0@c>fNlO
z2y#O5Y7&5{2FV#ALRQJlaEGHbnxMjq7TGG8!YuA$R=g$4ZLCtpH(a(58}x?pg5cej
zRV5)HtRIyml`-(srqxC71E@YEP;Ho<O<9<qQ0^4wpKn6`ldf{!9Ri~AC`Q0o?TKYy
zTD*&KMpR+}%vdh2YS-gxWsUmo3>$soaE#N#n{!<4SwTK)SD$UId9m}@OSz>y>{4+)
zn&ixf_Ar{dsxX8)*$i%{JQ1Px%!N%UQH2cfjYEA)k!9sPXGSI$a7V3Wo2GqfSd*g(
zel)=|$Z1&7X_K7Zd?P$enBFLv2WyF!u&k_76`_bK6ij1c0S2mF6l&|BLE7(#U4~p4
zed6%U?WM?<Jf3at2s3;@rUco2MW%}%-#hCFKPe(qo*dw&@MR5`e{b1ZAJLVYY$N7W
z<?m!tM8}OAFr|9Jl@W{Ui?Y%XqF-~_>`-Q|7H|jRU7uShQ7YyyUT-MoU5dwUT}nBH
z%gY@GxA7)hf3o7<3savXy1=}U;TOpDqZFh)^orT#Wpvy`;SQH!CU5}j*hq!No1rgL
zieQJ!wYQPAusMT0OM403faU5^P|$PfH^|rc4NQ!#{RlwPk%kr<ofL|XJPVYA2B9n+
zTYrbPRKiGJOr;Sj?p-Be;C^od9izwQ)cL#|kU+4!v<GsLS|Q9!e6aHXj-}$)53;(r
zfj!WP?OatqE*K`f`PJCM^5ED<KUMnS>iw^{^y4WN9D<vcES##)8M#TmR(RN`bk;AU
z1Za5a`cB4`_l8ob%+$*FC0wRMv|>*meT_#%_c8Oe>oiVT5TpI?Pa``e#1$b{RZoOd
zQ5|Z1G4w9(Vs!lO8jK_zd!2qb^7oF*&}uDHpZLrTRSm9*!v|-w;d(*P-LJ?UxxjIS
zFA)MbVH>st&L+b##l^pH`8b;5ZSNCn2e8yC=}7atRZoE9@_7`mlXuPLCN@qPx)XP|
zwzTUsMInp!3lyd>7^R6FSUiYF2D+`Z&~Kg#eQ|k*3fJ^jI^!8|vbMNCywDegrqY$4
z(x(f{3@Q+NKfNA%O;K(1C8DFE&d29l@D|12y1)Mhy|RkHg5ibpw(g8CbtmTzZ|p4C
z{ZA&+6{H0Op38HVf4q@>12b`5_Ok?{=~4NhLYT6<h9}&nx+2+mrr@HO+N0yiRQ;A<
z3I1dwT`2!1XkT#5S}ACeQTtMGuT3o8H8B&;sb^Zee?*Jq6c8vXE{*P3X0YJZ@jFL7
z=}{gcPJ+KmQ*--Z)D$&A%D2xn93&&4i9FpfUH*$N_5)#7$8?V)X4S$*;ev)uqoumK
zeMwsGf%T$cv=p`#agm8e9vbsr;J>pkc2t6S5$2e0L|D}BOS9u+4v#K+q~Xd~)P&>m
zg<jw{!gyv_slqPDDTy*dw(wj{vRqF$O)OdS!X_sQmaKnz&ri`Ik|i`dQkP0qbV}my
za4&w4!G%ihbS0-G3N*R*Pz60k;bV#T_zXr2IeoFCoaN5eCiv;2nf)A9JeRYwq-ErG
zCg&tjP*NzieNO;|)&o7sYJRMSIN0db*V43<I@$ba%j{^&2+y&jsXsFjUyIo??B}B6
zqQi7ybm%$J0qzWY;6hy%V;cqh7k>OduR#gzZ~#ets49JJ^(M#N2n(n3<u_x4_!<xF
zZshP^d{KG)gqfJD_}R_Q0r)@voDWQ$=$*p~QXR*KU47kwzacIDU(omv#Q@v!A&k+k
z^8P@*sUt%ap*J%q3qJ?TFDpFoTSjsLEKoZ`j%(N!>s)<0IZ{wC6}Em%6p587^gIa$
zg#?$QIlAmL1HTCk2{YBOE+{sLZ#Xuu3%c3TK$5hdpsP#U8M}|!hN%mitJuRt;VP>=
z5uctb{iYh_v#hnNDs7s+y9qN5Srl^Dd?xz1W+FXSU1hn;P#zV+ab+$Wd4;<%C2YgV
z&Q%hJiJ36bmWR}24`X#|U-Hu+8#1&{dD}9tC^>Eb68TL?6u%T2+OQ*NjdmUslIrLk
z-5X7L^g<tbKGKe1>-|vrxR*$Ydx@~MD2t5ZM}zRR_jv;O{e`6=*E`4s;jeQQm)%$(
zvOnk!HBr^nAsKsyf}ERs0r*A@1|eQBcTe|=MkvZb4CU&|Q#Z6#m((3}ccw2X#Xqn{
zM+)zs!f&lpm`$F<k*ND4YPhRVjHpoGshNLQA+mAoc+6io_Kb((U1Q`N>AY7uhj~s*
zIy1}TS%qp(A@!;y7~aPh5^N&)ADerDNOPK`-AzYYBbpk(9GB0CekamK&#~vo@eJga
zx&7X;`1<bCHgp5V$2ST&;j9kGS+B43pe0ca_o2;$E#R&f_=rNqd{tct6@6p=2<!eA
zBZKtbD7M-lbDwkRCn`YZn)an-+WMH~ROx=^a>9hO6*+^73bG<JcPJNnC-@``W?Klb
zpw7|AxG>NdAZ+O7XaUPf0>ksdFcI0n4LYj!q;AT2GIefP@p-c76?&A9+aF$sTTSYS
z${@5G9%eu;J>LBBI)r;N=Z-3;D3uc!d!8{v)z>)T1lo#J;8T!?q7)8vuZb@7h3VZ8
z^|DEIQ$*e@?NUNFNO}gAF?-?VEP$|oiwz*YY31r;k?IJet70EJx>-E|nt~PIYMewz
zRODc1xq{Qhlv7K{=-nNlqMc%RQ>|w^H()ceO%|lj`NN*l*C6^E#(i5{HlqR#;N^zW
z`7ro=7<_&dd_D?3KMp=W2|hm!K0iD1T)-B!y1roQ5mFSC%X2^CuID+mCyLEHOm{!{
z1XJz94?lp9k3JwDpM3BEaMXtn{m+Mw{Le?9`JcbQ_o3S#K6(^<`Nc#3%SWFDS3bs%
z_+LK7-(Dqe`1oP)?ICW5e0xY9TSafBU8b8j=EtVFB3!67dQxwvDG=PkUrD{=Ab-%_
zaptuP!g%Z;*JWQ0W<O{NE5szRKYpp2YZp=qWr5stdj~Wz<O#U{a_|C-#}q^FW#olb
zm~O6XPtwk8%ksCRDI%+J^JFRoE$j5`w<9eo3va&g*iFmQma0}cD<Nr38ECzMb|Cv6
zt<x+o_3uYoQWvwC?p(1Ye-*PY!lmC!@~eYRN9aE-Jpm(uK6y#~CP((uvt86jbK5mM
zJ0-14u8&s2)C~L`ntl0*gCq;2yNGwmY{C_+9_Jm~_IUe(d`Au2<(-gtyyqaqCVOr_
z%T5X#8g^Ty5X-FqGKTt~(N+`{>KyhIRnio!52EA2FK=bHi^@lSdBq>@a1~FGJl0_@
zcx6$gQ39}sYn0bDLmg`#b*C~hwYp<py6C}!2m1lA$kka%#t4Nlt6>9p#jJ8+Okktn
zrB}pu#a7h}**BwxY(wd`q|>NdA2noug}X9MIbyN17AtJHR9bHpTITTp;yckJ&F?m;
z4+>INbp#%XY>bfQBL5-wY3@~vr+kMC^pGs!w$%9c(OpcGyD2y>L-Fwv<}M1t)CNcL
z8!o+Y{*r^tVgAZq@cL+k<{qz`Ch;FV<jh>^OwJuNLSw_4@F%9vt-L<L4kh5|ui0t&
zmt9rDeZW!eDRL`~3x*y5afrHh6b|@fx1kQl6+2|Csdx%To?Yktb&#xw3btFt6{Jv4
zxMiI(hV}k{C&Lo`{*qN%`6aSL$lu)ZH_}QY!9hNyHtZ@xVSxQR5s(U4^DsEaaLKU{
z%Q0M%CEX@2lrLAP<N%Vvs<z8-xEwmpH$6dXhgAT7n=<+i_k2quva9cw=Tq+)9UaFh
zPV&srsh)$aa&c^Uhienu;TXhk=*WMJ-(&*fILww<?~EE{*DAHlzQ=)1er_GMRjn^|
zPlsYt@-tze?-b#`#_#`q3PiKdhDlPI92Zf*K`L_H@MiiPim1Drd@=tK-ZX-G7r`(6
z*0=uBe`NVfI(*LOEyF~KKZ8daKl>T)+6!ldTsq0n==EBXOtoszz^2#g&+LUaHYX28
u^Lf&>lj!+0Q}ZxLUXU>@(*D}Td$9}C0Aal=Z)#f`A%~~@M=0=c_5T4<hC>$s
--- a/host/tools/configtool/standalone/wxwin/docsystem.cpp
+++ b/host/tools/configtool/standalone/wxwin/docsystem.cpp
@@ -30,7 +30,7 @@
 // Author(s):   julians
 // Contact(s):  julians
 // Date:        2001/04/04
-// Version:     $Id: docsystem.cpp,v 1.18 2001/05/16 16:08:24 julians Exp $
+// Version:     $Id: docsystem.cpp,v 1.19 2001/12/11 15:59:51 julians Exp $
 // Purpose:
 // Description: Various classes for the documentation system
 // Requires:
@@ -84,6 +84,24 @@ ecHtmlIndexer::ecHtmlIndexer(bool useRel
 #else
     m_useRelativeURLs = FALSE;
 #endif
+    m_useOldDocs = TRUE;
+
+    // Initialise some tables
+    AddTutorialDirectory(wxT("arm"), wxT("ARM"));
+    AddTutorialDirectory(wxT("am31-33"), wxT("AM31-33"));
+    AddTutorialDirectory(wxT("i386pc"), wxT("i386 PC"));
+    AddTutorialDirectory(wxT("ppc"), wxT("PowerPC"));
+    AddTutorialDirectory(wxT("sh3"), wxT("SH-3"));
+    AddTutorialDirectory(wxT("sparclite"), wxT("SPARClite"));
+    AddTutorialDirectory(wxT("mips"), wxT("MIPS"));
+    AddTutorialDirectory(wxT("v850"), wxT("V850"));
+
+    AddEntityTranslation(wxT("&#8212;"), wxT("--"));
+    AddEntityTranslation(wxT("&#38;"), wxT("&"));
+    AddEntityTranslation(wxT("&#8220;"), wxT("\""));
+    AddEntityTranslation(wxT("&#8221;"), wxT("\""));
+    AddEntityTranslation(wxT("&#0091;"), wxT("["));
+    AddEntityTranslation(wxT("&#0093;"), wxT("]"));
 }
 
 ecHtmlIndexer::~ecHtmlIndexer()
@@ -148,7 +166,7 @@ bool ecHtmlIndexer::CreateHHCByExamining
     if (parser.ParseFile(htmlFile))
     {
         stream << "<LI> <OBJECT type=\"text/sitemap\"><param name=\"Name\" value=\"";
-        stream << title << wxString("\">");
+        stream << TranslateEntities(title) << wxString("\">");
         
         if (!topURL.IsEmpty())
         {
@@ -280,7 +298,7 @@ bool ecHtmlIndexer::CreateHHCByExamining
     if (parser.ParseFile(htmlFile))
     {
         stream << "<LI> <OBJECT type=\"text/sitemap\"><param name=\"Name\" value=\"";
-        stream << title << wxString("\">");
+        stream << TranslateEntities(title) << wxString("\">");
         
         if (!topURL.IsEmpty())
         {
@@ -297,8 +315,20 @@ bool ecHtmlIndexer::CreateHHCByExamining
             if (tag->GetType() == wxSimpleHtmlTag_Close && tag->NameIs("DL")) level -- ;
             if (tag->GetType() == wxSimpleHtmlTag_Open && tag->NameIs("A") && tag->HasAttribute("HREF") && level > 0)
                 CreateHHCOutputItem(tag, level, indent, pathPrefix, docDir, stream);
-            
-            tag = tag->GetNext();
+
+            // If we get to list of figures/tables/examples, finish
+            if (tag->GetType() == wxSimpleHtmlTag_Text)
+            {
+                if (tag->GetText() == wxT("List of Figures") ||
+                    tag->GetText() == wxT("List of Tables") ||
+                    tag->GetText() == wxT("List of Examples"))
+                {
+                    tag = NULL;
+                }
+            }
+
+            if (tag)
+                tag = tag->GetNext();
         }
 
         // Close any remaining levels
@@ -327,7 +357,7 @@ bool ecHtmlIndexer::CreateHHCItem(const 
     for (i = 0; i < indent*2; i++) stream << " ";
     
     stream << "<LI> <OBJECT type=\"text/sitemap\"><param name=\"Name\" value=\"";
-    stream << title << "\"><param name=\"Local\" value=\"";
+    stream << TranslateEntities(title) << "\"><param name=\"Local\" value=\"";
     stream << topURL1 << "\"></OBJECT>\n";
 
     return TRUE;
@@ -365,7 +395,7 @@ void ecHtmlIndexer::CreateHHCOutputItem(
             for (i = 0; i < indent*2; i++) stream << " ";
 
             stream << "<LI> <OBJECT type=\"text/sitemap\"><param name=\"Name\" value=\"";
-            stream << text << "\"><param name=\"Local\" value=\"";
+            stream << TranslateEntities(text) << "\"><param name=\"Local\" value=\"";
             stream << url1 << "\"></OBJECT>";
         }
         stream << "\n";
@@ -382,7 +412,7 @@ void ecHtmlIndexer::CreateHHCOutputItem(
     for (i = 0; i < indent*2; i++) stream << " ";
 
     stream << "<LI> <OBJECT type=\"text/sitemap\"><param name=\"Name\" value=\"";
-    stream << text << "\"><param name=\"Local\" value=\"";
+    stream << TranslateEntities(text) << "\"><param name=\"Local\" value=\"";
     stream << url1 << "\"></OBJECT>\n";
 }
 
@@ -408,7 +438,7 @@ bool ecHtmlIndexer::CreateHHCStartSectio
         url1 = docDir + sep + url1;
 
     stream << "<LI> <OBJECT type=\"text/sitemap\"><param name=\"Name\" value=\"";
-    stream << title << wxString("\">");
+    stream << TranslateEntities(title) << wxString("\">");
     
     if (!topURL.IsEmpty())
     {
@@ -460,13 +490,16 @@ Title=eCos\n";
 
     stream << 
 "[WINDOWS]\n\
-mainwin=\"eCos Documentation\",\"eCos.hhc\",\"eCos.hhk\",,\"index.html\",\"http://sources.redhat.com/ecos/\",\"Net Release\",\"http://www.redhat.com/products/ecos/\",\"eCos Product\",0x40060420,,0xc287e,[0,0,762,400],,,,,,,0\n\
+mainwin=\"eCos Documentation\",\"eCos.hhc\",,,\"index.html\",\"http://sources.redhat.com/ecos/\",\"Net Release\",\"http://www.redhat.com/products/ecos/\",\"eCos Product\",0x40060420,,0xc287e,[0,0,762,400],,,,,,,0\n\
 \n\
 [FILES]\n\
 index.html\n\
 \n\
 [INFOTYPES]\n" ;
 
+    // When we have the ability to generate a hhk, replace above line with:
+    // mainwin=\"eCos Documentation\",\"eCos.hhc\",\"eCos.hhk\",,\"index.html\",\"http://sources.redhat.com/ecos/\",\"Net Release\",\"http://www.redhat.com/products/ecos/\",\"eCos Product\",0x40060420,,0xc287e,[0,0,762,400],,,,,,,0\n\
+
     return TRUE;
 
 }
@@ -483,7 +516,7 @@ bool ecHtmlIndexer::CreateHHCPackagesSec
     // and then generate the multiple files. Otherwise we'll be repeating the same "Getting Started with eCos"
     // line. I.e. it'll only look right if we only have one tutorial.
     stream << "<LI> <OBJECT type=\"text/sitemap\"><param name=\"Name\" value=\"";
-    stream << title << wxString("\">");
+    stream << TranslateEntities(title) << wxString("\">");
     
     if (!topURL.IsEmpty())
     {
@@ -515,7 +548,7 @@ bool ecHtmlIndexer::CreateHHCPackagesSec
                 url = htmlPath + wxString(wxFILE_SEP_PATH) + Redirect(htmlPath, url);
 
                 stream << "<LI> <OBJECT type=\"text/sitemap\"><param name=\"Name\" value=\"";
-                stream << strPackageName << wxString("\">");
+                stream << TranslateEntities(strPackageName) << wxString("\">");
                 
                 if (!url.IsEmpty())
                 {
@@ -815,13 +848,40 @@ void ecHtmlIndexer::ClearItems()
     m_indexItems.Clear();
 }
 
+// Set m_useOldDocs to TRUE if we find old-style docs
+bool ecHtmlIndexer::CheckDocEra(const wxString& reposDir)
+{
+    // We look for tutorials/arm/ecos-tutorial.1.html to see if it's old-style
+    wxString sep(wxFILE_SEP_PATH);
+    
+    wxString docDir(reposDir + sep + wxString(wxT("doc"))) ;
+    
+    // The CVS repository has an HTML subdirectory, but the
+    // packaged version doesn't
+    if (wxDirExists(docDir + sep + wxT("html")))
+        docDir = docDir + sep + wxString(wxT("html"));
+    
+    wxString armTutorial = docDir + sep + wxString(wxT("tutorials")) + sep +
+        wxString(wxT("arm")) + sep + wxString(wxT("ecos-tutorial.1.html")) ;
+
+    m_useOldDocs = wxFileExists(armTutorial);
+    return m_useOldDocs;
+}
+
+
 // Top-level function: generate appropriate index files
 // and place them either in the install directory or if that is read-only,
 // in the user's .eCos directory.
 // Returns TRUE and the created project file if successful
 bool ecHtmlIndexer::IndexDocs(const wxString& reposDir, wxString& projectFile, bool force)
 {
-    AddStartSection(wxT("Getting Started with eCos"), wxT(""));
+    CheckDocEra(reposDir);
+
+    if (UseOldDocs())
+    {
+        // Old-style docs, where HTML is mostly generated from PageMaker
+
+        AddStartSection(wxT("Getting Started with eCos"), wxT(""));
         AddIndexByClass(wxT("AM31-33"), wxT("tutorials/am31-33/ecos-tutorial.1.html"), wxT("tutorials/am31-33/ecos-tutorial.2.html"));
         AddIndexByClass(wxT("ARM"), wxT("tutorials/arm/ecos-tutorial.1.html"), wxT("/tutorials/arm/ecos-tutorial.2.html"));
         AddIndexByClass(wxT("i386 PC"), wxT("tutorials/i386pc/ecos-tutorial.1.html"), wxT("tutorials/i386pc/ecos-tutorial.2.html"));
@@ -830,40 +890,149 @@ bool ecHtmlIndexer::IndexDocs(const wxSt
         AddIndexByClass(wxT("SPARClite"), wxT("tutorials/sparclite/ecos-tutorial.1.html"), wxT("tutorials/sparclite/ecos-tutorial.2.html"));
         AddIndexByClass(wxT("MIPS"), wxT("tutorials/mips/ecos-tutorial.1.html"), wxT("tutorials/mips/ecos-tutorial.2.html"));
         AddIndexByClass(wxT("V850"), wxT("tutorials/v850/ecos-tutorial.1.html"), wxT("tutorials/v850/ecos-tutorial.2.html"));
-    AddEndSection();
-
-    AddIndexByClass(wxT("eCos User's Guide"), wxT("guides/user-guides.1.html"), wxT("guides/user-guides.2.html"));
-    
-    // We don't yet know how to parse the RedBoot guide
-    AddIndexItem(wxT("RedBoot User's Guide"), wxT("redboot/redboot.html"));
-
-    AddIndexByClass(wxT("Linux Configuration Tool Guide"), wxGetApp().GetFullAppPath(wxT("manual/user-guides.4.html")), wxGetApp().GetFullAppPath(wxT("manual/user-guides.2.html")));
-    
-    AddIndexByList(wxT("eCos Component Writer's Guide"), wxT("cdl/cdl-guide.html"), wxT("cdl/cdl-guide.html"));
-    
-    AddIndexByClass(wxT("eCos Reference Manual"), wxT("ref/ecos-ref.1.html"), wxT("ref/ecos-ref.2.html"));
-    
-    AddIndexByClass(wxT("eCos-EL/IX Compatibility Guide"), wxT("ecos-elix/ecos-elix.html"), wxT("ecos-elix/ecos-elix.1.html"), 1);
-    
-    AddStartSection(wxT("GNUPro Toolkit Reference Manual"));
+        AddEndSection();
+        
+        AddIndexByClass(wxT("eCos User's Guide"), wxT("guides/user-guides.1.html"), wxT("guides/user-guides.2.html"));
+        
+        AddIndexByList(wxT("RedBoot User's Guide"), wxT("redboot/redboot.html"), wxT("redboot/redboot.html"));
+        
+        AddIndexByClass(wxT("Linux Configuration Tool Guide"), wxGetApp().GetFullAppPath(wxT("manual/user-guides.4.html")), wxGetApp().GetFullAppPath(wxT("manual/user-guides.2.html")));
+        
+        AddIndexByList(wxT("eCos Component Writer's Guide"), wxT("cdl/cdl-guide.html"), wxT("cdl/cdl-guide.html"));
+        
+        AddIndexByClass(wxT("eCos Reference Manual"), wxT("ref/ecos-ref.1.html"), wxT("ref/ecos-ref.2.html"));
+        
+        AddIndexByClass(wxT("eCos-EL/IX Compatibility Guide"), wxT("ecos-elix/ecos-elix.html"), wxT("ecos-elix/ecos-elix.1.html"), 1);
+        
+        AddStartSection(wxT("GNUPro Toolkit Reference Manual"));
         // Start at indent 1 to avoid a spurious level
-        AddIndexByClass(wxT("ARM"), wxT("ref/gnupro-ref/arm/ARM_COMBO_front.html"), wxT("ref/gnupro-ref/ARM_COMBOTOC.html"), 1);
+        AddIndexByClass(wxT("ARM"), wxT("ref/gnupro-ref/arm/ARM_COMBO_front.html"), wxT("ref/gnupro-ref/arm/ARM_COMBOTOC.html"), 1);
         AddIndexByClass(wxT("Fujitsu SPARClite"), wxT("ref/gnupro-ref/sparclite/index.html"), wxT("ref/gnupro-ref/sparclite/index.html"));
-        AddIndexByClass(wxT("Matsushita MN10300"), wxT("ref/gnupro-ref/mn10300/am33_front.html"), wxT("ref/gnupro-ref/mn10300/am33toc.html"));
+        AddIndexByClass(wxT("Matsushita MN10300"), wxT("ref/gnupro-ref/mn10300/am33_front.html"), wxT("ref/gnupro-ref/mn10300/am33toc.html"), 1);
         AddIndexByClass(wxT("PowerPC"), wxT("ref/gnupro-ref/powerpc/index.html"), wxT("ref/gnupro-ref/powerpc/index.html"));
         AddIndexByClass(wxT("Toshiba MIPS TX39"), wxT("/gnupro-ref/tx39/index.html"), wxT("/gnupro-ref/tx39/index.html"));
-
+        
         // Don't parse HTML, just add this item, if the page exists.
         // Presumably the HTML can't be parsed for some reason.
         AddIndexItem(wxT("Toshiba MIPS TX49"), wxT("ref/gnupro-ref/tx49/tx49_ref.html"));
+        
+        AddIndexByClass(wxT("Hitachi SuperH"), wxT("ref/gnupro-ref/sh/SH_front.html"), wxT("ref/gnupro-ref/sh/SHTOC.html"), 1);
+        
+        AddIndexItem(wxT("NEC V850"), wxT("ref/gnupro-ref/v850/v850_ref_3.html"));
+        AddIndexByClass(wxT("NEC VR4300"), wxT("ref/gnupro-ref/vr4300/Vr43REF_front.html"), wxT("ref/gnupro-ref/vr4300/Vr43REFTOC.html"), 1);
+        AddEndSection();
+    }
+    else
+    {
+        // NEW-STYLE DOCUMENTATION (HTML is generated from SGML)
 
-        AddIndexByClass(wxT("Hitachi SuperH"), wxT("ref/gnupro-ref/sh/SH_front.html"), wxT("ref/gnupro-ref/sh/SHTOC.html"));
+        // Get a list of all tutorials
+
+        wxArrayString tutorials;
+
+        wxString sep(wxFILE_SEP_PATH);
+        
+        wxString docDir(reposDir + sep + wxString(wxT("doc"))) ;
+        
+        // The CVS repository has an HTML subdirectory, but the
+        // packaged version doesn't
+        if (wxDirExists(docDir + sep + wxT("html")))
+            docDir = docDir + sep + wxString(wxT("html"));
+
+        docDir += sep ;
+        docDir += wxString(wxT("tutorials"));
 
+        wxLogNull log;
+        wxDir dir(docDir);
+        
+        if (dir.IsOpened())
+        {
+            wxString filename;
+            bool cont = dir.GetFirst(& filename, wxT("*"), wxDIR_DIRS);
+            while (cont)
+            {
+                if (filename != wxT(".") && filename != wxT(".."))
+                    tutorials.Add(filename);
+                
+                cont = dir.GetNext(& filename);
+            }
+        }
+
+        AddStartSection(wxT("Getting Started with eCos"), wxT(""));
+        size_t i;
+        for (i = 0; i < tutorials.GetCount(); i++)
+        {
+            wxString tutorial(tutorials[i]);
+            wxString tutorialRelativePath = wxT("tutorials/") + tutorial + wxT("/ecos-tutorial.html");
+
+            // Use a more friendly name than just the directory if it's available
+            AddIndexByList(TranslateTutorialDirectory(tutorial), tutorialRelativePath, tutorialRelativePath);
+        }
+        AddEndSection();
+
+        AddIndexByList(wxT("eCos User's Guide"), wxT("guides/ecos-user-guide.html"), wxT("guides/ecos-user-guide.html"));
+        AddIndexByList(wxT("RedBoot User's Guide"), wxT("redboot/redboot.html"), wxT("redboot/redboot.html"));
+        AddIndexByList(wxT("eCos Component Writer's Guide"), wxT("cdl/cdl-guide.html"), wxT("cdl/cdl-guide.html"));       
+        AddIndexByList(wxT("eCos Reference Manual"), wxT("ref/ecos-reference-manual.html"), wxT("ref/ecos-reference-manual.html"));
+        AddIndexByList(wxT("eCos-EL/IX Compatibility Guide"), wxT("ecos-elix/elix-compatibility.html"), wxT("ecos-elix/elix-compatibility.html"));
+
+        //// TOOLCHAIN REFERENCE MANUALS
+        AddStartSection(wxT("GNUPro Toolkit Reference Manual"));
+        // Start at indent 1 to avoid a spurious level
+        AddIndexByClass(wxT("ARM"), wxT("ref/gnupro-ref/arm/ARM_COMBO_front.html"), wxT("ref/gnupro-ref/arm/ARM_COMBOTOC.html"), 1);
+        AddIndexByClass(wxT("Fujitsu SPARClite"), wxT("ref/gnupro-ref/sparclite/index.html"), wxT("ref/gnupro-ref/sparclite/index.html"), 1);
+        AddIndexByClass(wxT("Matsushita MN10300"), wxT("ref/gnupro-ref/mn10300/am33_front.html"), wxT("ref/gnupro-ref/mn10300/am33toc.html"), 1);
+        AddIndexByClass(wxT("PowerPC"), wxT("ref/gnupro-ref/powerpc/index.html"), wxT("ref/gnupro-ref/powerpc/index.html"));
+        AddIndexByClass(wxT("Toshiba MIPS TX39"), wxT("/gnupro-ref/tx39/index.html"), wxT("/gnupro-ref/tx39/index.html"));
+        
+        // Don't parse HTML, just add this item, if the page exists.
+        // Presumably the HTML can't be parsed for some reason.
+        AddIndexItem(wxT("Toshiba MIPS TX49"), wxT("ref/gnupro-ref/tx49/tx49_ref.html"));
+        
+        AddIndexByClass(wxT("Hitachi SuperH"), wxT("ref/gnupro-ref/sh/SH_front.html"), wxT("ref/gnupro-ref/sh/SHTOC.html"), 1);
+        
         AddIndexItem(wxT("NEC V850"), wxT("ref/gnupro-ref/v850/v850_ref_3.html"));
-        AddIndexByClass(wxT("NEC VR4300"), wxT("ref/gnupro-ref/vr4300/Vr43REF_front.html"), wxT("ref/gnupro-ref/vr4300/Vr43REFTOC.html"));
-    AddEndSection();
+        AddIndexByClass(wxT("NEC VR4300"), wxT("ref/gnupro-ref/vr4300/Vr43REF_front.html"), wxT("ref/gnupro-ref/vr4300/Vr43REFTOC.html"), 1);
+        AddEndSection();
+    }
 
     DoIndexDocs(reposDir, projectFile, force);
     
     return TRUE;
 }
+
+// Some things should be translated in the contents
+void ecHtmlIndexer::AddEntityTranslation(const wxString& entity, const wxString& translation)
+{
+    m_entityTableNames.Add(entity);
+    m_entityTableValues.Add(translation);
+}
+
+// Apply all translations to this string
+wxString ecHtmlIndexer::TranslateEntities(const wxString& toTranslate)
+{
+    wxString result(toTranslate);
+    size_t i;
+    for (i = 0; i < m_entityTableNames.GetCount(); i++)
+    {
+        result.Replace(m_entityTableNames[i], m_entityTableValues[i]);
+    }
+    return result;
+}
+
+// Mapping from directory to user-viewable name
+void ecHtmlIndexer::AddTutorialDirectory(const wxString& dirName, const wxString& title)
+{
+    m_tutorialTableNames.Add(dirName);
+    m_tutorialTableValues.Add(title);
+}
+
+wxString ecHtmlIndexer::TranslateTutorialDirectory(const wxString& dirName)
+{
+    int i = m_tutorialTableNames.Index(dirName);
+    if (i >= 0)
+        return m_tutorialTableValues[i];
+    else
+        return dirName;
+}
+
--- a/host/tools/configtool/standalone/wxwin/docsystem.h
+++ b/host/tools/configtool/standalone/wxwin/docsystem.h
@@ -116,14 +116,36 @@ public:
     void AddEndSection();
     void ClearItems();
 
+//// Symbol tables
+
+    // Some things should be translated in the contents
+    void AddEntityTranslation(const wxString& entity, const wxString& translation);
+    // Apply all translations to this string
+    wxString TranslateEntities(const wxString& toTranslate);
+
+    // Mapping from directory to user-viewable name
+    void AddTutorialDirectory(const wxString& dirName, const wxString& title);
+    wxString TranslateTutorialDirectory(const wxString& dirName);
+
 //// Accessors
     wxList& GetIndexItems() { return m_indexItems; }
     bool UseRelativeURLs() const { return m_useRelativeURLs; }
+    bool UseOldDocs() const { return m_useOldDocs; }
+
+//// Helpers
+
+    // Set m_useOldDocs to TRUE if we find old-style docs
+    bool CheckDocEra(const wxString& reposDir) ;
 
 private:
     // List of ecIndexItems
     wxList  m_indexItems;
     bool    m_useRelativeURLs;
+    bool    m_useOldDocs; // if TRUE, we have the old-style docs generated by FrameMaker
+    wxArrayString m_entityTableNames; // Translations for awkward symbols not processed by wxHTML or MS HTML Help such as &#8212; (--)
+    wxArrayString m_entityTableValues; // values for the above
+    wxArrayString m_tutorialTableNames; // Directory -> title mapping e.g. arm -> ARM, sparclite -> Fujitsu SPARClite
+    wxArrayString m_tutorialTableValues;
 };
 
 class ecIndexItem: public wxObject
--- a/host/tools/configtool/standalone/wxwin/packagesdlg.cpp
+++ b/host/tools/configtool/standalone/wxwin/packagesdlg.cpp
@@ -30,7 +30,7 @@
 // Author(s):   julians
 // Contact(s):  julians
 // Date:        2000/09/28
-// Version:     $Id: packagesdlg.cpp,v 1.3 2001/06/27 12:48:18 julians Exp $
+// Version:     $Id: packagesdlg.cpp,v 1.9 2001/12/14 17:34:03 julians Exp $
 // Purpose:
 // Description: Implementation file for ecPackagesDialog
 // Requires:
@@ -63,6 +63,7 @@
 
 #include "wx/cshelp.h"
 #include "wx/valgen.h"
+#include "wx/tokenzr.h"
 
 #include "configtool.h"
 #include "packagesdlg.h"
@@ -74,12 +75,17 @@ BEGIN_EVENT_TABLE(ecPackagesDialog, ecDi
     EVT_BUTTON(wxID_CANCEL, ecPackagesDialog::OnCancel)
     EVT_BUTTON(ecID_PACKAGES_DIALOG_ADD, ecPackagesDialog::OnAdd)
     EVT_BUTTON(ecID_PACKAGES_DIALOG_REMOVE, ecPackagesDialog::OnRemove)
-	EVT_LISTBOX_DCLICK(ecID_PACKAGES_DIALOG_AVAILABLE_LIST, ecPackagesDialog::OnDblClickListBox1)
-	EVT_LISTBOX_DCLICK(ecID_PACKAGES_DIALOG_USE_LIST, ecPackagesDialog::OnDblClickListBox2)
-	EVT_LISTBOX(ecID_PACKAGES_DIALOG_AVAILABLE_LIST, ecPackagesDialog::OnClickListBox1)
-	EVT_LISTBOX(ecID_PACKAGES_DIALOG_USE_LIST, ecPackagesDialog::OnClickListBox2)
+    EVT_LISTBOX_DCLICK(ecID_PACKAGES_DIALOG_AVAILABLE_LIST, ecPackagesDialog::OnDblClickListBox1)
+    EVT_LISTBOX_DCLICK(ecID_PACKAGES_DIALOG_USE_LIST, ecPackagesDialog::OnDblClickListBox2)
+    EVT_LISTBOX(ecID_PACKAGES_DIALOG_AVAILABLE_LIST, ecPackagesDialog::OnClickListBox1)
+    EVT_LISTBOX(ecID_PACKAGES_DIALOG_USE_LIST, ecPackagesDialog::OnClickListBox2)
     EVT_LISTBOX(ecID_PACKAGES_DIALOG_VERSION, ecPackagesDialog::OnSelectVersion)
     EVT_INIT_DIALOG(ecPackagesDialog::OnInitDialog)
+    EVT_BUTTON(ecID_PACKAGES_DIALOG_CLEAR, ecPackagesDialog::OnClearKeywords)
+    EVT_CHECKBOX(ecID_PACKAGES_DIALOG_OMIT_HARDWARE, ecPackagesDialog::OnClickOmitHardwarePackages)
+    EVT_CHECKBOX(ecID_PACKAGES_DIALOG_EXACT_MATCH, ecPackagesDialog::OnClickExactMatch)
+    EVT_TEXT(ecID_PACKAGES_DIALOG_KEYWORDS, ecPackagesDialog::OnUpdateKeywordText)
+    EVT_IDLE(ecPackagesDialog::OnIdle)
 END_EVENT_TABLE()
 
 // ----------------------------------------------------------------------------
@@ -87,160 +93,207 @@ END_EVENT_TABLE()
 // ----------------------------------------------------------------------------
 
 // Frame constructor
-ecPackagesDialog::ecPackagesDialog(wxWindow* parent)
+ecPackagesDialog::ecPackagesDialog(wxWindow* parent):
+m_timer(this)
 {
     m_bHardwarePackageSelected = FALSE;
-
+    m_keywords = wxEmptyString;
+    m_updateLists = FALSE;
+    m_updateInterval = 600; // Milliseconds
+    wxStartTimer();
+    
     SetExtraStyle(wxDIALOG_EX_CONTEXTHELP);
-
+    
     ecDialog::Create(parent, ecID_PACKAGES_DIALOG, _("Packages"),
         wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER);
-
+    
     CreateControls(this);
-
+    
+    m_timer.Start(200);
+    
     Centre(wxBOTH);
 }
 
 ecPackagesDialog::~ecPackagesDialog()
 {
+    m_timer.Stop();
 }
 
 // TODO: implement wxLB_SORT style in wxGTK.
 void ecPackagesDialog::CreateControls(wxWindow* parent)
 {
     wxSizer *item0 = new wxBoxSizer( wxVERTICAL );
-
+    
     wxSizer *item1 = new wxBoxSizer( wxHORIZONTAL );
-
+    
     wxSizer *item2 = new wxBoxSizer( wxVERTICAL );
-
+    
     wxStaticText *item3 = new wxStaticText( parent, wxID_STATIC, _("Available &packages:"), wxDefaultPosition, wxDefaultSize, 0 );
     item2->Add( item3, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
-
+    
     wxString *strs4 = (wxString*) NULL;
-    wxListBox *item4 = new wxListBox( parent, ecID_PACKAGES_DIALOG_AVAILABLE_LIST, wxDefaultPosition, wxSize(180,190), 0, strs4, wxLB_SORT );
+    wxListBox *item4 = new wxListBox( parent, ecID_PACKAGES_DIALOG_AVAILABLE_LIST, wxDefaultPosition, wxSize(230,190), 0, strs4, wxLB_SORT|wxLB_HSCROLL );
     item2->Add( item4, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 );
-
+    
     item1->Add( item2, 1, wxGROW|wxALIGN_CENTER_HORIZONTAL|wxALL, 0 );
-
+    
     wxSizer *item5 = new wxBoxSizer( wxVERTICAL );
-
+    
     wxButton *item6 = new wxButton( parent, ecID_PACKAGES_DIALOG_ADD, _("&Add >>"), wxDefaultPosition, wxDefaultSize, 0 );
     item5->Add( item6, 0, wxALIGN_CENTRE|wxALL, 5 );
-
+    
     wxButton *item7 = new wxButton( parent, ecID_PACKAGES_DIALOG_REMOVE, _("<< &Remove"), wxDefaultPosition, wxDefaultSize, 0 );
     item5->Add( item7, 0, wxALIGN_CENTRE|wxALL, 5 );
-
+    
     item1->Add( item5, 0, wxALIGN_CENTRE|wxALL, 0 );
-
+    
     wxSizer *item8 = new wxBoxSizer( wxVERTICAL );
-
+    
     wxStaticText *item9 = new wxStaticText( parent, wxID_STATIC, _("&Use these packages:"), wxDefaultPosition, wxDefaultSize, 0 );
     item8->Add( item9, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
-
+    
     wxString *strs10 = (wxString*) NULL;
-    wxListBox *item10 = new wxListBox( parent, ecID_PACKAGES_DIALOG_USE_LIST, wxDefaultPosition, wxSize(180,190), 0, strs10, wxLB_SORT );
+    wxListBox *item10 = new wxListBox( parent, ecID_PACKAGES_DIALOG_USE_LIST, wxDefaultPosition, wxSize(230,190), 0, strs10, wxLB_SORT|wxLB_HSCROLL );
     item8->Add( item10, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 );
-
+    
     item1->Add( item8, 1, wxGROW|wxALIGN_CENTER_HORIZONTAL|wxALL, 0 );
-
+    
     item0->Add( item1, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
-
+    
     wxStaticText *item11 = new wxStaticText( parent, wxID_STATIC, _("&Version:"), wxDefaultPosition, wxDefaultSize, 0 );
     item0->Add( item11, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 10 );
-
+    
     wxString *strs12 = (wxString*) NULL;
     wxChoice *item12 = new wxChoice( parent, ecID_PACKAGES_DIALOG_VERSION, wxDefaultPosition, wxSize(100,-1), 0, strs12, 0 );
     item0->Add( item12, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 10 );
-
-    wxTextCtrl *item13 = new wxTextCtrl( parent, ecID_PACKAGES_DIALOG_DESCRIPTION, _(""), wxDefaultPosition, wxSize(80,70), wxTE_MULTILINE );
+    
+    wxTextCtrl *item13 = new wxTextCtrl( parent, ecID_PACKAGES_DIALOG_DESCRIPTION, _(""), wxDefaultPosition, wxSize(80,110), wxTE_MULTILINE );
     item0->Add( item13, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 10 );
-
-    wxSizer *item14 = new wxBoxSizer( wxHORIZONTAL );
-
-    wxButton *item15 = new wxButton( parent, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 );
-    item15->SetDefault();
-    item14->Add( item15, 0, wxALIGN_CENTRE|wxALL, 5 );
-
-    wxButton *item16 = new wxButton( parent, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
-    item14->Add( item16, 0, wxALIGN_CENTRE|wxALL, 5 );
-
-    item0->Add( item14, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 );
-
+    
+    wxStaticText *item14 = new wxStaticText( parent, wxID_STATIC, _("&Keywords:"), wxDefaultPosition, wxDefaultSize, 0 );
+    item0->Add( item14, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 10 );
+    
+    wxSizer *item15 = new wxBoxSizer( wxHORIZONTAL );
+    
+    wxTextCtrl *item16 = new wxTextCtrl( parent, ecID_PACKAGES_DIALOG_KEYWORDS, _(""), wxDefaultPosition, wxSize(80,-1), 0 );
+    item15->Add( item16, 1, wxALIGN_CENTRE|wxALL, 5 );
+    
+    wxButton *item17 = new wxButton( parent, ecID_PACKAGES_DIALOG_CLEAR, _("C&lear"), wxDefaultPosition, wxDefaultSize, 0 );
+    item15->Add( item17, 0, wxALIGN_CENTRE|wxALL, 5 );
+    
+    item0->Add( item15, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
+    
+    wxSizer *item18 = new wxBoxSizer( wxHORIZONTAL );
+    
+    wxCheckBox *item19 = new wxCheckBox( parent, ecID_PACKAGES_DIALOG_OMIT_HARDWARE, _("&Omit hardware packages"), wxDefaultPosition, wxDefaultSize, 0 );
+    item18->Add( item19, 0, wxALIGN_CENTRE|wxALL, 5 );
+    
+    wxCheckBox *item20 = new wxCheckBox( parent, ecID_PACKAGES_DIALOG_EXACT_MATCH, _("&Match exactly"), wxDefaultPosition, wxDefaultSize, 0 );
+    item18->Add( item20, 0, wxALIGN_CENTRE|wxALL, 5 );
+    
+    item18->Add( 20, 20, 1, wxALIGN_CENTRE|wxALL, 5 );
+    
+    wxButton *item21 = new wxButton( parent, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 );
+    item21->SetDefault();
+    item18->Add( item21, 0, wxALIGN_CENTRE|wxALL, 5 );
+    
+    wxButton *item22 = new wxButton( parent, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
+    item18->Add( item22, 0, wxALIGN_CENTRE|wxALL, 5 );
+    
+    item0->Add( item18, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 );
+    
 #if 0
     wxSizer *item0 = new wxBoxSizer( wxVERTICAL );
-
+    
     wxSizer *item1 = new wxBoxSizer( wxHORIZONTAL );
-
+    
     wxSizer *item2 = new wxBoxSizer( wxVERTICAL );
-
-    wxStaticText *item3 = new wxStaticText( parent, wxID_STATIC, "Available &packages:", wxDefaultPosition, wxDefaultSize, 0 );
+    
+    wxStaticText *item3 = new wxStaticText( parent, wxID_STATIC, _("Available &packages:"), wxDefaultPosition, wxDefaultSize, 0 );
     item2->Add( item3, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
-
-    wxListBox *item4 = new wxListBox( parent, ecID_PACKAGES_DIALOG_AVAILABLE_LIST, wxDefaultPosition, wxSize(180,190), 0, NULL, wxLB_EXTENDED|wxLB_HSCROLL|wxLB_SORT );
-    item2->Add( item4, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT|wxBOTTOM, 5 );
-
-    item1->Add( item2, 0, wxALIGN_CENTRE|wxALL, 0 );
-
+    
+    wxString *strs4 = (wxString*) NULL;
+    wxListBox *item4 = new wxListBox( parent, ecID_PACKAGES_DIALOG_AVAILABLE_LIST, wxDefaultPosition, wxSize(230,190), 0, strs4, wxLB_SORT|wxLB_HSCROLL );
+    item2->Add( item4, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 );
+    
+    item1->Add( item2, 1, wxGROW|wxALIGN_CENTER_HORIZONTAL|wxALL, 0 );
+    
     wxSizer *item5 = new wxBoxSizer( wxVERTICAL );
-
-    wxButton *item6 = new wxButton( parent, ecID_PACKAGES_DIALOG_ADD, "&Add >>", wxDefaultPosition, wxDefaultSize, 0 );
+    
+    wxButton *item6 = new wxButton( parent, ecID_PACKAGES_DIALOG_ADD, _("&Add >>"), wxDefaultPosition, wxDefaultSize, 0 );
     item5->Add( item6, 0, wxALIGN_CENTRE|wxALL, 5 );
-
-    wxButton *item7 = new wxButton( parent, ecID_PACKAGES_DIALOG_REMOVE, "<< &Remove", wxDefaultPosition, wxDefaultSize, 0 );
+    
+    wxButton *item7 = new wxButton( parent, ecID_PACKAGES_DIALOG_REMOVE, _("<< &Remove"), wxDefaultPosition, wxDefaultSize, 0 );
     item5->Add( item7, 0, wxALIGN_CENTRE|wxALL, 5 );
-
+    
     item1->Add( item5, 0, wxALIGN_CENTRE|wxALL, 0 );
-
+    
     wxSizer *item8 = new wxBoxSizer( wxVERTICAL );
-
-    wxStaticText *item9 = new wxStaticText( parent, wxID_STATIC, "&Use these packages:", wxDefaultPosition, wxDefaultSize, 0 );
+    
+    wxStaticText *item9 = new wxStaticText( parent, wxID_STATIC, _("&Use these packages:"), wxDefaultPosition, wxDefaultSize, 0 );
     item8->Add( item9, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
-
-    wxListBox *item10 = new wxListBox( parent, ecID_PACKAGES_DIALOG_USE_LIST, wxDefaultPosition, wxSize(180,190), 0, NULL, wxLB_EXTENDED|wxLB_HSCROLL|wxLB_SORT );
-    item8->Add( item10, 0, wxALIGN_CENTRE|wxLEFT|wxRIGHT|wxBOTTOM, 5 );
-
-    item1->Add( item8, 0, wxALIGN_CENTRE|wxALL, 0 );
-
-    item0->Add( item1, 0, wxALIGN_CENTRE|wxALL, 5 );
-
-    wxStaticText *item11 = new wxStaticText( parent, wxID_STATIC, "&Version:", wxDefaultPosition, wxDefaultSize, 0 );
+    
+    wxString *strs10 = (wxString*) NULL;
+    wxListBox *item10 = new wxListBox( parent, ecID_PACKAGES_DIALOG_USE_LIST, wxDefaultPosition, wxSize(230,190), 0, strs10, wxLB_SORT|wxLB_HSCROLL );
+    item8->Add( item10, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 );
+    
+    item1->Add( item8, 1, wxGROW|wxALIGN_CENTER_HORIZONTAL|wxALL, 0 );
+    
+    item0->Add( item1, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
+    
+    wxStaticText *item11 = new wxStaticText( parent, wxID_STATIC, _("&Version:"), wxDefaultPosition, wxDefaultSize, 0 );
     item0->Add( item11, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 10 );
-
-    wxChoice *item12 = new wxChoice( parent, ecID_PACKAGES_DIALOG_VERSION, wxDefaultPosition, wxSize(100,-1), 0, NULL, 0 );
+    
+    wxString *strs12 = (wxString*) NULL;
+    wxChoice *item12 = new wxChoice( parent, ecID_PACKAGES_DIALOG_VERSION, wxDefaultPosition, wxSize(100,-1), 0, strs12, 0 );
     item0->Add( item12, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 10 );
-
-    wxTextCtrl *item13 = new wxTextCtrl( parent, ecID_PACKAGES_DIALOG_DESCRIPTION, "", wxDefaultPosition, wxSize(80,70), wxTE_MULTILINE );
-    item0->Add( item13, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 10 );
-
-    wxSizer *item14 = new wxBoxSizer( wxHORIZONTAL );
-
-    wxButton *item15 = new wxButton( parent, wxID_OK, "&OK", wxDefaultPosition, wxDefaultSize, 0 );
-    item15->SetDefault();
-    item14->Add( item15, 0, wxALIGN_CENTRE|wxALL, 5 );
-
-    wxButton *item16 = new wxButton( parent, wxID_CANCEL, "&Cancel", wxDefaultPosition, wxDefaultSize, 0 );
-    item14->Add( item16, 0, wxALIGN_CENTRE|wxALL, 5 );
-
+    
+    wxTextCtrl *item13 = new wxTextCtrl( parent, ecID_PACKAGES_DIALOG_DESCRIPTION, _(""), wxDefaultPosition, wxSize(80,110), wxTE_MULTILINE );
+    item0->Add( item13, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 10 );
+    
+    wxStaticText *item14 = new wxStaticText( parent, wxID_STATIC, _("&Keywords:"), wxDefaultPosition, wxDefaultSize, 0 );
+    item0->Add( item14, 0, wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 10 );
+    
+    wxSizer *item15 = new wxBoxSizer( wxHORIZONTAL );
+    
+    wxTextCtrl *item16 = new wxTextCtrl( parent, ecID_PACKAGES_DIALOG_KEYWORDS, _(""), wxDefaultPosition, wxSize(80,-1), 0 );
+    item15->Add( item16, 1, wxALIGN_CENTRE|wxALL, 5 );
+    
+    wxButton *item17 = new wxButton( parent, ecID_PACKAGES_DIALOG_CLEAR, _("C&lear"), wxDefaultPosition, wxDefaultSize, 0 );
+    item15->Add( item17, 0, wxALIGN_CENTRE|wxALL, 5 );
+    
+    item0->Add( item15, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT, 5 );
+    
+    wxSizer *item18 = new wxBoxSizer( wxHORIZONTAL );
+    
+    wxCheckBox *item19 = new wxCheckBox( parent, ecID_PACKAGES_DIALOG_OMIT_HARDWARE, _("Omit hardware packages"), wxDefaultPosition, wxDefaultSize, 0 );
+    item18->Add( item19, 0, wxALIGN_CENTRE|wxALL, 5 );
+    
+    item18->Add( 20, 20, 1, wxALIGN_CENTRE|wxALL, 5 );
+    
+    wxButton *item20 = new wxButton( parent, wxID_OK, _("&OK"), wxDefaultPosition, wxDefaultSize, 0 );
+    item20->SetDefault();
+    item18->Add( item20, 0, wxALIGN_CENTRE|wxALL, 5 );
+    
+    wxButton *item21 = new wxButton( parent, wxID_CANCEL, _("&Cancel"), wxDefaultPosition, wxDefaultSize, 0 );
+    item18->Add( item21, 0, wxALIGN_CENTRE|wxALL, 5 );
+    
+    item0->Add( item18, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 );
+#endif
+    
 #ifdef __WXGTK__
     wxButton *contextButton = new wxContextHelpButton( parent );
-    item14->Add( contextButton, 0, wxALIGN_CENTRE|wxALL, 5 );
-#endif
-
-    item0->Add( item14, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxBOTTOM, 5 );
+    item18->Add( contextButton, 0, wxALIGN_CENTRE|wxALL, 5 );
 #endif
-
-#ifdef __WXGTK__
-    wxButton *contextButton = new wxContextHelpButton( parent );
-    item14->Add( contextButton, 0, wxALIGN_CENTRE|wxALL, 5 );
-#endif
-
+    
+    parent->FindWindow( ecID_PACKAGES_DIALOG_KEYWORDS )->SetFocus();
+    
     parent->SetAutoLayout( TRUE );
     parent->SetSizer( item0 );
     parent->Layout();
     item0->Fit( parent );
     //item0->SetSizeHints( parent );
-
+    
     // Add context-sensitive help text
     parent->FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST )->SetHelpText(_("Displays the list of packages available, but not currently loaded."));
     parent->FindWindow( ecID_PACKAGES_DIALOG_USE_LIST )->SetHelpText(_("Displays the list of packages currently loaded."));
@@ -248,38 +301,35 @@ void ecPackagesDialog::CreateControls(wx
     parent->FindWindow( ecID_PACKAGES_DIALOG_REMOVE )->SetHelpText(_("Removes one or more packages from the list to be loaded."));
     parent->FindWindow( ecID_PACKAGES_DIALOG_VERSION )->SetHelpText(_("Displays the version of the selected packages."));
     parent->FindWindow( ecID_PACKAGES_DIALOG_DESCRIPTION )->SetHelpText(_("Displays a description of the selected package (blank if more than one package is selected)."));
+    parent->FindWindow( ecID_PACKAGES_DIALOG_KEYWORDS )->SetHelpText(_("Enter keywords here to restrict displayed packages."));
+    parent->FindWindow( ecID_PACKAGES_DIALOG_CLEAR )->SetHelpText(_("Clears the keyword field."));
+    parent->FindWindow( ecID_PACKAGES_DIALOG_OMIT_HARDWARE)->SetHelpText(_("Check this to omit hardware packages, uncheck to show all packages."));
+    parent->FindWindow( ecID_PACKAGES_DIALOG_EXACT_MATCH )->SetHelpText(_("Check this to display exact matches between keyword and aliases (case insensitive)."));
     parent->FindWindow( wxID_OK )->SetHelpText(_("Closes the dialog and saves any changes you have made."));
     parent->FindWindow( wxID_CANCEL )->SetHelpText(_("Closes the dialog without saving any changes you have made."));
-
+    
 #if __WXGTK__
     parent->FindWindow( wxID_CONTEXT_HELP )->SetHelpText(_("Invokes context-sensitive help for the clicked-on window."));
 #endif
-
+    
     // Add validators
     parent->FindWindow( ecID_PACKAGES_DIALOG_DESCRIPTION )->SetValidator(wxGenericValidator(& m_packageDescription));
+    parent->FindWindow( ecID_PACKAGES_DIALOG_KEYWORDS )->SetValidator(wxGenericValidator(& m_keywords));
+    parent->FindWindow( ecID_PACKAGES_DIALOG_OMIT_HARDWARE )->SetValidator(wxGenericValidator(& wxGetApp().GetSettings().m_omitHardwarePackages));
+    parent->FindWindow( ecID_PACKAGES_DIALOG_EXACT_MATCH )->SetValidator(wxGenericValidator(& wxGetApp().GetSettings().m_matchPackageNamesExactly));
 }
 
 void ecPackagesDialog::OnInitDialog(wxInitDialogEvent& event)
 {
+    // Note: InitControls must be here, because data will be added
+    // between construction of the dialog, and OnInitDialog.
     InitControls();
+    TransferDataToWindow();
 }
 
 void ecPackagesDialog::InitControls()
 {
-	wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
-	wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
-
-    // Initialize the controls
-    int i;
-    for (i = 0; i < GetCount()-1; i++)
-    {
-        const wxString& str = m_items[i];
-        wxListBox* lb = m_arnItems[i] ? useList : availableList;
-
-        lb->Append(str, (void*) i);
-    }
-
-    UpdateAddRemoveButtons();
+    Fill();
 }
 
 void ecPackagesDialog::OnCancel(wxCommandEvent& event)
@@ -289,30 +339,169 @@ void ecPackagesDialog::OnCancel(wxComman
 
 void ecPackagesDialog::OnOK(wxCommandEvent& event)
 {
+    TransferDataFromWindow();
     event.Skip();
 }
 
+// For each word in keywords, is it contained in 'str'?
+bool ecPackagesDialog::MatchesKeyword(wxArrayString& keywords, const wxString& str)
+{
+    // _Every_ keyword must match
+    size_t i;
+    for (i = 0; i < keywords.GetCount(); i++)
+    {
+        if (str.Find(keywords[i]) == -1)
+            return FALSE;
+    }
+    return TRUE;
+}
+
+void ecPackagesDialog::Fill()
+{
+    wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
+    wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
+    ecConfigToolDoc * pDoc = wxGetApp().GetConfigToolDoc ();
+
+    // wxGTK doesn't deselect items properly when clearing, I think
+    int i;
+    for (i = 0; i < availableList->GetCount(); i++)
+        if (availableList->Selected(i))
+            availableList->Deselect(i);
+    for (i = 0; i < useList->GetCount(); i++)
+        if (useList->Selected(i))
+            useList->Deselect(i);
+    
+    availableList->Clear();
+    useList->Clear();
+    ClearDescription();
+    
+    wxString s2(m_keywords);
+    s2.MakeLower();
+    
+    // Tokenize
+    wxArrayString keywords;
+    wxStringTokenizer tok(s2);
+    while (tok.HasMoreTokens())
+    {
+        keywords.Add(tok.GetNextToken());
+    }
+    
+    // Initialize the controls
+    for (i = 0; i < GetCount()-1; i++)
+    {
+        const wxString& str = m_items[i];
+        wxListBox* lb = m_arnItems[i] ? useList : availableList;
+        
+        wxString macroName(pDoc->GetPackageName (str));
+        
+        // check if the package is a hardware package
+        
+        if ((!wxGetApp().GetSettings().m_omitHardwarePackages) || !pDoc->GetCdlPkgData ()->is_hardware_package (ecUtils::UnicodeToStdStr (macroName)))
+        {
+            bool matches = TRUE;
+            
+            if (!m_keywords.IsEmpty())
+            {
+                // Descriptive name
+                wxString s1(str);
+                s1.MakeLower();
+
+                // macro name
+                wxString s3(macroName);
+                s3.MakeLower();
+
+                // Match all aliases
+                const std::vector<std::string> & aliases = pDoc->GetCdlPkgData ()->get_package_aliases (ecUtils::UnicodeToStdStr (macroName));
+                    
+                if (wxGetApp().GetSettings().m_matchPackageNamesExactly)
+                {
+                    int noMatches = 0;
+
+                    if (s2 == s1 || s2 == s3)
+                        noMatches ++;
+
+                    size_t j;
+                    for (j = 0; j < aliases.size(); j ++)
+                    {
+                        wxString alias(aliases[j].c_str());
+                        alias.MakeLower();
+                        if (s2 == alias)
+                            noMatches ++;
+                    }
+
+                    matches = (noMatches > 0);                   
+
+                }
+                else
+                {
+                    // Concatenate all possible text together, and match against that
+                    wxString toMatch;
+                    
+                    toMatch += s1;
+                    
+                    toMatch += s3;
+                    
+                    size_t j;
+                    for (j = 0; j < aliases.size(); j ++)
+                    {
+                        wxString alias(aliases[j].c_str());
+                        alias.MakeLower();
+                        toMatch += alias;
+                    }
+                    
+                    matches = MatchesKeyword(keywords, toMatch);
+                }
+            }
+            
+            if (matches)
+                lb->Append(str, (void*) i);
+        }
+    }
+    
+    UpdateAddRemoveButtons();
+    
+    if (availableList->GetCount() == 1)
+    {
+        availableList->SetSelection(0);
+        UpdatePackageDescription();
+        UpdateVersionList ();
+        UpdateHardwareSelectionFlag ();
+    }
+    else if (useList->GetCount() == 1)
+    {
+        useList->SetSelection(0);
+        UpdatePackageDescription();
+        UpdateVersionList ();
+        UpdateHardwareSelectionFlag ();
+    }
+    wxTextCtrl* textCtrl = (wxTextCtrl*) FindWindow( ecID_PACKAGES_DIALOG_KEYWORDS );
+    // Necessary or TransferDataToWindow will cause insertion position to change
+    textCtrl->SetInsertionPointEnd();
+}
+
 void ecPackagesDialog::Add(wxListBox* from, wxListBox* to)
 {
-	wxArrayInt selections;
-	wxStringList selectionsStrings;
-	int n = from -> GetSelections( selections );
-
-	if (n > 0)
-	{
-		int i;
-		for (i = 0; i < selections.GetCount(); i++)
-		{
-			wxString str = from -> GetString(selections[i]);
-			selectionsStrings.Add(str);
-		}
-
-		// Now delete from one list and remove from t'other
-		for (i = 0; i < selectionsStrings.Number(); i++)
-		{
-			wxString str = selectionsStrings[i];
-
-			// Remove
+    wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
+    
+    wxArrayInt selections;
+    wxStringList selectionsStrings;
+    int n = from -> GetSelections( selections );
+    
+    if (n > 0)
+    {
+        int i;
+        for (i = 0; i < selections.GetCount(); i++)
+        {
+            wxString str = from -> GetString(selections[i]);
+            selectionsStrings.Add(str);
+        }
+        
+        // Now delete from one list and remove from t'other
+        for (i = 0; i < selectionsStrings.Number(); i++)
+        {
+            wxString str = selectionsStrings[i];
+            
+            // Remove
             int toDelete =  from -> FindString(str);
             int itemIndex = -1;
             if (toDelete > -1)
@@ -320,17 +509,26 @@ void ecPackagesDialog::Add(wxListBox* fr
                 itemIndex = (int) from -> GetClientData(toDelete);
                 from -> Delete(toDelete);
             }
-
+            
             wxASSERT (itemIndex > -1);
-
-			// Add
+            
+            // Add
             to -> Append(str, (void*) itemIndex);
-
+            
+            if (to == useList)
+            {
+                m_added.Add(str);
+            }
+            else
+            {
+                m_added.Remove(str);
+            }
+            
             // Select it
             int addedIndex = to->FindString(str);
             to->Select(addedIndex);
-
-		}
+            
+        }
         //ClearDescription();
         ClearSelections(* from);
         UpdateHardwareSelectionFlag();
@@ -341,71 +539,71 @@ void ecPackagesDialog::Add(wxListBox* fr
 
 void ecPackagesDialog::OnAdd(wxCommandEvent& event)
 {
-	if (m_bHardwarePackageSelected)
+    if (m_bHardwarePackageSelected)
     {
-		HardwarePackageMessageBox ();
+        HardwarePackageMessageBox ();
         return;
     }
-	wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
-	wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
-
+    wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
+    wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
+    
     Add(availableList, useList);
-
+    
     UpdateAddRemoveButtons();
 }
 
 void ecPackagesDialog::OnRemove(wxCommandEvent& event)
 {
-	if (m_bHardwarePackageSelected)
+    if (m_bHardwarePackageSelected)
     {
-		HardwarePackageMessageBox ();
+        HardwarePackageMessageBox ();
         return;
     }
-
-	wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
-	wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
-
+    
+    wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
+    wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
+    
     Add(useList, availableList);
-
+    
     UpdateAddRemoveButtons();
 }
 
 void ecPackagesDialog::OnDblClickListBox1(wxCommandEvent& event)
 {
-	if (m_bHardwarePackageSelected)
+    if (m_bHardwarePackageSelected)
     {
-		HardwarePackageMessageBox ();
+        HardwarePackageMessageBox ();
         return;
     }
-
-	wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
-	wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
-
+    
+    wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
+    wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
+    
     Add(availableList, useList);
-
+    
     UpdateAddRemoveButtons();
 }
 
 void ecPackagesDialog::OnDblClickListBox2(wxCommandEvent& event)
 {
-	if (m_bHardwarePackageSelected)
+    if (m_bHardwarePackageSelected)
     {
-		HardwarePackageMessageBox ();
+        HardwarePackageMessageBox ();
         return;
     }
-
-	wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
-	wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
-
+    
+    wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
+    wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
+    
     Add(useList, availableList);
-
+    
     UpdateAddRemoveButtons();
 }
 
 void ecPackagesDialog::OnClickListBox1(wxCommandEvent& event)
 {
-	wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
-	wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
+    wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
+    wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
     
 #if 0    
     int sel = event.GetSelection();
@@ -415,19 +613,19 @@ void ecPackagesDialog::OnClickListBox1(w
         DisplayDescription(availableList->GetString(sel));
     }
 #endif
-
+    
     ClearSelections(*useList);
-	UpdatePackageDescription ();
-	UpdateVersionList ();
-	UpdateHardwareSelectionFlag ();
+    UpdatePackageDescription ();
+    UpdateVersionList ();
+    UpdateHardwareSelectionFlag ();
     UpdateAddRemoveButtons();
 }
 
 void ecPackagesDialog::OnClickListBox2(wxCommandEvent& event)
 {
-	wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
-	wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
-
+    wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
+    wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
+    
 #if 0    
     int sel = event.GetSelection();
     if (sel > -1)
@@ -436,78 +634,131 @@ void ecPackagesDialog::OnClickListBox2(w
         DisplayDescription(useList->GetString(sel));
     }
 #endif
-
+    
     ClearSelections(*availableList);
     UpdatePackageDescription ();
-	UpdateVersionList ();
-	UpdateHardwareSelectionFlag ();
+    UpdateVersionList ();
+    UpdateHardwareSelectionFlag ();
     UpdateAddRemoveButtons();
 }
 
 void ecPackagesDialog::OnSelectVersion(wxCommandEvent& event)
 {
-	wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
-	wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
+    wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
+    wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
     wxChoice* versionChoice = (wxChoice*) FindWindow( ecID_PACKAGES_DIALOG_VERSION );
-
+    
     if (-1 == versionChoice->GetSelection ()) // if there is no version selection
-		return; // do nothing
-
-	wxListBox * pListBox = NULL;
-
+        return; // do nothing
+    
+    wxListBox * pListBox = NULL;
+    
     wxArrayInt selected1, selected2;
     availableList->GetSelections(selected1);
     useList->GetSelections(selected2);
-
-	int nListSelCount = selected1.GetCount ();
-	if (nListSelCount > 0)
-	{
-		pListBox = availableList;
-	}
-	else
-	{
-		nListSelCount = selected2.GetCount ();
-		if (nListSelCount)
-			pListBox = useList;
-	}
-
-	wxASSERT (pListBox);
-
+    
+    int nListSelCount = selected1.GetCount ();
+    if (nListSelCount > 0)
+    {
+        pListBox = availableList;
+    }
+    else
+    {
+        nListSelCount = selected2.GetCount ();
+        if (nListSelCount)
+            pListBox = useList;
+    }
+    
+    wxASSERT (pListBox);
+    
     if (!pListBox)
         return;
-
-	// retrieve the list box indices of the selected packages
-
+    
+    // retrieve the list box indices of the selected packages
+    
     wxArrayInt* selected = (pListBox == availableList ? & selected1 : & selected2);
-
+    
     int nIndex;
-	for (nIndex = 0; nIndex < nListSelCount; nIndex++) // for each selected package
-	{
-		// set the package version to that specified in the version combo box
+    for (nIndex = 0; nIndex < nListSelCount; nIndex++) // for each selected package
+    {
+        // set the package version to that specified in the version combo box
         wxString str = versionChoice->GetString(nIndex);
-
+        
         // itemIndex is the index into the list of item names. It gets stored with all the listbox items.
         int itemIndex = (int) pListBox->GetClientData((*selected)[nIndex]);
         m_currentVersions[(size_t)itemIndex] = str;
-	}
+    }
+}
+
+void ecPackagesDialog::OnClearKeywords(wxCommandEvent& event)
+{
+    wxTextCtrl* textCtrl = (wxTextCtrl*) FindWindow( ecID_PACKAGES_DIALOG_KEYWORDS );
+    textCtrl->SetValue(wxT(""));
+    TransferDataFromWindow();
+    Fill();
+    m_updateLists = FALSE;
+    wxStartTimer();
+    FindWindow( ecID_PACKAGES_DIALOG_KEYWORDS )->SetFocus();
+}
+
+void ecPackagesDialog::OnUpdateKeywordText(wxCommandEvent& event)
+{
+    // Work around a bug in GTK+ that sends a text update command when
+    // clicking on one of the listboxes.
+    wxTextCtrl* textCtrl = (wxTextCtrl*) FindWindow( ecID_PACKAGES_DIALOG_KEYWORDS );
+    wxString value = textCtrl->GetValue();
+    if (value == m_keywords)
+        return;
+    
+    TransferDataFromWindow();
+    m_updateLists = TRUE;
+    wxStartTimer();
+}
+
+void ecPackagesDialog::OnClickOmitHardwarePackages(wxCommandEvent& event)
+{
+    TransferDataFromWindow();
+    Fill();
+}
+
+void ecPackagesDialog::OnClickExactMatch(wxCommandEvent& event)
+{
+    TransferDataFromWindow();
+    Fill();
+}
+
+void ecPackagesDialog::OnIdle(wxIdleEvent& event)
+{
+    long elapsed = wxGetElapsedTime(FALSE);
+    if (m_updateLists && (elapsed > m_updateInterval))
+    {
+        m_updateLists = FALSE;
+        Fill();
+        wxStartTimer();
+    }
 }
 
 void ecPackagesDialog::Insert(const wxString& str, bool added, const wxString& descr, const wxString& version)
 {
-	wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
-	wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
-
-	m_items.Add(str);
-	m_descriptions.Add(str);
+    wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
+    wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
+    
+    m_items.Add(str);
+    m_descriptions.Add(str);
     m_currentVersions.Add(version);
     m_arnItems.Add(added);
-
-	//(added ? useList : availableList) -> Append(str);
+    
+    if (added)
+        m_added.Add(str);
+    
+    //(added ? useList : availableList) -> Append(str);
 }
 
 bool ecPackagesDialog::IsAdded(const wxString& str)
 {
-	return (((wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST ))->FindString(str) > -1) ;
+    return (m_added.Index(str) != wxNOT_FOUND);
+    
+    //	return (((wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST ))->FindString(str) > -1) ;
 }
 
 static int ecPositionInStringList(const wxStringList& list, const wxString& item)
@@ -518,18 +769,49 @@ static int ecPositionInStringList(const 
             return i;
         else
             i ++;
-    return -1;
+        return -1;
 }
 
 void ecPackagesDialog::DisplayDescription(const wxString& item)
 {
-    wxTextCtrl* descrCtrl = (wxTextCtrl*) FindWindow( ecID_PACKAGES_DIALOG_DESCRIPTION ) ;
-
-    int pos = ecPositionInStringList(m_items, item);
-    if (pos > -1)
+    //wxTextCtrl* descrCtrl = (wxTextCtrl*) FindWindow( ecID_PACKAGES_DIALOG_DESCRIPTION ) ;
+    ecConfigToolDoc * pDoc = wxGetApp().GetConfigToolDoc ();
+    
+    //    int pos = ecPositionInStringList(m_items, item);
+    //    if (pos > -1)
     {
-        wxString descr = m_descriptions[pos];
-        descrCtrl->SetValue(descr);
+        wxString text;
+        //        wxString descr = m_descriptions[pos];
+        //        text += descr;
+        //        text += wxT("\n");
+        
+        wxString macroName(pDoc->GetPackageName (item));
+        
+        // Match all aliases
+        const std::vector<std::string> & aliases = pDoc->GetCdlPkgData ()->get_package_aliases (ecUtils::UnicodeToStdStr (macroName));
+        
+        size_t j;
+        for (j = 0; j < aliases.size(); j ++)
+        {
+            if (j == 1)
+                text += wxT(".\nAliases: ");
+            else if (j > 1)
+                text += wxT(", ");
+            
+            wxString alias(aliases[j].c_str());
+            text += alias;
+        }
+        text += wxT("\nMacro: ");
+        text += macroName;
+        text += wxT("\n\n");
+        
+        wxString descr = pDoc->GetCdlPkgData ()->get_package_description (ecUtils::UnicodeToStdStr (macroName)).c_str ();
+        
+        text += ecUtils::StripExtraWhitespace (descr);
+        
+        m_packageDescription = text;
+        
+        //descrCtrl->SetValue(text);
     }
 }
 
@@ -543,9 +825,9 @@ wxString ecPackagesDialog::GetVersion (c
 {
     int nCount;
     for (nCount = GetCount() - 1; nCount >= 0; --nCount)
-	{
+    {
         if (m_items [nCount] == item)
-		{
+        {
             return m_currentVersions [nCount];
         }
     }
@@ -555,229 +837,231 @@ wxString ecPackagesDialog::GetVersion (c
 
 void ecPackagesDialog::UpdateHardwareSelectionFlag()
 {
-	m_bHardwarePackageSelected = FALSE;
-
-	wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
-	wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
-	wxListBox * pListBox = NULL;
-
+    m_bHardwarePackageSelected = FALSE;
+    
+    wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
+    wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
+    wxListBox * pListBox = NULL;
+    
     wxArrayInt selections1, selections2;
     wxArrayInt* selections = NULL;
     availableList->GetSelections(selections1);
     useList->GetSelections(selections2);
-
-	int nListSelCount = selections1.GetCount ();
-	if (nListSelCount)
-	{
-		pListBox = availableList;
+    
+    int nListSelCount = selections1.GetCount ();
+    if (nListSelCount)
+    {
+        pListBox = availableList;
         selections = & selections1;
-	}
-	else
-	{
-		nListSelCount = selections2.GetCount ();
-		if (nListSelCount)
+    }
+    else
+    {
+        nListSelCount = selections2.GetCount ();
+        if (nListSelCount)
         {
-			pListBox = useList;
+            pListBox = useList;
             selections = & selections2;
         }
-	}
-
-	if (pListBox) // if there are packages selected
-	{
-		ecConfigToolDoc * pDoc = wxGetApp().GetConfigToolDoc ();
-
-		// retrieve the list box indices of the selected packages
-
-		//int * arnIndices = new int [nListSelCount];
-		//pListBox->GetSelItems (nListSelCount, arnIndices);
-
+    }
+    
+    if (pListBox) // if there are packages selected
+    {
+        ecConfigToolDoc * pDoc = wxGetApp().GetConfigToolDoc ();
+        
+        // retrieve the list box indices of the selected packages
+        
+        //int * arnIndices = new int [nListSelCount];
+        //pListBox->GetSelItems (nListSelCount, arnIndices);
+        
         int nIndex;
-		for (nIndex = 0; nIndex < nListSelCount; nIndex++) // for each selected package
-		{
-			wxString strPackageAlias = pListBox->GetString((*selections)[nIndex]);
-
-			// check if the package is a hardware package
-
-			//TRACE (_T("Checking '%s' for hardware status\n"), strPackageAlias);
-			if (pDoc->GetCdlPkgData ()->is_hardware_package (ecUtils::UnicodeToStdStr (pDoc->GetPackageName (strPackageAlias))))
-			{
-				m_bHardwarePackageSelected = TRUE;
-				break;
-			}
-		}
-	}
+        for (nIndex = 0; nIndex < nListSelCount; nIndex++) // for each selected package
+        {
+            wxString strPackageAlias = pListBox->GetString((*selections)[nIndex]);
+            
+            // check if the package is a hardware package
+            
+            //TRACE (_T("Checking '%s' for hardware status\n"), strPackageAlias);
+            if (pDoc->GetCdlPkgData ()->is_hardware_package (ecUtils::UnicodeToStdStr (pDoc->GetPackageName (strPackageAlias))))
+            {
+                m_bHardwarePackageSelected = TRUE;
+                break;
+            }
+        }
+    }
 }
 
 void ecPackagesDialog::HardwarePackageMessageBox()
 {
     // TODO: could give the user the choice of going to the template dialog.
-	wxMessageBox (wxT("Add and remove hardware packages by selecting a new hardware template."),
+    wxMessageBox (wxT("Add and remove hardware packages by selecting a new hardware template."),
         wxGetApp().GetSettings().GetAppName(), wxICON_EXCLAMATION|wxOK, this);
 }
 
 void ecPackagesDialog::UpdatePackageDescription ()
 {
     ecConfigToolDoc * pDoc = wxGetApp().GetConfigToolDoc ();
-
+    
     wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
-	wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
-
-	wxListBox * pListBox = NULL;
-
+    wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
+    
+    wxListBox * pListBox = NULL;
+    
     wxArrayInt selections1, selections2;
     wxArrayInt* selections = NULL;
     availableList->GetSelections(selections1);
     useList->GetSelections(selections2);
-
-	if (1 == selections1.GetCount ())
+    
+    if (1 == selections1.GetCount ())
     {
-		pListBox = availableList;
+        pListBox = availableList;
         selections = & selections1;
     }
-	else if (1 == selections2.GetCount ())
+    else if (1 == selections2.GetCount ())
     {
-		pListBox = useList;
+        pListBox = useList;
         selections = & selections2;
     }
-
-	if (pListBox && selections)
-	{
-		int nIndex = (*selections)[0];
-		wxString strPackageAlias = pListBox->GetString(nIndex);
-		m_packageDescription = pDoc->GetCdlPkgData ()->get_package_description (ecUtils::UnicodeToStdStr (pDoc->GetPackageName (strPackageAlias))).c_str ();
-		m_packageDescription = ecUtils::StripExtraWhitespace (m_packageDescription);
-	}
-	else
-	{
-		m_packageDescription = wxEmptyString;
-	}
+    
+    if (pListBox && selections)
+    {
+        int nIndex = (*selections)[0];
+        wxString strPackageAlias = pListBox->GetString(nIndex);
+        
+        DisplayDescription(strPackageAlias);
+        //m_packageDescription = pDoc->GetCdlPkgData ()->get_package_description (ecUtils::UnicodeToStdStr (pDoc->GetPackageName (strPackageAlias))).c_str ();
+        //m_packageDescription = ecUtils::StripExtraWhitespace (m_packageDescription);
+    }
+    else
+    {
+        m_packageDescription = wxEmptyString;
+    }
     TransferDataToWindow ();
 }
 
 void ecPackagesDialog::UpdateVersionList ()
 {
     ecConfigToolDoc * pDoc = wxGetApp().GetConfigToolDoc ();
-
+    
     wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
-	wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
+    wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
     wxChoice* versionChoice = (wxChoice*) FindWindow( ecID_PACKAGES_DIALOG_VERSION );
-
+    
     versionChoice->Clear(); // clear the version combo box
-
+    
     wxArrayInt selections1, selections2;
     wxArrayInt* selections = NULL;
     availableList->GetSelections(selections1);
     useList->GetSelections(selections2);
     wxListBox* pListBox = NULL;
-
-	if (selections1.GetCount () > 0)
+    
+    if (selections1.GetCount () > 0)
     {
-		pListBox = availableList;
+        pListBox = availableList;
         selections = & selections1;
     }
-	else if (selections2.GetCount () > 0)
+    else if (selections2.GetCount () > 0)
     {
-		pListBox = useList;
+        pListBox = useList;
         selections = & selections2;
     }
-
-	if (pListBox) // if there are packages selected
-	{
-		std::list<std::string> common_versions;
-		bool bCommonSelectedVersion = true;
-		int nCommonVersionIndex=-1;
+    
+    if (pListBox) // if there are packages selected
+    {
+        std::list<std::string> common_versions;
+        bool bCommonSelectedVersion = true;
+        int nCommonVersionIndex=-1;
         int nListSelCount = selections->GetCount();
-
-		// retrieve the list box indices of the selected packages
-
-		//int * arnIndices = new int [nListSelCount];
-		//pListBox->GetSelItems (nListSelCount, arnIndices);
+        
+        // retrieve the list box indices of the selected packages
+        
+        //int * arnIndices = new int [nListSelCount];
+        //pListBox->GetSelItems (nListSelCount, arnIndices);
         int nIndex;
-		for (nIndex = 0; nIndex < nListSelCount; nIndex++) // for each selected package
-		{
-			// retrieve the first package alias
-			wxString strPackageAlias = pListBox->GetString ((*selections)[nIndex]);
-
-			// retrieve the dialog item array index for use in
-			// comparing current version strings
-			const int nVersionIndex = (int) pListBox->GetClientData ((*selections)[nIndex]);
-
-			// retrieve the installed version array
-
-			//TRACE (_T("Retrieving versions for '%s'\n"), strPackageAlias);
-			const std::vector<std::string>& versions = pDoc->GetCdlPkgData ()->get_package_versions (ecUtils::UnicodeToStdStr (pDoc->GetPackageName (strPackageAlias)));
-
-			if (0 == nIndex) // if this is the first selected package
-			{
-				// use the version array to initialise a linked list of version
-				// strings held in common between the selected packages
+        for (nIndex = 0; nIndex < nListSelCount; nIndex++) // for each selected package
+        {
+            // retrieve the first package alias
+            wxString strPackageAlias = pListBox->GetString ((*selections)[nIndex]);
+            
+            // retrieve the dialog item array index for use in
+            // comparing current version strings
+            const int nVersionIndex = (int) pListBox->GetClientData ((*selections)[nIndex]);
+            
+            // retrieve the installed version array
+            
+            //TRACE (_T("Retrieving versions for '%s'\n"), strPackageAlias);
+            const std::vector<std::string>& versions = pDoc->GetCdlPkgData ()->get_package_versions (ecUtils::UnicodeToStdStr (pDoc->GetPackageName (strPackageAlias)));
+            
+            if (0 == nIndex) // if this is the first selected package
+            {
+                // use the version array to initialise a linked list of version
+                // strings held in common between the selected packages
                 unsigned int uCount;
-				for (uCount = 0; uCount < versions.size (); uCount++)
-				{
-					//TRACE (_T("Adding common version '%s'\n"), wxString (versions [uCount].c_str ()));
-					common_versions.push_back (versions [uCount]);
-				}
-				nCommonVersionIndex = nVersionIndex; // save the item array index
-			}
-			else // this is not the first selected package
-			{
-				std::list<std::string>::iterator i_common_versions = common_versions.begin ();
-				while (i_common_versions != common_versions.end ()) // iterate through the common versions
-				{
-					if (versions.end () == std::find (versions.begin (), versions.end (), * i_common_versions)) // if the common version is not in the versions list
-					{
-						//TRACE (_T("Removing common version '%s'\n"), CString (i_common_versions->c_str ()));
-						common_versions.erase (i_common_versions++); // remove the version from the common versions list
-					}
-					else
-					{
-						i_common_versions++;
-					}
-				}
-				if (bCommonSelectedVersion) // if the selected versions of all preceding packages are identical
-				{
-					// check if the selected version of this package matches that of the preceding ones
-					bCommonSelectedVersion = (m_currentVersions [nVersionIndex] == m_currentVersions [nCommonVersionIndex]);
-				}
-			}
-		}
-
-		// add the common versions to the version combo box
-
-		std::list<std::string>::iterator i_common_versions;
-		for (i_common_versions = common_versions.begin (); i_common_versions != common_versions.end (); i_common_versions++)
-		{
-			//TRACE (_T("Adding version '%s'\n"), CString (i_common_versions->c_str ()));
-			versionChoice->Append(wxString (i_common_versions->c_str ()));
-		}
-
-		// select the common current version (if any) in the version combo box
-
-		if (bCommonSelectedVersion)
-		{
-			//TRACE (_T("Selecting version '%s'\n"), m_arstrVersions [nCommonVersionIndex]);
-			versionChoice->SetStringSelection (m_currentVersions [nCommonVersionIndex]);
-		}
-
-		// enable the version combo box only if there are multiple common versions
-
-		versionChoice->Enable (common_versions.size () > 1);
-	}
-	else // there are no packages selected
-	{
-		versionChoice->Enable (FALSE); // disable the version combo box
-	}
+                for (uCount = 0; uCount < versions.size (); uCount++)
+                {
+                    //TRACE (_T("Adding common version '%s'\n"), wxString (versions [uCount].c_str ()));
+                    common_versions.push_back (versions [uCount]);
+                }
+                nCommonVersionIndex = nVersionIndex; // save the item array index
+            }
+            else // this is not the first selected package
+            {
+                std::list<std::string>::iterator i_common_versions = common_versions.begin ();
+                while (i_common_versions != common_versions.end ()) // iterate through the common versions
+                {
+                    if (versions.end () == std::find (versions.begin (), versions.end (), * i_common_versions)) // if the common version is not in the versions list
+                    {
+                        //TRACE (_T("Removing common version '%s'\n"), CString (i_common_versions->c_str ()));
+                        common_versions.erase (i_common_versions++); // remove the version from the common versions list
+                    }
+                    else
+                    {
+                        i_common_versions++;
+                    }
+                }
+                if (bCommonSelectedVersion) // if the selected versions of all preceding packages are identical
+                {
+                    // check if the selected version of this package matches that of the preceding ones
+                    bCommonSelectedVersion = (m_currentVersions [nVersionIndex] == m_currentVersions [nCommonVersionIndex]);
+                }
+            }
+        }
+        
+        // add the common versions to the version combo box
+        
+        std::list<std::string>::iterator i_common_versions;
+        for (i_common_versions = common_versions.begin (); i_common_versions != common_versions.end (); i_common_versions++)
+        {
+            //TRACE (_T("Adding version '%s'\n"), CString (i_common_versions->c_str ()));
+            versionChoice->Append(wxString (i_common_versions->c_str ()));
+        }
+        
+        // select the common current version (if any) in the version combo box
+        
+        if (bCommonSelectedVersion)
+        {
+            //TRACE (_T("Selecting version '%s'\n"), m_arstrVersions [nCommonVersionIndex]);
+            versionChoice->SetStringSelection (m_currentVersions [nCommonVersionIndex]);
+        }
+        
+        // enable the version combo box only if there are multiple common versions
+        
+        versionChoice->Enable (common_versions.size () > 1);
+    }
+    else // there are no packages selected
+    {
+        versionChoice->Enable (FALSE); // disable the version combo box
+    }
 }
 
 void ecPackagesDialog::UpdateAddRemoveButtons()
 {
     wxListBox* availableList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_AVAILABLE_LIST );
-	wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
-
+    wxListBox* useList = (wxListBox*) FindWindow( ecID_PACKAGES_DIALOG_USE_LIST );
+    
     wxArrayInt selections1, selections2;
     availableList->GetSelections(selections1);
     useList->GetSelections(selections2);
-
+    
     FindWindow( ecID_PACKAGES_DIALOG_ADD )->Enable( selections1.GetCount() > 0 );
     FindWindow( ecID_PACKAGES_DIALOG_REMOVE )->Enable( selections2.GetCount() > 0 );
 }
@@ -790,3 +1074,28 @@ void ecPackagesDialog::ClearSelections(w
         lbox.Deselect(i);
     }
 }
+
+void ecPackagesTimer::Notify()
+{
+    static bool s_inNotify = FALSE;
+    
+    if (s_inNotify)
+        return;
+    
+    s_inNotify = TRUE;
+    
+    // On Windows, simply having the timer going will ping the message queue
+    // and cause idle processing to happen.
+    // On Unix, this doesn't happen so we have to do the processing explicitly.
+#ifdef __WXMSW__
+    // Nothing to do
+#else
+    if ( m_dialog )
+    {
+        wxIdleEvent event;
+        m_dialog->OnIdle(event);
+    }
+#endif
+    
+    s_inNotify = FALSE;
+}
--- a/host/tools/configtool/standalone/wxwin/packagesdlg.h
+++ b/host/tools/configtool/standalone/wxwin/packagesdlg.h
@@ -30,7 +30,7 @@
 // Author(s):   julians
 // Contact(s):  julians
 // Date:        2000/09/28
-// Version:     $Id: packagesdlg.h,v 1.2 2001/03/23 13:38:04 julians Exp $
+// Version:     $Id: packagesdlg.h,v 1.6 2001/12/14 17:34:04 julians Exp $
 // Purpose:
 // Description: Header file for ecPackagesDialog
 // Requires:
@@ -51,6 +51,29 @@
 #endif
 
 #include "ecutils.h"
+#include "wx/timer.h"
+
+/*
+ * ecPackagesTimer
+ * Just to force idle processing now and again
+ * so that the keyword search works under OSes that
+ * have unreliable OnIdle processing
+ */
+
+class ecPackagesDialog;
+class ecPackagesTimer: public wxTimer
+{
+public:
+    ecPackagesTimer(ecPackagesDialog* dialog) { m_dialog = dialog; }
+
+    virtual void Notify() ;
+ protected:
+    ecPackagesDialog* m_dialog;
+};
+
+/*
+ * Add/remove packages
+ */
 
 class ecPackagesDialog : public ecDialog
 {
@@ -65,52 +88,73 @@ public:
     void OnCancel(wxCommandEvent& event);
     void OnAdd(wxCommandEvent& event);
     void OnRemove(wxCommandEvent& event);
-	void OnClickListBox1(wxCommandEvent& event);
-	void OnClickListBox2(wxCommandEvent& event);
-	void OnDblClickListBox1(wxCommandEvent& event);
-	void OnDblClickListBox2(wxCommandEvent& event);
-	void OnSelectVersion(wxCommandEvent& event);
+    void OnClickListBox1(wxCommandEvent& event);
+    void OnClickListBox2(wxCommandEvent& event);
+    void OnDblClickListBox1(wxCommandEvent& event);
+    void OnDblClickListBox2(wxCommandEvent& event);
+    void OnSelectVersion(wxCommandEvent& event);
     void OnInitDialog(wxInitDialogEvent& event);
 
 //// Operations
     void CreateControls(wxWindow* parent);
     void InitControls();
-	void Insert(const wxString& str, bool added, const wxString& descr = wxEmptyString, const wxString& version = wxEmptyString);
+    void Fill();
+    void Insert(const wxString& str, bool added, const wxString& descr = wxEmptyString, const wxString& version = wxEmptyString);
     void Add(wxListBox* from, wxListBox* to);
     void DisplayDescription(const wxString& item);
     void ClearDescription();
     void HardwarePackageMessageBox();
-	void UpdateHardwareSelectionFlag();
-	void UpdatePackageDescription();
-	void UpdateVersionList();
+    void UpdateHardwareSelectionFlag();
+    void UpdatePackageDescription();
+    void UpdateVersionList();
     void UpdateAddRemoveButtons();
     void ClearSelections(wxListBox& lbox);
 
+    void OnClearKeywords(wxCommandEvent& event);
+    void OnUpdateKeywordText(wxCommandEvent& event);
+    void OnClickOmitHardwarePackages(wxCommandEvent& event);
+    void OnClickExactMatch(wxCommandEvent& event);
+
+    void OnIdle(wxIdleEvent& event);
+
+//// Helpers
+    // For each word in keywords, is it contained in 'str'?
+    bool MatchesKeyword(wxArrayString& keywords, const wxString& str);
+
 //// Accessors
-	bool IsAdded(const wxString& str) ;
-	int GetCount() const { return m_items.Number(); }
-	wxString GetVersion (const wxString& item);
+    bool IsAdded(const wxString& str) ;
+    int GetCount() const { return m_items.Number(); }
+    wxString GetVersion (const wxString& item);
 
 protected:
 
 private:
     DECLARE_EVENT_TABLE()
 
-	wxStringList	m_items;
-	wxStringList	m_descriptions;
+    wxStringList    m_items;
+    wxStringList    m_descriptions;
     wxArrayString   m_currentVersions;
+    wxArrayString   m_added; // All those packages currently (or to-be) added
     wxArrayInt      m_arnItems;   // Whether in 'use list' (1) or not (0)
 
     bool            m_bHardwarePackageSelected;
     wxString        m_packageDescription;
+    wxString        m_keywords;
+    bool            m_updateLists; // If true, the keyword changed and we need to update the lists
+    long            m_updateInterval; // Interval before display is updated
+    ecPackagesTimer m_timer;
 };
 
-#define ecID_PACKAGES_DIALOG_AVAILABLE_LIST 10066
-#define ecID_PACKAGES_DIALOG_ADD 10067
-#define ecID_PACKAGES_DIALOG_REMOVE 10068
-#define ecID_PACKAGES_DIALOG_USE_LIST 10069
-#define ecID_PACKAGES_DIALOG_VERSION 10070
-#define ecID_PACKAGES_DIALOG_DESCRIPTION 10071
+#define ecID_PACKAGES_DIALOG_AVAILABLE_LIST     10066
+#define ecID_PACKAGES_DIALOG_ADD                10067
+#define ecID_PACKAGES_DIALOG_REMOVE             10068
+#define ecID_PACKAGES_DIALOG_USE_LIST           10069
+#define ecID_PACKAGES_DIALOG_VERSION            10070
+#define ecID_PACKAGES_DIALOG_DESCRIPTION        10071
+#define ecID_PACKAGES_DIALOG_KEYWORDS           10072
+#define ecID_PACKAGES_DIALOG_CLEAR              10073
+#define ecID_PACKAGES_DIALOG_OMIT_HARDWARE      10074
+#define ecID_PACKAGES_DIALOG_EXACT_MATCH        10075
 
 #endif
         // _ECOS_PACKAGESDLG_H_
--- a/host/tools/configtool/standalone/wxwin/runtestsdlg.h
+++ b/host/tools/configtool/standalone/wxwin/runtestsdlg.h
@@ -30,7 +30,7 @@
 // Author(s):   julians
 // Contact(s):  julians
 // Date:        2000/09/29
-// Version:     $Id: runtestsdlg.h,v 1.10 2001/06/29 13:48:23 julians Exp $
+// Version:     $Id: runtestsdlg.h,v 1.11 2001/12/13 15:30:27 julians Exp $
 // Purpose:
 // Description: Header file for ecRunTestsDialog
 // Requires:
@@ -59,7 +59,7 @@
 /*
  * ecRunTestsTimer
  * Just to force idle processing now and again while
- * the tests are runnin
+ * the tests are running
  */
 
 class ecRunTestsTimer: public wxTimer
--- a/host/tools/configtool/standalone/wxwin/setup/configtool.iss
+++ b/host/tools/configtool/standalone/wxwin/setup/configtool.iss
@@ -4,13 +4,13 @@
 
 [Setup]
     MinVersion=4.0,4.0
-    AppName=eCos Configuration Tool 2.08
+    AppName=eCos Configuration Tool 2.09
     AppId=eCos Configuration Tool
     CreateUninstallRegKey=1
     UsePreviousAppDir=1
     UsePreviousGroup=1
-    AppVersion=2.08
-    AppVerName=eCos Configuration Tool 2.08
+    AppVersion=2.09
+    AppVerName=eCos Configuration Tool 2.09
     AppCopyright=Copyright © Red Hat Inc., 2001
     BackColor=$FF0000
     BackColor2=$000000
@@ -29,7 +29,7 @@
     AlwaysCreateUninstallIcon=1
     Uninstallable=1
     DefaultDirName=c:\Program Files\Red Hat\eCos Configuration Tool
-    DefaultGroupName=Red Hat eCos Configuration Tool 2.08
+    DefaultGroupName=Red Hat eCos Configuration Tool 2.09
     LicenseFile=v:\deliver\configtool\license.txt
     InfoBeforeFile=v:\deliver\configtool\readme.txt
     MessagesFile=compiler:default.isl
@@ -213,7 +213,7 @@
 ; DO NOT DELETE THEM or you may be unable to reload the script
 
 ;[ScriptSetup]
-;VerNum=2.08
+;VerNum=2.09
 ;InnoVer=1.3
 ;AddVerTo=AppVerName
 ;SetupFilename=setup.exe
--- a/packages/compat/posix/current/ChangeLog
+++ b/packages/compat/posix/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-12-11  Nick Garnett  <nickg@redhat.com>
+
+	* tests/mqueue2.c (cyg_user_start): Added CYG_TEST_INIT() to
+	NOTAPPLICABLE variant, otherwise the order of breakpoints are all
+	wrong and the testfarm registers a failure.
+
 2001-11-06  Gary Thomas  <gthomas@redhat.com>
 
 	* include/muttypes.h: Need <pkgconf/kernel.h> configuration info,
--- a/packages/compat/posix/current/tests/mqueue2.c
+++ b/packages/compat/posix/current/tests/mqueue2.c
@@ -58,6 +58,7 @@
 void
 cyg_user_start(void)
 {
+    CYG_TEST_INIT();
     CYG_TEST_NA( NA_MSG );
 }
 
--- a/packages/devs/eth/amd/pcnet/current/src/if_pcnet.c
+++ b/packages/devs/eth/amd/pcnet/current/src/if_pcnet.c
@@ -991,7 +991,7 @@ pcnet_send(struct eth_drv_sc *sc, struct
                 _SU32(cpd->txd, PCNET_TD_PTR));
 #endif
 
-    // This delay seems to be necessary on some platforms
+    // This delay seems to be necessary on some platforms 
     // Why it is needed is not clear, but removing it or
     // reducing it cause transmission failures in RedBoot (at least).
     CYGACC_CALL_IF_DELAY_US(100);
--- a/packages/devs/eth/arm/flexanet/current/ChangeLog
+++ b/packages/devs/eth/arm/flexanet/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-12-10  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* cdl/flexanet_eth_drivers.cdl (CYGDAT_DEVS_ETH_ARM_FLEXANET_ESA):
+	Ensure default ESA has a value that is both locally administered and
+	*not* broadcast.
+
 2001-07-27  Jordi Colomer  <jco@ict.es>
 	
 	* Initial version of support for LAN91CXX ethernet controller
--- a/packages/devs/eth/arm/flexanet/current/cdl/flexanet_eth_drivers.cdl
+++ b/packages/devs/eth/arm/flexanet/current/cdl/flexanet_eth_drivers.cdl
@@ -87,7 +87,7 @@ cdl_package CYGPKG_DEVS_ETH_ARM_FLEXANET
     cdl_option CYGDAT_DEVS_ETH_ARM_FLEXANET_ESA {
         display       "The ethernet station address (MAC)"
         flavor        data
-        default_value {"{0x11, 0x12, 0x13, 0x14, 0x15, 0x16}"}
+        default_value {"{0x12, 0x13, 0x14, 0x15, 0x16, 0x17}"}
         description   "A static ethernet station address. 
             Caution: Booting two systems with the same MAC on the same
             network, will cause severe conflicts."
--- a/packages/devs/eth/ns/dp83902a/current/ChangeLog
+++ b/packages/devs/eth/ns/dp83902a/current/ChangeLog
@@ -1,3 +1,12 @@
+2001-12-10  Richard Sandiford  <rsandifo@redhat.com>
+
+	* src/if_dp83902a.c (dp83902a_RxEvent): Remove unused argument.
+	(dp83902a_TxEvent): Likewise.
+	(dp83902a_BufEvent): Remove.
+	(dp83902a_ClearCounters): New.
+	(dp83902a_Overflow): New.
+	(dp83902a_poll): Rework polling loop to use the new functions.
+
 2001-10-16  Jesper Skov  <jskov@redhat.com>
 
 	* include/dp83902a.h: Removed hardwired buffer
--- a/packages/devs/eth/ns/dp83902a/current/src/if_dp83902a.c
+++ b/packages/devs/eth/ns/dp83902a/current/src/if_dp83902a.c
@@ -42,7 +42,7 @@
 //#####DESCRIPTIONBEGIN####
 //
 // Author(s):    gthomas
-// Contributors: gthomas, jskov
+// Contributors: gthomas, jskov, rsandifo
 // Date:         2001-06-13
 // Purpose:      
 // Description:
@@ -477,7 +477,7 @@ dp83902a_send(struct eth_drv_sc *sc, str
 // 'dp83902a_recv' will be called to actually fetch it from the hardware.
 //
 static void
-dp83902a_RxEvent(struct eth_drv_sc *sc, int stat)
+dp83902a_RxEvent(struct eth_drv_sc *sc)
 {
     struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)sc->driver_private;
     cyg_uint8 *base = dp->base;
@@ -637,7 +637,7 @@ dp83902a_recv(struct eth_drv_sc *sc, str
 }
 
 static void
-dp83902a_TxEvent(struct eth_drv_sc *sc, int stat)
+dp83902a_TxEvent(struct eth_drv_sc *sc)
 {
     struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)sc->driver_private;
     cyg_uint8 *base = dp->base;
@@ -669,14 +669,61 @@ dp83902a_TxEvent(struct eth_drv_sc *sc, 
     (sc->funs->eth_drv->tx_done)(sc, key, 0);
 }
 
+// Read the tally counters to clear them.  Called in response to a CNT
+// interrupt.
+static int
+dp83902a_ClearCounters(struct eth_drv_sc *sc)
+{
+    struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)sc->driver_private;
+    cyg_uint8 *base = dp->base;
+    cyg_uint8 cnt1, cnt2, cnt3;
+
+    DP_IN(base, DP_FER, cnt1);
+    DP_IN(base, DP_CER, cnt2);
+    DP_IN(base, DP_MISSED, cnt3);
+    DP_OUT(base, DP_ISR, DP_ISR_CNT);
+}
+
+// Deal with an overflow condition.  This code follows the procedure set
+// out in section 7.0 of the datasheet.
 static void
-dp83902a_BufEvent(struct eth_drv_sc *sc, int stat)
+dp83902a_Overflow(struct eth_drv_sc *sc)
 {
-    // What to do if the receive buffers overflow?
-    if (stat & DP_ISR_OFLW) {
-        // Note: [so far] it seems safe to just ignore this condition
-        // The Linux driver goes through extraordinary pains to handle
-        // it, including totally shutting down the chip and restarting.
+    struct dp83902a_priv_data *dp = (struct dp83902a_priv_data *)sc->driver_private;
+    cyg_uint8 *base = dp->base;
+    cyg_uint8 isr;
+
+    // Issue a stop command and wait 1.6ms for it to complete.
+    CR_UP();
+    DP_OUT(base, DP_CR, DP_CR_STOP | DP_CR_NODMA);
+    CYGACC_CALL_IF_DELAY_US(1600);
+
+    // Clear the remote byte counter registers.
+    DP_OUT(base, DP_RBCL, 0);
+    DP_OUT(base, DP_RBCH, 0);
+
+    // Enter loopback mode while we clear the buffer.
+    DP_OUT(base, DP_TCR, DP_TCR_LOCAL); 
+    DP_OUT(base, DP_CR, DP_CR_START | DP_CR_NODMA);
+    CR_DOWN();
+
+    // Read in as many packets as we can and acknowledge any and receive
+    // interrupts.  Since the buffer has overflowed, a receive event of
+    // some kind will have occured.
+    dp83902a_RxEvent(sc);
+    DP_OUT(base, DP_ISR, DP_ISR_RxP|DP_ISR_RxE);
+
+    // Clear the overflow condition and leave loopback mode.
+    DP_OUT(base, DP_ISR, DP_ISR_OFLW);
+    DP_OUT(base, DP_TCR, DP_TCR_NORMAL);
+
+    // If a transmit command was issued, but no transmit event has occured,
+    // restart it here.
+    DP_IN(base, DP_ISR, isr);
+    if (dp->tx_started && !(isr & (DP_ISR_TxP|DP_ISR_TxE))) {
+        CR_UP();
+        DP_OUT(base, DP_CR, DP_CR_NODMA | DP_CR_TXPKT | DP_CR_START);
+        CR_DOWN();
     }
 }
 
@@ -694,18 +741,31 @@ dp83902a_poll(struct eth_drv_sc *sc)
     CR_DOWN();
     DP_IN(base, DP_ISR, isr);
     while (0 != isr) {
-        DP_OUT(base, DP_ISR, isr);      // Clear set bits
-        if (!dp->running) break;        // Is this necessary?
-        // Check for tx_started on TX event since these may happen
-        // spuriously it seems.
-        if (isr & (DP_ISR_TxP|DP_ISR_TxE) && dp->tx_started) {
-            dp83902a_TxEvent(sc, isr);
+        // The CNT interrupt triggers when the MSB of one of the error
+        // counters is set.  We don't much care about these counters, but
+        // we should read their values to reset them.
+        if (isr & DP_ISR_CNT) {
+            dp83902a_ClearCounters(sc);
         }
-        if (isr & (DP_ISR_RxP|DP_ISR_RxE)) {
-            dp83902a_RxEvent(sc, isr);
-        }
-        if (isr & (DP_ISR_OFLW|DP_ISR_CNT)) {
-            dp83902a_BufEvent(sc, isr);
+        // Check for overflow.  It's a special case, since there's a
+        // particular procedure that must be followed to get back into
+        // a running state.
+        if (isr & DP_ISR_OFLW) {
+            dp83902a_Overflow(sc);
+        } else {
+            // Other kinds of interrupts can be acknowledged simply by
+            // clearing the relevant bits of the ISR.  Do that now, then
+            // handle the interrupts we care about.
+            DP_OUT(base, DP_ISR, isr);      // Clear set bits
+            if (!dp->running) break;        // Is this necessary?
+            // Check for tx_started on TX event since these may happen
+            // spuriously it seems.
+            if (isr & (DP_ISR_TxP|DP_ISR_TxE) && dp->tx_started) {
+                dp83902a_TxEvent(sc);
+            }
+            if (isr & (DP_ISR_RxP|DP_ISR_RxE)) {
+                dp83902a_RxEvent(sc);
+            }
         }
         DP_IN(base, DP_ISR, isr);
     }
--- a/packages/devs/eth/smsc/lan91cxx/current/ChangeLog
+++ b/packages/devs/eth/smsc/lan91cxx/current/ChangeLog
@@ -1,3 +1,11 @@
+2001-12-12  Hugo Tyson  <hmt@redhat.com>
+
+	* src/if_lan91cxx.c (lan91cxx_recv): If discarding data due to
+	caller out of buffers, we must read-out and discard the packet to
+	correctly complete the transaction.  Bogus assert for buffer
+	pointer removed; other asserts from not discarding data assuaged
+	by first change above.
+
 2001-08-17  Hugo Tyson  <hmt@redhat.com>
 
 	* src/if_lan91cxx.c (lan91cxx_poll): The interrupt acknowledge
--- a/packages/devs/eth/smsc/lan91cxx/current/src/if_lan91cxx.c
+++ b/packages/devs/eth/smsc/lan91cxx/current/src/if_lan91cxx.c
@@ -987,8 +987,14 @@ lan91cxx_recv(struct eth_drv_sc *sc, str
                 plen -= sizeof(*data);
             }
         }
+        else { // must actively discard ie. read it from the chip anyway.
+            while (mlen >= sizeof(*data)) {
+                (void)get_data(sc);
+                mlen -= sizeof(*data);
+                plen -= sizeof(*data);
+            }
+        }
     }
-    CYG_ASSERT( data, "No sg data for end byte" );
     val = get_data(sc); // Read control word unconditionally
     CYG_ASSERT(val & LAN91CXX_CONTROLBYTE_RX, 
                "Controlbyte is not for Rx");
--- a/packages/hal/common/current/ChangeLog
+++ b/packages/hal/common/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-12-12  Jesper Skov  <jskov@redhat.com>
+
+	* include/hal_stub.h: Add goto to the used label.
+	* src/hal_misc.c: Added (dummy) got for label used in
+	CYGARC_HAL_GET_RETURN_ADDRESS_BACKUP.
+
 2001-12-05  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* src/dbg-threads-syscall.c (dbg_thread_syscall): Don't bother to
--- a/packages/hal/common/current/include/hal_stub.h
+++ b/packages/hal/common/current/include/hal_stub.h
@@ -231,12 +231,17 @@ do {                                    
 #endif
 
 // This macro may already have been defined by the architecture HAL
+// Notice the trick to *use* the label - sometimes the tools want to
+// move the label if unused, which is bad.
 #ifndef CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION
 #define CYG_HAL_GDB_LEAVE_CRITICAL_IO_REGION( _old_ )                         \
 do {                                                                          \
     cyg_hal_gdb_remove_break( (target_register_t)&&cyg_hal_gdb_break_place ); \
     HAL_RESTORE_INTERRUPTS(_old_);                                            \
+    _old_ = 1; /* actually use the label as a label... */                     \
 cyg_hal_gdb_break_place:;                                                     \
+    if ( (_old_)-- > 0 ) /* ...or the compiler might move it! */              \
+        goto cyg_hal_gdb_break_place;                                         \
 } while ( 0 )
 #endif
 
--- a/packages/hal/common/current/src/hal_misc.c
+++ b/packages/hal/common/current/src/hal_misc.c
@@ -60,12 +60,18 @@
 // Macro for finding return address. 
 #ifndef CYGARC_HAL_GET_RETURN_ADDRESS
 
-#define CYGARC_HAL_GET_RETURN_ADDRESS(_x_) \
-  (_x_) = (CYG_ADDRWORD)&&__backup_return_address
+#define CYGARC_HAL_GET_RETURN_ADDRESS(_x_, _dummy_)     \
+    CYG_MACRO_START                                     \
+    (_dummy_) = 1;                                      \
+    (_x_) = (CYG_ADDRWORD)&&__backup_return_address;    \
+    CYG_MACRO_END
 
-#define CYGARC_HAL_GET_RETURN_ADDRESS_BACKUP() \
-__backup_return_address:
-
+#define CYGARC_HAL_GET_RETURN_ADDRESS_BACKUP(_dummy_)   \
+    CYG_MACRO_START                                     \
+__backup_return_address:                                \
+    if ((_dummy_)-- > 0)                                \
+        goto __backup_return_address;                   \
+    CYG_MACRO_END
 #endif
 
 //--------------------------------------------------------------------------
@@ -91,6 +97,11 @@ cyg_hal_is_break(char *buf, int size)
     return false;
 }
 
+// Keep this variable global, to prevent the compiler removing it (and
+// the goto-reference) due to being local to the function where it is
+// used. Yes, it's ugly.
+int _cyg_hal_compiler_dummy;
+
 void 
 cyg_hal_user_break( CYG_ADDRWORD *regs )
 {
@@ -102,14 +113,14 @@ cyg_hal_user_break( CYG_ADDRWORD *regs )
     CYG_WORD32 __pc;
     HAL_SavedRegisters *sreg = (HAL_SavedRegisters *)regs;
 
-    CYGARC_HAL_GET_RETURN_ADDRESS(__ra);
+    CYGARC_HAL_GET_RETURN_ADDRESS(__ra, _cyg_hal_compiler_dummy);
 
     if( regs == NULL ) __pc = __ra;
     else  CYGARC_HAL_GET_PC_REG(sreg, __pc);
 
     CYGACC_CALL_IF_INSTALL_BPT_FN((void *)__pc);
 
-    CYGARC_HAL_GET_RETURN_ADDRESS_BACKUP();
+    CYGARC_HAL_GET_RETURN_ADDRESS_BACKUP(_cyg_hal_compiler_dummy);
     
 #else
 
--- a/packages/hal/i386/arch/current/ChangeLog
+++ b/packages/hal/i386/arch/current/ChangeLog
@@ -1,3 +1,13 @@
+2001-12-11  Nick Garnett  <nickg@redhat.com>
+
+	* src/i386.ld (SECTION_rel__got): Added entry for
+	.rel.gnu.linkonce* that more recent versions of the compiler seem
+	to generate.
+
+2001-12-07  Jonathan Larmour  <jlarmour@redhat.com>
+
+	* src/i386.ld: Add missing close bracket.
+
 2001-12-06  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* src/i386.ld: Add .rel.text and .rel.data sections to avoid
--- a/packages/hal/i386/arch/current/src/i386.ld
+++ b/packages/hal/i386/arch/current/src/i386.ld
@@ -93,11 +93,11 @@ GROUP(libtarget.a libgcc.a)
     > _region_
 
 // Note: The __ in the name is an encoding of the .
-#define SECTION_rel__got(_region_, _vma_, _lma_)        \
-    .rel.text _vma_ : _lma_ { *(.rel.text*) } > _region_      \
-    .rel.data _vma_ : _lma_ { *(.rel.data*) } > _region_      \
-    .rel.got _vma_ : _lma_                                            \
-    { *(.rel.got)      }                                        \
+#define SECTION_rel__got(_region_, _vma_, _lma_)                                \
+    .rel.text _vma_ : _lma_ { *(.rel.text*) *(.rel.gnu.linkonce*) } > _region_  \
+    .rel.data _vma_ : _lma_ { *(.rel.data*) } > _region_                        \
+    .rel.got _vma_ : _lma_                                                      \
+    { *(.rel.got)      }                                                        \
     > _region_
 
 #define SECTION_data(_region_, _vma_, _lma_)                       \
--- a/packages/hal/i386/pc/current/ChangeLog
+++ b/packages/hal/i386/pc/current/ChangeLog
@@ -1,3 +1,9 @@
+2001-12-07  Nick Garnett  <nickg@redhat.com>
+
+	* include/plf_intr.h: Added definition of HAL_DELAY_US() so that
+	this is used instead of the delay loop in delay_us(). This is
+	necessary to handle fast Pentiums and Athlons.
+
 2001-10-16  Mark Salter  <msalter@redhat.com>
 
 	* misc/redboot_FLOPPY_D850GB.ecm: New file. RedBoot config for
--- a/packages/hal/i386/pc/current/include/plf_intr.h
+++ b/packages/hal/i386/pc/current/include/plf_intr.h
@@ -69,5 +69,12 @@
 #define HAL_PLATFORM_RESET_ENTRY	 &hal_pc_reset
 
 //---------------------------------------------------------------------------
+// Microsecond delay
+
+__externC void hal_delay_us(int us);
+
+#define HAL_DELAY_US(_us) hal_delay_us(_us)
+
+//---------------------------------------------------------------------------
 #endif // ifndef CYGONCE_HAL_PLF_INTR_H
 // End of plf_intr.h
--- a/packages/hal/synth/arch/current/ChangeLog
+++ b/packages/hal/synth/arch/current/ChangeLog
@@ -1,3 +1,7 @@
+2001-12-07  Bart Veer  <bartv@redhat.com>
+
+	* include/hal_io.h: Added cyg_hal_sys_getcwd()
+
 2001-08-02  Bart Veer  <bartv@redhat.com>
 
 	* include/hal_intr.h:
--- a/packages/hal/synth/arch/current/include/hal_io.h
+++ b/packages/hal/synth/arch/current/include/hal_io.h
@@ -331,6 +331,10 @@ externC int             cyg_hal_sys_gett
 
 // The actual implementation appears to return the new brk() value.
 externC void*           cyg_hal_sys_brk(void*);
+
+// Returns the number of characters placed in the buffer or <0 for error,
+// not a char*. 
+externC int             cyg_hal_sys_getcwd(char*, int);
  
 // ----------------------------------------------------------------------------
 // Interaction between the application and the auxiliary.
--- a/packages/hal/synth/i386linux/current/ChangeLog
+++ b/packages/hal/synth/i386linux/current/ChangeLog
@@ -1,3 +1,7 @@
+2001-12-07  Bart Veer  <bartv@redhat.com>
+
+	* src/syscall-i386-linux-1.0.S: added getcwd() system call
+
 2001-08-02  Bart Veer  <bartv@redhat.com>
 
 	* src/context.S, include/arch.inc, include/var_arch.h:
--- a/packages/hal/synth/i386linux/current/src/syscall-i386-linux-1.0.S
+++ b/packages/hal/synth/i386linux/current/src/syscall-i386-linux-1.0.S
@@ -424,4 +424,4 @@ SYSCALL5(_newselect)
 SYSCALL3(readv)
 SYSCALL3(writev)
 SYSCALL1(fdatasync)
-
+SYSCALL2(getcwd)
--- a/packages/io/eth/current/ChangeLog
+++ b/packages/io/eth/current/ChangeLog
@@ -1,3 +1,30 @@
+2001-12-12  Hugo Tyson  <hmt@redhat.com>
+
+	* src/net/eth_drv.c (START_CONSOLE,END_CONSOLE): New macros akin
+	to those within RedBoot's internal net_io.c, for directing warning
+	messages to a serial line if required.  All printf's wrapped in
+	them for safety.
+
+	* cdl/eth_drivers.cdl (CYGPKG_IO_ETH_DRIVERS_WARN_FORCE_CONSOLE):
+	and ..._NUMBER, new options to direct application warning output
+	somewhere useful (less harmful) for when you are debugging over
+	the net.  Trying to print within a call which occurred from within
+	RedBoot itself is such a recursive situation as to be fatal.
+	Defaults are disabled, you must choose to set these up if
+	you want to debug your app safely over the network.
+
+2001-12-12  Hugo Tyson  <hmt@redhat.com>
+
+	* src/stand_alone/eth_drv.c (DIAG_DUMP_BUF_HDR,DIAG_DUMP_BUF_BDY):
+	Separate macros for debug dumps of ethernet header and body.
+	(eth_drv_write): Use them.
+	(eth_drv_copy_recv): Do not corrupt the static data pointer, so
+	that if we are erroneously called twice, at least what we pass is
+	a packet, rather than random memory; do not escape to SEGV.  Guard
+	against NULL sg_list[].buf pointers, in case caller out of MBUFs.
+	(eth_drv_recv): Only dump packet if we actually have a buffer.
+	Only forward the packet if actually have a buffer.
+
 2001-12-04  Richard Sandiford  <rsandifo@redhat.com>
 
 	* src/stand_alone/eth_drv.c (eth_drv_read): Check that the return
--- a/packages/io/eth/current/cdl/eth_drivers.cdl
+++ b/packages/io/eth/current/cdl/eth_drivers.cdl
@@ -80,7 +80,7 @@ cdl_package CYGPKG_IO_ETH_DRIVERS {
         default_value 1
         compile       net/eth_drv.c
 
-    	cdl_option CYGPKG_IO_ETH_DRIVERS_WARN_NO_MBUFS {
+    	cdl_component CYGPKG_IO_ETH_DRIVERS_WARN_NO_MBUFS {
 	    display	"Warn when there are no more mbufs"
 	    flavor	bool
 	    default_value 1
@@ -92,6 +92,26 @@ cdl_package CYGPKG_IO_ETH_DRIVERS {
 	        out is bad for performance but not fatal, not a crash.
                 You might want to turn off the warnings to preserve realtime
                 properties of the system even in extremis."
+
+	    cdl_component CYGPKG_IO_ETH_DRIVERS_WARN_FORCE_CONSOLE {
+		display		"Force warning output to particular console"
+		default_value	0
+		flavor		bool
+		active_if 		CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
+		description "
+		Enabling this forces warning output somewhere useful, such
+		as a particular serial port when performing network debugging."
+		
+		cdl_option CYGPKG_IO_ETH_DRIVERS_WARN_FORCE_CONSOLE_NUMBER {
+		    display		"Console number for warning output"
+		    flavor 		data
+		    default_value	0
+		    description "
+		    0 is normally serial 0, 1 is serial 1.  Some boards don't have a
+		    serial 0, or if they do it's not brought out to a connector.  Hence
+		    the need to change this."
+		}
+	    }
 	}
 
 	cdl_component CYGPKG_IO_ETH_DRIVERS_SIMULATED_FAILURES {
--- a/packages/io/eth/current/src/net/eth_drv.c
+++ b/packages/io/eth/current/src/net/eth_drv.c
@@ -265,6 +265,26 @@ simulate_fail_corrupt_sglist( struct eth
 #endif // CYGPKG_IO_ETH_DRIVERS_SIMULATED_FAILURES
 // ------------------------------------------------------------------------
 
+#if defined(CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT) && defined(CYGPKG_IO_ETH_DRIVERS_WARN_FORCE_CONSOLE)
+
+#include <cyg/hal/hal_if.h>
+
+// Use with care!  Local variable defined!
+#define START_CONSOLE()  {                                                                     \
+     int _cur_console;                                                                         \
+     _cur_console = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT); \
+     CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGPKG_IO_ETH_DRIVERS_WARN_FORCE_CONSOLE_NUMBER)
+
+#define END_CONSOLE()                                   \
+     CYGACC_CALL_IF_SET_CONSOLE_COMM(_cur_console);     \
+}
+
+#else
+#define START_CONSOLE()
+#define END_CONSOLE()
+#endif
+// ------------------------------------------------------------------------
+
 static int  eth_drv_ioctl(struct ifnet *, u_long, caddr_t);
 static void eth_drv_send(struct ifnet *);
 
@@ -529,8 +549,11 @@ eth_drv_send(struct ifnet *ifp)
 #endif
 
 #ifdef CYGDBG_IO_ETH_DRIVERS_DEBUG
-        if (cyg_io_eth_net_debug)
+        if (cyg_io_eth_net_debug) {
+            START_CONSOLE();
             diag_printf("Sending %d bytes\n", m0->m_pkthdr.len);
+            END_CONSOLE();
+        }
 #endif
 
         /* We need to use m->m_pkthdr.len, so require the header */
@@ -555,13 +578,19 @@ eth_drv_send(struct ifnet *ifp)
                 sg_len++;
 #ifdef CYGDBG_IO_ETH_DRIVERS_DEBUG
             if (cyg_io_eth_net_debug) {
+                START_CONSOLE();
                 diag_printf("xmit %d bytes at %x sg[%d]\n", len, data, sg_len);
                 if ( cyg_io_eth_net_debug > 1)
                     diag_dump_buf(data, len);
+                END_CONSOLE();
             }
 #endif
             if ( MAX_ETH_DRV_SG < sg_len ) {
+#ifdef CYGPKG_IO_ETH_DRIVERS_WARN_NO_MBUFS
+                START_CONSOLE();
                 diag_printf("too many mbufs to tx, %d > %d\n", sg_len, MAX_ETH_DRV_SG );
+                END_CONSOLE();
+#endif
                 sg_len = 0;
                 break; // drop it on the floor
             }
@@ -681,7 +710,9 @@ eth_drv_recv(struct eth_drv_sc *sc, int 
     MGETHDR(m, M_DONTWAIT, MT_DATA);
     if (m == 0) {
 #ifdef CYGPKG_IO_ETH_DRIVERS_WARN_NO_MBUFS
+        START_CONSOLE();
         diag_printf("warning: eth_recv out of MBUFs\n");
+        END_CONSOLE();
 #endif
     }
 
@@ -714,7 +745,9 @@ eth_drv_recv(struct eth_drv_sc *sc, int 
             if (m == 0) {
                 m_freem(top);
 #ifdef CYGPKG_IO_ETH_DRIVERS_WARN_NO_MBUFS
+                START_CONSOLE();
                 diag_printf("out of MBUFs [2]");
+                END_CONSOLE();
 #endif
                 sg_list[sg_len].buf = (CYG_ADDRESS)0;
                 sg_list[sg_len].len = total_len;
@@ -730,7 +763,9 @@ eth_drv_recv(struct eth_drv_sc *sc, int 
                 m_freem(top);
                 m_free(m);
 #ifdef CYGPKG_IO_ETH_DRIVERS_WARN_NO_MBUFS
+                START_CONSOLE();
                 diag_printf("warning: eth_recv out of MBUFs\n");
+                END_CONSOLE();
 #endif
                 sg_list[sg_len].buf = (CYG_ADDRESS)0;
                 sg_list[sg_len].len = total_len;
@@ -762,6 +797,7 @@ eth_drv_recv(struct eth_drv_sc *sc, int 
 
 #ifdef CYGDBG_IO_ETH_DRIVERS_DEBUG
     if (cyg_io_eth_net_debug) {
+        START_CONSOLE();
         for (i = 0;  i < sg_len;  i++) {
             if (sg_list[i].buf) {
                 diag_printf("rx %d bytes at %x sg[%d]\n", sg_list[i].len, sg_list[i].buf, i);
@@ -769,6 +805,7 @@ eth_drv_recv(struct eth_drv_sc *sc, int 
                     diag_dump_buf((void *)sg_list[i].buf, sg_list[i].len);
             }
         }
+        END_CONSOLE();
     }
 #endif
     m = top;
--- a/packages/io/eth/current/src/stand_alone/eth_drv.c
+++ b/packages/io/eth/current/src/stand_alone/eth_drv.c
@@ -68,6 +68,12 @@ struct eth_drv_funs eth_drv_funs = {eth_
 
 #ifdef CYGDBG_IO_ETH_DRIVERS_DEBUG
 int cyg_io_eth_net_debug = CYGDBG_IO_ETH_DRIVERS_DEBUG_VERBOSITY;
+// Usually just the header is enough, the body slows things too much.
+#define DIAG_DUMP_BUF_HDR( a, b ) if (0 < cyg_io_eth_net_debug) diag_dump_buf( (a), (b) )
+#define DIAG_DUMP_BUF_BDY( a, b ) if (1 < cyg_io_eth_net_debug) diag_dump_buf( (a), (b) )
+#else
+#define DIAG_DUMP_BUF_HDR( a, b )
+#define DIAG_DUMP_BUF_BDY( a, b )
 #endif
 
 unsigned char      __local_enet_addr[ETHER_ADDR_LEN+2];
@@ -253,8 +259,8 @@ eth_drv_write(char *eth_hdr, char *buf, 
         int old_console;
         old_console = start_console();
         diag_printf("Ethernet send:\n");
-        diag_dump_buf(eth_hdr, 14);
-        diag_dump_buf(buf, len);
+        DIAG_DUMP_BUF_HDR(eth_hdr, 14);
+        DIAG_DUMP_BUF_BDY(buf, len);
         end_console(old_console);
     }
 #endif
@@ -382,12 +388,15 @@ eth_drv_copy_recv(struct eth_drv_sc *sc,
                   struct eth_drv_sg *sg_list,
                   int sg_len)
 {
-    int i;   
+    int i;
+    unsigned char *ppp;
     CYGARC_HAL_SAVE_GP();
+    ppp = eth_drv_copy_recv_buf;        // Be safe against being called again by accident
     for (i = 0;  i < sg_len;  i++) {
-        memcpy((unsigned char *)sg_list[i].buf, 
-               eth_drv_copy_recv_buf, sg_list[i].len);
-        eth_drv_copy_recv_buf += sg_list[i].len;
+        if ( sg_list[i].buf )           // Be safe against discarding calls
+            memcpy((unsigned char *)sg_list[i].buf, 
+                   ppp, sg_list[i].len);
+        ppp += sg_list[i].len;
     }
     CYGARC_HAL_RESTORE_GP();
 }
@@ -426,7 +435,7 @@ eth_drv_recv(struct eth_drv_sc *sc, int 
         diag_printf("%s: packet of %d bytes dropped\n", __FUNCTION__, total_len);
         end_console(old_console);
 #endif
-        buf = (char *)0;  // Drivers know this means "the bit bucket"
+        buf = (unsigned char *)0;  // Drivers know this means "the bit bucket"
     }
     sg_list[0].buf = (CYG_ADDRESS)buf;
     sg_list[0].len = total_len;
@@ -438,13 +447,18 @@ eth_drv_recv(struct eth_drv_sc *sc, int 
         int old_console;
         old_console = start_console();
         diag_printf("Ethernet recv:\n");
-        diag_dump_buf(buf, 14);
-        diag_dump_buf(buf+14, total_len-14);
+        if ( buf ) {
+            DIAG_DUMP_BUF_HDR(buf, 14);
+            DIAG_DUMP_BUF_BDY(buf+14, total_len-14);
+        }
+        else
+            diag_printf("  ...NULL buffer.\n");
         end_console(old_console);
     }
 #endif
 #ifdef CYGSEM_IO_ETH_DRIVERS_PASS_PACKETS
-    if (sc->funs->eth_drv_old != (struct eth_drv_funs *)0) {
+    if ((unsigned char *)0 != buf &&    // Only pass on a packet we actually got!
+        sc->funs->eth_drv_old != (struct eth_drv_funs *)0) {
         void (*hold_recv)(struct eth_drv_sc *sc,
                           struct eth_drv_sg *sg_list,
                           int sg_len);
@@ -465,8 +479,8 @@ eth_drv_recv(struct eth_drv_sc *sc, int 
         msg->len = total_len;
         eth_drv_msg_put(&eth_msg_full, msg);
 #ifdef CYGSEM_IO_ETH_DRIVERS_WARN
-    } else {
-        diag_dump_buf(sg_list[0].buf, sg_list[0].len);
+    // there was an else with a dump_buf() here but it's
+    // meaningless; sg_list[0].buf is NULL!
 #endif
     }
     CYGARC_HAL_RESTORE_GP();
--- a/packages/kernel/current/ChangeLog
+++ b/packages/kernel/current/ChangeLog
@@ -1,3 +1,8 @@
+2001-12-12  Jesper Skov  <jskov@redhat.com>
+
+	* tests/kcache2.c (time_ilock): Put some dummy goto statements in
+	to prevent compiler from moving labels around.
+
 2001-11-29  Jonathan Larmour  <jlarmour@redhat.com>
 
 	* src/sched/mlqueue.cxx (timeslice_cpu): Reset timeslice_count on
--- a/packages/kernel/current/tests/kcache2.c
+++ b/packages/kernel/current/tests/kcache2.c
@@ -562,11 +562,16 @@ static void test_dinvalidate(void)
 //  o Time difference between repeatedly executing a bunch of instructions
 //    with and without locking.
 #ifdef HAL_ICACHE_LOCK
-static void iloop(unsigned long* start, unsigned long* end)
+static void iloop(unsigned long* start, unsigned long* end, int dummy)
 {
+    // dummy is just used to fool the compiler to not move the labels
+    // around. All callers should call with dummy=0;
+
     register char c;
     register CYG_INTERRUPT_STATE oldints;
 
+    if (1 == dummy) goto label_end;
+
  label_start:
     // Invalidating shouldn't affect locked lines.
     HAL_DISABLE_INTERRUPTS(oldints);
@@ -644,6 +649,8 @@ static void iloop(unsigned long* start, 
 
     *start = (unsigned long) &&label_start;
     *end = (unsigned long) &&label_end;
+
+    if (1 == dummy) goto label_start;
 }
 
 static void time_ilock(void)
@@ -661,7 +668,7 @@ static void time_ilock(void)
 
     count0 = cyg_current_time();
     for (k = 0; k < time_ilock_loops; k++) {
-        iloop(&start, &end);
+        iloop(&start, &end, 0);
     }
     count1 = cyg_current_time();
     t = count1 - count0;
@@ -671,7 +678,7 @@ static void time_ilock(void)
 
     count0 = cyg_current_time();
     for (k = 0; k < time_ilock_loops; k++) {
-        iloop(&start, &end);
+        iloop(&start, &end, 0);
     }
     count1 = cyg_current_time();
     t = count1 - count0;
--- a/packages/net/tcpip/current/ChangeLog
+++ b/packages/net/tcpip/current/ChangeLog
@@ -1,3 +1,22 @@
+2001-12-14  Hugo Tyson  <hmt@redhat.com>
+
+	* src/sys/net/if_ethersubr.c (ether_output): Never ever print
+	anything!  It can recurse unexpectedly if debugging over net.
+
+2001-12-10  Andrew Lunn <andrew.lunn@ascom.ch>
+
+	* cdl/net.cdl: Add configury to eliminate network timing stats.
+	* src/include/machine/param.h: Timing statistics for things like 
+	memcpy, mbuf_alloc etc now use configury to determine if the
+	statistics code should be compiled.
+	* src/ecos/support.c: Ditto.
+	* tests/nc_test_slave.c: Only print timing stats when they
+	are enabled. 
+	* tests/tcp_echo.c: Ditto.
+	* tests/nc_test_master.c: Allow building with SNMP lib which has
+	its own gettimeofday(). This should be fixed better a different
+	way but will do for now.
+	
 2001-12-06  Hugo Tyson  <hmt@redhat.com>
 
 	* src/lib/bootp_support.c (init_net): Just re-tabbed and checked
--- a/packages/net/tcpip/current/cdl/net.cdl
+++ b/packages/net/tcpip/current/cdl/net.cdl
@@ -432,6 +432,15 @@ cdl_package CYGPKG_NET {
         }
     }
 
+    cdl_option CYGDBG_NET_TIMING_STATS {
+        display       "Network timing statistics"
+        default_value 0
+        description   "
+                This component controls whether there is diagnostic 
+                information about how long memcpy, malloc, mbuf_alloc
+                etc take to perform."
+    }
+
     cdl_component CYGPKG_NET_OPTIONS {
         display "Networking support build options"
         flavor  none
--- a/packages/net/tcpip/current/include/machine/param.h
+++ b/packages/net/tcpip/current/include/machine/param.h
@@ -122,6 +122,7 @@ struct net_stats {
     cyg_uint32       min_time, max_time, total_time;
 };
 
+#ifdef CYGDBG_NET_TIMING_STATS
 #define START_STATS()                                   \
     cyg_uint32 start_time, end_time, elapsed_time;      \
     HAL_CLOCK_READ(&start_time);
@@ -141,6 +142,10 @@ struct net_stats {
         stats.max_time = elapsed_time;                                                  \
     stats.total_time += elapsed_time;                                                   \
     stats.count++;
+#else
+#define START_STATS() 
+#define FINISH_STATS(X)
+#endif
 
 // timeout support
 typedef void (timeout_fun)(void *);
--- a/packages/net/tcpip/current/src/ecos/support.c
+++ b/packages/net/tcpip/current/src/ecos/support.c
@@ -138,6 +138,7 @@ static cyg_mempool_fix net_clusters_pool
 static cyg_handle_t    net_clusters;
 static char            net_clusters_refcnt[(NET_CLUSTERS_SIZE/MCLBYTES)+1];
 
+#ifdef CYGDBG_NET_TIMING_STATS
 static struct net_stats  stats_malloc, stats_free, 
     stats_memcpy, stats_memset,
     stats_mbuf_alloc, stats_mbuf_free, stats_cluster_alloc;
@@ -191,6 +192,7 @@ show_net_times(void)
     show_net_stats(&stats_memcpy,        "Net memcpy");
     show_net_stats(&stats_memset,        "Net memset");
 }
+#endif /* CYGDBG_NET_TIMING_STATS */ 
 
 void *
 cyg_net_malloc(u_long size, int type, int flags)
--- a/packages/net/tcpip/current/src/sys/net/if_ethersubr.c
+++ b/packages/net/tcpip/current/src/sys/net/if_ethersubr.c
@@ -548,8 +548,8 @@ ether_output(ifp, m0, dst, rt0)
 
 	default:
 #ifdef __ECOS
-		diag_printf("%s: can't handle af%d\n", ifp->if_xname,
-                            dst->sa_family);
+//		diag_printf("%s: can't handle af%d\n", ifp->if_xname,
+//                            dst->sa_family);
 #else
 		printf("%s: can't handle af%d\n", ifp->if_xname,
 			dst->sa_family);
--- a/packages/net/tcpip/current/tests/nc_test_master.c
+++ b/packages/net/tcpip/current/tests/nc_test_master.c
@@ -121,6 +121,7 @@ pexit(char *s)
 }
 
 #ifdef __ECOS
+#ifndef CYGPKG_SNMPLIB
 int
 gettimeofday(struct timeval *tv, struct timezone *tz)
 {
@@ -129,8 +130,11 @@ gettimeofday(struct timeval *tv, struct 
     tv->tv_sec = cur_time / 100;
     tv->tv_usec = (cur_time % 100) * 10000;
 }
+#else
+int
+gettimeofday(struct timeval *tv, struct timezone *tz);
 #endif
-
+#endif
 void
 show_results(const char *msg, struct timeval *start, 
              struct timeval *end, int nbufs, int buflen,
--- a/packages/net/tcpip/current/tests/nc_test_slave.c
+++ b/packages/net/tcpip/current/tests/nc_test_slave.c
@@ -92,7 +92,9 @@ static void do_some_random_computation(i
 
 #ifdef __ECOS
 #define test_param_t cyg_addrword_t
+#ifdef CYGDBG_NET_TIMING_STATS
 extern void show_net_times(void);
+#endif
 #else
 #define test_param_t int
 #endif
@@ -137,7 +139,9 @@ void
 pexit(char *s)
 {
     perror(s);
+#ifdef CYGDBG_NET_TIMING_STATS
     show_net_times();
+#endif
     cyg_test_exit();
 }
 
@@ -559,7 +563,9 @@ net_test(test_param_t param)
 #endif
     }
     nc_slave(param);
+#ifdef CYGDBG_NET_TIMING_STATS
     show_net_times();
+#endif
     cyg_test_exit();
 }
 
--- a/packages/net/tcpip/current/tests/tcp_echo.c
+++ b/packages/net/tcpip/current/tests/tcp_echo.c
@@ -540,10 +540,12 @@ echo_test(cyg_addrword_t p)
                 (int)idle_thread_count, i);
 
 //#ifdef CYGDBG_USE_ASSERTS
+#ifdef CYGDBG_NET_TIMING_STATS 
     {
         extern void show_net_times(void);
         show_net_times();
     }
+#endif
 //#endif
 }
 
--- a/packages/redboot/current/ChangeLog
+++ b/packages/redboot/current/ChangeLog
@@ -1,3 +1,18 @@
+2001-12-12  Hugo Tyson  <hmt@redhat.com>
+
+	* cdl/redboot.cdl (CYGDBG_REDBOOT_NET_DEBUG_CONSOLE_NUMBER): New
+	option to control the console number for network debug messages.
+	For platforms where serial0 is supported (due to common variant
+	HAL code) but not connected; serial1 is all you get, say.
+
+	* src/net/net_io.c (start_console): Use it.
+
+2001-12-10  Nick Garnett  <nickg@redhat.com>
+
+	* src/net/cksum.c (__pseudo_sum): Fixed method of adding protocol
+	field to checksum. Some compilers optimize some of this away to
+	give a bogus result.
+
 2001-12-06  Jesper Skov  <jskov@redhat.com>
 
 	* src/load.c (do_load): Fix warning.
--- a/packages/redboot/current/cdl/redboot.cdl
+++ b/packages/redboot/current/cdl/redboot.cdl
@@ -154,6 +154,16 @@ cdl_package CYGPKG_REDBOOT {
                 This option is overriden by the configuration stored in flash."
         }
 
+	cdl_option CYGDBG_REDBOOT_NET_DEBUG_CONSOLE_NUMBER {
+	    display	     "Console number for net debug information"
+	    flavor           data
+	    default_value    0
+	    description "
+	    0 is normally serial port 0, 1 is serial port 1.  Some boards don't
+	    have a serial 0, or it may not be brought out to a connector,
+	    so this option is available to change things."
+	}    
+
         cdl_component CYGDAT_REDBOOT_DEFAULT_IP_ADDR {
             display          "Default IP address"
             flavor           booldata
@@ -205,12 +215,12 @@ cdl_package CYGPKG_REDBOOT {
     }
 
     cdl_option CYGPKG_REDBOOT_ANY_CONSOLE {
-        display       "Allow RedBoot to use any I/O channel for it's console."
+        display       "Allow RedBoot to use any I/O channel for its console."
         flavor        bool
         default_value 1
         description   "
           If this option is enabled then RedBoot will attempt to use all
-          defined serial I/O channels for it's console device.  Once input
+          defined serial I/O channels for its console device.  Once input
           arrives at one of these channels then the console will use only
           that port."
     }
--- a/packages/redboot/current/src/net/cksum.c
+++ b/packages/redboot/current/src/net/cksum.c
@@ -93,17 +93,21 @@ int
 {
     int    sum;
     word   *p;
-    char   cbuf[2];
 
+    union {
+	unsigned char c[2];
+	unsigned short s;
+    } su;
+    
     p = (word *)ip->source;
     sum  = *p++;
     sum += *p++;
     sum += *p++;
     sum += *p++;
     
-    cbuf[0] = 0;
-    cbuf[1] = ip->protocol;
-    sum += *(word *)cbuf;
+    su.c[0] = 0;
+    su.c[1] = ip->protocol;
+    sum += su.s;
 
     sum += ip->length;
     
--- a/packages/redboot/current/src/net/net_io.c
+++ b/packages/redboot/current/src/net/net_io.c
@@ -415,7 +415,7 @@ start_console(void)
 {
     int cur_console;
     cur_console = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
-    CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
+    CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGDBG_REDBOOT_NET_DEBUG_CONSOLE_NUMBER);
     return cur_console;
 }