windows-nt/Source/XPSP1/NT/base/ntsetup/legacy/dll/parse1.c
2020-09-26 16:20:57 +08:00

160 lines
4.2 KiB
C

#include "precomp.h"
#pragma hdrstop
/**************************************************************************/
/***** Common Library Component - Parse Table Handling Routines 1 *********/
/**************************************************************************/
// Return the number of items in the given parse table.
static size_t countScp ( PSCP pscpTable )
{
size_t i ;
for (i = 0; pscpTable[i].sz ; i++) ;
return i;
}
// Compare two parse table structures
static int __cdecl compareScps ( const void * scp1, const void * scp2 )
{
return _stricmp( ((PSCP) scp1)->sz, ((PSCP) scp2)->sz );
}
// Allocate and initialize a sorted version of the given
// parse table
static PSCP reallocateSorted ( PSCP pscpTable )
{
size_t cItems = countScp( pscpTable ) ;
PSCP pscpSorted = (PSCP) calloc( cItems, sizeof (SCP) ) ;
if (pscpSorted == NULL)
return NULL;
// Copy and sort the new table.
memcpy( (void *) pscpSorted,
(void *) pscpTable,
(size_t) cItems * sizeof (SCP) );
qsort( pscpSorted,
cItems,
sizeof (SCP),
compareScps );
return pscpSorted ;
}
static PSPT allocateParseTable ( PSCP pscpTable )
{
PSPT pspt = malloc( sizeof (SPT) ) ;
if (pspt == NULL) {
return NULL;
}
pspt->pscpSorted = reallocateSorted( pscpTable ) ;
if (pspt->pscpSorted == NULL) {
free( pspt );
return NULL ;
}
pspt->pscpBase = pscpTable ;
pspt->cItems = countScp( pscpTable );
pspt->spcDelim = pscpTable[ pspt->cItems ].spc ;
return pspt ;
}
static void destroyParseTable ( PSPT parseTable )
{
free( parseTable->pscpSorted );
free( parseTable );
}
/*
** Purpose:
** Initializes a Parsing Table so a string can be searched for and its
** corresponding code found and returned.
** Arguments:
** pscp: a non-NULL array of SCPs with the last one having an sz value
** of NULL and an SPC for indicating errors.
** Returns:
** NULL if an error occurs.
** Non-NULL if the operation was successful.
**
**************************************************************************/
PSPT APIENTRY PsptInitParsingTable(pscp)
PSCP pscp;
{
AssertDataSeg();
ChkArg(pscp != (PSCP)NULL, 1, (PSPT)NULL);
return allocateParseTable( pscp ) ;
}
/*
** Purpose:
** Searches for a string in a String Parsing Table and returns its
** associated code.
** Arguments:
** pspt: non-NULL String Parsing Table initialized by a successful
** call to PsptInitParsingTable()..
** sz: non-NULL string to search for.
** Returns:
** The corresponding SPC if sz is in pspt, or the SPC associated with
** the NULL in pspt if sz could not be found.
**
**************************************************************************/
SPC APIENTRY SpcParseString(pspt, sz)
PSPT pspt;
SZ sz;
{
PSCP pscpResult ;
SCP scpTemp ;
AssertDataSeg();
ChkArg(pspt != (PSPT)NULL, 1, spcError);
ChkArg(sz != (SZ)NULL, 2, spcError);
if (pspt == NULL || sz == NULL)
return 0 ;
scpTemp.sz = sz ;
pscpResult = (PSCP) bsearch( (void *) & scpTemp,
(void *) pspt->pscpSorted,
pspt->cItems,
sizeof (SCP),
compareScps );
return pscpResult
? pscpResult->spc
: pspt->spcDelim ;
}
/*
** Purpose:
** Destroys a Parse Table (freeing any memory allocated).
** Arguments:
** pspt: non-NULL String Parsing Table to be destroyed that was
** initialized with a successful call to PsptInitParsingTable().
** Returns:
** fFalse if an error occurred.
** fTrue if successful.
**
**************************************************************************/
BOOL APIENTRY FDestroyParsingTable(pspt)
PSPT pspt;
{
AssertDataSeg();
ChkArg(pspt != (PSPT)NULL, 1, fFalse);
destroyParseTable( pspt );
return(fTrue);
}