/*****************************************************************************
 * 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;		//状態マップの名前					必須
	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
ST_MapHdr* MapHdr_new(char* name, char* initState);
//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以外のツールについては、今すぐにマルチステートメント対応が必要な訳ではないのですが、上述の通り変更箇所は少ないので、他のツールも一緒に変更しておく事にしました。
//-----------------------------------------------------------------------------
//バージョン定義
//-----------------------------------------------------------------------------
#define VERSION "20161002"
//-----------------------------------------------------------------------------
#endif/*__WINAPP_H__*/
