/*
** Command & Conquer Generals Zero Hour(tm)
** Copyright 2025 Electronic Arts Inc.
**
** 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 3 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, see .
*/
/////////////////////////////////////////////////////////////////////////EA-V1
// $File: //depot/GeneralsMD/Staging/code/Libraries/Source/profile/profile_cmd.cpp $
// $Author: mhoffe $
// $Revision: #2 $
// $DateTime: 2003/08/12 15:05:00 $
//
// ©2003 Electronic Arts
//
// Profile module command interface
//////////////////////////////////////////////////////////////////////////////
#include "_pch.h"
unsigned ProfileCmdInterface::numResIf;
ProfileCmdInterface::Factory *ProfileCmdInterface::resIf;
void ProfileCmdInterface::AddResultFunction(ProfileResultInterface* (*func)(int, const char * const *),
const char *name, const char *arg)
{
DFAIL_IF(!func) return;
DFAIL_IF(!name) return;
for (unsigned k=0;kWriteResults();
resFunc[k]->Delete();
}
}
bool ProfileCmdInterface::Execute(class Debug& dbg, const char *cmd, CommandMode cmdmode,
unsigned argn, const char * const * argv)
{
// just for convenience...
bool normalMode=cmdmode==CommandMode::Normal;
if (!strcmp(cmd,"help"))
{
if (!normalMode)
return true;
if (!argn)
{
dbg << "profile group help:\n"
" result, caller, clear, add, view\n";
return true;
}
else if (!strcmp(argv[0],"result"))
{
dbg << "result\n\n"
"Shows the list of available result functions and their\n"
"optional parameters.\n"
"\n"
"result [ .. ]\n\n"
"Adds the given result function to be executed on program\n"
"exit.\n";
}
else if (!strcmp(argv[0],"caller"))
{
dbg << "caller [ (+|-) ]\n\n"
"Enables/disables recording of caller information while\n"
"performing function level profiling. Turned off by default\n"
"since CPU hit is non-zero.\n";
}
else if (!strcmp(argv[0],"clear"))
{
dbg << "clear\n\n"
"Clears the profile inclusion/exclusion list.\n";
return true;
}
else if (!strcmp(argv[0],"add"))
{
dbg << "add (+|-) \n"
"\n"
"Adds a pattern to the profile list. By default all\n"
"profile ranges are disabled. Each new range is then checked\n"
"against all pattern in this list. If a match is found the\n"
"active/inactive state is modified accordingly (+ for active,\n"
"- for inactive). The final state is always the last match.";
return true;
}
else if (!strcmp(argv[0],"view"))
{
dbg << "view\n\n"
"Shows the active pattern list.\n";
return true;
}
return false;
}
// command: result
if (!strcmp(cmd,"result"))
{
if (!argn)
{
for (unsigned k=0;kpattern,pattern))
{
// remove this entry
Profile::PatternListEntry *cur=*entryPtr;
*entryPtr=cur->next;
ProfileFreeMemory(cur->pattern);
ProfileFreeMemory(cur);
}
else
entryPtr=&((*entryPtr)->next);
}
// must fixup lastPatternEntry now
if (Profile::firstPatternEntry)
{
for (Profile::PatternListEntry *cur=Profile::firstPatternEntry;cur->next;cur=cur->next);
Profile::lastPatternEntry=cur;
}
else
Profile::lastPatternEntry=NULL;
return true;
}
// command: add
if (!strcmp(cmd,"add"))
{
// add a pattern
if (argn<2)
dbg << "Please specify mode and pattern";
else
{
// alloc new pattern entry
Profile::PatternListEntry *cur=(Profile::PatternListEntry *)
ProfileAllocMemory(sizeof(Profile::PatternListEntry));
// init
cur->next=NULL;
cur->isActive=*argv[0]=='+';
cur->pattern=(char *)ProfileAllocMemory(strlen(argv[1])+1);
strcpy(cur->pattern,argv[1]);
// add to list
if (Profile::lastPatternEntry)
Profile::lastPatternEntry->next=cur;
else
Profile::firstPatternEntry=cur;
Profile::lastPatternEntry=cur;
}
return true;
}
// command: view
if (!strcmp(cmd,"view"))
{
// show list of defined patterns
for (Profile::PatternListEntry *cur=Profile::firstPatternEntry;cur;cur=cur->next)
dbg << (cur->isActive?"+ ":"- ") << cur->pattern << "\n";
return true;
}
// unknown command
return false;
}