/*****************************************************************************
 * Bison/Flexプログラム部分をテストするための、Windowsアプリケーションの雛型 *
 * □ビルド・実行方法:                                                       *
 * ┃"C:\Program Files (x86)\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT"  *
 * ┃make -f winapp.mk run                                                   *
 *****************************************************************************/
#ifndef __WINAPP_H__
#define __WINAPP_H__
/*{{定型コード:winapp.h======================================================*/
#include <clip.h>
/* y.tab.y */
extern int yynerrs;
#if     (YYDEBUG!=0)
extern int yydebug;
#endif/*(YYDEBUG!=0)*/
int yyparse();
void yyerror(const char* fmt, ...);
/* lex.yy.l */
extern FILE* yyin;
extern FILE* yyout;
extern int yylineno;
int yylex();
void yylex_init(FILE* input_file);
/* winapp.c */
void push_location(const char* path);
void pop_location();
/*}}定型コード:winapp.h======================================================*/
//-----------------------------------------------------------------------------
//構造体定義
//-----------------------------------------------------------------------------
//状態マップ
typedef struct _ST_Map {
	int			line;		//行番号。エラーメッセージのためだけに使用する。
	struct _ST_MapHdr*	mapHdr;		//状態マップのヘッダ					必須
	struct _ST_MapBody*	mapBody;	//状態マップのボディ					必須
} ST_Map;
//状態マップのヘッダ
typedef struct _ST_MapHdr {
	int			line;		//行番号。エラーメッセージのためだけに使用する。
	char*			name;		//状態マップの名前					必須
	struct _ST_Func*	initAct;	//初期化Act関数						初期化Act関数が無ければNULL	//{{2017/01/06追加:clipfsm.cにて状態マップに初期化Act関数を定義出来るようにした事に伴い、dFsmMapC.exeも変更後のレジストリ構造を出力するように変更しました。}}
	char*			initState;	//初期状態の名前					必須
} ST_MapHdr;
//状態マップのボディ
typedef struct _ST_MapBody {
	int			line;		//行番号。エラーメッセージのためだけに使用する。
	struct _ST_Func*	entry;		//Entry関数						Entry関数が無ければNULL
	struct _ST_Func*	exit;		//exit関数						Exit関数が無ければNULL
	struct _ST_Func*	suspend;	//Suspend関数						Suspend関数が無ければNULL
	struct _ST_Func*	resume;		//Resume関数						Resume関数が無ければNULL
	ght_hash_table_t*	ht_transSet;	//遷移セットのハッシュテーブル				要素数(0)も許可				遷移名をキーとする。
	ght_hash_table_t*	ht_state;	//状態のハッシュテーブル				要素数(0)は不可			y.tab.yでは判断出来ないので、winapp.cで判断せよ。
	char*			property;	//状態マップの中で@{～@}で指定された、プロパティテーブルスクリプトを連結する。		状態マップの中で@{～@}が指定されていなければNULL
} ST_MapBody;
//状態
typedef struct _ST_State {
	int			line;		//行番号。エラーメッセージのためだけに使用する。
	char*			name;		//状態の名前						必須
	struct _ST_StateBody*	stateBody;	//状態のボディ						必須
} ST_State;
//状態のボディ
typedef struct _ST_StateBody {
	int			line;		//行番号。エラーメッセージのためだけに使用する。
	struct _ST_Func*	entry;		//Entry関数						Entry関数が無ければNULL		┐
	struct _ST_Func*	exit;		//Exit関数						Exit関数が無ければNULL		│
	struct _ST_Func*	suspend;	//Suspend関数						Suspend関数が無ければNULL	├どれか一つは必須。y.tab.yでは判断出来ないので、winapp.cで判断せよ。
	struct _ST_Func*	resume;		//Resume関数						Resume関数が無ければNULL	│
	ght_hash_table_t*	ht_transSet;	//遷移セットのハッシュテーブル				要素数(0)も許可			┘	遷移名をキーとする。
} ST_StateBody;
//遷移セット
typedef struct _ST_TransSet {
	int			line;		//行番号。エラーメッセージのためだけに使用する。
	char*			name;		//遷移の名前						必須
	ght_hash_table_t*	ht_trans;	//遷移のハッシュテーブル				要素数(0)には成り得ない。		ガード名をキーとする。ガードが無い遷移は長さ(0)のキーを持つ。ガード名が空文字の遷移は終端文字のみの長さ(1)のキーを持つので区別できる。
} ST_TransSet;
//遷移
typedef struct _ST_Trans {
	int			line;		//行番号。エラーメッセージのためだけに使用する。
	char*			name;		//遷移の名前						必須
	struct _ST_TransBody*	transBody;	//遷移のボディ						必須
} ST_Trans;
//遷移のボディ
typedef struct _ST_TransBody {
	int			line;		//行番号。エラーメッセージのためだけに使用する。
	struct _ST_Func* 	guard;		//Guard関数						Guard関数が無ければNULL
	struct _ST_Func*	act;		//Act関数						Act関数が無ければNULL		┬何れか一方は必須。y.tab.yでは判断出来ないので、winapp.cで判断せよ。
	struct _ST_NextState*	nextState;	//遷移先状態						遷移先状態が無ければNULL	┘
} ST_TransBody;
//関数
typedef struct _ST_Func {
	int			line;		//行番号。エラーメッセージのためだけに使用する。
	char*			name;		//関数の名前						必須。命名をツールに任せる指定([],{})ならば、ツールが命名するまで""となる。
	char*			code;		//関数のコード						コードが無ければNULL
	int			op;		//関数の種類						1=(void(*)(ST_FsmObj*)),2=(int(*)(ST_FsmObj*,int,void*)),3=(void(*)(ST_FsmObj*,int,void*))	1はEntry/Exit/Suspend/Resume関数,2はGuard関数,3はAct関数に相当する。
} ST_Func;
//遷移先状態
typedef struct _ST_NextState {
	int			line;		//行番号。エラーメッセージのためだけに使用する。
	int			op;		//1=set,2=push,3=pop					必須
	char*			state;		//遷移先状態の名前					op=1,2の場合は必須。op=3の場合はNULL
} ST_NextState;
//-----------------------------------------------------------------------------
//グローバル関数宣言
//-----------------------------------------------------------------------------
void add_source(char* source);
void add_property(char* property);
void add_map(ST_Map* map);
//ST_Map
ST_Map* Map_new(ST_MapHdr* mapHdr, ST_MapBody* mapBody);
//ST_MapHdr
//{{2017/01/06変更:clipfsm.cにて状態マップに初期化Act関数を定義出来るようにした事に伴い、dFsmMapC.exeも変更後のレジストリ構造を出力するように変更しました。
//ST_MapHdr* MapHdr_new(char* name, char* initState);
//↓2017/01/06変更:clipfsm.cにて状態マップに初期化Act関数を定義出来るようにした事に伴い、dFsmMapC.exeも変更後のレジストリ構造を出力するように変更しました。
ST_MapHdr* MapHdr_new(char* name, ST_Func* initAct, char* initState);
//}}2017/01/06変更:clipfsm.cにて状態マップに初期化Act関数を定義出来るようにした事に伴い、dFsmMapC.exeも変更後のレジストリ構造を出力するように変更しました。
//ST_MapBody
ST_MapBody* MapBody_new();
ST_MapBody* MapBody_addEntry(   ST_MapBody* mapBody, ST_Func* entry);
ST_MapBody* MapBody_addExit(    ST_MapBody* mapBody, ST_Func* exit);
ST_MapBody* MapBody_addSuspend( ST_MapBody* mapBody, ST_Func* suspend);
ST_MapBody* MapBody_addResume(  ST_MapBody* mapBody, ST_Func* resume);
ST_MapBody* MapBody_addTrans(   ST_MapBody* mapBody, ST_Trans* trans);
ST_MapBody* MapBody_addState(   ST_MapBody* mapBody, ST_State* state);
ST_MapBody* MapBody_addProperty(ST_MapBody* mapBody, char* property);
//ST_State
ST_State* State_new(char* name, ST_StateBody* stateBody);
//ST_StateBody
ST_StateBody* StateBody_new();
ST_StateBody* StateBody_addEntry(  ST_StateBody* stateBody, ST_Func* entry);
ST_StateBody* StateBody_addExit(   ST_StateBody* stateBody, ST_Func* exit);
ST_StateBody* StateBody_addSuspend(ST_StateBody* stateBody, ST_Func* suspend);
ST_StateBody* StateBody_addResume( ST_StateBody* stateBody, ST_Func* resume);
ST_StateBody* StateBody_addTrans(  ST_StateBody* stateBody, ST_Trans* trans);
//ST_Trans
ST_Trans* Trans_new(char* name, ST_TransBody* transBody);
//ST_TransBody
ST_TransBody* TransBody_newGuard(                         ST_Func* guard);
ST_TransBody* TransBody_newAct(                           ST_Func* act);
ST_TransBody* TransBody_newState(                         ST_NextState* nextState);
ST_TransBody* TransBody_addGuard(ST_TransBody* transBody, ST_Func* guard);
ST_TransBody* TransBody_addAct(  ST_TransBody* transBody, ST_Func* act);
ST_TransBody* TransBody_addState(ST_TransBody* transBody, ST_NextState* nextState);
//ST_Func
ST_Func* Func_new(int op, char* name, char* code);
//ST_NextState
ST_NextState* NextState_new(int op, char* state);
//-----------------------------------------------------------------------------
//変更履歴
//-----------------------------------------------------------------------------
// * Sun Jun 21 22:22:12 JST 2015 Naoyuki Sawa
// - 1st リリース。
// * Fri Jun 26 01:21:28 JST 2015 Naoyuki Sawa
// - 遷移の要素を、順不同で記述できるように変更しました。
//   これまでは、「遷移名 [ガード条件] {アクション} 遷移先状態」の順序に固定でしたが、今後は、[ガード条件]と{アクション}と遷移先状態は、任意の順序で記述できます。
//   どの順序で記述しても、生成されるデータに違いは有りません。
//   尚、[ガード条件]は省略可,{アクション}と遷移先状態は片方のみ省略可である事は、これまでどおりです。
// * Mon Jun 29 21:48:11 JST 2015 Naoyuki Sawa
// - 遷移の名前が同じで、ガード条件が異なる、遷移セットを定義出来るようにしました。
//   優先順位は、「SMC - The State Machine Compiler」(http://smc.sourceforge.net/)を参考にさせて頂きました。
//     1-1-1. 現在の状態の、指定された遷移の、ガードが有る遷移で、ガード条件が成立した遷移	複数有る場合は順不同。現在の実装ではガード名の順としているが、その挙動に依存してはいけない。
//     1-1-2. 現在の状態の、指定された遷移の、ガードが無い遷移
//     1-2-1. 状態マップの、指定された遷移の、ガードが有る遷移で、ガード条件が成立した遷移	複数有る場合は順不同。現在の実装ではガード名の順としているが、その挙動に依存してはいけない。
//     1-2-2. 状態マップの、指定された遷移の、ガードが無い遷移
//     2-1-1. 現在の状態の、デフォルト遷移の、ガードが有る遷移で、ガード条件が成立した遷移	複数有る場合は順不同。現在の実装ではガード名の順としているが、その挙動に依存してはいけない。
//     2-1-2. 現在の状態の、デフォルト遷移の、ガードが無い遷移
//     2-2-1. 状態マップの、デフォルト遷移の、ガードが有る遷移で、ガード条件が成立した遷移	複数有る場合は順不同。現在の実装ではガード名の順としているが、その挙動に依存してはいけない。
//     2-2-2. 状態マップの、デフォルト遷移の、ガードが無い遷移
//   上記の順に検索して、実行できる遷移がなかった場合は、エラー停止します。
//   詳細は、/clip/clipfsm.cのFsmObj_ApplyTrans()の実装を参照してください。
// * Wed Jul 01 21:26:23 JST 2015 Naoyuki Sawa
// - スクリプト内で、関数のコード指定を出来るようにしました。
//   処理内容が短い場合は、Sample/Sample.txtのmap6の例のように、関数のコード指定で書く方が簡潔です。
//   処理内容が複雑な場合は、これまでどおり名前指定にして、関数定義はアプリケーション内で行う方が、保守の観点から望ましいです。
// - 関数のコード指定内での改行は、当ツール自体は対応していません。			//┐×××訂正×××
//   先にCプリプロセッサを通せば、行末のバックスラッシュによる行継続は可能です。	//┘下記コメント参照
// * Wed Jul 01 21:52:52 JST 2015 Naoyuki Sawa
// - 行末のバックスラッシュで行継続する機能を追加しました。
//   有限状態機械マップスクリプトはCプリプロセッサと相性が悪く、当ツールにかける前にCプリプロセッサを通してCプリプロセッサによる行継続を適用する事が難しい事が判ったからです。
//   有限状態機械マップスクリプト内の'%{～%}'の中でCプリプロセッサ疑似命令を使用していると、Cソースファイルに出力する前に展開されてしまい、予期しない結果になるからです。
//   上記の問題を避けるため、当ツール自体に、行末のバックスラッシュで行継続する機能を追加する事にしました。
// - '%{～%}','[`～`]','{`～`}'の中は、字句解析によって行継続しますので、行末のバックスラッシュ指定は不要です。
// * Sun Jul 12 21:50:47 JST 2015 Naoyuki Sawa
// - ght_hash_table.cがght_set_rehash()に対応した事に伴い、ght_create()のサイズを明示せずオートリサイズに任せるようにしました。
// * Wed Jul 29 09:09:12 JST 2015 Naoyuki Sawa
// - これまで、[`…`],{`…`}の中に、特定のシフトJIS文字が含まれていると、コンパイルエラーになる不具合がありました。
//   具体的には、2バイト目がバッククォートの文字コード(\x60)の文字('～','Ａ','形','伝'など)が含まれていた場合です。
// - 本日、`…`の中ではシフトJISを意識したスキャンを行うように修正したので、上記の不具合は無くなりました。
//   今後は、[`…`],{`…`}の中に、2バイト目がバッククォートの文字コード(\x60)の文字を含んでも、問題無く動作します。
// - ただし、[`…`],{`…`}の中に、「`」そのものを含むと、これまでと同様にコンパイルエラーになるので注意して下さい。
// * Sat Oct 10 21:13:38 JST 2015 Naoyuki Sawa
// - CLiPライブラリの更新に伴いリビルドしました。
//   当ツールには影響無かったのですが、他のツールをリビルドした日付に合わせて、当ツールもリビルドする事にしました。
// * Thu Oct 15 21:01:52 JST 2015 Naoyuki Sawa
// - '-n'オプションを追加しました。
//   詳細は、/clip/tool/dLotTblC/winapp.h の同日のコメントを参照して下さい。
// * Fri Oct 16 21:16:43 JST 2015 Naoyuki Sawa
// - clipstr.hのstrnatcmp(),strnatcasecmp()の動作を変更した事に伴い、当ツールをリビルドしました。
//   上記の関数の動作変更は、当ツールの使用方法では影響無いのですが、念のためにリビルドする事にしました。
// * Sat Nov 14 21:55:38 JST 2015 Naoyuki Sawa
// - 「Boehm GC」をマルチスレッド対応にした事,及び,それに伴ってclipbpe.cモジュールを修正した事に伴い、当ツールもプロジェクト設定の変更を行ってリビルドしました。
//   詳細は、/clip/tool/gc/README.TXT と /clip/clipbpe.c の2015/11/03のコメントを参照して下さい。
// * Sun Nov 22 21:02:41 JST 2015 Naoyuki Sawa
// - 環境変数'プログラム名_OPTION'で指定されたオプション(有れば)を、コマンドライン引数にマージするようにしました。
//   詳細は、/clip/clipmisc.c の同日のコメントを参照して下さい。
// - GCに'-DLARGE_CONFIG'を付けてリビルドした事に伴い、当アプリケーションもリビルドしました。
//   詳細は、/clip/tool/gc/README.TXT の同日のコメントを参照して下さい。
// * Thu Dec 24 21:13:58 JST 2015 Naoyuki Sawa
// - C言語ソースファイル名が指定されていたら、標準出力に出力するグローバル関数宣言を 'extern "C" {'～'}' で囲むようにしました。
//   アプリケーションが、グローバル関数をC++ソース内で実装した場合に、それらがCリンケージとなるようにするためです。
//   今回の変更は、C++を含むWin32プロジェクトのためだけであり、CのみのWin32プロジェクトや,P/ECEプロジェクトには影響有りません。
// * Wed Jan 06 21:02:12 JST 2016 Naoyuki Sawa
// - これまで、当関数が出力するグローバル関数宣言の先頭に'extern'を付けていましたが、無駄だったので削除しました。
//   2015/12/24に追加した、グローバル関数宣言の全体を囲む'extern "C" {'～'}'とは、別の話なので混同しないよう注意して下さい。
// - Func_compar()において関数の種類によるソートを削除しました。変更した理由は、以下の通りです。
//   このソートは関数宣言の出力順序に影響し、これまでは関数の種類ごとにまとまって出力されていました。
//   アプリケーションは、dFsmMapC.exeが出力した関数宣言をコピーして、関数の本体を実装する事が多いのですが、関数の種類ごとにまとまっていると使い辛い事が判りました。
//   関数の名前付けをdFsmMapC.exeに任せた場合、これまでは以下のような順で出力されていました。
//   │void FsmFunc_Map1_State1_enter(struct _ST_FsmObj* pFsmObj,int iState);
//   │void FsmFunc_Map1_State2_enter(struct _ST_FsmObj* pFsmObj,int iState);
//   │void FsmFunc_Map2_State3_enter(struct _ST_FsmObj* pFsmObj,int iState);
//   │void FsmFunc_Map1_State1_Trans1_act(struct _ST_FsmObj* pFsmObj,int iTrans,void* pParam);
//   │void FsmFunc_Map1_State2_Trans2_act(struct _ST_FsmObj* pFsmObj,int iTrans,void* pParam);
//   │void FsmFunc_Map2_State3_Trans3_act(struct _ST_FsmObj* pFsmObj,int iTrans,void* pParam);
//   しかし、アプリケーション側で関数の本体を実装する際は、マップ毎,状態毎に関数をまとめたい事が多く、関数宣言をコピーした後に手作業で並び替える手間が有りました。
//   今回、関数の種類によるソートを削除した事によって、今後は以下のように出力され、アプリケーション側で関数の本体を実装する時に並び替える手間が少なくなりました。
//   │void FsmFunc_Map1_State1_Trans1_act(struct _ST_FsmObj* pFsmObj,int iTrans,void* pParam);		┐┐
//   │void FsmFunc_Map1_State1_enter(struct _ST_FsmObj* pFsmObj,int iState);				┘│
//   │void FsmFunc_Map1_State2_Trans2_act(struct _ST_FsmObj* pFsmObj,int iTrans,void* pParam);		┐│
//   │void FsmFunc_Map1_State2_enter(struct _ST_FsmObj* pFsmObj,int iState);				┘┘
//   │void FsmFunc_Map2_State3_Trans3_act(struct _ST_FsmObj* pFsmObj,int iTrans,void* pParam);		┐┐
//   │void FsmFunc_Map2_State3_enter(struct _ST_FsmObj* pFsmObj,int iState);				┘┘
//   元々、関数の種類によるソートを行っていた事に必然性は無く、見易さのためだけでしたので、今回、関数の種類によるソートを削除した事による処理への影響は有りません。
//   尚、関数の名前付けをdFsmMapC.exeに任せずにスクリプト内で明示的に指定した場合は、必ずしもアプリケーションの使い易い順にまとまって出力されるとは限りませんが、
//   自然な関数の命名ならばだいたい自然なまとまりになると思います。
// * Wed Jan 06 22:02:30 JST 2016 Naoyuki Sawa
// - Enter関数に'変更前の状態'を示す引数を追加した事,及び,Leave関数に'変更後の状態'を示す引数を追加した事に伴い、当ツールが出力する関数プロトタイプも変更しました。
//   詳細は、/clip/clipfsm.c の同日のコメントを参照して下さい。
// * Thu Jan 07 21:54:54 JST 2016 Naoyuki Sawa
// - '-u'オプションを追加しました。
//   これまでは、状態マップ番号,状態番号,遷移番号を#define形式で出力していたので、番号を名前に変換したい時は、アプリケーション側で個別に対応する必要が有りました。
//   今後は、'-u'オプションを指定して、状態マップ番号,状態番号,遷移番号を列挙定義スクリプトに出力すれば、列挙定義の名前変換機能を利用出来るようになりました。
//   ただし、列挙定義スクリプトはそのままではC言語ヘッダファイルとしては利用出来ず、列挙定義コンパイラでコンパイルする必要が有る事に注意して下さい。
//   '-u'オプションを指定しなければ、これまで通り#define形式で出力する事も出来ますので、適宜、使い易い方を選択して下さい。
// * Wed Jan 20 21:28:09 JST 2016 Naoyuki Sawa
// - Suspend関数/Resume関数の追加,及び,Enter関数/Leave関数の名前をStart関数/Stop関数に変更した事に伴い、当ツールも変更しました。
//   詳細は、/clip/clipfsm.c の同日のコメントを参照して下さい。
// * Wed Feb 17 21:39:25 JST 2016 Naoyuki Sawa
// - Start関数/Stop関数の名前をEntry関数/Exit関数に変更した事に伴い、当ツールも変更しました。
//   詳細は、/clip/clipfsm.c の同日のコメントを参照して下さい。
// * Sun Feb 21 21:02:01 JST 2016 Naoyuki Sawa
// - libclipのライブラリ化の伴い、以下の変更を行いました。
//   ・extclip.hとextclip.cを削除しました。extclip.hとextclip.cはlibclipに含まれるようになったからです。
//   ・"CLiP Files"を削除しました。CLiPライブラリの各モジュールはlibclipに含まれるようになったからです。
//   当ツールの動作には変更有りません。
// * Sat Feb 27 21:21:24 JST 2016 Naoyuki Sawa
// - clipfsm.h モジュールの変更に伴い、当ツールも、以下の変更を行いました。
//   ・有限状態機械スクリプトの、状態マップの名前と同じ行で、初期状態の名前を指定するように変更しました。
//   ・出力するレジストリスクリプトに、各状態マップ毎に、初期状態の状態番号を出力するように変更しました。
// - 詳細は、clipfsm.h の同日のコメントを参照して下さい。
//   変更後の有限状態機械スクリプトの書式は、Sample/Sample.txtを参照して下さい。
// * Tue Mar 01 21:34:55 JST 2016 Naoyuki Sawa
// - clipstd.hにてC4131の警告レベルを引き上げましたが、Bison/Flexの生成コードには旧スタイルの宣言が使われているので、Bison/Flexの生成コードのみ警告レベルを元に戻しました。
// * Tue Mar 01 23:23:41 JST 2016 Naoyuki Sawa
// - C言語ソースファイルとC言語ヘッダファイルを分離して出力する場合(即ち-tオプション指定時)、C言語ヘッダファイル側(即ち標準出力側)の出力に、アプリケーション定義のグローバル関数の誤実装を防ぐためのマクロを出力するように変更しました。
//   具体的には、以下の通りです。
// - これまで、有限状態機械マップスクリプトで定義していないグローバル関数を、アプリケーションが誤って定義してしまった場合に、コンパイルやリンク時にエラーも警告も発生せず、見つけ辛いバグになる問題が有りました。
//   たとえば、次のような状況です。
//   ■問題点
//   ①最初に、以下のような有限状態機械マップスクリプトを定義していたとします。
//     │Map1 State1
//     │    State1
//     │        entry {}
//     │        Foo   {}
//     │    end
//     │end
//     当コンパイラで変換すると、C言語ヘッダファイルには以下の宣言が出力されます。
//     │void FsmFunc_Map1_State1_entry(struct _ST_FsmObj* pFsmObj, int iState);
//     │void FsmFunc_Map1_State1_Foo_act(struct _ST_FsmObj* pFsmObj, int iTrans, void* pParam) {
//     アプリケーションは、上記の宣言をソースにコピーして、関数の本体を実装するでしょう。
//     │void FsmFunc_Map1_State1_entry(struct _ST_FsmObj* pFsmObj, int iState) {
//     │  ～
//     │}
//     │void FsmFunc_Map1_State1_Foo_act(struct _ST_FsmObj* pFsmObj, int iTrans, void* pParam) {
//     │  ～
//     │}
//   ②その後、有限状態機械の設計変更等の理由で、entry時の処理が不要と判断して、有限状態機械マップスクリプトを以下のように変更したとします。
//     │Map1 State1
//     │    State1
//     │        Foo   {}
//     │    end
//     │end
//     当コンパイラで変換すると、C言語ヘッダファイルには以下の宣言が出力されます。
//     │void FsmFunc_Map1_State1_Foo_act(struct _ST_FsmObj* pFsmObj, int iTrans, void* pParam) {
//     正しくは、上記の変更に伴ってアプリケーションのソースファイルからもFsmFunc_Map1_State1_entry()を削除すべきです。
//     しかし、削除するのを忘れてそのまま残っていても、コンパイルエラーもリンクエラーも発生しません。
//     アプリケーションソース側だけを見ると、FsmFunc_Map1_State1_entry()が呼ばれる事を期待してしまいますが、実際には、呼び出される事は有りません。
//     これは、発見し辛いバグの原因になる恐れが有ります。
//     │void FsmFunc_Map1_State1_entry(struct _ST_FsmObj* pFsmObj, int iState) {	//C言語ヘッダファイルには宣言されていない関数
//     │  ～	//アプリケーション作成者はこの処理が呼ばれる事を期待しているかも知れないが、呼び出される事は無い。コンパイル・リンク時に警告もエラーも表示されず、気付き辛い。
//     │}
//     │void FsmFunc_Map1_State1_Foo_act(struct _ST_FsmObj* pFsmObj, int iTrans, void* pParam) {
//     │  ～
//     │}
//   ■解決策
//   上記の問題点を解決するために、C言語ヘッダファイルでのグローバル関数宣言方法を、変更しました。
//   上と同じ状況で、変更後の出力では問題が回避できる事を、以下に示します。
//   ①最初に、以下のような有限状態機械マップスクリプトを定義していたとします。
//     │Map1 State1
//     │    State1
//     │        entry {}
//     │        Foo   {}
//     │    end
//     │end
//     当コンパイラで変換すると、C言語ヘッダファイルには以下の宣言が出力されます。
//     │#define FSMFUNC_Map1_State1_entry void FsmFunc_Map1_State1_entry(struct _ST_FsmObj* pFsmObj, int iState)			┐
//     │#define FSMFUNC_Map1_State1_Foo_act void FsmFunc_Map1_State1_Foo_act(struct _ST_FsmObj* pFsmObj, int iTrans, void* pParam)	├アプリケーションソースでは、この範囲を意識する必要は有りません。
//     │#define FSMFUNC_(name) FSMFUNC_##name												┘
//     │FSMFUNC_(Map1_State1_entry);													┬アプリケーションソースに、この宣言をコピーして、関数本体を実装して下さい。
//     │FSMFUNC_(Map1_State1_Foo_act);													┘
//     アプリケーションは、上記の宣言をソースにコピーして、関数の本体を実装して下さい。
//     │FSMFUNC_(Map1_State1_entry) {
//     │  ～
//     │}
//     │FSMFUNC_(Map1_State1_Foo_act) {
//     │  ～
//     │}
//   ②その後、有限状態機械の設計変更等の理由で、entry時の処理が不要と判断して、有限状態機械マップスクリプトを以下のように変更したとします。
//     │Map1 State1
//     │    State1
//     │        Foo   {}
//     │    end
//     │end
//     当コンパイラで変換すると、C言語ヘッダファイルには以下の宣言が出力されます。
//     │#define FSMFUNC_Map1_State1_Foo_act void FsmFunc_Map1_State1_Foo_act(struct _ST_FsmObj* pFsmObj, int iTrans, void* pParam)
//     │#define FSMFUNC_(name) FSMFUNC_##name
//     │FSMFUNC_(Map1_State1_Foo_act);
//     正しくは、上記の変更に伴ってアプリケーションのソースファイルからもFsmFunc_Map1_State1_entry()を削除すべきです。
//     しかし、削除するのを忘れてそのまま残ってコンパイルした場合、FSMFUNC_Map1_State1_entryが定義されていないというコンパイルエラーが発生して、削除し忘れた事に気付けます。
//     │FSMFUNC_(Map1_State1_entry) {	//FSMFUNC_Map1_State1_entryが定義されていないというコンパイルエラーが発生して、削除し忘れた事に気付ける。
//     │  ～
//     │}
//     │FSMFUNC_(Map1_State1_Foo_act) {
//     │  ～
//     │}
//   ■注意点:
//   アプリケーションソースでは、上記の例のように、'FSMFUNC_(～)'のマクロを使って、グローバル関数を実装するようにして下さい。
//   'FSMFUNC_(～)'のマクロを使わずに、普通の関数宣言を用いてグローバル関数を実装してしまうと、変更前と同じ問題が生じます。
// - 尚、今回の変更は、C言語ソースファイルとC言語ヘッダファイルを分離して出力した場合(即ち-tオプション指定時)の、C言語ヘッダファイル側(即ち標準出力側)のみの変更です。
//   C言語ソースファイルとC言語ヘッダファイルを分離しない場合は、前述の問題点は発生しないので、今回の変更の影響は有りません。
//   また、前述の問題点はC言語ソースファイル側の出力には関係無い(あくまでアプリケーションソースでの実装のみの問題点であった)ので、今回の変更後も、C言語ソースファイル側の出力には変更有りません。
// * Fri Mar 04 21:22:19 JST 2016 Naoyuki Sawa
// - '-p'オプションを追加しました。
// - 有限状態機械スクリプトの中に、プロパティテーブルスクリプトも書ける、書式を追加しました。
//   アクターオブジェクトを定義する時に、状態マップと同名のプロパティテーブルを定義する事が多いので、有限状態機械スクリプトの中で両方をまとめて記述できると便利だからです。
//   C++やJava等のオブジェクト指向言語と似た、書き方が出来るようになりました。
//   ただし、有限状態機械スクリプトコンパイラは、プロパティテーブルスクリプトの内容を意識しません。
//   @{～@}で囲まれた範囲を、プロパティテーブルスクリプトと認識して、別のファイル(又は,標準出力の最後)にまとめて出力するだけであり、
//   プロパティテーブルスクリプト自体のコンパイルやエラー検出は、別途、プロパティーテーブルスクリプトコンパイラを実行しておこなって下さい。
// - 状態マップの外で@{～@}で囲まれた範囲は、そのまま、任意のプロパティーテーブルスクリプトとして出力します。
//   任意のtype定義や、任意のtable定義が可能です。
// - 状態マップの中で@{～@}で囲まれた範囲は、状態マップと同じ名前のプロパティーテーブルとして出力します。
//   プロパティテーブル名(=状態マップ名)と、最後のendは、自動的に出力されます。
//   @{～@}の中には、プロパティテーブルのフィールド定義を書いて下さい。
// - 状態マップの外の@{～@}も、状態マップの中の@{～@}も、一か所に纏めて書いても構いませんし、複数個所に分けて書いても構いません。
//   複数個所に書いても、複数個所に書いた内容を連結して出力し、どちらでも同じ結果になります。
// - <例>
//   │@{
//   │     UByte
//   │          range 0,255
//   │     end
//   │@}
//   │Map1 State1
//   │     @{
//   │          var1 :UByte <"%02X">
//   │     @}
//   │     State1
//   │          entry {}
//   │     end
//   │     @{
//   │          var2 :Byte  "説明文"
//   │     @}
//   │end
//   │@{
//   │     Byte
//   │          range -128,127
//   │     end
//   │@}
//   以下のようなプロパティテーブルスクリプトが出力されます。
//   │UByte
//   │     range 0,255
//   │end
//   │Byte
//   │     range -128,127
//   │end
//   │#//table
//   │Map1
//   │     var1 :UByte <"%02X">
//   │     var2 :Byte  "説明文"
//   │end
// * Sun Apr 24 21:05:43 JST 2016 Naoyuki Sawa
// - 2016/04/23に、/clip/clipstd.hにparsonとLibYAMLのインクルードを追加した事に伴い、当プロジェクトにもparsonとLibYAMLのインクルードパスとライブラリパスの設定を追加しました。
//   当プロジェクトはparsonもLibYAMLも使用していませんが、インクルードパスとライブラリパスの設定を追加しないとビルドエラーになるからです。
// - libclip.lib,gc.lib,pthreadVC2(d).lib,sqlite.lib,pdcurses.libのリンク指定を、/clip/libclip/extclip.hで指定するようにし、個別のアプリケーション設定からは削除しました。
//   parson.lib,yaml.libのリンク指定を、/clip/clipstd.hで指定するようにし、個別のアプリケーション設定からは削除しました。
// * Sat Jul 02 21:34:21 JST 2016 Naoyuki Sawa
// - 2016/06/14に、/clip/clipstd.hに'#pragma comment(lib, "liblua.lib")'を追加した事に伴い、当プロジェクトにもlibluaのライブラリパスの設定を追加しました。
//   現在の所、当プロジェクトはlibluaを使用していませんが、インクルードパスとライブラリパスの設定を追加しないとビルドエラーになるからです。
//   尚、libluaのインクルードパスは以前から設定していたので、今回、追加したのはlibluaのライブラリパスのみです。
// - 2016/07/01に、/clip/libclip/extclip.hに'#include <sqlite3.h>'と'#pragma comment(lib, "sqlite3.lib")'を追加した事に伴い、当プロジェクトにもsqlite3のインクルードパスとライブラリパスの設定を追加しました。
//   現在の所、当プロジェクトはsqlite3を使用していませんが、インクルードパスとライブラリパスの設定を追加しないとビルドエラーになるからです。
// * Sat Jul 09 21:38:42 JST 2016 Naoyuki Sawa
// - dFsmMapC.exeが出力する、Entry/Exit/Suspend/Resume関数プロトタイプの仮引数iStateの名前を、iAltStateに変更しました。
//   これらの関数の仮引数は、現在の状態を示しているのではなく、遷移先状態,又は,遷移元状態を示している事を強調するためです。
//   また、アプリケーション定義のこれらの関数の中で、現在の状態を取得するために「int iState=FsmObj_GetState(pFsmObj);」とする事が有り、仮引数名とローカル変数名が衝突する事を避けるために、仮引数名の方を変えておくのが(意味上からも)適切だと思ったからです。
// - 実際には、Entry/Resume関数ならば遷移元状態(iPrevState)、Exit/Suspend関数ならば遷移先状態(iNextState)ですから、iPrevState,又は,iPrevStateとする方がより判り易いのですが、そうはしませんでした。
//   Entry/Exit/Suspend/Resumeは関数シグネチャが同じであり、共有出来るので、仮引数の意味がiPrevStateとiNextStateで被る可能性が有るからです。(実際に共有するようなケースは、まず無いとは思いますが…)
//   従って、iPrevState,又は,iNextStateである事を意味するように、iAltStateという仮引数名にする事にしました。
// - 上記と同様の変更を、/clip/clipfsm.cに対しても行いました。
//   詳細は、/clip/clipfsm.cの同日のコメントを参照して下さい。
// * Fri Sep 16 21:30:10 JST 2016 Naoyuki Sawa
// - '-q'オプションを追加しました。
//   /clip/test.win/を元にしたプロジェクトで、VC++6.0のカスタムビルドから呼び出された場合に、'\r'による同じ行の重ね書きが上手く認識されず、VC++6.0の出力ペインに進捗表示が多く出過ぎて、その他の重要なエラーが見づらくなってしまう問題を避けるためです。
//   基本的には、VC++6.0のカスタムビルドから呼び出す場合だけに'-q'オプションを使用し、コマンドラインから呼び出す場合はこれまで通り'-q'オプションは指定しなくて構いません。
// * Wed Sep 21 21:20:16 JST 2016 Naoyuki Sawa
// - die(～)で終了していた箇所を、error(EXIT_FAILURE,～)で終了するように変更しました。
//   変更した理由は、以下の通りです。
// - die()は、標準エラー出力がコンソールでなければ、エラーメッセージをメッセージボックスで表示します。
//   通常はそれが望ましい動作なのですが、VC++6.0やVS2015のカスタムビルドとして当ツールを呼び出した場合に、使い辛い問題が生じます。
//   VC++6.0やVS2015は、カスタムビルドとして呼び出すツールの標準エラー出力をリダイレクトして、アウトプットウインドウに表示します。
//   標準エラー出力がコンソールでないので、当ツールはエラー終了する場合に、メッセージボックスを表示します。
//   結果として、カスタムビルドとして呼び出したツールがエラーになると、いちいちメッセージボックスを表示して停止し、使い辛い問題が生じました。
//   元々、die()が標準エラー出力がコンソールでなければエラーメッセージをメッセージボックスで表示するようにした理由は、コマンドプロンプトを持たないウインドウアプリケーションのためであり、
//   当ツールのようなコンソールアプリケーションの標準エラー出力がリダイレクトされた場合にメッセージボックスを表示する必要はあまり有りません。
//   そこで、当ツールがエラー終了する時にdie()を呼び出すのをやめて、error()で終了するように変更する事にしました。
// * Sun Sep 25 21:05:26 JST 2016 Naoyuki Sawa
// - /clip/test.win/lex.yy.lの'popen'対応処理を、当ツールのlex.yy.lにマージしました。
//   dFsmMapC.exeはCプリプロセッサと併用出来ないので、他のファイルを読み込むために'popen'対応が必要になったからです。
// - エラーメッセージに、現在の行番号だけでなく、現在のファイル名も表示するようにしました。
//   エラーメッセージの形式は、VC++6.0に合わせて、「ファイル名(行番号) : エラーメッセージ」としました。
// * Wed Sep 28 21:26:44 JST 2016 Naoyuki Sawa
// - error()の文字列の最後に余計な改行が付いていたのを削除しました。
//   error()は指定された文字列の後に(もし有ればエラー名を挟んで)自動的に改行を出力するので、アプリケーション側で文字列の最後に改行を付けると、文字列とエラー名の間に余計な改行が出力されたり、二回改行してしまう問題が生じていました。
// * Sun Oct 02 21:48:17 JST 2016 Naoyuki Sawa
// - ";"によるマルチステートメントに対応しました。
//   変更箇所は、lex.yy.lの「\n { return T_EOL; }」の上の行に、「";" |」を追加しただけです。
// - マルチステートメント対応が必要になった理由は、主にdDirSeqC.exeのためです。
//   Cプリプロセッサで一つのマクロで複数のact命令を生成する時に、Cプリプロセッサの制限のために複数行に分けられないからです。
//   今回マルチステートメントを対応した事によって、「act ～; act ～; act ～」のように一行で複数のact命令が可能になりました。
//   dDirSeqC.exe以外のツールについては、今すぐにマルチステートメント対応が必要な訳ではないのですが、上述の通り変更箇所は少ないので、他のツールも一緒に変更しておく事にしました。
// * Fri Jan 06 23:24:43 JST 2017 Naoyuki Sawa
// - clipfsm.cにて状態マップに初期化Act関数を定義出来るようにした事に伴い、dFsmMapC.exeも変更後のレジストリ構造を出力するように変更しました。
//   ■変更前
//   │FsmMap
//   │    Map0
//   │        Fsm_State_init    = State0  #//必須
//   │        State0
//   │            …
//   ■変更後
//   │FsmMap
//   │    Map0
//   │        Fsm_Init
//   │            Fsm_InitAct   = initAct #//任意
//   │            Fsm_InitState = State0  #//必須
//   │        end
//   │        State0
//   │            …
// * Sun Jan 08 21:43:34 JST 2017 Naoyuki Sawa
// - clipfsm.cにてFsm_Initの値を0x8000⇒0xFFFFに変更した事に伴い、当ツールもリビルドしました。
//   当ツール自体のソースには変更有りません。
// * Sun Jan 15 09:21:07 JST 2017 Naoyuki Sawa
// - 自己遷移を抑止するGuard関数の省略記法を追加しました。
//   詳細は、以下の通りです。
// - これまで当ツールを実際のアプリケーションで利用して来て、自己遷移を抑止するGuard関数を頻繁に定義する事に気付きました。
//   │Trans1 [`FsmObj_GetState(pFsmObj) != FsmState_State2`] {} State2
//   そのままでも問題無いのですが、あまりにも頻度が高いので、コピペして定義する際に判定式を変更し忘れたりして、バグの原因になり易い問題が有りました。
//   そこで、シンタックスシュガーとして、自己遷移を抑止するGuard関数の省略記法を追加する事にしました。
// - 変更後は、以下のように書けるようになりました。
//   │Trans1 [no-self-transition] {} State2
//   あくまでシンタックスシュガーであり、明示的に書いても省略記法で書いても、当ツールが生成するデータに違いは有りません。
// - 遷移先状態が無かったり、遷移先状態がpop遷移である遷移には、自己遷移を抑止するGuard関数の省略記法を指定する事は出来ません。
//   詳細は、winapp.cのTrans_new()の、2017/01/15追加部分のコメントを参照して下さい。
// * Sun Mar 05 23:35:48 JST 2017 Naoyuki Sawa
// - '-xc','-xcs'オプションを追加しました。
//   詳細は、/clip/tool/dRegTblC/winapp.hの2017/02/27のコメントを参照して下さい。
// - 今回、C#版の関数テーブルの出力には、少し工夫を凝らしました。
//   C言語版では、アプリケーション定義のグローバル関数の誤実装を防ぐために、'FSMFUNC_(～)'マクロを使用していました('Tue Mar 01 23:23:41 JST 2016 Naoyuki Sawa'のコメントを参照して下さい)が、
//   C#では同じ方法は使えないので、別の方法を使って、アプリケーション定義のグローバル関数の誤実装を防ぐようにしたからです。
//   詳細は、以下の通りです。
// - 当ツールが出力するソースファイルには、以下の要素が含まれています。
//   │①状態マップ番号,状態番号,遷移番号				'-u'オブションが指定されていない場合のみ出力します。
//   │②IFsmFuncインターフェイス
//   │③FsmFuncクラス(関数テーブルとローカル関数定義を含む部分)
//   │④FsmFuncクラス(グローバル関数定義を含む部分の雛形)	'#if false'～'#endif'で囲まれた、実質コメントです。
//   ①には特に工夫した点は無いので、以下では②～④だけについて説明します。
// - ②には、全ての関数の宣言が含まれています。
// - ③には、②の内、ローカル関数(=有限状態機械マップスクリプト内で実装した関数)の実装と、関数テーブルを作成するためのGetTable()関数の実装が含まれています。
// - ④には、②の内、アプリケーションが実装すべきグローバル関数(=有限状態機械マップスクリプト内で実装しなかった関数)の雛形が含まれています。
//   アプリケーションは、この雛形をアプリケーション側のソースにコピーして、具体的な実装を作成して下さい。
//   尚、dFsmMapC.exeが出力した、①②③(及び④)を含むソースファイル(一般的にはFsmMap.csという名前にします)は、そのままアプリケーションプロジェクトに含めれば良く、編集する必要は有りません。
// - 以上の仕組みで、アプリケーション定義のグローバル関数の誤実装が防まれる理由について、説明します。
//   ④の雛形を元にアプリケーション定義のグローバル関数を実装すると、'インターフェイスの明示的な実装'の書式になります。(IFsmFunc.関数名())の形式)
//   'インターフェイスの明示的な実装'の書式では、インターフェイスに定義していない関数を実装しようとすると、コンパイルエラーになります。
//   これによって、アプリケーションが、有限状態機械マップスクリプトで定義されていない無駄な関数を(意図せず)実装してしまうバグや、有限状態機械マップスクリプト上で廃止した関数がアプリケーションのソースに残ってしまうバグを防ぐ事が出来ます。
//   もっとも、アプリケーションが'インターフェイスの明示的な実装'の書式を使用せず、'インターフェイスの暗黙的な実装'の書式に変えて実装してしまうと上記の効果は無くなってしまうのですが、
//   'インターフェイスの明示的な実装'の書式と'インターフェイスの暗黙的な実装'の書式の違いは見た目にすぐ判るので、気付き辛いバグとなる可能性は低いと思います。
// - アプリケーションが、いずれかの関数の実装を忘れた場合は、普通にFsmFuncクラスの関数の実装が足りないコンパイルエラーになって、すぐに気付きます。
// - 上記の仕組みとするために、有限状態機械の関数は、FsmFuncクラスのクラス関数(=static関数)ではなく、インスタンス関数として実装する事にしました。
//   クラス関数では、上記の、インターフェイスを利用した間違いを防ぐ仕組みが使えないからです。
//   とは言え、アプリケーションの観点では、有限状態機械の関数がインスタンス関数である事を意識する必要はほとんど無いと思います。
//   FsmFuncクラスは実質シングルトンクラスであり、唯一のインスタンスが生成される契機は、FsmFunc.CreateTable()を呼び出した時です。(FsmFunc.CreateTable()を二回以上呼び出さないように注意して下さい。)
//   アプリケーションが、有限状態機械の関数の中で使用するモジュールスコープ変数を定義したい場合、FsmFuncクラスのstatic変数として定義して構いません。
//   インスタンス関数経由では有りますが、FsmFuncクラスが実質シングルトンクラスなので、static変数としても同じだからです。
//   static変数としておく方が、有限状態機械の関数以外から変数にアクセスしたい場合も便利だと思います。(FsmFuncのインスタンスを知らなくてもアクセス出来るから)
//   また、FsmFuncクラス内に、有限状態機械の各関数から利用する共通処理のユーティリティ関数等を設ける場合も、static関数として定義する方が良いと思います。
// - 本題と外れますが、FsmFuncクラスはパーシャルクラスとして定義してありますので、アプリケーション内の複数のモジュールに分散して実装する事が出来ます。
//   一般的には、有限状態機械マップ毎に別々のモジュールに分けて、実装する事になると思います。(これまでのC言語版でそうしていたのと同様です。)
//   また、パーシャルクラスが実装するインターフェイスの宣言は、一か所だけ宣言しておけば良いようです。
//   ③にて、「partial class FsmFunc : IFsmFunc {」と宣言していますので、アプリケーションが実装するソースでは、「partial class FsmFunc {」だけで大丈夫です。(④の雛形でもそうしています。)
// * Thu Mar 16 23:39:55 JST 2017 Naoyuki Sawa
// - 複数の入力ファイルを指定した時に、最後以外のファイルでエラーが発生した場合、当ツールの終了ステータスが0になっていたバグを修正しました。
//   詳細は、/clip/tool/dEnmDefC/winapp.hの同日のコメントを参照して下さい。
// * Mon May 08 08:35:51 JST 2017 Naoyuki Sawa
// - ライブラリのバグ修正に伴う、ツールのリビルドを行いました。
//   詳細は、clipmisc.cの'Sun May 07 09:13:01 JST 2017 Naoyuki Sawa'のコメントを参照して下さい。
//-----------------------------------------------------------------------------
//バージョン定義
//-----------------------------------------------------------------------------
#define VERSION "20170508"
//-----------------------------------------------------------------------------
#endif/*__WINAPP_H__*/
