diff --git a/docs/rh-log.txt b/docs/rh-log.txt index 9dfd9d61c0..f74b5e42e3 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,13 @@ +December 6, 2008 +- Moved ExpandEnvVars() from d_main.cpp to cmdlib.cpp. +- AutoExec paths now support the same variable expansion as the search paths. + Additionally, on Windows, the default autoexec path is now relative to + $PROGDIR, rather than using a fixed path to the executable's current + directory. +- All usable Autoload and AutoExec sections are now created at the top of + the config file along with some brief explanatory notes so they are + readily visible to anyone who wants to edit them. + December 6, 2008 (Changes by Graf Zahl) - Fixed: G_DoPlayDemo did not free the demobuffer or the CVAR backups when it failed to start the demo. @@ -19,7 +29,8 @@ December 1, 2008 (Changes by Graf Zahl) December 1, 2008 - Restored the multiplayer scoreboard's former centering so that it doesn't - look awful on widescreen intermissions. + look awful on widescreen intermissions. Also changed the column widths to + be font-dependant rather than fixed proportions of the screen width. - Fixed horizontal positioning of 'finished' on the Raven games when scaled. November 30, 2008 (Changes by Graf Zahl) diff --git a/src/cmdlib.cpp b/src/cmdlib.cpp index 84be27bea0..f1e087a283 100644 --- a/src/cmdlib.cpp +++ b/src/cmdlib.cpp @@ -469,3 +469,68 @@ int strbin (char *str) *str = 0; return str - start; } + +//========================================================================== +// +// ExpandEnvVars +// +// Expands environment variable references in a string. Intended primarily +// for use with IWAD search paths in config files. +// +//========================================================================== + +FString ExpandEnvVars(const char *searchpathstring) +{ + static const char envvarnamechars[] = + "01234567890" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "_" + "abcdefghijklmnopqrstuvwxyz"; + + if (searchpathstring == NULL) + return FString(""); + + const char *dollar = strchr(searchpathstring, '$'); + if (dollar == NULL) + { + return FString(searchpathstring); + } + + const char *nextchars = searchpathstring; + FString out = FString(searchpathstring, dollar - searchpathstring); + while ( (dollar != NULL) && (*nextchars != 0) ) + { + size_t length = strspn(dollar + 1, envvarnamechars); + if (length != 0) + { + FString varname = FString(dollar + 1, length); + if (stricmp(varname, "progdir") == 0) + { + out += progdir; + } + else + { + char *varvalue = getenv(varname); + if ( (varvalue != NULL) && (strlen(varvalue) != 0) ) + { + out += varvalue; + } + } + } + else + { + out += '$'; + } + nextchars = dollar + length + 1; + dollar = strchr(nextchars, '$'); + if (dollar != NULL) + { + out += FString(nextchars, dollar - nextchars); + } + } + if (*nextchars != 0) + { + out += nextchars; + } + return out; +} diff --git a/src/cmdlib.h b/src/cmdlib.h index cf9242af01..aafb9129cb 100644 --- a/src/cmdlib.h +++ b/src/cmdlib.h @@ -55,4 +55,6 @@ int strbin (char *str); void CreatePath(const char * fn); +FString ExpandEnvVars(const char *searchpathstring); + #endif diff --git a/src/configfile.cpp b/src/configfile.cpp index 23d47996ab..265c586853 100644 --- a/src/configfile.cpp +++ b/src/configfile.cpp @@ -3,7 +3,7 @@ ** Implements the basic .ini parsing class ** **--------------------------------------------------------------------------- -** Copyright 1998-2006 Randy Heit +** Copyright 1998-2008 Randy Heit ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -30,11 +30,6 @@ ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. **--------------------------------------------------------------------------- ** -** This could have been done with a lot less source code using the STL and -** maps, but how much larger would the object code be? -** -** Regardless of object size, I had not considered the possibility of using -** the STL when I wrote this. */ #include @@ -46,6 +41,12 @@ #define READBUFFERSIZE 256 +//==================================================================== +// +// FConfigFile Constructor +// +//==================================================================== + FConfigFile::FConfigFile () { Sections = CurrentSection = NULL; @@ -54,6 +55,12 @@ FConfigFile::FConfigFile () PathName = ""; } +//==================================================================== +// +// FConfigFile Constructor +// +//==================================================================== + FConfigFile::FConfigFile (const char *pathname, void (*nosechandler)(const char *pathname, FConfigFile *config, void *userdata), void *userdata) @@ -65,6 +72,12 @@ FConfigFile::FConfigFile (const char *pathname, LoadConfigFile (nosechandler, userdata); } +//==================================================================== +// +// FConfigFile Copy Constructor +// +//==================================================================== + FConfigFile::FConfigFile (const FConfigFile &other) { Sections = CurrentSection = NULL; @@ -74,6 +87,12 @@ FConfigFile::FConfigFile (const FConfigFile &other) *this = other; } +//==================================================================== +// +// FConfigFile Destructor +// +//==================================================================== + FConfigFile::~FConfigFile () { FConfigSection *section = Sections; @@ -90,11 +109,18 @@ FConfigFile::~FConfigFile () delete[] (char *)entry; entry = nextentry; } + section->~FConfigSection(); delete[] (char *)section; section = nextsection; } } +//==================================================================== +// +// FConfigFile Copy Operator +// +//==================================================================== + FConfigFile &FConfigFile::operator = (const FConfigFile &other) { FConfigSection *fromsection, *tosection; @@ -116,6 +142,14 @@ FConfigFile &FConfigFile::operator = (const FConfigFile &other) return *this; } +//==================================================================== +// +// FConfigFile :: ClearConfig +// +// Removes all sections and entries from the config file. +// +//==================================================================== + void FConfigFile::ClearConfig () { CurrentSection = Sections; @@ -130,11 +164,73 @@ void FConfigFile::ClearConfig () LastSectionPtr = &Sections; } +//==================================================================== +// +// FConfigFile :: ChangePathName +// +//==================================================================== + void FConfigFile::ChangePathName (const char *pathname) { PathName = pathname; } +//==================================================================== +// +// FConfigFile :: CreateSectionAtStart +// +// Creates the section at the start of the file if it does not exist. +// Otherwise, simply moves the section to the start of the file. +// +//==================================================================== + +void FConfigFile::CreateSectionAtStart (const char *name) +{ + NewConfigSection (name); + MoveSectionToStart (name); +} + +//==================================================================== +// +// FConfigFile :: MoveSectionToStart +// +// Moves the named section to the start of the file if it exists. +// Otherwise, does nothing. +// +//==================================================================== + +void FConfigFile::MoveSectionToStart (const char *name) +{ + FConfigSection *section = FindSection (name); + + if (section != NULL) + { + FConfigSection **prevsec = &Sections; + while (*prevsec != NULL && *prevsec != section) + { + prevsec = &((*prevsec)->Next); + } + *prevsec = section->Next; + section->Next = Sections; + Sections = section; + if (LastSectionPtr == §ion->Next) + { + LastSectionPtr = prevsec; + } + } +} + + +//==================================================================== +// +// FConfigFile :: SetSection +// +// Sets the current section to the named one, optionally creating it +// if it does not exist. Returns true if the section exists (even if +// it was newly created), false otherwise. +// +//==================================================================== + bool FConfigFile::SetSection (const char *name, bool allowCreate) { FConfigSection *section = FindSection (name); @@ -151,6 +247,14 @@ bool FConfigFile::SetSection (const char *name, bool allowCreate) return false; } +//==================================================================== +// +// FConfigFile :: SetFirstSection +// +// Sets the current section to the first one in the file. +// +//==================================================================== + bool FConfigFile::SetFirstSection () { CurrentSection = Sections; @@ -162,6 +266,14 @@ bool FConfigFile::SetFirstSection () return false; } +//==================================================================== +// +// FConfigFile :: SetNextSection +// +// Advances the current section to the next one in the file. +// +//==================================================================== + bool FConfigFile::SetNextSection () { if (CurrentSection != NULL) @@ -176,6 +288,14 @@ bool FConfigFile::SetNextSection () return false; } +//==================================================================== +// +// FConfigFile :: GetCurrentSection +// +// Returns the name of the current section. +// +//==================================================================== + const char *FConfigFile::GetCurrentSection () const { if (CurrentSection != NULL) @@ -185,6 +305,14 @@ const char *FConfigFile::GetCurrentSection () const return NULL; } +//==================================================================== +// +// FConfigFile :: ClearCurrentSection +// +// Removes all entries from the current section. +// +//==================================================================== + void FConfigFile::ClearCurrentSection () { if (CurrentSection != NULL) @@ -204,6 +332,30 @@ void FConfigFile::ClearCurrentSection () } } +//==================================================================== +// +// FConfigFile :: SectionIsEmpty +// +// Returns true if the current section has no entries. If there is +// no current section, it is also considered empty. +// +//==================================================================== + +bool FConfigFile::SectionIsEmpty() +{ + return (CurrentSection == NULL) || (CurrentSection->RootEntry == NULL); +} + + +//==================================================================== +// +// FConfigFile :: NextInSection +// +// Provides the next key/value pair in the current section. Returns +// true if there was another, false otherwise. +// +//==================================================================== + bool FConfigFile::NextInSection (const char *&key, const char *&value) { FConfigEntry *entry = CurrentEntry; @@ -217,6 +369,15 @@ bool FConfigFile::NextInSection (const char *&key, const char *&value) return true; } +//==================================================================== +// +// FConfigFile :: GetValueForKey +// +// Returns the value for the specified key in the current section, +// returning NULL if the key does not exist. +// +//==================================================================== + const char *FConfigFile::GetValueForKey (const char *key) const { FConfigEntry *entry = FindEntry (CurrentSection, key); @@ -228,6 +389,16 @@ const char *FConfigFile::GetValueForKey (const char *key) const return NULL; } +//==================================================================== +// +// FConfigFile :: SetValueForKey +// +// Sets they key/value pair as specified in the current section. If +// duplicates are allowed, it always creates a new pair. Otherwise, it +// will overwrite the value of an existing key with the same name. +// +//==================================================================== + void FConfigFile::SetValueForKey (const char *key, const char *value, bool duplicates) { if (CurrentSection != NULL) @@ -245,6 +416,12 @@ void FConfigFile::SetValueForKey (const char *key, const char *value, bool dupli } } +//==================================================================== +// +// FConfigFile :: FindSection +// +//==================================================================== + FConfigFile::FConfigSection *FConfigFile::FindSection (const char *name) const { FConfigSection *section = Sections; @@ -256,6 +433,12 @@ FConfigFile::FConfigSection *FConfigFile::FindSection (const char *name) const return section; } +//==================================================================== +// +// FConfigFile :: FindEntry +// +//==================================================================== + FConfigFile::FConfigEntry *FConfigFile::FindEntry ( FConfigFile::FConfigSection *section, const char *key) const { @@ -268,15 +451,23 @@ FConfigFile::FConfigEntry *FConfigFile::FindEntry ( return probe; } +//==================================================================== +// +// FConfigFile :: NewConfigSection +// +//==================================================================== + FConfigFile::FConfigSection *FConfigFile::NewConfigSection (const char *name) { FConfigSection *section; + char *memblock; section = FindSection (name); if (section == NULL) { size_t namelen = strlen (name); - section = (FConfigSection *)new char[sizeof(*section)+namelen]; + memblock = new char[sizeof(*section)+namelen]; + section = ::new(memblock) FConfigSection; section->RootEntry = NULL; section->LastEntryPtr = §ion->RootEntry; section->Next = NULL; @@ -288,6 +479,12 @@ FConfigFile::FConfigSection *FConfigFile::NewConfigSection (const char *name) return section; } +//==================================================================== +// +// FConfigFile :: NewConfigEntry +// +//==================================================================== + FConfigFile::FConfigEntry *FConfigFile::NewConfigEntry ( FConfigFile::FConfigSection *section, const char *key, const char *value) { @@ -306,6 +503,12 @@ FConfigFile::FConfigEntry *FConfigFile::NewConfigEntry ( return entry; } +//==================================================================== +// +// FConfigFile :: LoadConfigFile +// +//==================================================================== + void FConfigFile::LoadConfigFile (void (*nosechandler)(const char *pathname, FConfigFile *config, void *userdata), void *userdata) { FILE *file = fopen (PathName, "r"); @@ -326,6 +529,12 @@ void FConfigFile::LoadConfigFile (void (*nosechandler)(const char *pathname, FCo } } +//==================================================================== +// +// FConfigFile :: ReadConfig +// +//==================================================================== + bool FConfigFile::ReadConfig (void *file) { char readbuf[READBUFFERSIZE]; @@ -394,11 +603,23 @@ bool FConfigFile::ReadConfig (void *file) return true; } +//==================================================================== +// +// FConfigFile :: ReadLine +// +//==================================================================== + char *FConfigFile::ReadLine (char *string, int n, void *file) const { return fgets (string, n, (FILE *)file); } +//==================================================================== +// +// FConfigFile :: WriteConfigFile +// +//==================================================================== + bool FConfigFile::WriteConfigFile () const { FILE *file = fopen (PathName, "w"); @@ -414,6 +635,10 @@ bool FConfigFile::WriteConfigFile () const while (section != NULL) { entry = section->RootEntry; + if (section->Note.IsNotEmpty()) + { + fprintf (file, "%s", section->Note.GetChars()); + } fprintf (file, "[%s]\n", section->Name); while (entry != NULL) { @@ -427,10 +652,24 @@ bool FConfigFile::WriteConfigFile () const return true; } +//==================================================================== +// +// FConfigFile :: WriteCommentHeader +// +// Override in a subclass to write a header to the config file. +// +//==================================================================== + void FConfigFile::WriteCommentHeader (FILE *file) const { } +//==================================================================== +// +// FConfigFile :: FConfigEntry :: SetValue +// +//==================================================================== + void FConfigFile::FConfigEntry::SetValue (const char *value) { if (Value != NULL) @@ -441,14 +680,62 @@ void FConfigFile::FConfigEntry::SetValue (const char *value) strcpy (Value, value); } +//==================================================================== +// +// FConfigFile :: GetPosition +// +// Populates a struct with the current position of the parse cursor. +// +//==================================================================== + void FConfigFile::GetPosition (FConfigFile::Position &pos) const { pos.Section = CurrentSection; pos.Entry = CurrentEntry; } +//==================================================================== +// +// FConfigFile :: SetPosition +// +// Sets the parse cursor to a previously retrieved position. +// +//==================================================================== + void FConfigFile::SetPosition (const FConfigFile::Position &pos) { CurrentSection = pos.Section; CurrentEntry = pos.Entry; } + +//==================================================================== +// +// FConfigFile :: SetSectionNote +// +// Sets a comment note to be inserted into the INI verbatim directly +// ahead of the section. Notes are lost when the INI is read so must +// be explicitly set to be maintained. +// +//==================================================================== + +void FConfigFile::SetSectionNote(const char *section, const char *note) +{ + SetSectionNote(FindSection(section), note); +} + +void FConfigFile::SetSectionNote(const char *note) +{ + SetSectionNote(CurrentSection, note); +} + +void FConfigFile::SetSectionNote(FConfigSection *section, const char *note) +{ + if (section != NULL) + { + if (note == NULL) + { + note = ""; + } + section->Note = note; + } +} diff --git a/src/configfile.h b/src/configfile.h index e34489b372..11453e5611 100644 --- a/src/configfile.h +++ b/src/configfile.h @@ -2,7 +2,7 @@ ** configfile.h ** **--------------------------------------------------------------------------- -** Copyright 1998-2006 Randy Heit +** Copyright 1998-2008 Randy Heit ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -50,12 +50,17 @@ public: FConfigFile &operator= (const FConfigFile &other); bool HaveSections () { return Sections != NULL; } + void CreateSectionAtStart (const char *name); + void MoveSectionToStart (const char *name); + void SetSectionNote (const char *section, const char *note); + void SetSectionNote (const char *note); bool SetSection (const char *section, bool allowCreate=false); bool SetFirstSection (); bool SetNextSection (); const char *GetCurrentSection () const; void ClearCurrentSection (); + bool SectionIsEmpty (); bool NextInSection (const char *&key, const char *&value); const char *GetValueForKey (const char *key) const; void SetValueForKey (const char *key, const char *value, bool duplicates=false); @@ -86,6 +91,7 @@ private: FConfigEntry *RootEntry; FConfigEntry **LastEntryPtr; FConfigSection *Next; + FString Note; char Name[1]; // + length of name }; @@ -99,6 +105,7 @@ private: FConfigEntry *FindEntry (FConfigSection *section, const char *key) const; FConfigSection *NewConfigSection (const char *name); FConfigEntry *NewConfigEntry (FConfigSection *section, const char *key, const char *value); + void SetSectionNote (FConfigSection *section, const char *note); public: class Position diff --git a/src/d_main.cpp b/src/d_main.cpp index bc230f6cd9..2418e47e09 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -1656,71 +1656,6 @@ static int CheckIWAD (const char *doomwaddir, WadStuff *wads) return numfound; } -//========================================================================== -// -// ExpandEnvVars -// -// Expands environment variable references in a string. Intended primarily -// for use with IWAD search paths in config files. -// -//========================================================================== - -static FString ExpandEnvVars(const char *searchpathstring) -{ - static const char envvarnamechars[] = - "01234567890" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "_" - "abcdefghijklmnopqrstuvwxyz"; - - if (searchpathstring == NULL) - return FString (""); - - const char *dollar = strchr (searchpathstring,'$'); - if (dollar == NULL) - { - return FString (searchpathstring); - } - - const char *nextchars = searchpathstring; - FString out = FString (searchpathstring, dollar - searchpathstring); - while ( (dollar != NULL) && (*nextchars != 0) ) - { - size_t length = strspn(dollar + 1, envvarnamechars); - if (length != 0) - { - FString varname = FString (dollar + 1, length); - if (stricmp (varname, "progdir") == 0) - { - out += progdir; - } - else - { - char *varvalue = getenv (varname); - if ( (varvalue != NULL) && (strlen(varvalue) != 0) ) - { - out += varvalue; - } - } - } - else - { - out += '$'; - } - nextchars = dollar + length + 1; - dollar = strchr (nextchars, '$'); - if (dollar != NULL) - { - out += FString (nextchars, dollar - nextchars); - } - } - if (*nextchars != 0) - { - out += nextchars; - } - return out; -} - //========================================================================== // // CheckIWADinEnvDir diff --git a/src/gameconfigfile.cpp b/src/gameconfigfile.cpp index 820804971c..7a5aa223d9 100644 --- a/src/gameconfigfile.cpp +++ b/src/gameconfigfile.cpp @@ -3,7 +3,7 @@ ** An .ini parser specifically for zdoom.ini ** **--------------------------------------------------------------------------- -** Copyright 1998-2006 Randy Heit +** Copyright 1998-2008 Randy Heit ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -120,6 +120,60 @@ FGameConfigFile::FGameConfigFile () #endif SetValueForKey ("Path", "$DOOMWADDIR", true); } + + // Create auto-load sections, so users know what's available. + // Note that this totem pole is the reverse of the order that + // they will appear in the file. + CreateSectionAtStart("Chex3.Autoload"); + CreateSectionAtStart("Chex.Autoload"); + CreateSectionAtStart("Strife.Autoload"); + CreateSectionAtStart("HexenDemo.Autoload"); + CreateSectionAtStart("HexenDK.Autoload"); + CreateSectionAtStart("Hexen.Autoload"); + CreateSectionAtStart("Heretic.Autoload"); + CreateSectionAtStart("FreeDM.Autoload"); + CreateSectionAtStart("Freedoom1.Autoload"); + CreateSectionAtStart("Freedoom.Autoload"); + CreateSectionAtStart("Plutonia.Autoload"); + CreateSectionAtStart("TNT.Autoload"); + CreateSectionAtStart("Doom2.Autoload"); + CreateSectionAtStart("Doom1.Autoload"); + CreateSectionAtStart("Doom.Autoload"); + CreateSectionAtStart("Global.Autoload"); + + // The same goes for auto-exec files. + CreateStandardAutoExec("Chex.AutoExec", true); + CreateStandardAutoExec("Strife.AutoExec", true); + CreateStandardAutoExec("Hexen.AutoExec", true); + CreateStandardAutoExec("Heretic.AutoExec", true); + CreateStandardAutoExec("Doom.AutoExec", true); + + // Move search paths back to the top. + MoveSectionToStart("FileSearch.Directories"); + MoveSectionToStart("IWADSearch.Directories"); + + // Add some self-documentation. + SetSectionNote("IWADSearch.Directories", + "# These are the directories to automatically search for IWADs.\n" + "# Each directory should be on a separate line, preceded by Path=\n"); + SetSectionNote("FileSearch.Directories", + "# These are the directories to search for wads added with the -file\n" + "# command line parameter, if they cannot be found with the path\n" + "# as-is. Layout is the same as for IWADSearch.Directories\n"); + SetSectionNote("Doom.AutoExec", + "# Files to automatically execute when running the corresponding game.\n" + "# Each file should be on its own line, preceded by Path=\n\n"); + SetSectionNote("Global.Autoload", + "# WAD files to always load. These are loaded after the IWAD but before\n" + "# any files added with -file. Place each file on its own line, preceded\n" + "# by Path=\n"); + SetSectionNote("Doom.Autoload", + "# Wad files to automatically load depending on the game and IWAD you are\n" + "# playing. You may have have files that are loaded for all similar IWADs\n" + "# (the game) and files that are only loaded for particular IWADs. For example,\n" + "# any files listed under Doom.Autoload will be loaded for any version of Doom,\n" + "# but files listed under Doom2.Autoload will only load when you are\n" + "# playing Doom 2.\n\n"); } FGameConfigFile::~FGameConfigFile () @@ -128,8 +182,7 @@ FGameConfigFile::~FGameConfigFile () void FGameConfigFile::WriteCommentHeader (FILE *file) const { - fprintf (file, "# This file was generated by " GAMENAME " " DOTVERSIONSTR " on %s" - "# It is not really meant to be modified outside of ZDoom, nyo.\n\n", myasctime ()); + fprintf (file, "# This file was generated by " GAMENAME " " DOTVERSIONSTR " on %s\n", myasctime()); } void FGameConfigFile::MigrateStub (const char *pathname, FConfigFile *config, void *userdata) @@ -507,6 +560,25 @@ FString FGameConfigFile::GetConfigPath (bool tryProg) #endif } +void FGameConfigFile::CreateStandardAutoExec(const char *section, bool start) +{ + if (!SetSection(section)) + { + FString path; +#ifndef unix + path = "$PROGDIR/autoexec.cfg"; +#else + path = GetUserFile ("autoexec.cfg"); +#endif + SetSection (section, true); + SetValueForKey ("Path", path.GetChars()); + } + if (start) + { + MoveSectionToStart(section); + } +} + void FGameConfigFile::AddAutoexec (DArgs *list, const char *game) { char section[64]; @@ -537,34 +609,19 @@ void FGameConfigFile::AddAutoexec (DArgs *list, const char *game) { // If .AutoExec section does not exist, create it // with a default autoexec.cfg file present. - if (!SetSection (section)) - { - FString path; - -#ifndef unix - if (Args->CheckParm ("-cdrom")) - { - path = CDROM_DIR "\\autoexec.cfg"; - } - else - { - path = progdir; - path += "autoexec.cfg"; - } -#else - path = GetUserFile ("autoexec.cfg"); -#endif - SetSection (section, true); - SetValueForKey ("Path", path.GetChars()); - } + CreateStandardAutoExec(section, false); // Run any files listed in the .AutoExec section - if (SetSection (section)) + if (!SectionIsEmpty()) { while (NextInSection (key, value)) { - if (stricmp (key, "Path") == 0 && FileExists (value)) + if (stricmp (key, "Path") == 0 && *value != '\0') { - list->AppendArg (value); + FString expanded_path = ExpandEnvVars(value); + if (FileExists(expanded_path)) + { + list->AppendArg (ExpandEnvVars(value)); + } } } } diff --git a/src/gameconfigfile.h b/src/gameconfigfile.h index 8970c87aba..f4ba727ac4 100644 --- a/src/gameconfigfile.h +++ b/src/gameconfigfile.h @@ -2,7 +2,7 @@ ** gameconfigfile.h ** **--------------------------------------------------------------------------- -** Copyright 1998-2006 Randy Heit +** Copyright 1998-2008 Randy Heit ** All rights reserved. ** ** Redistribution and use in source and binary forms, with or without @@ -56,6 +56,7 @@ public: protected: void WriteCommentHeader (FILE *file) const; + void CreateStandardAutoExec (const char *section, bool start); private: static void MigrateStub (const char *pathname, FConfigFile *config, void *userdata);