mirror of https://github.com/lianthony/NT4.0
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.
586 lines
13 KiB
586 lines
13 KiB
/**********************************************************************/
|
|
/** Microsoft Windows/NT **/
|
|
/** Copyright(c) Microsoft Corp., 1991 **/
|
|
/**********************************************************************/
|
|
|
|
/*
|
|
SPROLOG.CXX
|
|
|
|
SPROLOG C++ Wrapper class implementation
|
|
|
|
FILE HISTORY:
|
|
DavidHov 10/3/91 Created
|
|
DavidHov 11/22/91 Added exception handling
|
|
DavidHov 03/25/92 Separated exception hanling for MIPS build
|
|
|
|
*/
|
|
|
|
#include "pch.hxx"
|
|
#pragma hdrstop
|
|
|
|
extern "C"
|
|
{
|
|
#include "prtypes.h" // SPROLOG basic types
|
|
#include "prmain.h" // Include the internal
|
|
#include "prextern.h" // SP.LIB definitions
|
|
#include "sprolog.h" // Message defs
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: SPROLOG::SPROLOG
|
|
|
|
SYNOPSIS: Constructor of SPROLOG object.
|
|
|
|
ENTRY: Nothing
|
|
|
|
EXIT: standard
|
|
|
|
RETURNS:
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
SPROLOG :: SPROLOG ()
|
|
: _spState( SP_VOID ),
|
|
_err( 0 ),
|
|
_pszDefConsult( NULL ),
|
|
_msgId( 0 ),
|
|
_pszMsg( NULL )
|
|
{
|
|
if ( QueryError() )
|
|
return ;
|
|
|
|
Reset() ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: SPROLOG::~SPROLOG
|
|
|
|
SYNOPSIS: Destructor of SPROLOG wrapper object
|
|
|
|
ENTRY:
|
|
|
|
EXIT:
|
|
|
|
RETURNS:
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
SPROLOG :: ~ SPROLOG ()
|
|
{
|
|
ResetDefaultConsult( NULL ) ;
|
|
Reset();
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: SPROLOG::Init
|
|
|
|
SYNOPSIS: Initialize the interpreter. This includes allocating
|
|
the zones, etc. If there is a "default consultation"
|
|
file, consult it.
|
|
|
|
NOTE: This only occurs if the state is SP_VOID.
|
|
Otherwise, the result is always TRUE and nothing
|
|
occurs.
|
|
|
|
ENTRY:
|
|
|
|
EXIT:
|
|
|
|
RETURNS:
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
BOOL SPROLOG :: Init ()
|
|
{
|
|
BOOL fResult = TRUE ;
|
|
|
|
if ( _spState == SP_VOID )
|
|
{
|
|
if ( fResult = ::init_prolog() )
|
|
{
|
|
_spState = SP_INIT ;
|
|
|
|
if ( _pszDefConsult )
|
|
{
|
|
fResult = Consult( _pszDefConsult ) ;
|
|
}
|
|
}
|
|
#if defined(DEBUG)
|
|
TRACEEOL( SZ("NCPA/SP: interpreter initialized, result = ") << fResult ) ;
|
|
#endif
|
|
}
|
|
return fResult ;
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: SPROLOG::ResetDefaultConsult
|
|
|
|
SYNOPSIS: Establish the name of the default consultation file.
|
|
This is a disk file which will be automatically
|
|
consulted before any other SProlog queries or consultations
|
|
are performed.
|
|
|
|
N.B.: THIS FEATURE IS NOT NORMALLY USED BY THE NCPA!
|
|
|
|
ENTRY: const TCHAR * pszFileName the file name
|
|
|
|
EXIT:
|
|
|
|
RETURNS:
|
|
|
|
NOTES: A copy is made of the input string.
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
BOOL SPROLOG :: ResetDefaultConsult ( const TCHAR * pszFileName )
|
|
{
|
|
BOOL fResult = TRUE ;
|
|
|
|
if ( _pszDefConsult )
|
|
{
|
|
delete _pszDefConsult ;
|
|
}
|
|
|
|
_pszDefConsult = NULL ;
|
|
|
|
if ( pszFileName )
|
|
{
|
|
_pszDefConsult = new TCHAR [ ::strlenf( (TCHAR *) pszFileName ) + sizeof(TCHAR) ] ;
|
|
if ( fResult = _pszDefConsult != NULL )
|
|
{
|
|
::strcpyf( (TCHAR *) _pszDefConsult, (TCHAR *) pszFileName ) ;
|
|
}
|
|
}
|
|
return fResult ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: SPROLOG::DoQueryOrConsult
|
|
|
|
SYNOPSIS: Query or Consult either a text file or a text string
|
|
|
|
ENTRY: const TCHAR * pszFileName if !NULL, the name of the file
|
|
const TCHAR * pszData if !NULL, ptr to data string
|
|
|
|
EXIT: TCHAR * pchResult location to store result
|
|
ULONG lcbResult capacity of result string
|
|
|
|
RETURNS: BOOL FALSE if query fails
|
|
|
|
NOTES: This is the ONLY direct interface routine to the
|
|
SProlog exception handling wrapper function,
|
|
SpDoQueryConsult().
|
|
|
|
The purpose of this routine is to perform the
|
|
necessary character promotions/demotions for UNICODE.
|
|
|
|
If UNICODE, buffers are allocated for either the
|
|
file name or data buffer (only one is ever present)
|
|
and the result buffer (if query). The operands
|
|
are then demoted to CHAR; the result buffer, if
|
|
required, is promoted to WCHAR upon exit.
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
|
|
BOOL SPROLOG :: DoQueryOrConsult (
|
|
const TCHAR * pszFileName, // File to read and query/consult
|
|
const TCHAR * pszData, // Data buffer to query/consult
|
|
TCHAR * pchResult, // Output data buffer (query only)
|
|
ULONG lcbResult ) // Size of output buffer (query only)
|
|
{
|
|
BOOL fResult ;
|
|
|
|
#if defined(UNICODE)
|
|
|
|
BOOL fQuery = pchResult != NULL,
|
|
fFile = pszFileName != NULL ;
|
|
|
|
int cchInData = ::strlenf( fFile ? pszFileName : pszData )
|
|
+ (sizeof (CHAR) * 2) ;
|
|
|
|
CHAR * pchInData = new CHAR [ cchInData ] ;
|
|
CHAR * pchOutData = NULL ;
|
|
|
|
if ( fQuery ) // Allocate the output buffer.
|
|
{
|
|
pchOutData = new CHAR [ lcbResult ] ;
|
|
}
|
|
|
|
if ( pchInData && (pchOutData || (!fQuery)) )
|
|
{
|
|
ALIAS_STR nlsInData( fFile ? pszFileName : pszData ) ;
|
|
CHAR * pchTempFile = NULL,
|
|
* pchTempData = NULL ;
|
|
|
|
nlsInData.MapCopyTo( pchInData, cchInData ) ;
|
|
|
|
if ( fFile )
|
|
{
|
|
pchTempFile = pchInData ;
|
|
}
|
|
else
|
|
{
|
|
pchTempData = pchInData ;
|
|
}
|
|
|
|
#if defined(DEBUG) && defined(NEVER)
|
|
if ( ! (fQuery || fFile) )
|
|
{
|
|
// Write the consultation data to a temp file
|
|
|
|
DISKFILE dfConsult( SZ("NCPACSLT.TMP"), OF_WRITE ) ;
|
|
if ( dfConsult.QueryOpen() )
|
|
{
|
|
dfConsult.Write( (TCHAR *) pchTempData, cchInData ) ;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
fResult = ::SpDoQueryConsult( pchTempFile, pchTempData,
|
|
pchOutData, lcbResult, & _err ) ;
|
|
|
|
if ( fResult && fQuery ) // If there is an output buffer
|
|
{
|
|
NLS_STR nlsOutData ;
|
|
|
|
nlsOutData.MapCopyFrom( pchOutData ) ;
|
|
|
|
if ( fResult = ((_err = nlsOutData.QueryError()) == 0) )
|
|
{
|
|
// Allocation and mapping were successful.
|
|
// Return the result data.
|
|
|
|
::strcpyf( pchResult, nlsOutData.QueryPch() ) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
delete pchInData ;
|
|
delete pchOutData ;
|
|
|
|
#else
|
|
|
|
fResult = ::SpDoQueryConsult( pszFileName, pszData, pchResult, lcbResult, & _err ) ;
|
|
|
|
#endif
|
|
|
|
return fResult ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: SPROLOG::DoConsult
|
|
|
|
SYNOPSIS: Consult either a text file or a text string
|
|
|
|
ENTRY: const TCHAR * pszFileName if !NULL, the name of the file
|
|
const TCHAR * pszData if !NULL, ptr to data string
|
|
|
|
EXIT: BOOL FALSE if consultation fails
|
|
|
|
RETURNS:
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
|
|
BOOL SPROLOG :: DoConsult ( const TCHAR * pszFileName, const TCHAR * pszData )
|
|
{
|
|
|
|
#if defined(DEBUG)
|
|
if ( pszFileName )
|
|
{
|
|
TRACEEOL( SZ("NCPA/SP: consultation of file: [")
|
|
<< pszFileName << SZ("]") );
|
|
}
|
|
else
|
|
{
|
|
TRACEEOL( SZ("NCPA/SP: consult data") );
|
|
}
|
|
#endif
|
|
|
|
if ( ! Init() )
|
|
{
|
|
#if defined(DEBUG)
|
|
DBGEOL( SZ("NCPA/SP: attempt to consult without initializing interpreter") ) ;
|
|
#endif
|
|
return FALSE ;
|
|
}
|
|
|
|
return DoQueryOrConsult( pszFileName, pszData, NULL, 0 ) ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: SPROLOG::DoQuery
|
|
|
|
SYNOPSIS: Query either a text file or a text string
|
|
|
|
ENTRY: const TCHAR * pszFileName if !NULL, the name of the file
|
|
const TCHAR * pszData if !NULL, ptr to data string
|
|
|
|
EXIT: TCHAR * pchResult location to store result
|
|
ULONG lcbResult capacity of result string
|
|
|
|
RETURNS: BOOL FALSE if query fails
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
|
|
BOOL SPROLOG :: DoQuery
|
|
( const TCHAR * pszFileName,
|
|
const TCHAR * pszData,
|
|
TCHAR * pchResult,
|
|
ULONG lcbResult )
|
|
{
|
|
BOOL fResult ;
|
|
|
|
#if defined(DEBUG)
|
|
if ( pszFileName )
|
|
{
|
|
TRACEEOL( SZ("NCPA/SP: query attempt on file: [")
|
|
<< pszFileName << SZ("]") );
|
|
}
|
|
else
|
|
{
|
|
TRACEEOL( SZ("NCPA/SP: query attempt: [") << pszData << SZ("]") );
|
|
}
|
|
#endif
|
|
|
|
if ( ! Init() )
|
|
{
|
|
#if defined(DEBUG)
|
|
DBGEOL( SZ("NCPA/SP: attempt to query without initializing interpreter") ) ;
|
|
#endif
|
|
return FALSE ;
|
|
}
|
|
|
|
fResult = DoQueryOrConsult( pszFileName, pszData, pchResult, lcbResult ) ;
|
|
|
|
#if defined(DEBUG)
|
|
if ( fResult )
|
|
{
|
|
TRACEEOL( SZ("NCPA/SP: query result: [") << pchResult << SZ("]") );
|
|
}
|
|
else
|
|
{
|
|
TRACEEOL( SZ("NCPA/SP: query failed!") );
|
|
}
|
|
#endif
|
|
|
|
return fResult ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: SPROLOG::ConsultData
|
|
|
|
SYNOPSIS: Public interface to consult a string.
|
|
|
|
ENTRY:
|
|
|
|
EXIT:
|
|
|
|
RETURNS:
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
// Consult a data string
|
|
|
|
BOOL SPROLOG :: ConsultData ( const TCHAR * pszData )
|
|
{
|
|
BOOL fResult ;
|
|
|
|
#if defined(DEBUG)
|
|
TRACEEOL( SZ("NCPA/SP: consulting data...") );
|
|
#endif
|
|
|
|
fResult = DoConsult( NULL, pszData ) ;
|
|
|
|
#if defined(DEBUG)
|
|
if ( fResult )
|
|
{
|
|
TRACEEOL( SZ("NCPA/SP: consultation successful") );
|
|
}
|
|
else
|
|
{
|
|
TRACEEOL( SZ("NCPA/SP: consultation failed!") );
|
|
}
|
|
#endif
|
|
|
|
return fResult ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: SPROLOG::Consult
|
|
|
|
SYNOPSIS: Public interface to consult a file
|
|
|
|
ENTRY:
|
|
|
|
EXIT:
|
|
|
|
RETURNS:
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
// Consult a file
|
|
|
|
BOOL SPROLOG :: Consult ( const TCHAR * pszFileName )
|
|
{
|
|
return DoConsult( pszFileName, NULL ) ;
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: SPROLOG::Query
|
|
|
|
SYNOPSIS: Public interface to query a file
|
|
|
|
ENTRY:
|
|
|
|
EXIT:
|
|
|
|
RETURNS:
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
|
|
BOOL SPROLOG :: Query
|
|
( const TCHAR * pszFileName, TCHAR * pchResult, ULONG lcbResult )
|
|
{
|
|
return DoQuery( pszFileName, NULL, pchResult, lcbResult ) ;
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: SPROLOG::QueryData
|
|
|
|
SYNOPSIS: Public interface to query a string
|
|
|
|
ENTRY:
|
|
|
|
EXIT:
|
|
|
|
RETURNS:
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
BOOL SPROLOG :: QueryData
|
|
( const TCHAR * pszData, TCHAR * pchResult, ULONG lcbResult )
|
|
{
|
|
BOOL fResult = DoQuery( NULL, pszData, pchResult, lcbResult ) ;
|
|
|
|
return fResult ;
|
|
}
|
|
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: SPROLOG::Reset
|
|
|
|
SYNOPSIS: Reset the interpreter entirely.
|
|
Destroy all zones, etc.
|
|
|
|
ENTRY:
|
|
|
|
EXIT:
|
|
|
|
RETURNS:
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
// Reset the Interpreter
|
|
BOOL SPROLOG :: Reset ()
|
|
{
|
|
#if defined(DEBUG)
|
|
TRACEEOL( SZ("NCPA/SP: interpreter reset") ) ;
|
|
#endif
|
|
|
|
switch ( _spState )
|
|
{
|
|
case SP_VOID:
|
|
break ;
|
|
|
|
case SP_QUERY:
|
|
case SP_CONSULT:
|
|
case SP_TERM:
|
|
case SP_INIT:
|
|
case SP_INTERR:
|
|
default:
|
|
::end_prolog();
|
|
break ;
|
|
}
|
|
_spState = SP_VOID ;
|
|
|
|
_err = 0 ;
|
|
|
|
return TRUE ;
|
|
}
|
|
|
|
/*******************************************************************
|
|
|
|
NAME: SPROLOG::SPROLOG
|
|
|
|
SYNOPSIS:
|
|
|
|
ENTRY:
|
|
|
|
EXIT:
|
|
|
|
RETURNS:
|
|
|
|
NOTES:
|
|
|
|
HISTORY:
|
|
|
|
********************************************************************/
|
|
// Return the last error encountered.
|
|
|
|
APIERR SPROLOG :: QueryError ()
|
|
{
|
|
return _err ? _err : BASE::QueryError() ;
|
|
}
|
|
|
|
// End of SPROLOG.CXX
|