blob: c1de8b65557c70dc94b4bde94362bc38ae143cc6 [file] [log] [blame]
/*
* Legal Notice
*
* This document and associated source code (the "Work") is a part of a
* benchmark specification maintained by the TPC.
*
* The TPC reserves all right, title, and interest to the Work as provided
* under U.S. and international laws, including without limitation all patent
* and trademark rights therein.
*
* No Warranty
*
* 1.1 TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THE INFORMATION
* CONTAINED HEREIN IS PROVIDED "AS IS" AND WITH ALL FAULTS, AND THE
* AUTHORS AND DEVELOPERS OF THE WORK HEREBY DISCLAIM ALL OTHER
* WARRANTIES AND CONDITIONS, EITHER EXPRESS, IMPLIED OR STATUTORY,
* INCLUDING, BUT NOT LIMITED TO, ANY (IF ANY) IMPLIED WARRANTIES,
* DUTIES OR CONDITIONS OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR
* PURPOSE, OF ACCURACY OR COMPLETENESS OF RESPONSES, OF RESULTS, OF
* WORKMANLIKE EFFORT, OF LACK OF VIRUSES, AND OF LACK OF NEGLIGENCE.
* ALSO, THERE IS NO WARRANTY OR CONDITION OF TITLE, QUIET ENJOYMENT,
* QUIET POSSESSION, CORRESPONDENCE TO DESCRIPTION OR NON-INFRINGEMENT
* WITH REGARD TO THE WORK.
* 1.2 IN NO EVENT WILL ANY AUTHOR OR DEVELOPER OF THE WORK BE LIABLE TO
* ANY OTHER PARTY FOR ANY DAMAGES, INCLUDING BUT NOT LIMITED TO THE
* COST OF PROCURING SUBSTITUTE GOODS OR SERVICES, LOST PROFITS, LOSS
* OF USE, LOSS OF DATA, OR ANY INCIDENTAL, CONSEQUENTIAL, DIRECT,
* INDIRECT, OR SPECIAL DAMAGES WHETHER UNDER CONTRACT, TORT, WARRANTY,
* OR OTHERWISE, ARISING IN ANY WAY OUT OF THIS OR ANY OTHER AGREEMENT
* RELATING TO THE WORK, WHETHER OR NOT SUCH AUTHOR OR DEVELOPER HAD
* ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES.
*
* Contributors:
* Gradient Systems
*/
#include "config.h"
#include "porting.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "error_msg.h"
#include "dist.h"
#include "date.h"
#include "decimal.h"
#include "misc.h"
#include "genrand.h"
#include "substitution.h"
#include "StringBuffer.h"
extern template_t *pCurrentTemplate,
*g_Template;
int ParseFile(char *szPath);
/*
* Routine:
* Purpose:
* Algorithm:
* Data Structures:
*
* Params:
* Returns:
* Called By:
* Calls:
* Assumptions:
* Side Effects:
* TODO: None
*/
int
compareSubstitution(const void *p1, const void *p2)
{
substitution_t *pS1 = (substitution_t *)p1,
*pS2 = (substitution_t *)p2;
if (pS1 == NULL)
{
if (pS2 == NULL)
return(0);
else
return(-1);
}
if (pS2 == NULL)
return(1);
return(strcasecmp(pS1->name, pS2->name));
}
/*
* Routine:
* Purpose:
* Algorithm:
* Data Structures:
*
* Params:
* Returns:
* Called By:
* Calls:
* Assumptions:
* Side Effects:
* TODO: None
*/
substitution_t *
findSubstitution(template_t *t, char *name, int *nUse)
{
int nChars,
nUseCount;
substitution_t *pSub;
static substitution_t tempSubstitution;
static int bInit = 0;
if (!bInit)
{
memset(&tempSubstitution, 0, sizeof(struct SUBSTITUTION_T));
tempSubstitution.name = malloc(100 * sizeof(char));
MALLOC_CHECK(tempSubstitution.name);
bInit = 1;
}
/* exclude any numeric suffix from search, but update nUses */
nChars = strcspn(name, "0123456789");
if (strlen(name) > 100)
tempSubstitution.name = realloc(tempSubstitution.name, strlen(name) + 1);
strncpy(tempSubstitution.name, name, nChars);
tempSubstitution.name[nChars] = '\0';
pSub = findList(t->SubstitutionList, (void *)&tempSubstitution);
if (!pSub) /* the substitution could be global; add a local reference */
{
pSub = findList(g_Template->SubstitutionList, (void *)&tempSubstitution);
if (pSub)
addList(t->SubstitutionList, pSub);
}
if (pSub)
{
nUseCount = atoi(name + nChars);
if (nUseCount == 0)
nUseCount = 1;
if (nUseCount > pSub->nUse)
pSub->nUse = nUseCount;
if (nUse) /* we're interested in the usage number */
*nUse = nUseCount;
return(pSub);
}
return(NULL);
}
/*
* Routine:
* Purpose:
* Algorithm:
* Data Structures:
*
* Params:
* Returns:
* Called By:
* Calls:
* Assumptions:
* Side Effects:
* TODO: None
*/
int
AddQuerySubstitution(template_t *t, char *szName, int nUse, int bEndSuffix)
{
substitution_t *pSub;
segment_t *pSegment;
int nSegmentCount;
if ((pSub = findSubstitution(t, szName, NULL)) == NULL)
ReportError(QERR_NO_INIT, szName, 1);
nSegmentCount = length(t->SegmentList);
if (nSegmentCount == 0) /* template starts with a substitution */
AddQuerySegment(t, "");
pSegment = (segment_t *)getItem(t->SegmentList, length(t->SegmentList));
if (pSegment->pSubstitution)
{
AddQuerySegment(t, "");
pSegment = (segment_t *)getItem(t->SegmentList, length(t->SegmentList));
}
pSegment->pSubstitution = pSub;
pSegment->nSubUse = bEndSuffix;
if (pSub->pAssignment->nFlags & (EXPR_FL_LIST|EXPR_FL_ULIST))
pSegment->nSubUse -= 1;
pSegment->nSubCount = nUse;
return(0);
}