Modified source engine (2017) developed by valve and leaked in 2020. Not for commercial purporses
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

407 lines
8.0 KiB

//========= Copyright Valve Corporation, All rights reserved. ============//
/*****************************************************************************
DUMPOBJ.CPP
*****************************************************************************/
#include "..\toollib\toollib.h"
typedef struct section_s
{
int size;
char* name;
section_s* nextPtr;
} section_t;
typedef struct obj_s
{
char* filename;
section_t* sectionPtr;
obj_s* nextPtr;
} obj_t;
obj_t* g_obj_head;
char g_sectionName[128];
bool g_bVerbose;
typedef struct
{
char* filename;
int size;
} entry_t;
/***********************************************************
_SortCallback
***********************************************************/
int _SortCallback(const void *a, const void *b)
{
entry_t* aPtr;
entry_t* bPtr;
aPtr = (entry_t*)a;
bPtr = (entry_t*)b;
return (aPtr->size-bPtr->size);
}
/***********************************************************
FreeInfo
***********************************************************/
void FreeInfo()
{
obj_t* objPtr;
obj_t* nextObjPtr;
section_t* sectionPtr;
section_t* nextSectionPtr;
objPtr = g_obj_head;
while (objPtr)
{
nextObjPtr = objPtr->nextPtr;
sectionPtr = objPtr->sectionPtr;
while (sectionPtr)
{
nextSectionPtr = sectionPtr->nextPtr;
TL_Free(sectionPtr->name);
TL_Free(sectionPtr);
sectionPtr = nextSectionPtr;
}
TL_Free(objPtr->filename);
TL_Free(objPtr);
objPtr = nextObjPtr;
}
}
/***********************************************************
AnalyzeData
***********************************************************/
void AnalyzeData()
{
obj_t* objPtr;
section_t* sectionPtr;
char* sections[128];
int totals[128];
int numSections;
int i;
int index;
int numEntries;
entry_t* entries;
int total;
printf("\n");
memset(totals, 0, sizeof(totals));
// determine unique sections
numSections = 0;
objPtr = g_obj_head;
while (objPtr)
{
sectionPtr = objPtr->sectionPtr;
while (sectionPtr)
{
for (i=0; i<numSections; i++)
{
if (!stricmp(sections[i],sectionPtr->name))
break;
}
if (i >= numSections)
{
// add it
sections[numSections] = sectionPtr->name;
numSections++;
assert(numSections < 128);
index = numSections-1;
}
else
index = i;
totals[index] += sectionPtr->size;
sectionPtr = sectionPtr->nextPtr;
}
objPtr = objPtr->nextPtr;
}
if (g_sectionName[0])
{
// dump only matching section
printf("Section: %s\n", g_sectionName);
printf("-------------------------\n");
// tally entries
numEntries = 0;
objPtr = g_obj_head;
while (objPtr)
{
sectionPtr = objPtr->sectionPtr;
while (sectionPtr)
{
if (!stricmp(g_sectionName, sectionPtr->name))
numEntries++;
sectionPtr = sectionPtr->nextPtr;
}
objPtr = objPtr->nextPtr;
}
// fill entries
if (numEntries)
{
entries = (entry_t*)TL_Malloc(numEntries*sizeof(entry_t));
numEntries = 0;
objPtr = g_obj_head;
while (objPtr)
{
sectionPtr = objPtr->sectionPtr;
while (sectionPtr)
{
if (!stricmp(g_sectionName, sectionPtr->name))
{
entries[numEntries].size = sectionPtr->size;
entries[numEntries].filename = objPtr->filename;
numEntries++;
}
sectionPtr = sectionPtr->nextPtr;
}
objPtr = objPtr->nextPtr;
}
// sort
qsort(entries, numEntries, sizeof(entry_t), _SortCallback);
// display results
int total = 0;
for (i=0; i<numEntries; i++)
{
printf("%8d %s\n", entries[i].size, entries[i].filename);
total += entries[i].size;
}
printf("-------------------------\n");
printf("%8d Total\n", total);
TL_Free(entries);
}
}
else
{
// dump all sections
printf("Sections:\n");
printf("---------\n");
total = 0;
for (i=0; i<numSections; i++)
{
printf("%8d %s\n", totals[i], sections[i]);
total += totals[i];
}
printf("---------\n");
printf("%8d\n", total);
}
}
/***********************************************************
LocalExec
***********************************************************/
int LocalExec(const char* batfilename, const char* arg1)
{
intptr_t pid;
int errcode;
const char* args[8];
args[0] = batfilename;
args[1] = arg1;
args[2] = NULL;
pid = _spawnvp(P_NOWAIT, batfilename, args);
_cwait(&errcode, pid, 0);
return (errcode);
}
/*****************************************************************************
GetInfo
*****************************************************************************/
void GetInfo(char* objFilename, char* batFilename, char* logFilename)
{
char buff[TL_MAXPATH];
int size;
char name[128];
char* ptr;
int errcode;
char* token;
obj_t* objPtr;
section_t* sectionPtr;
if (g_bVerbose)
printf("%s\n", objFilename);
ptr = objFilename;
if (!strnicmp(objFilename,".\\",2))
{
ptr += 2;
getcwd(buff, sizeof(buff));
TL_AddSeperatorToPath(buff, buff);
strcat(buff, ptr);
}
else
strcpy(buff, objFilename);
// exec the batch file with the obj file
errcode = LocalExec(batFilename, buff);
if (errcode)
{
printf("Failed on %s\n", buff);
return;
}
// add new object node
objPtr = (obj_t*)TL_Malloc(sizeof(obj_t));
objPtr->filename = (char*)TL_Malloc((int)strlen(objFilename)+1);
strcpy(objPtr->filename, objFilename);
// link it in
objPtr->nextPtr = g_obj_head;
g_obj_head = objPtr;
// read the results
TL_LoadScriptFile(logFilename);
while (1)
{
token = TL_GetToken(true);
if (!token || !token[0])
break;
if (!stricmp(token, "summary"))
break;
else
TL_SkipRestOfLine();
}
while (1)
{
token = TL_GetToken(true);
if (!token || !token[0])
break;
sscanf(token, "%x", &size);
token = TL_GetToken(true);
if (!token || !token[0])
break;
strcpy(name, token);
// add new section node
sectionPtr = (section_t*)TL_Malloc(sizeof(section_t));
sectionPtr->name = (char*)TL_Malloc((int)strlen(name)+1);
strcpy(sectionPtr->name, name);
sectionPtr->size = size;
// link it in
sectionPtr->nextPtr = objPtr->sectionPtr;
objPtr->sectionPtr = sectionPtr;
}
TL_FreeScriptFile();
}
/*****************************************************************************
Usage
*****************************************************************************/
void Usage(void)
{
printf("usage: dumpobj <*.obj> [-s section] [-r] [-v]\n");
exit(-1);
}
/*****************************************************************************
main
*****************************************************************************/
int main(int argc, char* argv[])
{
tlfile_t** filelist;
int filecount;
int i;
int recurse;
int section;
FILE* fp;
char* vcvarsPath;
char batFilename[TL_MAXPATH];
char txtFilename[TL_MAXPATH];
batFilename[0] = '\0';
txtFilename[0] = '\0';
TL_Setup("DUMPOBJ",argc,argv);
// find critical path to vcvars32.bat
vcvarsPath = "c:\\Program Files\\Microsoft Visual Studio .Net 2003\\Vc7\\bin\\vcvars32.bat";
if (!TL_Exists(vcvarsPath))
TL_Error("Cannot find: %s\n", vcvarsPath);
if (argc < 2)
Usage();
recurse = TL_CheckParm("r");
filecount = TL_FindFiles2(argv[1], recurse != 0, &filelist);
g_bVerbose = TL_CheckParm("v") != 0;
section = TL_CheckParm("s");
if (section && section+1 < argc)
strcpy(g_sectionName, argv[section+1]);
else
g_sectionName[0] = '\0';
strcpy(batFilename,"c:\\");
TL_TempFilename(batFilename);
TL_ReplaceDosExtension(batFilename, ".bat");
strcpy(txtFilename,"c:\\");
TL_TempFilename(txtFilename);
TL_ReplaceDosExtension(txtFilename, ".txt");
if (filecount)
{
// create bat file
fp = fopen(batFilename, "wt+");
if (!fp)
TL_Error("Could not open bat file '%s'", batFilename);
fprintf(fp, "@echo off\n");
fprintf(fp, "@call \"%s\" > nul: \n", vcvarsPath);
fprintf(fp, "@dumpbin %%1 > %s\n", txtFilename);
fclose(fp);
}
for (i=0; i<filecount; i++)
GetInfo(filelist[i]->filename, batFilename, txtFilename);
if (filecount)
AnalyzeData();
if (filecount)
{
FreeInfo();
unlink(batFilename);
unlink(txtFilename);
}
TL_FreeFileList(filecount,filelist);
TL_End(false);
return (0);
}