mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-22 20:21:26 +00:00
SVN r349 (trunk)
This commit is contained in:
parent
28ea15d8f4
commit
2c2261884c
5 changed files with 194 additions and 45 deletions
|
@ -1,3 +1,12 @@
|
|||
October 4, 2006
|
||||
- Added alias parameter substitution. Instances of %x in the alias command
|
||||
string will be replaced with parameter x when the alias is executed.
|
||||
- Fixed: When FString::LockBuffer() had to create a new string because the
|
||||
RefCount was higher than one, the new string was not actually locked.
|
||||
- FConsoleAlias now stores the commands in FStrings.
|
||||
- BuildString() now returns an FString.
|
||||
- Added the muslib license text to muslib.h.
|
||||
|
||||
October 4, 2006 (Changes by Graf Zahl)
|
||||
- When exiting the level on a damaging floor the player could be in the pain
|
||||
state and make its pain noise at the start of the next level.
|
||||
|
|
|
@ -846,53 +846,117 @@ void FConsoleCommand::Run (FCommandLine &argv, APlayerPawn *who, int key)
|
|||
|
||||
FConsoleAlias::FConsoleAlias (const char *name, const char *command, bool noSave)
|
||||
: FConsoleCommand (name, NULL),
|
||||
bRunning (false), bKill (false)
|
||||
bRunning(false), bKill(false)
|
||||
{
|
||||
m_Command[noSave] = copystring (command);
|
||||
m_Command[!noSave] = NULL;
|
||||
m_Command[noSave] = command;
|
||||
m_Command[!noSave] = FString();
|
||||
// If the command contains % characters, assume they are parameter markers
|
||||
// for substitution when the command is executed.
|
||||
bDoSubstitution = (strchr (command, '%') != NULL);
|
||||
}
|
||||
|
||||
FConsoleAlias::~FConsoleAlias ()
|
||||
{
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
if (m_Command[i] != NULL)
|
||||
{
|
||||
delete[] m_Command[i];
|
||||
m_Command[i] = NULL;
|
||||
}
|
||||
}
|
||||
m_Command[1] = m_Command[0] = FString();
|
||||
}
|
||||
|
||||
char *BuildString (int argc, char **argv)
|
||||
FString BuildString (int argc, char **argv)
|
||||
{
|
||||
char temp[1024];
|
||||
char *cur;
|
||||
int arg;
|
||||
|
||||
if (argc == 1)
|
||||
{
|
||||
return copystring (*argv);
|
||||
return *argv;
|
||||
}
|
||||
else
|
||||
{
|
||||
cur = temp;
|
||||
FString buf;
|
||||
int arg;
|
||||
|
||||
for (arg = 0; arg < argc; arg++)
|
||||
{
|
||||
if (strchr (argv[arg], ' '))
|
||||
{
|
||||
cur += sprintf (cur, "\"%s\" ", argv[arg]);
|
||||
buf.AppendFormat ("\"%s\" ", argv[arg]);
|
||||
}
|
||||
else
|
||||
{
|
||||
cur += sprintf (cur, "%s ", argv[arg]);
|
||||
buf.AppendFormat ("%s ", argv[arg]);
|
||||
}
|
||||
}
|
||||
temp[strlen (temp) - 1] = 0;
|
||||
return copystring (temp);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// SubstituteAliasParams
|
||||
//
|
||||
// Given an command line and a set of arguments, replace instances of
|
||||
// %x or %{x} in the command line with argument x. If argument x does not
|
||||
// exist, then the empty string is substituted in its place.
|
||||
//
|
||||
// Substitution is not done inside of quoted strings.
|
||||
//
|
||||
// To avoid a substitution, use %%. The %% will be replaced by a single %.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
FString SubstituteAliasParams (FString &command, FCommandLine &args)
|
||||
{
|
||||
// Do substitution by replacing %x with the argument x.
|
||||
// If there is no argument x, then %x is simply removed.
|
||||
|
||||
// For some reason, strtoul's stop parameter is non-const.
|
||||
char *p = command.LockBuffer(), *start = p;
|
||||
unsigned long argnum;
|
||||
FString buf;
|
||||
|
||||
while (*p != '\0')
|
||||
{
|
||||
if (*p == '%' && ((p[1] >= '0' && p[1] <= '9') || p[1] == '{' || p[1] == '%'))
|
||||
{
|
||||
if (p[1] == '%')
|
||||
{
|
||||
// Do not substitute. Just collapse to a single %.
|
||||
buf.AppendCStrPart (start, p - start + 1);
|
||||
start = p = p + 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Do a substitution. Output what came before this.
|
||||
buf.AppendCStrPart (start, p - start);
|
||||
|
||||
// Extract the argument number and substitute the corresponding argument.
|
||||
argnum = strtoul (p + 1 + (p[1] == '{'), &start, 10);
|
||||
if ((p[1] != '{' || *start == '}') && argnum < args.argc())
|
||||
{
|
||||
buf += args[argnum];
|
||||
}
|
||||
p = (start += (p[1] == '{' && *start == '}'));
|
||||
}
|
||||
else if (*p == '"')
|
||||
{
|
||||
// Don't substitute inside quoted strings.
|
||||
p++;
|
||||
while (*p != '\0' && (*p != '"' || *(p-1) == '\\'))
|
||||
p++;
|
||||
if (*p != '\0')
|
||||
p++;
|
||||
}
|
||||
else
|
||||
{
|
||||
p++;
|
||||
}
|
||||
}
|
||||
// Return whatever was after the final substitution.
|
||||
if (p > start)
|
||||
{
|
||||
buf.AppendCStrPart (start, p - start);
|
||||
}
|
||||
command.UnlockBuffer();
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static int DumpHash (FConsoleCommand **table, bool aliases, const char *pattern=NULL)
|
||||
{
|
||||
int bucket, count;
|
||||
|
@ -939,7 +1003,7 @@ void FConsoleAlias::PrintAlias ()
|
|||
|
||||
void FConsoleAlias::Archive (FConfigFile *f)
|
||||
{
|
||||
if (f != NULL && m_Command[0] != NULL)
|
||||
if (f != NULL && !m_Command[0].IsEmpty())
|
||||
{
|
||||
f->SetValueForKey ("Name", m_Name, true);
|
||||
f->SetValueForKey ("Command", m_Command[0], true);
|
||||
|
@ -1066,7 +1130,7 @@ void C_ExecCmdLineParams ()
|
|||
{
|
||||
if (*Args.GetArg (currArg++) == '+')
|
||||
{
|
||||
char *cmdString;
|
||||
FString cmdString;
|
||||
int cmdlen = 1;
|
||||
int argstart = currArg - 1;
|
||||
|
||||
|
@ -1078,10 +1142,10 @@ void C_ExecCmdLineParams ()
|
|||
cmdlen++;
|
||||
}
|
||||
|
||||
if ( (cmdString = BuildString (cmdlen, Args.GetArgList (argstart))) )
|
||||
cmdString = BuildString (cmdlen, Args.GetArgList (argstart));
|
||||
if (!cmdString.IsEmpty())
|
||||
{
|
||||
C_DoCommand (cmdString + 1);
|
||||
delete[] cmdString;
|
||||
C_DoCommand (&cmdString[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1105,19 +1169,29 @@ void FConsoleAlias::Run (FCommandLine &args, APlayerPawn *who, int key)
|
|||
return;
|
||||
}
|
||||
|
||||
int index = m_Command[1] != NULL;
|
||||
char *mycommand = m_Command[index];
|
||||
m_Command[index] = NULL;
|
||||
bRunning = true;
|
||||
AddCommandString (mycommand, key);
|
||||
bRunning = false;
|
||||
if (m_Command[index] != NULL)
|
||||
{ // The alias realiased itself, so delete the memory used by this command.
|
||||
delete[] mycommand;
|
||||
int index = !m_Command[1].IsEmpty();
|
||||
FString savedcommand = m_Command[index], mycommand;
|
||||
m_Command[index] = FString();
|
||||
|
||||
if (bDoSubstitution)
|
||||
{
|
||||
mycommand = SubstituteAliasParams (savedcommand, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
mycommand = savedcommand;
|
||||
}
|
||||
|
||||
bRunning = true;
|
||||
AddCommandString (mycommand.LockBuffer(), key);
|
||||
mycommand.UnlockBuffer();
|
||||
bRunning = false;
|
||||
if (m_Command[index].IsEmpty())
|
||||
{ // The alias is unchanged, so put the command back so it can be used again.
|
||||
m_Command[index] = mycommand;
|
||||
// If the command had been non-empty, then that means that executing this
|
||||
// alias caused it to realias itself, so the old command will be forgotten
|
||||
// once this function returns.
|
||||
m_Command[index] = savedcommand;
|
||||
}
|
||||
if (bKill)
|
||||
{ // The alias wants to remove itself
|
||||
|
@ -1127,15 +1201,15 @@ void FConsoleAlias::Run (FCommandLine &args, APlayerPawn *who, int key)
|
|||
|
||||
void FConsoleAlias::Realias (const char *command, bool noSave)
|
||||
{
|
||||
if (m_Command[1] != NULL)
|
||||
if (!noSave && !m_Command[1].IsEmpty())
|
||||
{
|
||||
noSave = true;
|
||||
}
|
||||
if (m_Command[noSave] != NULL)
|
||||
{
|
||||
delete[] m_Command[noSave];
|
||||
}
|
||||
m_Command[noSave] = copystring (command);
|
||||
m_Command[noSave] = command;
|
||||
|
||||
// If the command contains % characters, assume they are parameter markers
|
||||
// for substitution when the command is executed.
|
||||
bDoSubstitution = (strchr (command, '%') != NULL);
|
||||
bKill = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,7 @@ void C_ArchiveAliases (FConfigFile *f);
|
|||
void C_SetAlias (const char *name, const char *cmd);
|
||||
|
||||
// build a single string out of multiple strings
|
||||
char *BuildString (int argc, char **argv);
|
||||
FString BuildString (int argc, char **argv);
|
||||
|
||||
// Class that can parse command lines
|
||||
class FCommandLine
|
||||
|
@ -121,7 +121,8 @@ public:
|
|||
void Realias (const char *command, bool noSave);
|
||||
void SafeDelete ();
|
||||
protected:
|
||||
char *m_Command[2];
|
||||
FString m_Command[2]; // Slot 0 is saved to the ini, slot 1 is not.
|
||||
bool bDoSubstitution;
|
||||
bool bRunning;
|
||||
bool bKill;
|
||||
};
|
||||
|
|
|
@ -8,6 +8,70 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/* From muslib175.zip/README.1ST:
|
||||
|
||||
1.1 - Disclaimer of Warranties
|
||||
------------------------------
|
||||
|
||||
#ifdef LAWYER
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
#else
|
||||
|
||||
Use this software at your own risk.
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
1.2 - Terms of Use
|
||||
------------------
|
||||
|
||||
This library may be used in any freeware or shareware product free of
|
||||
charge. The product may not be sold for profit (except for shareware) and
|
||||
should be freely available to the public. It would be nice of you if you
|
||||
credited me in your product and notified me if you use this library.
|
||||
|
||||
If you want to use this library in a commercial product, contact me
|
||||
and we will make an agreement. It is a violation of the law to make money
|
||||
of this product without prior signing an agreement and paying a license fee.
|
||||
This licence will allow its holder to sell any products based on MUSLib,
|
||||
royalty-free. There is no need to buy separate licences for different
|
||||
products once the licence fee is paid.
|
||||
|
||||
|
||||
1.3 - Contacting the Author
|
||||
---------------------------
|
||||
|
||||
Internet (address valid probably until the end of year 1998):
|
||||
xarnos00@dcse.fee.vutbr.cz
|
||||
|
||||
FIDO:
|
||||
2:423/36.2
|
||||
|
||||
Snail-mail:
|
||||
|
||||
Vladimir Arnost
|
||||
Ceska 921
|
||||
Chrudim 4
|
||||
537 01
|
||||
CZECH REPUBLIC
|
||||
|
||||
Voice-mail (Czech language only, not recommended; weekends only):
|
||||
|
||||
+42-455-2154
|
||||
*/
|
||||
|
||||
#ifndef __MUSLIB_H_
|
||||
#define __MUSLIB_H_
|
||||
|
||||
|
|
|
@ -138,6 +138,7 @@ char *FString::LockBuffer()
|
|||
AllocBuffer (old->Len);
|
||||
StrCopy (Chars, old->Chars(), old->Len);
|
||||
old->Release();
|
||||
Data()->RefCount = -1;
|
||||
}
|
||||
return Chars;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue