Turn options into arrays instead of heap to allow easy copying into a per

thread/client option duplicate.
This commit is contained in:
blythe%netscape.com 2002-05-03 00:32:23 +00:00
Родитель d1ebe1d3c7
Коммит 2c6f9105ba
2 изменённых файлов: 74 добавлений и 126 удалений

Просмотреть файл

@ -312,17 +312,17 @@ int initOptions(int aArgCount, char** aArgArray)
/*
** Set the program name.
*/
globals.mOptions.mProgramName = aArgArray[0];
PR_snprintf(globals.mOptions.mProgramName, sizeof(globals.mOptions.mProgramName), "%s", aArgArray[0]);
/*
** As a default, stdin is the input.
*/
globals.mOptions.mFileName = stdinDash;
PR_snprintf(globals.mOptions.mFileName, sizeof(globals.mOptions.mFileName), "%s", stdinDash);
/*
** As a default, this directory is the output.
*/
globals.mOptions.mOutputDir = outputDir;
PR_snprintf(globals.mOptions.mOutputDir, sizeof(globals.mOptions.mOutputDir), "%s", outputDir);
/*
** As a default, this is the port to listen for http requests.
@ -377,13 +377,13 @@ int initOptions(int aArgCount, char** aArgArray)
/*
** category file
**/
globals.mOptions.mCategoryFile = "rules.txt";
*/
PR_snprintf(globals.mOptions.mCategoryFile, sizeof(globals.mOptions.mCategoryFile), "%s", "rules.txt");
/*
** Default category name - name of root category
*/
globals.mOptions.mCategoryName = strdup(ST_ROOT_CATEGORY_NAME);
PR_snprintf(globals.mOptions.mCategoryName, sizeof(globals.mOptions.mCategoryName), "%s", ST_ROOT_CATEGORY_NAME);
/*
** Go through all arguments.
@ -409,7 +409,7 @@ int initOptions(int aArgCount, char** aArgArray)
** If the entire option is a dash,
** then input is stdin.
*/
globals.mOptions.mFileName = stdinDash;
PR_snprintf(globals.mOptions.mFileName, sizeof(globals.mOptions.mFileName), "%s", stdinDash);
}
break;
@ -478,7 +478,7 @@ int initOptions(int aArgCount, char** aArgArray)
*/
if('\0' != aArgArray[traverse][2])
{
globals.mOptions.mOutputDir = &aArgArray[traverse][2];
PR_snprintf(globals.mOptions.mOutputDir, sizeof(globals.mOptions.mOutputDir), "%s", &aArgArray[traverse][2]);
}
else
{
@ -830,16 +830,12 @@ int initOptions(int aArgCount, char** aArgArray)
*/
for(looper = 0; ST_SUBSTRING_MATCH_MAX > looper; looper++)
{
if(NULL != globals.mOptions.mRestrictText[looper])
if('\0' != globals.mOptions.mRestrictText[looper][0])
{
continue;
}
globals.mOptions.mRestrictText[looper] = strdup(&aArgArray[traverse][2]);
if(NULL == globals.mOptions.mRestrictText[looper])
{
retval = __LINE__;
}
PR_snprintf(globals.mOptions.mRestrictText[looper], sizeof(globals.mOptions.mRestrictText[looper]), "%s", &aArgArray[traverse][2]);
break;
}
@ -866,9 +862,7 @@ int initOptions(int aArgCount, char** aArgArray)
*/
if('\0' != aArgArray[traverse][2])
{
if (globals.mOptions.mCategoryFile)
free(globals.mOptions.mCategoryFile);
globals.mOptions.mCategoryFile = strdup(&aArgArray[traverse][2]);
PR_snprintf(globals.mOptions.mCategoryFile, sizeof(globals.mOptions.mCategoryFile), "%s", &aArgArray[traverse][2]);
}
else
{
@ -885,9 +879,7 @@ int initOptions(int aArgCount, char** aArgArray)
*/
if('\0' != aArgArray[traverse][2])
{
if (globals.mOptions.mCategoryName)
free(globals.mOptions.mCategoryName);
globals.mOptions.mCategoryName = strdup(&aArgArray[traverse][2]);
PR_snprintf(globals.mOptions.mCategoryName, sizeof(globals.mOptions.mCategoryName), "%s", &aArgArray[traverse][2]);
}
else
{
@ -923,7 +915,7 @@ int initOptions(int aArgCount, char** aArgArray)
/*
** File to process.
*/
globals.mOptions.mFileName = aArgArray[traverse];
PR_snprintf(globals.mOptions.mFileName, sizeof(globals.mOptions.mFileName), "%s", aArgArray[traverse]);
}
}
@ -1633,7 +1625,7 @@ int harvestRun(const STRun* aInRun, STRun* aOutRun, STOptions* aOptions)
*/
for(looper = 0; ST_SUBSTRING_MATCH_MAX > looper; looper++)
{
if(NULL != globals.mOptions.mRestrictText[looper] && '\0' != globals.mOptions.mRestrictText[looper][0])
if('\0' != globals.mOptions.mRestrictText[looper][0])
{
if(0 == hasCallsiteMatch(current->mEvents[0].mCallsite, globals.mOptions.mRestrictText[looper], ST_FOLLOW_PARENTS))
{
@ -1929,6 +1921,7 @@ STRun* createRunFromGlobal(void)
if(NULL != retval)
{
STCategoryNode* node = NULL;
int failure = 0;
int harvestRes = harvestRun(&globals.mRun, retval, NULL);
if(0 == harvestRes)
@ -1966,18 +1959,14 @@ STRun* createRunFromGlobal(void)
** if we are focussing on a category, return that run instead of
** the harvested run. Make sure to recalculate cost.
*/
if (globals.mOptions.mCategoryName)
node = findCategoryNode(globals.mOptions.mCategoryName, &globals);
if (node)
{
STCategoryNode* node = findCategoryNode(globals.mOptions.mCategoryName, &globals);
if (node)
{
/* Recalculate cost of run */
recalculateRunCost(node->run);
retval = node->run;
}
/* Recalculate cost of run */
recalculateRunCost(node->run);
retval = node->run;
}
}
return retval;
@ -2704,9 +2693,9 @@ void htmlAnchor(STRequest* inRequest, const char* aHref, const char* aText, cons
/*
** In any mode, don't make an href to the current page.
*/
if(0 != anchorLive && NULL != inRequest->mFileName)
if(0 != anchorLive && NULL != inRequest->mGetFileName)
{
if(0 == strcmp(aHref, inRequest->mFileName))
if(0 == strcmp(aHref, inRequest->mGetFileName))
{
anchorLive = 0;
}
@ -3188,11 +3177,11 @@ int getDataPRUint64(const char* aGetData, const char* aCheckFor, PRUint64* aStor
** Pull out the string data, if specified.
** Return !0 on failure.
*/
int getDataString(const char* aGetData, const char* aCheckFor, char** aStoreResult, int* aChanged)
int getDataString(const char* aGetData, const char* aCheckFor, char* aStoreResult, int inStoreResultLength, int* aChanged)
{
int retval = 0;
if(NULL != aGetData && NULL != aCheckFor && NULL != aStoreResult)
if(NULL != aGetData && NULL != aCheckFor && NULL != aStoreResult && 0 != inStoreResultLength)
{
const char* found = NULL;
PRInt32 scanRes = 0;
@ -3206,7 +3195,7 @@ int getDataString(const char* aGetData, const char* aCheckFor, char** aStoreResu
int length = 0;
const char* dataPoint = NULL;
const char* endPoint = NULL;
char* oldResult = NULL;
char oldResult[ST_OPTION_STRING_MAX];
int theLen = 0;
/*
@ -3228,56 +3217,52 @@ int getDataString(const char* aGetData, const char* aCheckFor, char** aStoreResu
/*
** Store original value if present.
*/
if(NULL != *aStoreResult)
{
oldResult = *aStoreResult;
}
PR_snprintf(oldResult, sizeof(oldResult), "%s", aStoreResult);
/*
** Allocate space for new string.
** We have enough space for this?
*/
theLen = (int)(endPoint - dataPoint);
*aStoreResult = (char*)malloc((size_t)(theLen + 1));
if(NULL != *aStoreResult)
if(inStoreResultLength > theLen)
{
int index1 = 0;
int index2 = 0;
strncpy(*aStoreResult, dataPoint, theLen);
(*aStoreResult)[theLen] = '\0';
strncpy(aStoreResult, dataPoint, theLen);
aStoreResult[theLen] = '\0';
/*
** Here's a totally suboptimal and bug prone unhexcaper.
*/
for(; index1 <= theLen; index1++)
{
if('%' == (*aStoreResult)[index1] && '\0' != (*aStoreResult)[index1 + 1] && '\0' != (*aStoreResult)[index1 + 2])
if('%' == aStoreResult[index1] && '\0' != aStoreResult[index1 + 1] && '\0' != aStoreResult[index1 + 2])
{
int unhex = 0;
if('9' >= (*aStoreResult)[index1 + 1])
if('9' >= aStoreResult[index1 + 1])
{
unhex |= (((*aStoreResult)[index1 + 1] - '0') << 4);
unhex |= ((aStoreResult[index1 + 1] - '0') << 4);
}
else
{
unhex |= ((toupper((*aStoreResult)[index1 + 1]) - 'A' + 10) << 4);
unhex |= ((toupper(aStoreResult[index1 + 1]) - 'A' + 10) << 4);
}
if('9' >= (*aStoreResult)[index1 + 2])
if('9' >= aStoreResult[index1 + 2])
{
unhex |= ((*aStoreResult)[index1 + 2] - '0');
unhex |= (aStoreResult[index1 + 2] - '0');
}
else
{
unhex |= (toupper((*aStoreResult)[index1 + 2]) - 'A' + 10);
unhex |= (toupper(aStoreResult[index1 + 2]) - 'A' + 10);
}
index1 += 2;
(*aStoreResult)[index1] = unhex;
aStoreResult[index1] = unhex;
}
(*aStoreResult)[index2++] = (*aStoreResult)[index1];
aStoreResult[index2++] = aStoreResult[index1];
}
/*
@ -3287,25 +3272,16 @@ int getDataString(const char* aGetData, const char* aCheckFor, char** aStoreResu
{
if(NULL != oldResult)
{
if(0 != strcmp(oldResult, *aStoreResult))
if(0 != strcmp(oldResult, aStoreResult))
{
(*aChanged) = (*aChanged) + 1;
}
}
else if('\0' != (*aStoreResult)[0])
else if('\0' != aStoreResult[0])
{
(*aChanged) = (*aChanged) + 1;
}
}
/*
** Free off the prior value if relevant.
*/
if(NULL != oldResult)
{
free(oldResult);
oldResult = NULL;
}
}
else
{
@ -5117,19 +5093,17 @@ int applySettings(STRequest* inRequest)
for(looper = 0; ST_SUBSTRING_MATCH_MAX > looper; looper++)
{
PR_snprintf(looper_buf, sizeof(looper_buf), "mRestrictText%d", looper);
getRes += getDataString(inRequest->mGetData, looper_buf, &globals.mOptions.mRestrictText[looper], &changedSet);
getRes += getDataString(inRequest->mGetData, looper_buf, globals.mOptions.mRestrictText[looper], sizeof(globals.mOptions.mRestrictText[looper]), &changedSet);
}
getRes += getDataString(inRequest->mGetData, "mCategoryName", &globals.mOptions.mCategoryName, &changedCategory);
getRes += getDataString(inRequest->mGetData, "mCategoryName", globals.mOptions.mCategoryName, sizeof(globals.mOptions.mCategoryName), &changedCategory);
/*
** Sanity check options
*/
if (changedCategory && (!globals.mOptions.mCategoryName || !*globals.mOptions.mCategoryName
if (changedCategory && (!globals.mOptions.mCategoryName[0]
|| !findCategoryNode(globals.mOptions.mCategoryName, &globals)))
{
if (globals.mOptions.mCategoryName)
free(globals.mOptions.mCategoryName);
globals.mOptions.mCategoryName = strdup(ST_ROOT_CATEGORY_NAME);
PR_snprintf(globals.mOptions.mCategoryName, sizeof(globals.mOptions.mCategoryName), "%s", ST_ROOT_CATEGORY_NAME);
}
/*
@ -5155,18 +5129,14 @@ int applySettings(STRequest* inRequest)
** right node and set the cache.mSortedRun. We need to recompute
** cost though. But that is cheap.
*/
if (globals.mOptions.mCategoryName)
STCategoryNode* node = findCategoryNode(globals.mOptions.mCategoryName, &globals);
if (node)
{
STCategoryNode* node = findCategoryNode(globals.mOptions.mCategoryName, &globals);
if (node)
{
/* Recalculate cost of run */
recalculateRunCost(node->run);
globals.mCache.mSortedRun = node->run;
}
/* Recalculate cost of run */
recalculateRunCost(node->run);
globals.mCache.mSortedRun = node->run;
}
}
@ -5324,7 +5294,7 @@ int displaySettings(STRequest* inRequest)
PR_fprintf(inRequest->mFD, "Keep all the strings together near the top of this list, as the code will stop trying to match on the first empty string.<br>\n");
for(looper = 0; ST_SUBSTRING_MATCH_MAX > looper; looper++)
{
PR_fprintf(inRequest->mFD, "<input type=text name=\"mRestrictText%d\" value=\"%s\"><br>\n", looper, NULL == globals.mOptions.mRestrictText[looper] ? "" : globals.mOptions.mRestrictText[looper]);
PR_fprintf(inRequest->mFD, "<input type=text name=\"mRestrictText%d\" value=\"%s\"><br>\n", looper, globals.mOptions.mRestrictText[looper]);
}
PR_fprintf(inRequest->mFD, "<hr>\n");
@ -5423,7 +5393,7 @@ int handleRequest(tmreader* aTMR, PRFileDesc* aFD, const char* aFileName, const
memset(&request, 0, sizeof(request));
request.mFD = aFD;
request.mFileName = aFileName;
request.mGetFileName = aFileName;
request.mGetData = aGetData;
/*
@ -5484,10 +5454,10 @@ int handleRequest(tmreader* aTMR, PRFileDesc* aFD, const char* aFileName, const
if(request.mGetData && *request.mGetData)
{
char* categoryName = NULL;
int getRes = getDataString(request.mGetData, "mCategory", &categoryName, NULL);
char categoryName[ST_OPTION_STRING_MAX];
int getRes = getDataString(request.mGetData, "mCategory", categoryName, sizeof(categoryName), NULL);
STCategoryNode* node;
if (categoryName && *categoryName &&
if (*categoryName &&
strcmp(categoryName, globals.mOptions.mCategoryName) &&
(node = findCategoryNode(categoryName, &globals)))
{
@ -5497,9 +5467,7 @@ int handleRequest(tmreader* aTMR, PRFileDesc* aFD, const char* aFileName, const
recalculateRunCost(node->run);
globals.mCache.mSortedRun = node->run;
if (globals.mOptions.mCategoryName)
free(globals.mOptions.mCategoryName);
globals.mOptions.mCategoryName = categoryName;
PR_snprintf(globals.mOptions.mCategoryName, sizeof(globals.mOptions.mCategoryName), "%s", categoryName);
}
}
@ -6334,18 +6302,6 @@ int main(int aArgCount, char** aArgArray)
}
}
/*
** Options cleanup.
*/
for(looper = 0; ST_SUBSTRING_MATCH_MAX > looper; looper++)
{
if(NULL != globals.mOptions.mRestrictText[looper])
{
free(globals.mOptions.mRestrictText[looper]);
globals.mOptions.mRestrictText[looper] = NULL;
}
}
if(0 != retval)
{
REPORT_ERROR(retval, main);

Просмотреть файл

@ -136,6 +136,11 @@
*/
#define ST_ROOT_CATEGORY_NAME "All"
/*
** Size of our option string buffers.
*/
#define ST_OPTION_STRING_MAX 256
/*
** Set the desired resolution of the timevals.
** The resolution is just mimicking what is recorded in the trace-malloc
@ -392,18 +397,18 @@ typedef struct __struct_STOptions
/*
** The string which identifies this program.
*/
const char* mProgramName;
char mProgramName[ST_OPTION_STRING_MAX];
/*
** File from which we retrieve the input.
** The input should have been generated from a trace malloc run.
*/
const char* mFileName;
char mFileName[ST_OPTION_STRING_MAX];
/*
** Which directory we will take over and write our output.
*/
const char* mOutputDir;
char mOutputDir[ST_OPTION_STRING_MAX];
/*
** The various batch mode requests we've received.
@ -480,33 +485,20 @@ typedef struct __struct_STOptions
/*
** Restrict callsite backtraces to those containing text.
*/
char* mRestrictText[ST_SUBSTRING_MATCH_MAX];
char mRestrictText[ST_SUBSTRING_MATCH_MAX][ST_OPTION_STRING_MAX];
/*
** File containing rules to categorize allocations
*/
char* mCategoryFile;
char mCategoryFile[ST_OPTION_STRING_MAX];
/*n
** Category to focus report on. NULL if not focussing on a category.
/*
** Category to focus report on. '\0' if not focussing on a category.
*/
char *mCategoryName;
char mCategoryName[ST_OPTION_STRING_MAX];
} STOptions;
/*
** STRequestOptions
**
** These options are likely to change on a per request/client basis.
** Careful on adding too many options here, this struct also hashes
** our content cache and more options means fewer cache hits.
*/
typedef struct __struct_STRequestOptions
{
int nothing;
}
STRequestOptions;
/*
** STRequest
**
@ -522,7 +514,7 @@ typedef struct __struct_STRequest
/*
** The filename requested.
*/
const char* mFileName;
const char* mGetFileName;
/*
** The GET form data, if any.
@ -532,7 +524,7 @@ typedef struct __struct_STRequest
/*
** Options specific to this request.
*/
STRequestOptions mOptions;
STOptions mOptions;
} STRequest;
/*
@ -552,7 +544,7 @@ typedef struct __struct_STCache
/*
** Category the mSortedRun belongs to. NULL if not to any category.
*/
const char *mCategoryName;
char mCategoryName[ST_OPTION_STRING_MAX];
/*
** Footprint graph cache.