/*****************************************************************************
 * 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======================================================*/
/*---------------------------------------------------------------------------*/
/* 構造体定義 */
//keyBody
typedef struct _ST_KeyBody {
	struct _ST_KeyBody*	redir;				//optimize2()で設定する。	NULLでなければ最適化により別のキーボディに統合された事を示す。二段階以上に辿る可能性も有ることに注意せよ。
	union {
		int		index;				//optimize2()で設定する。	走査順で前方(インデクスが小さい方)のキーボディにのみ一致させ、後方(インデクスが大きい方)には一致させないために、連番を振る。
		int		addr;				//setKeyBodyAddr()で設定する。
	};
	//キー
	ght_hash_table_t*	ht_Key;
	struct obstack		o_Key;				//高速化のためにo_Keyを使ってTBL_Keyを伸張する事にした。
	int			nKey;
	struct _ST_Key**	TBL_Key/*[nKey]*/;
	//値
	ght_hash_table_t*	ht_ValueRow;
	struct obstack		o_ValueRow;			//高速化のためにo_ValueRowを使ってTBL_ValueRowを伸張する事にした。
	int			nValueRow;
	struct _ST_ValueRow**	TBL_ValueRow/*[nValueRow]*/;
	//文字列
	ght_hash_table_t*	ht_StringRow;
	struct obstack		o_StringRow;			//高速化のためにo_StringRowを使ってTBL_StringRowを伸張する事にした。
	int			nStringRow;
	struct _ST_StringRow**	TBL_StringRow/*[nStringRow]*/;
	//BLOB
	ght_hash_table_t*	ht_BlobRow;
	struct obstack		o_BlobRow;			//高速化のためにo_BlobRowを使ってTBL_BlobRowを伸張する事にした。
	int			nBlobRow;
	struct _ST_BlobRow**	TBL_BlobRow/*[nBlobRow]*/;
} ST_KeyBody;
//key
typedef struct _ST_Key {
	struct _ST_NameRow*	nameRow;
	struct _ST_KeyBody*	keyBody;
} ST_Key;
typedef struct _ST_Blob {
	struct obstack		o_data;				//高速化のためにo_dataを使ってdataを伸張する事にした。
	int			addr;				//─2パス目で設定する。
	int			size;				//┬1パス目で設定する。
	uint8_t*		data/*[size]*/;			//┤
	int			bitsLeft;			//┘最終バイトの残りビット数。	このフィールドが1～7ならば次のビット格納要求は最終のバイトの(1<<(8-bitsLeft))の位置に格納する。このフィールドが1～7の時にbyte,half,wordの格納を行う場合はバイト境界まで進める(即ち確実にbitsLeft=0とする)。このフィールドが1～7の時もデータ全体として見れば完全なのでどのタイミングでもST_Blobのファイナライズは不要である。
} ST_Blob;
//nameRow
typedef struct _ST_NameRow {
	int			line;				//行番号。エラーメッセージのためだけに使用する。
	int			name;				//(0～(1<<24)-1)=数値,それ以外=文字列をstr2num()で変換した値。
} ST_NameRow;
//valueRow
typedef struct _ST_ValueRow {
	int			line;				//行番号。エラーメッセージのためだけに使用する。
	int			name;				//(0～(1<<24)-1)=数値,それ以外=文字列をstr2num()で変換した値。
	int			data;				//(0～(1<<24)-1)=数値,それ以外=文字列をstr2num()で変換した値。
} ST_ValueRow;
//stringRow
typedef struct _ST_StringRow {
	int			line;				//行番号。エラーメッセージのためだけに使用する。
	int			name;				//(0～(1<<24)-1)=数値,それ以外=文字列をstr2num()で変換した値。
	char*			s;				//文字列データ。インターン済みでTBL_String[]内の文字列を指す。
} ST_StringRow;
//blobRow
typedef struct _ST_BlobRow {
	int			line;				//行番号。エラーメッセージのためだけに使用する。
	int			name;				//(0～(1<<24)-1)=数値,それ以外=文字列をstr2num()で変換した値。
	ST_Blob*		blob;				//BLOBデータ。インターン済みでTBL_Blob[]内のデータを指す。
} ST_BlobRow;
/*---------------------------------------------------------------------------*/
/* グローバル関数宣言 */
int cast_dbl_to_int(double d);
void add_keyBody(ST_KeyBody* keyBody);
ST_KeyBody* KeyBody_new();
ST_KeyBody* KeyBody_addKey(ST_KeyBody* keyBody, ST_Key* key);
ST_KeyBody* KeyBody_addValueRow(ST_KeyBody* keyBody, ST_ValueRow* valueRow);
ST_KeyBody* KeyBody_addStringRow(ST_KeyBody* keyBody, ST_StringRow* stringRow);
ST_KeyBody* KeyBody_addBlobRow(ST_KeyBody* keyBody, ST_BlobRow* blobRow);
ST_Key* Key_new(ST_NameRow* nameRow, ST_KeyBody* keyBody);
ST_NameRow* NameRow_new(int name);
ST_ValueRow* ValueRow_new(int name, int data);
ST_StringRow* StringRow_new(int name, char* s);
ST_BlobRow* BlobRow_new(int name, ST_Blob* blob);
int Name_newExpr(int expr);
int Name_newLabel(char* label);
int Data_newExpr(int expr);
int Data_newLabel(char* label);
int Bit_new(int expr);
int Byte_new(int expr);
int Half_new(int expr);
int Exp10_new(int expr);	//{{2017/02/16追加:BLOBのデータ定義に'exp10'のプレフィクス指定を追加しました。}}
char* String_intern(char* s);
ST_Blob* Blob_newBit(int bit);
ST_Blob* Blob_addBit(ST_Blob* blob, int bit);
ST_Blob* Blob_newByte(int byte);
ST_Blob* Blob_addByte(ST_Blob* blob, int byte);
ST_Blob* Blob_newHalf(int half);
ST_Blob* Blob_addHalf(ST_Blob* blob, int half);
ST_Blob* Blob_newWord(int word);
ST_Blob* Blob_addWord(ST_Blob* blob, int word);
ST_Blob* Blob_newFp16(double d);
ST_Blob* Blob_addFp16(ST_Blob* blob, double d);
ST_Blob* Blob_newFp32(double d);
ST_Blob* Blob_addFp32(ST_Blob* blob, double d);
ST_Blob* Blob_newFp64(double d);
ST_Blob* Blob_addFp64(ST_Blob* blob, double d);
ST_Blob* Blob_newFile(char* file);
ST_Blob* Blob_addFile(ST_Blob* blob, char* file);
ST_Blob* Blob_intern(ST_Blob* blob);
/*---------------------------------------------------------------------------*/
/*--- 変更履歴 ---*/
// * Mon Mar 23 21:35:39 JST 2015 Naoyuki Sawa
// - 1st リリース。
// * Tue Mar 24 21:30:13 JST 2015 Naoyuki Sawa
// - 最適化処理1を実装しました。
// * Thu Mar 26 21:28:16 JST 2015 Naoyuki Sawa
// - 出力データ構造を大幅に変更しました。
//   実行処理の速度アップのための変更であり、スクリプトの書式や概念は変えていません。
// - 前回までの出力データ構造では、キーの数が多い時に、検索時間が非常に長くなる問題が有りました。
//   具体的には、約10000のサブキーが有る時、末尾のサブキーを検索するのに0.01秒ぐらい掛かりました。
//   大抵、1フレームで複数回キー検索を行うと思うので、1回に0.01秒は時間が掛かりすぎです。
// - 問題の原因は、キーの配列は一要素のサイズが不定(固定長のキー名+可変長のキーボディ)で、バイナリサーチ出来なかったからです。
//   尚、値の配列は一要素のサイズが固定(固定長の値名+固定長の値データ)でバイナリサーチ出来るので、この問題は有りませんでした。
// - 今回、キーの配列も一要素のサイズを固定(固定長のキー名+固定長のキーボディ距離)にして、バイナリサーチ出来るようにしました。
//   そのために、一要素当り3バイト(キーボディ距離を24ビットで表現したため)の容量増加になりました。
//   容量増加は望ましく有りませんが、この変更を行わないと実用的な速度が出ないので、やむを得ません。
//   少しでも容量増加を抑えるために、実用上充分な24ビット距離としました。
//   16ビット距離では10000個ぐらいキーが有るとオーバーして不足するし、32ビットでは無駄が多いので、24ビットが適切と思いました。
// - 最適化処理2を実装しました。
//   上記の高速化のために容量が増えましたが、最適化処理2により容量が減るので、ある程度容量増加を相殺できたと思います。
//   要検討:最適化処理2は複数回行うようにしてあるが、必要無いかも知れません。
//   dDirSeqC.exeの場合は複数回実行する事によって2回目以降にも最適化できる箇所が出現する事を確認したのですが、
//   当ツール(dRegSeqC.exe)のアルゴリズムでは必ず1回目で全て最適化でき2回目に最適化できる箇所が出現しないような気もします。
//   今までのところ、2回目で最適化出来る箇所が出現するようなサンプルデータを作れていません。
//   複数回実行しても少し時間が掛かるだけで実行結果に悪影響は無いので、とりあえずこのままとしておく事にします。
//   今後、2回目で最適化出来る箇所が出現するようなサンプルデータが得られたら、複数回実行するままにしてください。
//   或いはもし、2回目で最適化出来る箇所が出現しない事を証明出来たら、最適化処理2の複数回実行を削除してください。
// * Fri Mar 27 21:11:31 JST 2015 Naoyuki Sawa
// - 最適化処理1,最適化処理2を複数回行っていたのをやめました。
//   最適化処理1は元から、複数回行う必要が無いのが判っていました。
//   最適化処理2を複数回行う必要が有るかどうか検討したところ、どう考えても2回目に最適化できる箇所が出現しないと思いました。
//   深さ優先で操作して前方に対して同一のキーを探して行くのですから、一回で全て見つかるはずだからです。
//   そんなわけで複数回行っても無駄だったので、一回で終了するようにして、全体の処理時間を短縮しました。
// * Fri Apr 03 00:32:50 JST 2015 Naoyuki Sawa
// - 前バージョンまでは、「optimize2()が走査順で前方のキーボディにのみマッチさせる判断」が不充分で、後方のキーボディにもマッチしまっていたバグがありました。
//   たとえば、下記のような構造で、問題が起きていました。
//   □入力ﾌｧｲﾙ
//   │1
//   │ 3
//   │  4 = 5 #//｢REG_get_value_l(TBL_RegTbl,1,3,4,-1)｣の結果が正しくは6であるべきところ(-1)になってしまうような､間違ったﾃﾞｰﾀが出力されていた｡
//   │ end
//   │end
//   │2
//   │ 3
//   │  4 = 5 #//｢REG_get_value_l(TBL_RegTbl,2,3,4,-1)｣の結果が正しくは6であるべきところ(-1)になってしまうような､間違ったﾃﾞｰﾀが出力されていた｡
//   │ end
//   │end
//   ×出力ﾃﾞｰﾀ[誤]
//   │00 00
//   │00 02
//   │ 00 01  00 00 05
//   │ 00 02  00 00 00
//   │00 00
//   │00 01
//   │ 00 03  FF FF E9 #//本来ここが｢4=5｣の値を持つｷｰﾎﾞﾃﾞｨを指すべきなのだが､｢4=5｣の値を持つｷｰﾎﾞﾃﾞｨが存在せず､ﾙｰﾄｷｰﾎﾞﾃﾞｨへの誤った相対ｱﾄﾞﾚｽになっている｡
// - 具体的には、optimize2()の間違った動作は、以下のような処理の流れで起きていました。
//   ①
//   │1
//   │ 3
//   │  4 = 5
//   │ end
//   │end
//   │2
//   │ 3
//   │  4 = 5
//   │ end
//   │end
//   ②
//   │1
//   │ 3
//   │  ----- ─┐ 最適化されて実体が無くなる !!ここで後方に最適化しているのが間違い!!
//   │ end      │
//   │end       │
//   │2         │
//   │ 3        │
//   │  4 = 5 ←┘
//   │ end
//   │end
//   ③
//   │1
//   │ 3  ←───┐
//   │  ----- ─┐│
//   │ end      ││
//   │end       ││
//   │2         ││
//   │ ------ ─│┘最適化されて実体が無くなる
//   │ ------ ←┘
//   │ ------
//   │end
//   この後、output()が'2'のキーボディを出力しないので、'3'のキーボディの参照先の実体が無く、間違ったアドレス(0)への距離が出力されていました。
// - 今回のバージョンで修正し、必ず前方のキーボディにのみマッチさせるように修正しました。
//   修正後は正しく、以下のような処理の流れになりました。
//   ①
//   │1
//   │ 3
//   │  4 = 5
//   │ end
//   │end
//   │2
//   │ 3
//   │  4 = 5
//   │ end
//   │end
//   ②
//   │1
//   │ 3
//   │  4 = 5 ←┐
//   │ end      │
//   │end       │
//   │2         │
//   │ 3        │
//   │  ----- ─┘
//   │ end
//   │end
//   ③
//   │1
//   │ 3  ←───┐
//   │  4 = 5 ←┐│
//   │ end      ││
//   │end       ││
//   │2         ││
//   │ ------ ─│┘
//   │ ------ ─┘
//   │ ------
//   │end
// - 修正後は正しく、下記のデータが出力されるようになりました。
//   ○出力ﾃﾞｰﾀ[正]
//   │00 00
//   │00 02
//   │ 00 01  00 00 05
//   │ 00 02  00 00 00
//   │00 00
//   │00 01
//   │ 00 03  00 00 00 #//正しく｢4=5｣の値を持つｷｰﾎﾞﾃﾞｨを指すようになった｡
//   │00 01            #//┐
//   │ 00 04  00 05    #//├──｢4=5｣の値を持つｷｰﾎﾞﾃﾞｨ
//   │00 00            #//┘
// * Sat Apr 11 13:20:40 JST 2015 Naoyuki Sawa
// - 文字列のデータタイプを追加し、大幅な変更を行いました。
//   変更前のコードを参照するには、前回のアーカイブを参照してください。
// * Sun Oct 04 21:01:44 JST 2015 Naoyuki Sawa
// - clipreg.cの大幅な変更に伴い、当ツールも大幅な変更を行いました。
//   詳細は、clipreg.cの同日のコメントを参照して下さい。
// - レジストリテーブルのバイナリフォーマットの互換性も無くなりました。
//   変更前のソースとツールを'keep/17_レジストリテーブル形式変更前保存/'に保存しておきました。
// * Tue Oct 06 22:24:46 JST 2015 Naoyuki Sawa
// - 1パス目の処理を高速化しました。主な高速化手段は以下の通りです。
//   ・str2num()で、これまでは同じ文字列も通し番号の異なる数値に変換していましたが、同じ文字列は同じ数値に変換するように変更し、数値比較出来るようにしました。
//   ・KeyBody_addKey(),KeyBody_addValueRow(),KeyBody_addStringRow(),KeyBody_addBlobRow()で、これまでは同じ名前を検索するのにリニアサーチしていましたが、ハッシュテーブルを使うように変更しました。
//   ・KeyBody_addKey(),KeyBody_addValueRow(),KeyBody_addStringRow(),KeyBody_addBlobRow()で、これまでは配列の拡張にrealloc()を使っていましたが、Obstackを使うように変更しました。
// * Wed Oct 07 21:13:47 JST 2015 Naoyuki Sawa
// - String_intern(),Blob_intern()を高速化しました。
// * Thu Oct 08 21:52:46 JST 2015 Naoyuki Sawa
// - BLOBのデータ構造を少し変更しました。
//   これまでは、BLOBのサイズに(データ本体のバイト数)を格納していましたが、今後は、(データ本体のバイト数-1)を格納します。
//   他のフィールドには(要素数-1)を格納しているので、BLOBのサイズもそれらに合わせて統一する方が判り易いと思ったからです。
// - Blob_addByte()で、これまでは配列の拡張にrealloc()を使っていましたが、Obstackを使うように変更しました。
// * Fri Oct 09 21:09:22 JST 2015 Naoyuki Sawa
// - BLOBのデータ定義に'byte','half','word'のプレフィクス指定を追加しました。
//   これまではたとえばBLOBのデータとして0x12345678を含めたい時、
//   {0x78,0x56,0x34,0x12},又は,{0x12345678&255,(0x12345678>>8)&255,(0x12345678>>16)&255,(0x12345678>>24)&255}のように定義する必要が有りましたが、今後は{word 0x12345678}と書けます。
//   一つのBLOBのデータ内で、複数のプレフィクスを混在させる事も可能です。⇒{byte 0x12,half 0x1234,word 0x12345678}
//   プレフィクスを省略すれば、これまでどおり、byteと見なします。⇒{0x12}と{byte 0x12}は同じ意味です。
// - half,wordは、リトルエンディアンで格納する事にしました。
//   理由は、BLOB内のデータを構造体と見なしてアプリケーションが直接参照する時に、リトルエンディアンの方が扱い易いと思ったからです。
//   レジストリ構造の要素数や名前の値などはビッグエンディアンで格納していますが、BLOB内のデータはリトルエンディアンである事に注意してください。
//   尚、BLOB内のデータにビッグエンディアンで格納したい場合は、{0x12,0x34,0x56,0x78}のように明示的にバイト単位で指定してください。
// * Sat Oct 10 21:13:38 JST 2015 Naoyuki Sawa
// - '~'演算子を対応しました。
// * 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()の動作を変更した事に伴い、当ツールをリビルドしました。
//   上記の関数の動作変更は、当ツールの使用方法では影響無いのですが、念のためにリビルドする事にしました。
// * Thu Oct 29 21:30:16 JST 2015 Naoyuki Sawa
// - clipreg.cモジュールを修正した事に伴い、当ツールもリビルドしました。
//   当ツールのソースは、変更していません。
// * Sun Nov 08 21:48:30 JST 2015 Naoyuki Sawa
// - 「Boehm GC」をマルチスレッド対応にした事,及び,それに伴ってclipbpe.cモジュールを修正した事に伴い、当ツールもプロジェクト設定の変更を行ってリビルドしました。
//   詳細は、/clip/tool/gc/README.TXT と /clip/clipbpe.c の2015/11/03のコメントを参照して下さい。
// - BLOBのデータ定義に'bit'のプレフィクス指定を追加しました。
//   'bit'を1～7ビット格納した後に、'byte','half','word'の格納を行うと、バイト境界までパディングします。(例:x={bit 1,bit 0,bit 1,0xAB})
//   'bit'を1～7ビット格納した状態で、Blobを終端した場合も同様です。(例:x={bit 1,bit 0,bit 1})
//   詳細は、Blob_addBit(),Blob_addByte(),Blob_addHalf(),Blob_addWord()の実装を参照して下さい。
// * Sat Nov 14 21:55:38 JST 2015 Naoyuki Sawa
// - ゼロ除算エラーと、範囲外ビットシフトのハンドリングを追加しました。
//   これまでは前者はCPU例外で終了し、後者は無視してしまっていました。今後はエラーと見なします。
// - '%'演算子を対応しました。
// * Sun Nov 22 21:02:41 JST 2015 Naoyuki Sawa
// - 環境変数'プログラム名_OPTION'で指定されたオプション(有れば)を、コマンドライン引数にマージするようにしました。
//   詳細は、/clip/clipmisc.c の同日のコメントを参照して下さい。
// - GCに'-DLARGE_CONFIG'を付けてリビルドした事に伴い、当アプリケーションもリビルドしました。
//   詳細は、/clip/tool/gc/README.TXT の同日のコメントを参照して下さい。
// * Sun Dec 06 21:06:49 JST 2015 Naoyuki Sawa
// - 文字列式を追加しました。今回対応した文字列式は、以下の二種類のみです。
//   │("文字列")⇒文字列
//   │"文字列"+"文字列"⇒文字列
//   文字列式を追加した目的は、スクリプト上、複数の文字列に分けて記述する方が見た目に判り易い場合が有るからです。
//   文字列式を使わなくても最初から連結して記述すれば結果は同じになのですが、見た目の判り易さのために対応する事にしました。
// - C言語の書式に倣うならば「"文字列" "文字列"」なのですが、二つの文字列トークンの並びと区別出来なくなる事を避けるために、'+'を使う事にしました。
// - 文字列と数値の連結は、今回は、対応しない事にしました。
//   数値を文字列化して連結する場合、数値の書式を指定出来ないと、実用上、使い物にならないと思ったからです。
//   もし今後、文字列と数値の連結にも対応する場合は、その時に、数値の書式の指定方法を検討しようと思います。
// * Sat Jan 02 21:26:28 JST 2016 Naoyuki Sawa
// - '<<','>>'と'<','>'に対して、これまでlex.yy.lがどちらも'<','>'を返していましたが、前者についてはT_SHL,T_SHRを返すようにして区別しました。
//   詳細は、/clip/tool/dPrpTblC/winapp.h の2015/12/27のコメントを参照して下さい。
// * Sun Jan 03 21:17:56 JST 2016 Naoyuki Sawa
// - プレフィクス文字列を固定にしました。
//   これまで使って来てプレフィクス文字列を変更する必要性が無く、毎回'-p'オプションを指定する事が却って手間になる事が判ったからです。
//   この変更に伴い、'-p'オプションを廃止しました。
// * Sun Feb 21 21:02:01 JST 2016 Naoyuki Sawa
// - libclipのライブラリ化の伴い、以下の変更を行いました。
//   ・extclip.hとextclip.cを削除しました。extclip.hとextclip.cはlibclipに含まれるようになったからです。
//   ・"CLiP Files"を削除しました。CLiPライブラリの各モジュールはlibclipに含まれるようになったからです。
//   当ツールの動作には変更有りません。
// * Tue Mar 01 21:34:55 JST 2016 Naoyuki Sawa
// - clipstd.hにてC4131の警告レベルを引き上げましたが、Bison/Flexの生成コードには旧スタイルの宣言が使われているので、Bison/Flexの生成コードのみ警告レベルを元に戻しました。
// * Tue Apr 12 21:05:50 JST 2016 Naoyuki Sawa
// - BLOBのデータ定義に'file'のプレフィクス指定を追加しました。
//   ファイルの内容をそのままBLOBに取り込めるようになりました。
//   <例>
//   │Label1 = { file "Data1.bin" }
//   上記はファイル単体で一つのBLOBとした例ですが、複数のfile要素を並べたり、bit,byte,half,word要素と組み合わせる事も出来ます。
//   │Label1 = { word 0x01234567, file "Data1.bin", word 0x89ABCDEF, file "Data1.bin" }
//   とは言え実際には、file要素を使用する場合は、ファイル単体で一つのBLOBとする事がほとんどだと思います。
// * 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で指定するようにし、個別のアプリケーション設定からは削除しました。
// * Mon Apr 25 22:45:55 JST 2016 Naoyuki Sawa
// - 実数の計算式に対応しました。
//   暗黙の型変換のルールは、C言語と同じです。
//   キャスト演算子は、'(int)'と'(double)'のみ対応しています。
// - あくまでも途中計算で実数の計算式が使えるだけであり、最終的には整数にキャストする必要が有る事に注意して下さい。
//   例は、/clip/tool/dTexDefC/winapp.hの同日のコメントを参照して下さい。
// * Tue Apr 26 22:39:26 JST 2016 Naoyuki Sawa
// - 実数の計算式から、整数引数への、暗黙の型変換を対応しました。
//   '-w'オプションを指定しなければ、C言語と同様に、警告無しで処理します。
//   '-w'オプション,又は,'-wcast'オプションを指定すると、暗黙の型変換によって誤差が発生した時のみ警告を表示し、最終的にエラー終了します。
//   C言語と違って、誤差が発生しなかった時は警告を表示しない事に注意して下さい。
// - 上記の変更のために、'-w'オプションを処理する仕組みとして、getsubopt()を導入しました。
//   今後、他の種類の警告を追加する時は、この仕組みを使って警告を追加出来ます。
// * Thu Jun 09 21:26:53 JST 2016 Naoyuki Sawa
// - lex.yy.lにて、数値(T_NUM)の解析を、既存の10進数と16進数に加えて、新しく8進数と2進数も解析出来るようにしました。
// * 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を使用していませんが、インクルードパスとライブラリパスの設定を追加しないとビルドエラーになるからです。
// * Sun Jul 10 11:29:13 JST 2016 Naoyuki Sawa
// - y.tab.yのint_argの文法規則の最後に、「;」が抜けていたミスを修正しました。
//   bison.exeはこのような単純なミスを自動的に補ってくれるので、bison.exeのエラーにもならず、生成したプログラムの動作上も問題無く、これまで気付きませんでした。
//   しかし、間違った記述であった事には違い無いので、修正しておく事にしました。
// * Tue Aug 09 21:14:43 JST 2016 Naoyuki Sawa
// - BLOBのデータ定義に'fp16','fp32','fp64'のプレフィクス指定を追加しました。
//   使用方法は、'bit','byte','half','word'のプレフィクス指定と同様です。
//   <例>
//   │{fp16 1.2,fp16 3.4,fp16 5.6}
//   │{fp32 1.2,fp32 3.4,fp32 5.6}
//   │{fp64 1.2,fp64 3.4,fp64 5.6}
//   │{bit 1,byte 2,half 3,word 4,fp16 5.6,fp32 7.8,fp64 9.0,file "Data.bin"}		…他のプレフィクス指定との混在も可能です。ただし、自動的に境界整列は行われないので注意して下さい。(既存の他のプレフィクス指定と同様です。)
//   │{fp16 1,fp32 2,fp64 3}								…整数表現での指定も可能です。左記の例は{fp16 1.0,fp32 2.0,fp64 3.0}と書くのと同じです。尚、左記の例ではfp32,fp64がワード境界に整列していない事に注意して下さい。
// - 当初、プレフィクス名を'fp16','single','double'にしようかと思っていたのですが、最終的に、'fp16','fp32','fp64'とする事にしました。
//   理由の一つは、前者では'fp16'だけ名前が浮いていて判り辛いと思ったからです。
//   もう一つの理由は、既存のキャスト演算子'(double)'とキーワードが被って、(字句解析上は問題無いのですが)紛らわしいと思ったからです。
// * 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にマージしました。
//   当ツールの'popen'対応は必須ではないのですが、本日dFsmMapC.exeに上記の変更を行ったついでに当ツールも対応しておく事にしました。
// - エラーメッセージに、現在の行番号だけでなく、現在のファイル名も表示するようにしました。
//   エラーメッセージの形式は、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以外のツールについては、今すぐにマルチステートメント対応が必要な訳ではないのですが、上述の通り変更箇所は少ないので、他のツールも一緒に変更しておく事にしました。
// * Thu Feb 16 21:10:48 JST 2017 Naoyuki Sawa
// - BLOBのデータ定義に'exp10'のプレフィクス指定を追加しました。
//   使用方法は、'bit','byte','half','word'のプレフィクス指定と同様です。
//   exp10の形式については、cliplot.hの「16ビットで大きな値を表現するための、指数表現」のコメントを参照して下さい。
//   <例>
//   │{exp10 10,exp10 1000,exp10 100000,exp10 10000000,exp10 1000000000}
// * Mon Feb 27 22:08:56 JST 2017 Naoyuki Sawa
// - '-xc','-xcs'オプションを追加しました。
//   ラベル定義と、テキスト形式のデータ出力を、これまでのC言語形式に加えて、C#形式でも出力出来るようになりました。
//   普通はデータ出力はバイナリ形式で行うと思うので、テキスト形式のデータ出力の方のC#形式対応が役に立つ事はあまり無いと思いますが、テスト時にはテキスト形式でデータを出力する方が扱い易い事も有るので、一応、テキスト形式のデータ出力もC#形式に対応しておきました。
// - C#アプリケーションからレジストリデータにアクセスするには、/clip/libclip.net/clipreg.cs を使用して下さい。
// * Sun Mar 05 23:35:48 JST 2017 Naoyuki Sawa
// - dRegTblC.exeの引数にスクリプトファイル名を二個以上指定すると、最後のスクリプトファイルの内容しか出力されていなかった、バグを修正しました。
// - バグの原因は、add_keyBody()の処理が正しくなかった事でした。
//   dRegTblC.exeの引数にスクリプトファイル名を二個以上指定した場合、Bison/Flexは、全てのスクリプトファイルを連結した内容に対してパースを行うのではなく、個々のスクリプトファイルに対してパースを行います。(要するに、<<EOF>>が複数回現れます。)
//   そのため、トップレベルのKeyBodyが複数個生成され、add_keyBody()が複数回呼び出されます。
//   しかしこれまで、add_keyBody()は一回しか呼ばれない事を想定した処理になっていて、g_keyBodyを上書きしていました。
//   そのため、一個目のスクリプトファイルに対するadd_keyBody()の呼び出しによってg_keyBodyが格納された後、二個目のスクリプトファイルに対するadd_keyBody()の呼び出しによってg_keyBodyが上書きされてしまい、一個目のスクリプトファイルの内容が消えてしまっていました。
//   正しくは、二個目以降のスクリプトファイルに対するadd_keyBody()の呼び出しならば(=既にg_keyBodyが格納されていたら)、上書きするのではなく、マージするのが正しい処理でした。
//   今回、そのように修正したので、dRegTblC.exeの引数にスクリプトファイル名を二個以上指定した場合も、正しく動作するようになりました。
// - かなり大きなバグなのですが、これまで気づかなかった理由は以下の通りです。
//   大抵の場合、レジストリスクリプトのコンパイルは、dRegTblC.exeを直接使用せずに、MkRegTbl.batを経由して使用しています。
//   MkRegTbl.batは、cpp.exeを通すして、指定されたファイルを一つのファイルに連結してから、dRegTblC.exeを呼び出しています。
//   そのため、図らずも、dRegTblC.exeに対しては一個のスクリプトファイルしか指定されていなかったので、上記のバグが顕在化していませんでした。
// * Thu Mar 16 23:39:55 JST 2017 Naoyuki Sawa
// - 複数の入力ファイルを指定した時に、最後以外のファイルでエラーが発生した場合、当ツールの終了ステータスが0になっていたバグを修正しました。
//   詳細は、/clip/tool/dEnmDefC/winapp.hの同日のコメントを参照して下さい。
/*---------------------------------------------------------------------------*/
/* バージョン定義 */
#define VERSION "20170316"
/*---------------------------------------------------------------------------*/
#endif/*__WINAPP_H__*/
