
//  ------------------------------------------------------------------
//  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, BUFSIZ);

        // 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;
}


//  ------------------------------------------------------------------
