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.
290 lines
9.2 KiB
290 lines
9.2 KiB
/*++
|
|
|
|
Copyright (c) 1991 Microsoft Corporation
|
|
Copyright (c) 1991 Nokia Data Systems AB
|
|
|
|
Module Name:
|
|
|
|
fsm.h
|
|
|
|
Abstract:
|
|
|
|
The file includes all internal definition of FSM2C compiler
|
|
(Finite State Machine to C).
|
|
|
|
Author:
|
|
|
|
Antti Saarenheimo [o-anttis] 06-MAY-1991
|
|
|
|
Revision History:
|
|
--*/
|
|
|
|
//******************* INCLUDES **********************
|
|
|
|
#include <nt.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <search.h>
|
|
#include <string.h>
|
|
#include <memory.h>
|
|
#include <malloc.h>
|
|
#include <ctype.h>
|
|
|
|
//********************* TYPE DEFINITIONS ************************
|
|
|
|
//
|
|
// FSM STATE MACHINE DATA STRTCTURES:
|
|
// ( -> = pointer, <-> = two way link, HDB = hash data base,
|
|
// This list is not complete, because some links are pointer arrays
|
|
// within a table, the others are direct pointer links.
|
|
// The table structures will be usually sorted during compiling,
|
|
// Some data structures are accessed as a tables in one phase and
|
|
// linked tree structures in the next one.
|
|
// The lower objects are shared by the higher level objects and
|
|
// the objects are joined together whenever it is possible.
|
|
// Actually that is the main idea of these structure: FSM size
|
|
// is minimized by these join operations. FSM complexity is also
|
|
// the main reason for the complexity of these data structures.
|
|
//
|
|
// [State][Input] -> TRANSITION
|
|
// TRANSITION <-> TRANSITION (* HDB *):
|
|
// -> StateInput -> StateInput (* all input/state pairs using transit)
|
|
// -> INPUT_ACTIONS (* HBD *):
|
|
// -> COND_ACTION table (* elemnts are cond/action pairs *)
|
|
// -> CONDITION (hash DB)
|
|
// -> INPUT_ACTIONS (* HDB *)
|
|
// -> ACTION_PRIMITIVE (* table within INPUT_ACTIONS *)
|
|
// -> ACTION_CODE (* hash db *)
|
|
// later ACTION_NODES built to a link tree
|
|
//
|
|
// Used tools: Link, UnLink for linked lists, qsort, AddToTbl for the
|
|
// adding and expnading the pointer table objects.
|
|
//
|
|
|
|
|
|
typedef struct _FSM_CONDITION {
|
|
PSZ pszFsmCode;
|
|
PSZ pszC_Code;
|
|
} FSM_CONDITION, FAR *PFSM_CONDITION;
|
|
|
|
typedef struct _FSM_ACT_CODE {
|
|
PSZ pszFsmCode;
|
|
PSZ pszC_Code;
|
|
USHORT cReferCount;
|
|
} FSM_ACT_CODE, FAR *PFSM_ACT_CODE;
|
|
|
|
|
|
typedef struct _FSM_PRIMITIVE {
|
|
// the root pointers goes to the root of the tree and
|
|
// leafs poins to list of all leafs of this node (linked by pPeer)
|
|
struct _FSM_PRIMITIVE FAR *pRoot; // pNext pointer at first
|
|
struct _FSM_PRIMITIVE FAR *pLeafs; // pPrev at fist
|
|
struct _FSM_PRIMITIVE FAR *pPeer; // other elemements in the same level
|
|
|
|
PFSM_ACT_CODE pActCode; // pointer to the actual FSM and C code
|
|
|
|
BOOL boolCodeGenerated; // Set true, when the node has the C code
|
|
USHORT cReferences; // number of refecences to this primitive
|
|
ULONG usSpeedWeigth; // speed weigth of this node, used in optim.
|
|
|
|
// these are set, when the actual C- code is generated for this primitive,
|
|
// the primitive has always an own jump address, if it has more than
|
|
// one leafs.
|
|
USHORT usCase; // case number pointing to this primitive
|
|
USHORT usCaseForLabel; // case number used with the label
|
|
USHORT usLineInCase; // goto label number within the case
|
|
// eg: case_10_L3:
|
|
} FSM_PRIMITIVE, FAR *PFSM_PRIMITIVE;
|
|
|
|
|
|
typedef struct _FSM_ACTION {
|
|
struct {
|
|
PFSM_PRIMITIVE FAR *ppActPrim;
|
|
USHORT cActPrim;
|
|
USHORT cMaxActPrim;
|
|
} dt;
|
|
} FSM_ACTION, FAR *PFSM_ACTION;
|
|
|
|
|
|
typedef struct _COND_ACTION {
|
|
PFSM_ACTION pAction;
|
|
PFSM_CONDITION pCond;
|
|
} COND_ACTION, FAR *PCOND_ACTION;
|
|
|
|
|
|
typedef struct _INPUT_ACTIONS {
|
|
// set NULL when this is the only condition definiton
|
|
struct _INPUT_ACTIONS FAR * pAlternateConditions;
|
|
USHORT usCase; // case allocated for this
|
|
|
|
// Keep this sub structure in the beginning (make things easier)
|
|
struct {
|
|
PCOND_ACTION FAR * ppCondActions;
|
|
USHORT cCondActions; // how many now
|
|
USHORT cMaxCondActions; // max number until realloc
|
|
} dt;
|
|
|
|
} INPUT_ACTIONS, FAR * PINPUT_ACTIONS;
|
|
|
|
|
|
typedef struct _STATE_INPUT {
|
|
struct _STATE_INPUT FAR *pNext;
|
|
struct _STATE_INPUT FAR *pPrev;
|
|
USHORT usState;
|
|
USHORT usInput;
|
|
} STATE_INPUT, FAR *PSTATE_INPUT;
|
|
|
|
// this struct is not in the hash table:
|
|
typedef struct _FSM_TRANSIT {
|
|
struct _FSM_TRANSIT FAR *pNext;
|
|
struct _FSM_TRANSIT FAR *pPrev;
|
|
|
|
// This is some stuff for suntax checking used far before
|
|
// my powerful optimizers have been mixed all data structures
|
|
PSZ pszCondition;
|
|
PSZ pszAction;
|
|
PSZ pszInput;
|
|
USHORT usSpeed;
|
|
PSZ pszCurState;
|
|
USHORT usNewState;
|
|
USHORT usLine;
|
|
|
|
// This stuff is produced and modified by FsmMerger
|
|
PSTATE_INPUT pList;
|
|
USHORT cStateInputs;
|
|
PINPUT_ACTIONS pInputActions;
|
|
} FSM_TRANSIT, FAR *PFSM_TRANSIT;
|
|
|
|
typedef struct _LINK_FILE {
|
|
struct _LINK_FILE FAR * pNext;
|
|
struct _LINK_FILE FAR * pPrev;
|
|
USHORT usState;
|
|
PSZ pszLine;
|
|
} LINK_FILE, FAR * PLINK_FILE;
|
|
|
|
typedef struct _FSM_TOKEN {
|
|
PSZ pszToken; // token string
|
|
USHORT usToken; // # the token
|
|
USHORT usEnum; // enum value for the token
|
|
} FSM_TOKEN, FAR *PFSM_TOKEN;
|
|
|
|
typedef struct _FSM_STR_REDEF {
|
|
PSZ pszOrginal; // The orginal defined string
|
|
PSZ pszReplace; // its replacement
|
|
} FSM_STR_REDEF, FAR *PFSM_STR_REDEF;
|
|
|
|
// used to hold on any strings, used only for syntax checking of
|
|
// states and inputs
|
|
typedef struct _FSMS_STR {
|
|
PSZ pszStr;
|
|
USHORT usToken;
|
|
} FSMS_STR, FAR *PFSMS_STR;
|
|
|
|
|
|
//**************** CONSTANTS ************************
|
|
|
|
#define NEW( a ) memset((a = Alloc(sizeof(*(a)))), 0, sizeof(*(a)))
|
|
#define DEL( a ) free(a); a=0
|
|
|
|
// add also stack size to support longer lines:
|
|
#define MAX_LINE_LEN 512
|
|
enum HashErrors {
|
|
NO_ERROR = 0,
|
|
ERROR_HASH_NO_MEMORY,
|
|
ERROR_HASH_KEY_EXIST,
|
|
ERROR_HASH_NOT_FOUND};
|
|
|
|
enum FsmErrors {
|
|
FSM_NO_ERROR,
|
|
FSM_ERROR_NEW_STATE_UNDEFINED,
|
|
FSM_ERROR_UNSYNC_INPUT,
|
|
FSM_ERROR_UNDEFINED_VARIABLE,
|
|
FSM_ERROR_ALREADY_EXIST,
|
|
FSM_ERROR_INVALID_LINE,
|
|
FSM_ERROR_STATE_NOT_DEFINED,
|
|
FSM_ERROR_NO_MEMORY,
|
|
FSM_ERROR_INVALID_EXTENSION,
|
|
FSM_ERROR_FILE_NOT_FOUND,
|
|
FSM_ERROR_IN_FILE,
|
|
FSM_ERROR_MISSING_FIELD,
|
|
FSM_ERROR_CANNOT_WRITE,
|
|
FSM_ERROR_MISSING_CONDITION,
|
|
FSM_ERROR_INPUT_DISCARDED,
|
|
FSM_ERROR_INPUTS_DO_NOT_MATCH,
|
|
FSM_ERROR_NO_DEFAULT,
|
|
FSM_ERROR_OTHER_LINE
|
|
};
|
|
|
|
//********************* EXTERNS AND PROTOTYPES ************************
|
|
|
|
// Hash tables for the different types
|
|
extern PVOID hDefines;
|
|
extern PVOID hVariables;
|
|
extern PVOID hSynonymes;
|
|
extern PVOID hStates;
|
|
extern PVOID hInputs;
|
|
extern PVOID hConditions;
|
|
|
|
extern USHORT cStates;
|
|
extern USHORT cInputs;
|
|
extern PVOID FAR * FAR * pppStateInputs;
|
|
extern PUSHORT pusCondJumpTbl;
|
|
extern USHORT cCondJumpTbl;
|
|
extern PFSM_PRIMITIVE pActionTreeBase;
|
|
extern PUSHORT FAR * ppusStateInputs;
|
|
extern PFSM_TOKEN FAR * ppInputDefs;
|
|
extern PFSM_TOKEN FAR * ppStateDefs;
|
|
extern PSZ pszFsmName;
|
|
|
|
// function prototypes
|
|
|
|
PSZ StrNotBrk( PSZ pszStr, PSZ pszBreaks );
|
|
PSZ StrBrk( PSZ pszStr, PSZ pszBreaks );
|
|
PFSM_TRANSIT FsmFront( FILE *fd, PFSM_TRANSIT pBase );
|
|
PVOID LinkElement( PVOID pBase, PVOID pElement );
|
|
PVOID UnLinkElement( PVOID pElement );
|
|
PVOID StrHashNew( UINT cElemenst );
|
|
PVOID Alloc( UINT cbSize );
|
|
PVOID HashNew(
|
|
UINT cElements, // appr. # elements
|
|
INT (*Hash)( PVOID pKey ), // returns the hash key
|
|
INT (*Comp)( PVOID pKey1, PVOID pKey2 ), // Compares the keys
|
|
PVOID (*Alloc)( UINT cbSize ), // Allocates a memory block
|
|
VOID (*Free)( PVOID p) // Frees a memory block
|
|
);
|
|
VOID xFree( PVOID p );
|
|
INT HashAdd( PVOID hHash, PVOID pData);
|
|
INT HashUnlink( PVOID hHash, PVOID pData);
|
|
PVOID HashSearch( PVOID hHash, PVOID pKey );
|
|
UINT HashRead(
|
|
PVOID hHash, // hash handle
|
|
UINT cElemRead, // # elements to read
|
|
UINT iFirstElem, // index of the first element
|
|
PVOID pBuf[] // buffer for the elements
|
|
);
|
|
UINT HashDelete( PVOID hHash );
|
|
UINT HashLen( PVOID hHash );
|
|
PFSM_TRANSIT FsmBuild( PFSM_TRANSIT pBase );
|
|
VOID FsmCodeGeneration(
|
|
FILE * fd, // the handle of the c- file
|
|
PLINK_FILE pFile, // file read to a linked list
|
|
PFSM_TRANSIT pBase, // linked fsm state transitions
|
|
PSZ pszName // the default body of all names
|
|
);
|
|
PLINK_FILE FsmReadCFile( FILE *fd );
|
|
VOID PrintErrMsg( USHORT usLine, USHORT usErr, PSZ pszErr );
|
|
VOID AddToTable( PVOID pTbl, PVOID pElement);
|
|
INT ReadExpression(
|
|
PSZ pszSrc, // source string
|
|
PSZ pszDest1, // the first word
|
|
PUSHORT pusDest1, // its length
|
|
PSZ pszDest2, // the second word
|
|
PUSHORT pusDest2, // its length
|
|
PSZ pszSepars, // the separators
|
|
PSZ pszTermins // the terminators
|
|
);
|
|
PSZ StrAlloc( PSZ psz );
|
|
VOID FsmInitTables( void );
|
|
VOID PrintHelpMsg( void );
|
|
INT StriCmpFileExt( PSZ pszFile, PSZ pszExt );
|
|
|