808 lines
20 KiB
C
808 lines
20 KiB
C
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
Copyright (c) 1989-2000 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
ebase.c
|
||
|
||
Abstract:
|
||
|
||
This file generates the error recovery data base.
|
||
|
||
Notes:
|
||
|
||
1. Inputs to this module are the extable.* files generated by yacc in
|
||
response to the s switch.
|
||
2. Take the state vs token index file ( extable.h3 ), and generate the
|
||
state vs token table using the token index to token value
|
||
translations provided by extable.h1
|
||
3. Take the state vs expected RHS file ( extable.h2 ) and generate a
|
||
data base of expected RHS in every state.
|
||
|
||
Author:
|
||
|
||
vibhasc 11-15-91
|
||
|
||
----------------------------------------------------------------------------*/
|
||
|
||
/*****************************************************************************
|
||
local defines and includes
|
||
*****************************************************************************/
|
||
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <assert.h>
|
||
#include <malloc.h>
|
||
#include <string.h>
|
||
|
||
#include "ebase.h"
|
||
|
||
#define STATE_VS_TOKEN_INDEX_FILE "extable.h3"
|
||
#define TOKEN_TRANSLATION_FILE "extable.h1"
|
||
#define STATE_VS_EXPECTED_FILE "extable.h2"
|
||
#define ISVALIDTOKEN( i ) (TRUE)
|
||
#define MAX_TRANSLATION_LINE_SIZE (512)
|
||
|
||
#define TRUE 1
|
||
#define FALSE 0
|
||
/* from winerror.h */
|
||
#define ERROR_INVALID_DATA 13
|
||
|
||
#define CHECK_FSCAN_STATUS( fscanfcall ) \
|
||
if ( EOF == (fscanfcall) ) \
|
||
{ \
|
||
fprintf( stderr, \
|
||
"\nmidleb : error MIDLEB%d : unexpected end of input stream", \
|
||
ERROR_INVALID_DATA ); \
|
||
exit( ERROR_INVALID_DATA ); \
|
||
}
|
||
|
||
typedef unsigned int BOOL;
|
||
|
||
typedef enum _status
|
||
{
|
||
|
||
STATUS_OK = 0,
|
||
OUT_OF_MEMORY,
|
||
CANT_OPEN_INPUT_FILE,
|
||
CANT_OPEN_OUTPUT_FILE,
|
||
WRONG_ARGUMENT_COUNT
|
||
|
||
} STATUS_T;
|
||
|
||
typedef struct _xlat
|
||
{
|
||
char * pIncoming;
|
||
char * pTranslated;
|
||
struct _xlat *pNext;
|
||
} XLAT;
|
||
|
||
typedef struct _DBENTRY
|
||
{
|
||
short State;
|
||
char * pTranslated;
|
||
} DBENTRY;
|
||
|
||
/*****************************************************************************
|
||
global data
|
||
*****************************************************************************/
|
||
|
||
FILE * hStateVsTokenIndexFile;
|
||
FILE * hStateVsExpectedFile;
|
||
FILE * hOutput;
|
||
FILE * hXlatFile;
|
||
FILE * hTokXlatHdl;
|
||
SGOTO ** pSGoto;
|
||
short * pSGotoCount;
|
||
short ** pTokVsState;
|
||
short * pTokVsStateIndex;
|
||
short ValidStates;
|
||
short ValidTokens;
|
||
char * pPrefix;
|
||
XLAT * pXlat = 0,
|
||
* pXlatCur = 0;
|
||
DBENTRY * pDataBase;
|
||
short NTOKENS;
|
||
short ACCEPTCODE;
|
||
short * TokVal;
|
||
short * TokCount;
|
||
short NSTATES;
|
||
short MAXTOKVSSTATE;
|
||
short MAXSTATEVSTOK;
|
||
short MAXTOKENVALUE;
|
||
short MAXSTATEVSEXPECTED;
|
||
|
||
/*****************************************************************************
|
||
external procedures
|
||
*****************************************************************************/
|
||
|
||
STATUS_T Init( char *, char * );
|
||
STATUS_T Generate( FILE * );
|
||
STATUS_T OpenFileForReadProcessing( FILE **, char * );
|
||
void Dump( void );
|
||
BOOL SearchForStateInTokenVsState( short, short );
|
||
void TranslateExpectedConstructs( void );
|
||
char * Translate( char * );
|
||
|
||
|
||
void
|
||
main(
|
||
int argc,
|
||
char *argv[] )
|
||
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
||
Routine Description:
|
||
|
||
the main routine.
|
||
|
||
Arguments:
|
||
|
||
Standard
|
||
|
||
Return Value:
|
||
|
||
Exit Status
|
||
|
||
Notes:
|
||
|
||
Usage : ebase <OutputFilename> <Xlatefile> <prefix>
|
||
|
||
Xlatefile is the file where production names to message translation
|
||
is specified.
|
||
|
||
prefix is idl or acf. The expected string array is created with a
|
||
standard name prefixed with the user specified prefix.
|
||
----------------------------------------------------------------------------*/
|
||
{
|
||
|
||
STATUS_T Status;
|
||
|
||
fprintf( stderr, "Error Recovery Data Base Generator\n" );
|
||
|
||
|
||
if( argc == 4 )
|
||
{
|
||
|
||
pPrefix = argv[ 3 ];
|
||
|
||
if( (Status = Init( argv[ 1 ], argv[ 2 ] )) == STATUS_OK )
|
||
{
|
||
Status = Generate( hStateVsTokenIndexFile );
|
||
}
|
||
|
||
Dump();
|
||
|
||
TranslateExpectedConstructs();
|
||
|
||
}
|
||
else
|
||
{
|
||
|
||
fprintf( stderr, "Wrong argument count\n" );
|
||
fprintf( stderr, "Usage : midleb <output file or - > <translation-file-name> <prefix>\n");
|
||
Status = WRONG_ARGUMENT_COUNT;
|
||
|
||
}
|
||
|
||
exit( Status );
|
||
|
||
}
|
||
|
||
|
||
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
||
Routine Description:
|
||
|
||
Initialize
|
||
|
||
Arguments:
|
||
|
||
OutputName : output file name
|
||
XlatFilename : the production/token name to error message translation.
|
||
|
||
Return Value:
|
||
|
||
STATUS_T - OUT_OF_MEMORY or
|
||
- CANT_OPEN_INPUT_FILE or
|
||
- STATUS_OK
|
||
|
||
Notes:
|
||
|
||
Sets up the file handles for all the files that need to be read from
|
||
|
||
----------------------------------------------------------------------------*/
|
||
STATUS_T
|
||
Init(
|
||
char * OutputFileName,
|
||
char * XlatFileName )
|
||
{
|
||
STATUS_T Status;
|
||
int i;
|
||
|
||
Status = OpenFileForReadProcessing(
|
||
&hStateVsTokenIndexFile,
|
||
STATE_VS_TOKEN_INDEX_FILE );
|
||
|
||
if( Status == STATUS_OK )
|
||
{
|
||
Status = OpenFileForReadProcessing(
|
||
&hStateVsExpectedFile,
|
||
STATE_VS_EXPECTED_FILE );
|
||
|
||
if( Status == STATUS_OK )
|
||
{
|
||
Status = OpenFileForReadProcessing(
|
||
&hTokXlatHdl,
|
||
TOKEN_TRANSLATION_FILE );
|
||
if( Status == STATUS_OK )
|
||
{
|
||
Status = OpenFileForReadProcessing( &hXlatFile, XlatFileName );
|
||
|
||
if( Status == STATUS_OK )
|
||
{
|
||
if( strcmp( OutputFileName, "-" ) == 0 )
|
||
hOutput = stdout;
|
||
else if( (hOutput = fopen( OutputFileName , "w" )) == (FILE *)0 )
|
||
{
|
||
Status = CANT_OPEN_OUTPUT_FILE;
|
||
};
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if( Status != STATUS_OK )
|
||
return Status;
|
||
|
||
/** read in the required numbers from the TOKEN_TRANSLATION_FILE **/
|
||
|
||
CHECK_FSCAN_STATUS(
|
||
fscanf( hTokXlatHdl, "%hd %hd\n", &NTOKENS, &ACCEPTCODE ) );
|
||
|
||
/** read in the token translation table **/
|
||
|
||
TokVal = (short *)calloc( 1, NTOKENS * sizeof( short ) );
|
||
TokCount = (short *)calloc( 1, NTOKENS * sizeof( short ) );
|
||
|
||
if (!TokVal || !TokCount )
|
||
{
|
||
fprintf( stderr, "Out of memory.\n");
|
||
exit(OUT_OF_MEMORY);
|
||
}
|
||
|
||
for( i = 0;
|
||
i < NTOKENS;
|
||
i++ )
|
||
{
|
||
CHECK_FSCAN_STATUS(
|
||
fscanf( hTokXlatHdl, "%hd", &TokVal[ i ]) );
|
||
}
|
||
|
||
CHECK_FSCAN_STATUS(
|
||
fscanf( hTokXlatHdl, "\n" ) );
|
||
|
||
for( i = 0;
|
||
i < NTOKENS;
|
||
i++ )
|
||
{
|
||
CHECK_FSCAN_STATUS(
|
||
fscanf( hTokXlatHdl, "%hd", &TokCount[ i ]) );
|
||
}
|
||
|
||
CHECK_FSCAN_STATUS(
|
||
fscanf( hTokXlatHdl, "\n" ) );
|
||
|
||
CHECK_FSCAN_STATUS(
|
||
fscanf( hTokXlatHdl,
|
||
"%hd %hd %hd %hd %hd\n",
|
||
&NSTATES,
|
||
&MAXTOKVSSTATE,
|
||
&MAXSTATEVSTOK,
|
||
&MAXTOKENVALUE,
|
||
&MAXSTATEVSEXPECTED ) );
|
||
|
||
/** allocate memory now **/
|
||
|
||
pSGoto = (SGOTO **) calloc( 1,NSTATES * sizeof( SGOTO * ) );
|
||
|
||
pSGotoCount = (short *)calloc(1, NSTATES * sizeof( short ) );
|
||
|
||
pTokVsState = (short **)calloc( 1,(MAXTOKENVALUE+1) * sizeof( short * ) );
|
||
|
||
pTokVsStateIndex = (short *)calloc(1, (MAXTOKENVALUE+1) * sizeof( short ) );
|
||
|
||
pDataBase = ( DBENTRY * )calloc( 1, MAXSTATEVSEXPECTED * sizeof( DBENTRY ) );
|
||
|
||
|
||
if( !pSGoto || !pSGotoCount || !pTokVsState || !pTokVsStateIndex || !pDataBase )
|
||
{
|
||
fprintf( stderr, "Out of memory.\n");
|
||
exit(OUT_OF_MEMORY);
|
||
}
|
||
|
||
return Status;
|
||
}
|
||
|
||
|
||
STATUS_T
|
||
Generate(
|
||
FILE * hSVsTIndexFile )
|
||
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
||
Routine Description:
|
||
|
||
Generate the state vs token table, given the state vs token index table
|
||
in extable.h3 and token vs token index translation of extable.h1.
|
||
|
||
Arguments:
|
||
|
||
hStateVsTokenIndexFile - handle to the file which has the state vs
|
||
token index info.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
Notes:
|
||
|
||
The state vs token index file has the goto info for every valid token,
|
||
For every state, this file contains the goto ( or none ) for every valid
|
||
token ( represented by the token index ). Thus for each state, we lookup
|
||
to see if the state has a goto for a given token index. If it does, then
|
||
we translate the token index into a token value, and mark the goto for the
|
||
state for that token in the state vs token table.
|
||
|
||
In the end we will have a very sparse array, which contains all the states
|
||
and the gotos for the state for each token ( or the absence of any goto ).
|
||
|
||
We will use this table to generate two tables:
|
||
|
||
1. The set of all states which have a goto on a token
|
||
2. The set of all tokens valid for any state.
|
||
|
||
The exception to this rule is the accept action which is treated like
|
||
an absence of goto.
|
||
----------------------------------------------------------------------------*/
|
||
{
|
||
|
||
short iState,i,j,Temp,SGotoCount;
|
||
SGOTO *p;
|
||
|
||
/** fixup pointers to token vs state pointer array **/
|
||
|
||
for( i = 0;
|
||
i < NTOKENS;
|
||
i++ )
|
||
{
|
||
|
||
if( TokCount[ i ] )
|
||
{
|
||
j = TokVal[ i ];
|
||
|
||
if( ISVALIDTOKEN( j ) )
|
||
{
|
||
pTokVsState[ j ] = calloc( 1, TokCount[ i ] * sizeof( short ) );
|
||
|
||
if (!pTokVsState[ j ])
|
||
{
|
||
fprintf( stderr, "Out of memory.\n" );
|
||
exit( OUT_OF_MEMORY );
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
for( iState = 0;
|
||
iState < NSTATES;
|
||
++iState )
|
||
{
|
||
|
||
/** ignore the state number */
|
||
|
||
CHECK_FSCAN_STATUS(
|
||
fscanf( hSVsTIndexFile,
|
||
"%hd %c",
|
||
&Temp,
|
||
&Temp ) );
|
||
|
||
/** get the count of number of state goto entries **/
|
||
|
||
CHECK_FSCAN_STATUS(
|
||
fscanf( hSVsTIndexFile,
|
||
"%hd %c",
|
||
&SGotoCount,
|
||
&Temp ) );
|
||
|
||
/** now read in the goto vs token pairs **/
|
||
|
||
|
||
if( SGotoCount )
|
||
{
|
||
|
||
p = pSGoto[ iState ] = calloc( 1, SGotoCount * sizeof( SGOTO ) );
|
||
|
||
if (!p)
|
||
{
|
||
fprintf( stderr, "Out of memory.\n" );
|
||
exit( OUT_OF_MEMORY );
|
||
}
|
||
|
||
for( j = 0;
|
||
j < SGotoCount;
|
||
++j )
|
||
{
|
||
|
||
CHECK_FSCAN_STATUS(
|
||
fscanf( hSVsTIndexFile,
|
||
"%hd%c %hd",
|
||
&p->Goto,
|
||
&Temp,
|
||
&p->Token ) );
|
||
|
||
Temp = TokVal[ p->Token ];
|
||
|
||
if( ISVALIDTOKEN( Temp ) )
|
||
{
|
||
if( !SearchForStateInTokenVsState( Temp, p->Goto ) )
|
||
{
|
||
i = pTokVsStateIndex[ Temp ];
|
||
pTokVsStateIndex[ Temp ]++;
|
||
|
||
*(pTokVsState[Temp] + i ) = p->Goto;
|
||
}
|
||
p++;
|
||
pSGotoCount[ iState ]++;
|
||
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
|
||
}
|
||
return STATUS_OK;
|
||
}
|
||
|
||
STATUS_T
|
||
OpenFileForReadProcessing(
|
||
FILE ** pHandle,
|
||
char * pName )
|
||
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
|
||
Routine Description:
|
||
|
||
This process opens a file for read processing, reports an error if
|
||
the file could not be opened.
|
||
|
||
Arguments:
|
||
|
||
pHandle - pointer to a file handle deposition area.
|
||
pName - pointer to a file name, null terminated.
|
||
|
||
Return Value:
|
||
|
||
STATUS_T - STATUS_OK if all is well.
|
||
- CANT_OPEN_INPUT_FILE otherwise.
|
||
Notes:
|
||
|
||
----------------------------------------------------------------------------*/
|
||
{
|
||
FILE *hF;
|
||
|
||
if( ( hF = fopen( pName, "r" ) ) == (FILE *)NULL )
|
||
{
|
||
fprintf( stderr, "Cannot open input file : %s\n", pName );
|
||
return CANT_OPEN_INPUT_FILE;
|
||
}
|
||
*pHandle = hF;
|
||
return STATUS_OK;
|
||
}
|
||
|
||
|
||
void
|
||
Dump( void )
|
||
{
|
||
SGOTO * p;
|
||
short iTemp, i,j;
|
||
|
||
/** dump the state goto table **/
|
||
|
||
for( iTemp = 0, ValidStates = 0;
|
||
iTemp < NSTATES;
|
||
++iTemp )
|
||
{
|
||
|
||
p = pSGoto[ iTemp ];
|
||
|
||
if( j = pSGotoCount[ iTemp ] )
|
||
{
|
||
fprintf( hOutput, "\n SGOTO _sG%s%.4hd [ %d ] = { ", pPrefix, iTemp, j );
|
||
|
||
for( i = 0;
|
||
i < j;
|
||
i++ )
|
||
{
|
||
|
||
fprintf( hOutput
|
||
, " {%hd, %hd} %c"
|
||
, p[ i ].Goto
|
||
, TokVal[ p[ i ].Token]
|
||
, ( (i+1 == j) ? ' ' : ',' ));
|
||
|
||
}
|
||
|
||
fprintf( hOutput, "};" );
|
||
|
||
ValidStates++;
|
||
}
|
||
}
|
||
|
||
|
||
/** now dump the array of pointers to this **/
|
||
|
||
fprintf( hOutput, "\n\n#define VALIDSTATES_%s %d\n", pPrefix, ValidStates );
|
||
|
||
fprintf( hOutput, "\n\nSGOTOVECTOR SGoto%s[ VALIDSTATES_%s ] = {\n",pPrefix, pPrefix);
|
||
|
||
for( i = 0;
|
||
i < NSTATES;
|
||
++i )
|
||
{
|
||
if( pSGotoCount[ i ] )
|
||
{
|
||
fprintf( hOutput, "\n{ %d, _sG%s%.4hd, %d }"
|
||
, i
|
||
,pPrefix
|
||
, i
|
||
, pSGotoCount[ i ] );
|
||
fprintf( hOutput,"%c", ((i + 1 == NSTATES) ? ' ' : ',' ));
|
||
}
|
||
|
||
}
|
||
|
||
fprintf( hOutput, "\n};\n\n" );
|
||
|
||
/** count the valid token entries. i.e tokens for which states exist **/
|
||
|
||
fprintf(hOutput, "#if 0\n");
|
||
|
||
for( ValidTokens = 0, i = 0;
|
||
i < MAXTOKENVALUE;
|
||
++i )
|
||
{
|
||
|
||
if( pTokVsStateIndex[ i ] )
|
||
ValidTokens++;
|
||
}
|
||
|
||
/** dump the token vs state table **/
|
||
|
||
for( iTemp = 0;
|
||
iTemp < NTOKENS;
|
||
++iTemp )
|
||
{
|
||
|
||
|
||
if( j = pTokVsStateIndex[ TokVal[ iTemp ] ] )
|
||
{
|
||
|
||
fprintf( hOutput, "short _tS%s%.4d[ %d ] = {", pPrefix, TokVal[ iTemp ], j );
|
||
|
||
for( i = 0;
|
||
i < j;
|
||
++i )
|
||
{
|
||
|
||
fprintf( hOutput, " %d %c", *(pTokVsState[ TokVal[ iTemp ] ]+i),
|
||
(( i + 1 == j ) ? ' ' : ',' ));
|
||
|
||
}
|
||
|
||
fprintf( hOutput, "};\n" );
|
||
|
||
}
|
||
}
|
||
|
||
/** dump the vectors to the token vs state table **/
|
||
|
||
fprintf(hOutput, "\n#define VALIDTOKENS %d\n", ValidTokens );
|
||
fprintf( hOutput, "\nTOKVSSTATEVECTOR TokVsState%s[ VALIDTOKENS ] = { \n",pPrefix);
|
||
|
||
for( i = 0;
|
||
i < MAXTOKENVALUE+1;
|
||
++i )
|
||
{
|
||
|
||
if( j = pTokVsStateIndex[ i ])
|
||
{
|
||
fprintf( hOutput, "\n{ %d, _tS%s%.4d, %d }",i, pPrefix, i, j );
|
||
fprintf(hOutput, "%c", (i + 1 == NTOKENS) ? ' ' : ',' );
|
||
}
|
||
|
||
|
||
}
|
||
|
||
fprintf( hOutput, "\n\n};\n" );
|
||
fprintf( hOutput, "\n" );
|
||
|
||
fprintf(hOutput, "#endif\n");
|
||
|
||
}
|
||
|
||
|
||
BOOL
|
||
SearchForStateInTokenVsState(
|
||
short TokenValue,
|
||
short Goto )
|
||
{
|
||
int i,j;
|
||
|
||
for( i = 0, j = pTokVsStateIndex[ TokenValue ];
|
||
i < j;
|
||
++i )
|
||
{
|
||
if( *(pTokVsState[ TokenValue ] + i) == Goto )
|
||
return TRUE;
|
||
}
|
||
return FALSE;
|
||
}
|
||
|
||
void
|
||
TranslateExpectedConstructs( void )
|
||
{
|
||
int i,State,Count,Temp;
|
||
char Buffer[ MAX_TRANSLATION_LINE_SIZE ];
|
||
char Buffer1[ MAX_TRANSLATION_LINE_SIZE ];
|
||
DBENTRY *p;
|
||
XLAT *pX;
|
||
|
||
/**
|
||
firstly, read in the translation data base, which shows the
|
||
expected token name vs the actual error string the compiler wants to
|
||
output.
|
||
**/
|
||
|
||
for(;;)
|
||
{
|
||
i = fscanf( hXlatFile,
|
||
"%[^ \t]%1s%[^\n]\n",
|
||
Buffer,
|
||
&Temp,
|
||
Buffer1 );
|
||
|
||
if( i == EOF || i == 0 )
|
||
break;
|
||
|
||
if( ( Buffer[0] != '$' ) && ( Buffer[1] != '$' ) )
|
||
{
|
||
pX = calloc( 1 , sizeof( XLAT ) );
|
||
|
||
if (!pX )
|
||
{
|
||
fprintf( stderr, "Out of memory!" );
|
||
exit(OUT_OF_MEMORY );
|
||
}
|
||
|
||
pX->pIncoming = malloc( strlen( Buffer ) + 1 );
|
||
|
||
if (!pX->pIncoming )
|
||
{
|
||
fprintf( stderr, "Out of memory!" );
|
||
exit(OUT_OF_MEMORY );
|
||
}
|
||
|
||
strcpy( pX->pIncoming, Buffer );
|
||
|
||
pX->pTranslated = malloc( strlen( Buffer1 ) + 1 );
|
||
|
||
if (!pX->pTranslated)
|
||
{
|
||
fprintf( stderr, "Out of memory!" );
|
||
exit(OUT_OF_MEMORY );
|
||
}
|
||
|
||
strcpy( pX->pTranslated, Buffer1 );
|
||
|
||
if( pXlatCur == 0 )
|
||
{
|
||
pXlatCur = pXlat = pX;
|
||
}
|
||
else
|
||
{
|
||
pXlatCur->pNext = pX;
|
||
pXlatCur = pX;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
Then read the STATE_VS_EXPECTED_FILE, and read in the expected
|
||
tokens/productions for each entry, as translated by looking up the
|
||
data base.
|
||
**/
|
||
|
||
p = pDataBase;
|
||
|
||
while( p < (pDataBase + MAXSTATEVSEXPECTED) )
|
||
{
|
||
|
||
CHECK_FSCAN_STATUS(
|
||
fscanf( hStateVsExpectedFile, "%d %c %d %c",
|
||
&State,
|
||
&Temp,
|
||
&Count,
|
||
&Temp,
|
||
Buffer ) );
|
||
|
||
|
||
|
||
if( Count )
|
||
{
|
||
CHECK_FSCAN_STATUS(
|
||
fscanf( hStateVsExpectedFile, " %[^\n]\n", Buffer ) );
|
||
p->State = (short) State;
|
||
p->pTranslated = Translate( Buffer );
|
||
p++;
|
||
}
|
||
else
|
||
CHECK_FSCAN_STATUS(
|
||
fscanf( hStateVsExpectedFile, "\n" ) );
|
||
|
||
}
|
||
/**
|
||
emit the state vs expected array with the proper prefix
|
||
**/
|
||
|
||
fprintf( hOutput, "\n#ifndef _DBENTRY_DEFINED\n" );
|
||
fprintf( hOutput, "\n#define _DBENTRY_DEFINED\n" );
|
||
fprintf( hOutput, "\ntypedef struct _DBENTRY {" );
|
||
fprintf( hOutput, "\n\t short State;");
|
||
fprintf( hOutput, "\n\t char * pTranslated;");
|
||
fprintf( hOutput, "\n} DBENTRY;\n");
|
||
fprintf( hOutput, "\n#endif\n" );
|
||
|
||
fprintf( hOutput, "\n#define MAXSTATEVSEXPECTED_SIZE_%s %d\n", pPrefix, MAXSTATEVSEXPECTED );
|
||
fprintf( hOutput, "\n DBENTRY %s_SyntaxErrorDB[ MAXSTATEVSEXPECTED_SIZE_%s ] = {\n", pPrefix, pPrefix);
|
||
|
||
for( p = pDataBase;
|
||
p < (pDataBase + MAXSTATEVSEXPECTED);
|
||
p++ )
|
||
{
|
||
fprintf( hOutput, "{ %d , \"%s\"},\n" , p->State, p->pTranslated );
|
||
}
|
||
|
||
fprintf( hOutput, "\n};\n" );
|
||
|
||
}
|
||
|
||
char *
|
||
Translate(
|
||
char *pIncoming )
|
||
{
|
||
char *p;
|
||
|
||
pXlatCur = pXlat;
|
||
|
||
while( pXlatCur )
|
||
{
|
||
if( strcmp( pXlatCur->pIncoming, pIncoming ) == 0 )
|
||
return pXlatCur->pTranslated;
|
||
pXlatCur = pXlatCur->pNext;
|
||
}
|
||
|
||
p = malloc( strlen( pIncoming ) + 1 );
|
||
|
||
if (!p )
|
||
{
|
||
fprintf( stderr, "Out of memory.\n" );
|
||
exit( OUT_OF_MEMORY );
|
||
}
|
||
|
||
strcpy( p, pIncoming );
|
||
|
||
return p;
|
||
}
|
||
|