1001 lines
37 KiB
C++
1001 lines
37 KiB
C++
|
|
// ------------------------------------------------------------------
|
|
// GoldED+
|
|
// Copyright (C) 1998-1999 Odinn Sorensen
|
|
// Copyright (C) 1999-2000 Alexander S. Aganichev
|
|
// ------------------------------------------------------------------
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License as
|
|
// published by the Free Software Foundation; either version 2 of the
|
|
// License, or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
// General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
// MA 02111-1307 USA
|
|
// ------------------------------------------------------------------
|
|
// $Id$
|
|
// ------------------------------------------------------------------
|
|
// Configuration functions, part 0.
|
|
// ------------------------------------------------------------------
|
|
|
|
#include <golded.h>
|
|
#include <gccfgg.h>
|
|
#include <gcprot.h>
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
bool cfgingroup = false;
|
|
char* val;
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
struct tglobalbool {
|
|
word crc_token;
|
|
};
|
|
|
|
// globalbool[] array elements shoulds be complemented with
|
|
// en_gswitches{} enumeration elements (see gecfgg.h).
|
|
// globalbool[] array must be sorted by value
|
|
tglobalbool globalbool[gswitches_last] = {
|
|
{ CRC_INTERNETLOOKUP }, // 0x0E22;
|
|
{ CRC_KLUDGECHRS }, // 0x0EEF;
|
|
{ CRC_MOUSE }, // 0x1B1B;
|
|
{ CRC_DISPLOCALHIGH }, // 0x1D8B;
|
|
{ CRC_AREALISTGROUPID }, // 0x1F75;
|
|
{ CRC_ASKDELORIG }, // 0x26DD;
|
|
{ CRC_LOOKUPLOCAL }, // 0x34E7;
|
|
{ CRC_DISPSTATUSLINE }, // 0x3FCF;
|
|
{ CRC_SCREENUSEBIOS }, // 0x43DE;
|
|
{ CRC_HIGHLIGHTUNREAD }, // 0x45DA;
|
|
{ CRC_AKAMATCHLOCAL }, // 0x4AC4;
|
|
{ CRC_FIDONULLFIX }, // 0x4F38;
|
|
{ CRC_DISPAUTONEXT }, // 0x52D9;
|
|
{ CRC_LOOKUPUSERBASE }, // 0x5852;
|
|
{ CRC_AREAKEEPLAST }, // 0x5876;
|
|
{ CRC_FILELISTPAGEBAR }, // 0x58AA;
|
|
{ CRC_PRINTFORMFEED }, // 0x59FB;
|
|
{ CRC_AREALISTNOS }, // 0x5FD7;
|
|
{ CRC_DISPPAGEBAR }, // 0x60A4;
|
|
{ CRC_INTERNETREPLY }, // 0x6253;
|
|
{ CRC_AREALISTPAGEBAR }, // 0x6C37;
|
|
{ CRC_USEMSGID }, // 0x6FDB;
|
|
{ CRC_LOOKUPNET }, // 0x7359;
|
|
{ CRC_JAMSMAPIHIGHWATER }, // 0x74A4;
|
|
{ CRC_SQUISHDIRECT }, // 0x7C35;
|
|
{ CRC_FIDOHWMARKS }, // 0x7E07;
|
|
{ CRC_MSGLISTPAGEBAR }, // 0x8041;
|
|
{ CRC_BEEPNOISES }, // 0x84D5;
|
|
{ CRC_SCREENSHADOWS }, // 0x8543;
|
|
{ CRC_EMPTYTEARLINE }, // 0x8D0A;
|
|
{ CRC_MENUDROPMSG }, // 0x9645;
|
|
{ CRC_BEEPLOCALMSG }, // 0x984C;
|
|
{ CRC_STATUSLINECLOCK }, // 0x9C8A;
|
|
{ CRC_TWITTO }, // 0x9DFE;
|
|
{ CRC_KEYBDEFAULTS }, // 0x9FAE;
|
|
{ CRC_DISPLISTWRAP }, // 0xB36D;
|
|
{ CRC_QUOTESPACING }, // 0xB403;
|
|
{ CRC_LOOKUPECHO }, // 0xB787;
|
|
{ CRC_KEYBEXT }, // 0xC48A;
|
|
{ CRC_BEEPCOMMENT }, // 0xC49E;
|
|
{ CRC_RCVDISABLESCFM }, // 0xD3B2;
|
|
{ CRC_QUOTEBLANK }, // 0xD3BB;
|
|
{ CRC_KEYBCLEAR }, // 0xD407;
|
|
{ CRC_DOSPROMPT }, // 0xD983;
|
|
{ CRC_AREACATCHUPREAD }, // 0xDAFF;
|
|
{ CRC_FORMFEEDSEPARATOR }, // 0xDBD6;
|
|
{ CRC_USEFLAGS }, // 0xE2B6;
|
|
{ CRC_JAMHARDDELETE }, // 0xE2D5;
|
|
{ CRC_DISPREALMSGNO }, // 0xE30F;
|
|
{ CRC_FRQWAZOO }, // 0xE49C;
|
|
{ CRC_MSGLISTVIEWSUBJ }, // 0xED92;
|
|
{ CRC_AKAMATCHECHO }, // 0xF0C1;
|
|
{ CRC_AREAFILEGROUPS }, // 0xF0E7;
|
|
{ CRC_AREAAUTONEXT }, // 0xF589;
|
|
{ CRC_TIMEOUTSAVEMSG }, // 0xF644;
|
|
{ CRC_NODELISTWARN }, // 0xF818;
|
|
{ CRC_AKAMATCHNET }, // 0xFD6E;
|
|
};
|
|
|
|
void CfgJAMSMAPIHighwater(bool value)
|
|
{
|
|
CFG->switches.handle(CRC_JAMSMAPIHIGHWATER, value ? "YES" : "NO");
|
|
}
|
|
|
|
bool gswitches::handle(word crc, const char* value) {
|
|
|
|
uint left,right,middle;
|
|
word cur;
|
|
|
|
if (value == NULL) {
|
|
STD_PRINTNL("! Illegall call of function: gswitches::handle(" << crc << ",NULL). File " __FILE__ " line " << __LINE__);
|
|
LOG_NULL_POINTER;
|
|
LOG.printf("! Illegall call of function: gswitches::handle(%04X,NULL). File %s line %i ", crc, __FILE__, __LINE__);
|
|
PointerErrorExit();
|
|
return 0;
|
|
}
|
|
|
|
left = 0;
|
|
right = gswitches_last - 1;
|
|
|
|
if((crc < globalbool[left].crc_token) or (crc > globalbool[right].crc_token))
|
|
return false;
|
|
|
|
do {
|
|
middle = (left + right)/2;
|
|
|
|
cur = globalbool[middle].crc_token;
|
|
|
|
if(crc < cur) {
|
|
right = middle - 1;
|
|
} else if(crc > cur) {
|
|
left = middle + 1;
|
|
}
|
|
else {
|
|
cfg[middle] = make_bool(GetYesno(value));
|
|
return true;
|
|
}
|
|
} while(left <= right);
|
|
|
|
return false;
|
|
}
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
int SwitchCfg(word crc, char k, char* v) {
|
|
|
|
if (v == NULL) {
|
|
STD_PRINTNL("! Illegall call of function: SwitchCfg(" << crc << "," << k << "," << "NULL). File " __FILE__ " line " << __LINE__);
|
|
LOG_NULL_POINTER;
|
|
LOG.printf("! Illegall call of function: SwitchCfg(%04X,%c,NULL). File %s line %i ", crc, k, __FILE__, __LINE__);
|
|
PointerErrorExit();
|
|
return false;
|
|
}
|
|
|
|
val = v;
|
|
bool found = true;
|
|
|
|
if(CFG->switches.handle(crc, v))
|
|
return true;
|
|
|
|
// Switch the first letter of the keyword
|
|
switch(g_toupper(k)) {
|
|
case 'A': goto SwitchA;
|
|
case 'B': goto SwitchB;
|
|
case 'C': goto SwitchC;
|
|
case 'D': goto SwitchD;
|
|
case 'E': goto SwitchE;
|
|
case 'F': goto SwitchF;
|
|
case 'G': goto SwitchG;
|
|
case 'H': goto SwitchH;
|
|
case 'I': goto SwitchI;
|
|
case 'J': goto SwitchJ;
|
|
case 'K': goto SwitchK;
|
|
case 'L': goto SwitchL;
|
|
case 'M': goto SwitchM;
|
|
case 'N': goto SwitchN;
|
|
case 'O': goto SwitchO;
|
|
case 'P': goto SwitchP;
|
|
case 'Q': goto SwitchQ;
|
|
case 'R': goto SwitchR;
|
|
case 'S': goto SwitchS;
|
|
case 'T': goto SwitchT;
|
|
case 'U': goto SwitchU;
|
|
case 'V': goto SwitchV;
|
|
case 'W': goto SwitchW;
|
|
case 'X': goto SwitchX;
|
|
case 'Y': goto SwitchY;
|
|
case 'Z': goto SwitchZ;
|
|
default: found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchA:
|
|
switch(crc) {
|
|
case CRC_ADDRESS : CfgAddress (); break;
|
|
case CRC_ADDRESSBOOKADD : CfgAddressbookadd (); break;
|
|
case CRC_ADDRESSLOOKUPFIRST: CfgAddresslookupfirst(); break;
|
|
case CRC_ADDRESSMACRO : CfgAddressmacro (); break;
|
|
case CRC_ADEPTXBBSPATH : CfgAdeptxbbspath (); break;
|
|
case CRC_ADEPTXBBSUSERNO : CfgAdeptxbbsuserno (); break;
|
|
case CRC_AKA : CfgAddress (); break;
|
|
case CRC_AKAMATCH : CfgAkamatch (); break;
|
|
case CRC_AKAMATCHFROMTO : CfgAkamatchfromto (); break;
|
|
case CRC_AKAMATCHING : CfgAkamatching (); break;
|
|
case CRC_AKAMATCHMANUALLY : CfgAkamatchmanually (); break;
|
|
case CRC_AREAAUTOID : CfgAreaautoid (); break;
|
|
case CRC_AREACFMREPLYTO : CfgAreacfmreplyto (); break;
|
|
case CRC_AREACOPYADDID : CfgAreacopyaddid (); break;
|
|
case CRC_AREACOPYDIRECT : CfgAreacopydirect (); break;
|
|
case CRC_AREACOPYTO : CfgAreacopyto (); break;
|
|
case CRC_AREADEF : CfgAreadef (); break;
|
|
case CRC_AREADESC : CfgAreadesc (); break;
|
|
case CRC_AREAEXCL : CfgAreaexcl (); break;
|
|
case CRC_AREAFORWARDDIRECT: CfgAreaforwarddirect(); break;
|
|
case CRC_AREAFREQDIRECT : CfgAreafreqdirect (); break;
|
|
case CRC_AREAFREQTO : CfgAreafreqto (); break;
|
|
case CRC_AREAINCL : CfgAreaincl (); break;
|
|
case CRC_AREAISEMAIL : CfgAreaisemail (); break;
|
|
case CRC_AREAISNEWS : CfgAreaisnews (); break;
|
|
case CRC_AREALISTECHOMAX : CfgArealistechomax (); break;
|
|
case CRC_AREALISTFORMAT : CfgArealistformat (); break;
|
|
case CRC_AREALISTGROUPORDER: CfgArealistgrouporder(); break;
|
|
case CRC_AREALISTSCAN : CfgArealistscan (); break;
|
|
case CRC_AREALISTSORT : CfgArealistsort (); break;
|
|
case CRC_AREALISTTYPE : CfgArealisttype (); break;
|
|
case CRC_AREAPATH : CfgAreapath (); break;
|
|
case CRC_AREAPMSCAN : CfgAreapmscan (); break;
|
|
case CRC_AREAPMSCANEXCL : CfgAreapmscanexcl (); break;
|
|
case CRC_AREAPMSCANINCL : CfgAreapmscanincl (); break;
|
|
case CRC_AREAREADONLY : CfgAreareadonly (); break;
|
|
case CRC_AREARECYCLEBIN : CfgArearecyclebin (); break;
|
|
case CRC_AREARENAME : CfgArearename (); break;
|
|
case CRC_AREAREPLYDIRECT : CfgAreareplydirect (); break;
|
|
case CRC_AREAREPLYTO : CfgAreareplyto (); break;
|
|
case CRC_AREASCAN : CfgAreascan (); break;
|
|
case CRC_AREASCANEXCL : CfgAreascanexcl (); break;
|
|
case CRC_AREASCANINCL : CfgAreascanincl (); break;
|
|
case CRC_AREASCANSORT : CfgAreascansort (); break;
|
|
case CRC_AREASEP : CfgAreasep (); break;
|
|
case CRC_AREASTART : CfgAreastart (); break;
|
|
case CRC_AREATYPEORDER : CfgAreatypeorder (); break;
|
|
case CRC_AREAYOUWROTETO : CfgAreayouwroteto (); break;
|
|
case CRC_ATTACHPATH : CfgAttachpath (); break;
|
|
case CRC_ATTRIBSATTACH : CfgAttribsattach (); break;
|
|
case CRC_ATTRIBSCC : CfgAttribscc (); break;
|
|
case CRC_ATTRIBSCFM : CfgAttribscfm (); break;
|
|
case CRC_ATTRIBSECHO : CfgAttribsecho (); break;
|
|
case CRC_ATTRIBSEMAIL : CfgAttribsemail (); break;
|
|
case CRC_ATTRIBSFRQ : CfgAttribsfrq (); break;
|
|
case CRC_ATTRIBSLOCAL : CfgAttribslocal (); break;
|
|
case CRC_ATTRIBSNET : CfgAttribsnet (); break;
|
|
case CRC_ATTRIBSNEWS : CfgAttribsnews (); break;
|
|
case CRC_ATTRIBUTES : CfgAttributes (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchB:
|
|
switch(crc) {
|
|
case CRC_BEEPFACTOR : CfgBeepfactor (); break;
|
|
case CRC_BEEPYOURMAIL : CfgBeepyourmail (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchC:
|
|
switch(crc) {
|
|
case CRC_CARBONCOPYLIST : CfgCarboncopylist (); break;
|
|
case CRC_COLOR : CfgColor (); break;
|
|
case CRC_COLORNAME : CfgColorname (); break;
|
|
case CRC_COLORSET : CfgColorset (); break;
|
|
case CRC_CONFIRMFILE : CfgConfirmfile (); break;
|
|
case CRC_CONFIRMRESPONSE : CfgConfirmresponse (); break;
|
|
case CRC_COOKIEPATH : CfgCookiepath (); break;
|
|
case CRC_CROSSPOST : CfgCrosspost (); break;
|
|
case CRC_CROSSPOSTLIST : CfgCrosspostlist (); break;
|
|
case CRC_CTRLINFO : CfgCtrlinfo (); break;
|
|
case CRC_CTRLINFOECHO : CfgCtrlinfoecho (); break;
|
|
case CRC_CTRLINFOEMAIL : CfgCtrlinfoemail (); break;
|
|
case CRC_CTRLINFOLOCAL : CfgCtrlinfolocal (); break;
|
|
case CRC_CTRLINFONET : CfgCtrlinfonet (); break;
|
|
case CRC_CTRLINFONEWS : CfgCtrlinfonews (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchD:
|
|
switch(crc) {
|
|
case CRC_DISPAREANO : CfgDispareano (); break;
|
|
case CRC_DISPATTACHSIZE : CfgDispattachsize (); break;
|
|
case CRC_DISPHDRDATESET : CfgDisphdrdateset (); break;
|
|
case CRC_DISPHDRLOCATION : CfgDisphdrlocation (); break;
|
|
case CRC_DISPHDRNAMESET : CfgDisphdrnameset (); break;
|
|
case CRC_DISPHDRNODESET : CfgDisphdrnodeset (); break;
|
|
case CRC_DISPLISTCURSOR : CfgDisplistcursor (); break;
|
|
case CRC_DISPMARGIN : CfgDispmargin (); break;
|
|
case CRC_DISPMSGSIZE : CfgDispmsgsize (); break;
|
|
case CRC_DISPPMFIRST : CfgDisppmfirst (); break;
|
|
case CRC_DISPSOFTCR : CfgDispsoftcr (); break;
|
|
case CRC_DISPTABSIZE : CfgDisptabsize (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchE:
|
|
switch(crc) {
|
|
case CRC_EDITAUTOATTACH : CfgEditautoattach (); break;
|
|
case CRC_EDITAUTOSAVE : CfgEditautosave (); break;
|
|
case CRC_EDITCHANGEDATE : CfgEditchangedate (); break;
|
|
case CRC_EDITCHARPARA : CfgEditcharpara (); break;
|
|
case CRC_EDITCHARSPACE : CfgEditcharspace (); break;
|
|
case CRC_EDITCOMMENT : CfgEditcomment (); break;
|
|
case CRC_EDITCOMPLETION : CfgEditcompletion (); break;
|
|
case CRC_EDITCRLFTERM : CfgEditcrlfterm (); break;
|
|
case CRC_EDITFIELDCLEAR : CfgEditfieldclear (); break;
|
|
case CRC_EDITHARDLINE : CfgEdithardline (); break;
|
|
case CRC_EDITHARDLINES : CfgEdithardlines (); break;
|
|
case CRC_EDITHARDTERM : CfgEdithardterm (); break;
|
|
case CRC_EDITHDRNAMESET : CfgEdithdrnameset (); break;
|
|
case CRC_EDITHDRNODESET : CfgEdithdrnodeset (); break;
|
|
case CRC_EDITHEADERATTRS : CfgEditheaderattrs (); break;
|
|
case CRC_EDITHEADERFIRST : CfgEditheaderfirst (); break;
|
|
case CRC_EDITINTERNAL : CfgEditinternal (); break;
|
|
case CRC_EDITMENU : CfgEditmenu (); break;
|
|
case CRC_EDITMIXCASE : CfgEditmixcase (); break;
|
|
case CRC_EDITOR : CfgEditor (); break;
|
|
case CRC_EDITORFILE : CfgEditorfile (); break;
|
|
case CRC_EDITQUOTEMARGIN : CfgEditquotemargin (); break;
|
|
case CRC_EDITREPLYRE : CfgEditreplyre (); break;
|
|
case CRC_EDITSAVEMENU : CfgEditsavemenu (); break;
|
|
case CRC_EDITSAVEUTIL : CfgEditsaveutil (); break;
|
|
case CRC_EDITSOFTCRXLAT : CfgEditsoftcrxlat (); break;
|
|
case CRC_EDITSPELLCHECK : CfgEditspellcheck (); break;
|
|
case CRC_EDITUNDELETE : CfgEditundelete (); break;
|
|
case CRC_ENDGROUP : CfgEndgroup (); break;
|
|
case CRC_ENCODEEMAILHEADERS: CfgEncodeemailheaders(); break;
|
|
case CRC_EVENT : CfgEvent (); break;
|
|
case CRC_EXCLUDENODES : CfgExcludenodes (); break;
|
|
case CRC_EXTERNOPTIONS : CfgExternoptions (); break;
|
|
case CRC_EXTERNUTIL : CfgExternutil (); break;
|
|
case CRC_EZYCOMMSGBASE : CfgEzycommsgbase (); break;
|
|
case CRC_EZYCOMUSERBASE : CfgEzycomuserbase (); break;
|
|
case CRC_EZYCOMUSERNO : CfgEzycomuserno (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchF:
|
|
switch(crc) {
|
|
case CRC_FIDOLASTREAD : CfgFidolastread (); break;
|
|
case CRC_FIDOMSGTYPE : CfgFidomsgtype (); break;
|
|
case CRC_FIDOUSERLIST : CfgFidouserlist (); break;
|
|
case CRC_FIDOUSERNO : CfgFidouserno (); break;
|
|
case CRC_FILEALIAS : CfgFilealias (); break;
|
|
case CRC_FORCETEMPLATE : CfgForcetemplate (); break;
|
|
case CRC_FRQEXT : CfgFrqext (); break;
|
|
case CRC_FRQNODEMAP : CfgFrqnodemap (); break;
|
|
case CRC_FRQOPTIONS : CfgFrqoptions (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchG:
|
|
switch(crc) {
|
|
case CRC_GEDHANDSHAKE : CfgGedhandshake (); break;
|
|
case CRC_GERMANKEYBOARD : CfgGermankeyboard (); break;
|
|
case CRC_GOLDBASEPATH : CfgGoldbasepath (); break;
|
|
case CRC_GOLDBASESYSPATH : CfgGoldbasesyspath (); break;
|
|
case CRC_GOLDBASEUSERNO : CfgGoldbaseuserno (); break;
|
|
case CRC_GOLDPATH : CfgGoldpath (); break;
|
|
case CRC_GROUP : CfgGroup (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchH:
|
|
switch(crc) {
|
|
case CRC_HUDSONPATH : CfgHudsonpath (); break;
|
|
case CRC_HUDSONSIZEWARN : CfgHudsonsizewarn (); break;
|
|
case CRC_HUDSONSYSPATH : CfgHudsonsyspath (); break;
|
|
case CRC_HUDSONUSERNO : CfgHudsonuserno (); break;
|
|
case CRC_HIGHLIGHTURLS : CfgHighlighturls (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchI:
|
|
switch(crc) {
|
|
case CRC_IGNORECHARSET : CfgIgnorecharset (); break;
|
|
case CRC_IMPORTBEGIN : CfgImportbegin (); break;
|
|
case CRC_IMPORTEND : CfgImportend (); break;
|
|
case CRC_INBOUNDPATH : CfgInboundpath (); break;
|
|
case CRC_INCLUDENODES : CfgIncludenodes (); break;
|
|
case CRC_INPUTFILE : CfgInputfile (); break;
|
|
case CRC_INTENSECOLORS : CfgIntensecolors (); break;
|
|
case CRC_INTERNETADDRESS : CfgInternetaddress (); break;
|
|
case CRC_INTERNETDOMAIN : CfgInternetdomain (); break;
|
|
case CRC_INTERNETGATE : CfgInternetgate (); break;
|
|
case CRC_INTERNETGATEEXP : CfgInternetgateexp (); break;
|
|
case CRC_INTERNETMSGID : CfgInternetmsgid (); break;
|
|
case CRC_INTERNETRFCBODY : CfgInternetrfcbody (); break;
|
|
case CRC_INTERNETVIAGATE : CfgInternetviagate (); break;
|
|
case CRC_INVALIDATE : CfgInvalidate (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchJ:
|
|
switch(crc) {
|
|
case CRC_JAMPATH : CfgJampath (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchK:
|
|
switch(crc) {
|
|
case CRC_KEYBMODE : CfgKeybmode (); break;
|
|
case CRC_KEYBSTACK : CfgKeybstack (); break;
|
|
case CRC_KLUDGE : CfgKludge (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchL:
|
|
switch(crc) {
|
|
case CRC_LATINTOLOCAL : CfgLatintolocal (); break;
|
|
case CRC_LOADLANGUAGE : CfgLoadlanguage (); break;
|
|
case CRC_LOCATIONALIAS : CfgLocationalias (); break;
|
|
case CRC_LOCATIONDELIMITER: CfgLocationdelimiter(); break;
|
|
case CRC_LOGFILE : CfgLogfile (); break;
|
|
case CRC_LOGFORMAT : CfgLogformat (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchM:
|
|
switch(crc) {
|
|
case CRC_MAILINGLIST : CfgMailinglist (); break;
|
|
case CRC_MAILTOSS : CfgMailtoss (); break;
|
|
case CRC_MAPPATH : CfgMappath (); break;
|
|
case CRC_MEMBER : CfgMember (); break;
|
|
case CRC_MENUMARKED : CfgMenumarked (); break;
|
|
case CRC_MENUNEXTAREA : CfgMenunextarea (); break;
|
|
case CRC_MSGLISTDATE : CfgMsglistdate (); break;
|
|
case CRC_MSGLISTFAST : CfgMsglistfast (); break;
|
|
case CRC_MSGLISTFIRST : CfgMsglistfirst (); break;
|
|
case CRC_MSGLISTHEADER : CfgMsglistheader (); break;
|
|
case CRC_MSGLISTWIDESUBJ : CfgMsglistwidesubj (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchN:
|
|
switch(crc) {
|
|
case CRC_NAMESFILE : CfgNamesfile (); break;
|
|
case CRC_NICKNAME : CfgNickname (); break;
|
|
case CRC_NETNAME : CfgNetname (); break;
|
|
case CRC_NODELIST : CfgNodelist (); break;
|
|
case CRC_NODEPATH : CfgNodepath (); break;
|
|
case CRC_NODEPATHFD : CfgNodepathfd (); break;
|
|
case CRC_NODEPATHIM : CfgNodepathfd (); break;
|
|
case CRC_NODEPATHV7 : CfgNodepathv7 (); break;
|
|
case CRC_NODEV7FLAGS : CfgNodev7flags (); break;
|
|
case CRC_NODEV7MODEM : CfgNodev7modem (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchO:
|
|
switch(crc) {
|
|
case CRC_ORGANIZATION : CfgOrganization (); break;
|
|
case CRC_ORIGIN : CfgOrigin (); break;
|
|
case CRC_OUTBOUNDPATH : CfgOutboundpath (); break;
|
|
case CRC_OUTPUTFILE : CfgOutputfile (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchP:
|
|
switch(crc) {
|
|
case CRC_PATHREPORTFILE : CfgPathreportfile (); break;
|
|
case CRC_PCBOARDPATH : CfgPcboardpath (); break;
|
|
case CRC_PCBOARDUSERNO : CfgPcboarduserno (); break;
|
|
case CRC_PEEKURLOPTIONS : CfgPeekurloptions (); break;
|
|
case CRC_PERSONALMAIL : CfgPersonalmail (); break;
|
|
case CRC_PLAY : CfgPlay (); break;
|
|
case CRC_PRINTDEVICE : CfgPrintdevice (); break;
|
|
case CRC_PRINTINIT : CfgPrintinit (); break;
|
|
case CRC_PRINTLENGTH : CfgPrintlength (); break;
|
|
case CRC_PRINTMARGIN : CfgPrintmargin (); break;
|
|
case CRC_PRINTRESET : CfgPrintreset (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchQ:
|
|
switch(crc) {
|
|
case CRC_QUOTEBUFFILE : CfgQuotebuffile (); break;
|
|
case CRC_QUOTEBUFMODE : CfgQuotebufmode (); break;
|
|
case CRC_QUOTECHARS : CfgQuotechars (); break;
|
|
case CRC_QUOTECTRL : CfgQuotectrl (); break;
|
|
case CRC_QUOTEMARGIN : CfgQuotemargin (); break;
|
|
case CRC_QUOTESTRING : CfgQuotestring (); break;
|
|
case CRC_QUOTESTOPS : CfgQuotestops (); break;
|
|
case CRC_QUOTEWRAPHARD : CfgQuotewraphard (); break;
|
|
case CRC_QUOTEUSENEWAI : CfgQuoteusenewai (); break;
|
|
case CRC_QWKBADMSGS : CfgQwkbadmsgs (); break;
|
|
case CRC_QWKCONFMAP : CfgQwkconfmap (); break;
|
|
case CRC_QWKEXPORTPATH : CfgQwkexportpath (); break;
|
|
case CRC_QWKIMPORTPATH : CfgQwkimportpath (); break;
|
|
case CRC_QWKOPTIONS : CfgQwkoptions (); break;
|
|
case CRC_QWKREPLYLINKER : CfgQwkreplylinker (); break;
|
|
case CRC_QWKTOSSLOG : CfgQwktosslog (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchR:
|
|
switch(crc) {
|
|
case CRC_RA2USERSBBS : CfgRa2usersbbs (); break;
|
|
case CRC_REPLYLINK : CfgReplylink (); break;
|
|
case CRC_REPLYLINKFLOAT : CfgReplylinkfloat (); break;
|
|
case CRC_REPLYLINKLIST : CfgReplylinklist (); break;
|
|
case CRC_REPLYLINKSHOWALWAYS:CfgReplylinkshowalways();break;
|
|
case CRC_ROBOTNAME : CfgRobotname (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchS:
|
|
switch(crc)
|
|
{
|
|
#if defined(GCFG_SPELL_INCLUDED)
|
|
case CRC_SCHECKERENABLED : CfgScheckerenabled (); break;
|
|
case CRC_SCHECKERDEFLANG : CfgScheckerdeflang (); break;
|
|
case CRC_SCHECKERUSERDIC : CfgScheckeruserdic (); break;
|
|
case CRC_SCHECKERDICPATH : CfgScheckerdicpath (); break;
|
|
#endif
|
|
case CRC_SCREENBLANKER : CfgScreenblanker (); break;
|
|
case CRC_SCREENMAXCOL : CfgScreenmaxcol (); break;
|
|
case CRC_SCREENMAXROW : CfgScreenmaxrow (); break;
|
|
case CRC_SCREENPALETTE : CfgScreenpalette (); break;
|
|
case CRC_SCREENSIZE : CfgScreensize (); break;
|
|
case CRC_SEARCHFOR : CfgSearchfor (); break;
|
|
case CRC_SEMAPHORE : CfgSemaphore (); break;
|
|
case CRC_SEQDIR : CfgSeqDir (); break;
|
|
case CRC_SEQMSGID : CfgSeqMsgId (); break;
|
|
case CRC_SEQOUTRUN : CfgSeqOutRun (); break;
|
|
case CRC_SHAREMODE : CfgSharemode (); break;
|
|
case CRC_SHOWDELETED : CfgShowdeleted (); break;
|
|
case CRC_SOUNDPATH : CfgSoundpath (); break;
|
|
case CRC_SOUPBADMSGS : CfgSoupbadmsgs (); break;
|
|
case CRC_SOUPEMAIL : CfgSoupemail (); break;
|
|
case CRC_SOUPEXPORTMARGIN : CfgSoupexportmargin (); break;
|
|
case CRC_SOUPEXPORTPATH : CfgSoupexportpath (); break;
|
|
case CRC_SOUPIMPORTPATH : CfgSoupimportpath (); break;
|
|
case CRC_SOUPNEWSRCFILE : CfgSoupnewsrcfile (); break;
|
|
case CRC_SOUPREPLYLINKER : CfgSoupreplylinker (); break;
|
|
case CRC_SOUPREPLYTO : CfgSoupreplyto (); break;
|
|
case CRC_SOUPTOSSLOG : CfgSouptosslog (); break;
|
|
case CRC_SQUISHSCAN : CfgSquishscan (); break;
|
|
case CRC_SQUISHUSERNO : CfgSquishuserno (); break;
|
|
case CRC_SQUISHUSERPATH : CfgSquishuserpath (); break;
|
|
case CRC_STATUSLINEHELP : CfgStatuslinehelp (); break;
|
|
case CRC_STRIPHTML : CfgStripHTML (); break;
|
|
case CRC_STYLECODEPUNCT : CfgStylecodepunct (); break;
|
|
case CRC_STYLECODES : CfgStylecodes (); break;
|
|
case CRC_STYLECODESTOPS : CfgStylecodestops (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchT:
|
|
switch(crc) {
|
|
case CRC_TAGLINE : CfgTagline (); break;
|
|
case CRC_TAGLINECHAR : CfgTaglinechar (); break;
|
|
case CRC_TAGLINESUPPORT : CfgTaglinesupport (); break;
|
|
case CRC_TASKTITLE : CfgTasktitle (); break;
|
|
case CRC_TEARLINE : CfgTearline (); break;
|
|
case CRC_TEMPLATE : CfgTemplate (); break;
|
|
case CRC_TEMPLATEMATCH : CfgTemplatematch (); break;
|
|
case CRC_TEMPLATEPATH : CfgTemplatepath (); break;
|
|
case CRC_TEMPPATH : CfgTemppath (); break;
|
|
case CRC_TIMEOUT : CfgTimeout (); break;
|
|
case CRC_TITLESTATUS : CfgTitlestatus (); break;
|
|
case CRC_TRANSLATE : CfgTranslate (); break;
|
|
case CRC_TRANSPARENTCOLORS: CfgTransparentcolors(); break;
|
|
case CRC_TWITMODE : CfgTwitmode (); break;
|
|
case CRC_TWITNAME : CfgTwitname (); break;
|
|
case CRC_TWITSUBJ : CfgTwitsubj (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchU:
|
|
switch(crc) {
|
|
case CRC_UNPACKER : CfgUnpacker (); break;
|
|
case CRC_URLHANDLER : CfgUrlhandler (); break;
|
|
case CRC_URLSCHEME : CfgUrlscheme (); break;
|
|
case CRC_USEAREA : CfgUsearea (); break;
|
|
case CRC_USECHARSET : CfgUsecharset (); break;
|
|
case CRC_USEFWD : CfgUsefwd (); break;
|
|
case CRC_USEINTL : CfgUseintl (); break;
|
|
case CRC_USEPID : CfgUsepid (); break;
|
|
case CRC_USERLIST : CfgUserlist (); break;
|
|
case CRC_USERLISTFILE : CfgUserlistfile (); break;
|
|
case CRC_USERNAME : CfgUsername (); break;
|
|
case CRC_USESOFTCRXLAT : CfgUsesoftcrxlat (); break;
|
|
case CRC_USETZUTC : CfgUsetzutc (); break;
|
|
case CRC_UUDECODEPATH : CfgUudecodepath (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchV:
|
|
switch(crc) {
|
|
case CRC_VIEWHIDDEN : CfgViewhidden (); break;
|
|
case CRC_VIEWKLUDGE : CfgViewkludge (); break;
|
|
case CRC_VIEWQUOTE : CfgViewquote (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchW:
|
|
switch(crc) {
|
|
case CRC_WHOTO : CfgWhoto (); break;
|
|
case CRC_WILDCATUSERNO : CfgWildcatuserno (); break;
|
|
case CRC_WRITEHEADER : CfgWriteheader (); break;
|
|
case CRC_WRITETEMPLATE : CfgWritetemplate (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchX:
|
|
switch(crc) {
|
|
case CRC_XLATCHARSET : CfgXlatcharset (); break;
|
|
case CRC_XLATCHARSETALIAS : CfgXlatcharsetalias (); break;
|
|
case CRC_XLATESCSET : CfgXlatescset (); break;
|
|
case CRC_XLATEXPORT : CfgXlatexport (); break;
|
|
case CRC_XLATIMPORT : CfgXlatimport (); break;
|
|
case CRC_XLATLOCALSET : CfgXlatlocalset (); break;
|
|
case CRC_XLATPATH : CfgXlatpath (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchY:
|
|
switch(crc) {
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
SwitchZ:
|
|
switch(crc) {
|
|
case CRC_ZONEGATING : CfgZonegating (); break;
|
|
default : found = false;
|
|
}
|
|
goto End;
|
|
|
|
End:
|
|
if(found)
|
|
return true;
|
|
|
|
if(cmdlineoldkeyw == false)
|
|
return false;
|
|
|
|
switch(crc) {
|
|
case CRC_AREA : CfgArea (); break;
|
|
case CRC_REGISTERKEY : break;
|
|
case CRC_REGISTERNAME : break;
|
|
case CRC_SERIALNO : break;
|
|
default : return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
static int do_if(char* val) {
|
|
|
|
if (val == NULL) {
|
|
STD_PRINTNL("! Illegall call of function: do_if(NULL). File " __FILE__ " line " << __LINE__);
|
|
LOG_NULL_POINTER;
|
|
LOG.printf("! Illegall call of function: do_if(NULL). File %s line %i.", __FILE__, __LINE__);
|
|
PointerErrorExit();
|
|
return 0;
|
|
}
|
|
if(strieql(val, "OS/2") or strieql(val, "OS2")) {
|
|
#ifdef __OS2__
|
|
return true;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
else if(strieql(val, "NT") or strieql(val, "W32") or strieql(val, "WIN32")) {
|
|
#ifdef __WIN32__
|
|
return true;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
else if(strieql(val, "386") or strieql(val, "DOS") or strieql(val, "DPMI32")) {
|
|
#ifdef __MSDOS__
|
|
return true;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
else if(strieql(val, "LINUX") or strieql(val, "UNIX")) {
|
|
#ifdef __UNIX__
|
|
return true;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
else if (strieql(val, "SPELL"))
|
|
{
|
|
#ifdef GCFG_SPELL_INCLUDED
|
|
return true;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
else if(strieql(val, "FIREBIRD"))
|
|
return true;
|
|
else if(strieql(val, "ASA") or strieql(val, "PLUS"))
|
|
return true;
|
|
else if(strieql(val, "YES") or strieql(val, "TRUE") or strieql(val, "ON"))
|
|
return true;
|
|
return !!atoi(val);
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
// Compile a GoldED text config file
|
|
// Return 1 if success, return 0 if error
|
|
|
|
int ReadCfg(const char* cfgfile, int ignoreunknown)
|
|
{
|
|
const word CRC_APP = 0x08B5;
|
|
|
|
Path cfg;
|
|
char buf[1024];
|
|
static int inuse = 0;
|
|
static int in_if = false;
|
|
static int in_else = false;
|
|
static int if_status = false;
|
|
char* val;
|
|
char* key;
|
|
char* cfgname;
|
|
word crc;
|
|
int cfgignore=NO, line=0;
|
|
|
|
if (cfgfile == NULL) {
|
|
STD_PRINTNL("! Illegall call of function: ReadCfg(NULL," << ignoreunknown << "). File " __FILE__ " line " << __LINE__);
|
|
LOG_NULL_POINTER;
|
|
LOG.printf("! Illegall call of function: ReadCfg(NULL,%i). File %s line %i ", ignoreunknown, __FILE__, __LINE__);
|
|
PointerErrorExit();
|
|
return 0;
|
|
}
|
|
// Open the file
|
|
if(strlen(cfgfile) >= GMAXPATH) {
|
|
STD_PRINTNL("* Filename '" << cfgfile << "' too long (max " << GMAXPATH-1 << " characters).");
|
|
LOG.ErrOpen();
|
|
LOG.printf("! Unable to use configuration file because filename too long (see next line):");
|
|
LOG.printf("%s",cfgfile);
|
|
cfgerrors++;
|
|
return 0; // Error: can't use too long file name
|
|
}
|
|
strxcpy(cfg, cfgfile, GMAXPATH);
|
|
MakePathname(cfg, CFG->goldpath, cfg);
|
|
if(cfg[0] == '\0') {
|
|
STD_PRINTNL("* Can't read '" << cfgfile << "': ca't construct full pathname, sorry");
|
|
LOG.ErrOpen();
|
|
LOG.printf("! Unable to use configuration file '%s' because unable to construct full pathname", cfgfile);
|
|
cfgerrors++;
|
|
return 0; // Error: can't use specified file name
|
|
}
|
|
|
|
gfile fp(cfg, "rt", CFG->sharemode);
|
|
if (fp.isopen())
|
|
{
|
|
cfgname = strrchr(cfg, '\\');
|
|
cfgname = cfgname ? cfgname+1 : cfg;
|
|
inuse++;
|
|
|
|
if (not quiet)
|
|
STD_PRINTNL("* Reading " << cfg);
|
|
|
|
// Assign file buffer
|
|
fp.SetvBuf(NULL, _IOFBF, 8192);
|
|
|
|
// Read each line
|
|
while (fp.Fgets((val=buf), sizeof(buf)))
|
|
{
|
|
line++;
|
|
|
|
// Replace TABs with SPACEs
|
|
strchg(val, '\t', ' ');
|
|
|
|
val = strskip_wht(val);
|
|
|
|
if(g_isalpha(*val)) {
|
|
|
|
// Extract key and val
|
|
crc = getkeyvalcrc(&key, &val);
|
|
|
|
int _gotcond = true;
|
|
switch(crc) {
|
|
case CRC_IF:
|
|
if (in_if)
|
|
{
|
|
STD_PRINTNL("* " << cfgname << ": Misplaced IF at line " << line << ". IF's cannot be nested.");
|
|
cfgerrors++;
|
|
}
|
|
in_if = true;
|
|
if_status = do_if(val);
|
|
cfgignore = not if_status;
|
|
break;
|
|
case CRC_ELIF:
|
|
case CRC_ELSEIF:
|
|
if (not in_if or in_else)
|
|
{
|
|
STD_PRINTNL("* " << cfgname << ": Misplaced ELIF/ELSEIF at line " << line << ".");
|
|
cfgerrors++;
|
|
}
|
|
if(if_status)
|
|
cfgignore = true;
|
|
else {
|
|
if_status = do_if(val);
|
|
cfgignore = not if_status;
|
|
}
|
|
break;
|
|
case CRC_ELSE:
|
|
if (not in_if or in_else)
|
|
{
|
|
STD_PRINTNL("* " << cfgname << ": Misplaced ELSE at line " << line << ".");
|
|
cfgerrors++;
|
|
}
|
|
in_else = true;
|
|
if_status ^= true;
|
|
cfgignore = not if_status;
|
|
break;
|
|
case CRC_ENDIF:
|
|
if (not in_if)
|
|
{
|
|
STD_PRINTNL("* " << cfgname << ": Misplaced ENDIF at line " << line << ".");
|
|
cfgerrors++;
|
|
}
|
|
cfgignore = false;
|
|
in_if = in_else = false;
|
|
break;
|
|
case CRC_IGNORE:
|
|
cfgignore ^= true;
|
|
break;
|
|
default:
|
|
_gotcond = false;
|
|
}
|
|
|
|
// Tell the world what we found
|
|
if (veryverbose)
|
|
{
|
|
char buff[256];
|
|
gsprintf(PRINTF_DECLARE_BUFFER(buff), " %c %04d: %s %s\n", cfgignore ? '-' : '+', line, key, val);
|
|
STD_PRINT(buff);
|
|
}
|
|
|
|
// Call switch function to act on the key
|
|
if(not cfgignore) {
|
|
if(not _gotcond) {
|
|
switch(crc) {
|
|
case CRC_INCLUDE:
|
|
strschg_environ(val, (buf+sizeof(buf))-val);
|
|
MapPath(val);
|
|
|
|
if (not quiet)
|
|
STD_PRINTNL("* Including " << val);
|
|
|
|
ReadCfg(val); // NOTE! This is a recursive call!
|
|
|
|
if (not quiet)
|
|
STD_PRINTNL("* Resuming " << cfg);
|
|
|
|
break;
|
|
case CRC_AREAFILE:
|
|
strschg_environ(val, (buf+sizeof(buf))-val);
|
|
MapPath(val);
|
|
|
|
if (not quiet)
|
|
STD_PRINTNL("* Handling " << key << " " << val);
|
|
|
|
AL.GetAreafile(val);
|
|
|
|
if (not quiet)
|
|
STD_PRINTNL("* Resuming " << cfg);
|
|
|
|
break;
|
|
case CRC_APP:
|
|
// Ignore 3rd party application lines
|
|
break;
|
|
case CRC_REM:
|
|
// Ignore remark lines
|
|
break;
|
|
default:
|
|
if (not SwitchCfg(crc, *key, val))
|
|
{
|
|
if (not ignoreunknown)
|
|
{
|
|
STD_PRINTNL("* " << cfgname << ": Unknown keyword \"" << key << "\" at line " << line << ".");
|
|
SayBibi();
|
|
cfgerrors++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Close and return all OK
|
|
fp.Fclose();
|
|
inuse--;
|
|
|
|
// When the final cfg is compiled
|
|
if (inuse == 0)
|
|
{
|
|
// Mark all areas listed in the NEWSRC file as newsgroups
|
|
if (*CFG->soupnewsrcfile)
|
|
{
|
|
gfile gfp(CFG->soupnewsrcfile, "rt");
|
|
if (gfp.isopen())
|
|
{
|
|
char buf2[512];
|
|
while (gfp.Fgets(buf2, sizeof(buf2)))
|
|
{
|
|
char* ptr = strpbrk(buf2, ":! ");
|
|
if(ptr) {
|
|
*ptr = NUL;
|
|
Area* ap = AL.AreaEchoToPtr(buf2);
|
|
if(ap)
|
|
ap->set_type(ap->isnet() ? GMB_SOUP|GMB_EMAIL|GMB_NET : GMB_SOUP|GMB_NEWSGROUP|GMB_ECHO);
|
|
}
|
|
}
|
|
gfp.Fclose();
|
|
}
|
|
}
|
|
|
|
if(*CFG->soupemail) {
|
|
Area* ap = AL.AreaEchoToPtr(CFG->soupemail);
|
|
if(ap)
|
|
ap->set_type(GMB_SOUP|GMB_EMAIL|GMB_NET);
|
|
}
|
|
|
|
std::vector<MailList>::iterator z;
|
|
for(z = CFG->mailinglist.begin(); z != CFG->mailinglist.end(); z++) {
|
|
Area* ap = AL.AreaEchoToPtr(z->echoid);
|
|
if(ap)
|
|
ap->set_type(GMB_SOUP|GMB_EMAIL|GMB_NET);
|
|
}
|
|
|
|
// Mark all QWK areas
|
|
if(QWK->FirstBBS()) {
|
|
do {
|
|
if(QWK->FirstConf()) {
|
|
do {
|
|
Area* ap = AL.AreaEchoToPtr(QWK->ConfName());
|
|
if(ap)
|
|
ap->set_type(ap->type() | GMB_QWK);
|
|
} while(QWK->NextConf());
|
|
}
|
|
} while(QWK->NextBBS());
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
else {
|
|
|
|
LOG.ErrOpen();
|
|
LOG.printf("! Unable to open configuration file.");
|
|
LOG.printf(": %s", cfg);
|
|
LOG.ErrOSInfo();
|
|
OpenErrorExit();
|
|
}
|
|
|
|
// Error opening file
|
|
return 0;
|
|
}
|
|
|
|
|
|
// ------------------------------------------------------------------
|