#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); }