/*****************************************************************************
 * 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======================================================*/
/*---------------------------------------------------------------------------*/
/* グローバル関数宣言 */
int cast_dbl_to_int(double d);
void inst_def(char* pLabel);
void inst_repeat();	//{{2017/02/11追加:ループ制御を追加しました。}}
void inst_end();
void inst_wait(int iTime);
void inst_ctrl(int iLogCh, int iAtt, int iPan, int fMask);
//{{2017/02/13変更:'play.w'命令を追加しました。
//void inst_play(int iLogCh, int iPhr, int iLoop, int iAtt, int iPan);
//↓2017/02/13変更:'play.w'命令を追加しました。
void inst_play(int iLogCh, int iPhr, int iLoop, int iAtt, int iPan, int bWait);
//}}2017/02/13変更:'play.w'命令を追加しました。
void inst_stop(int iLogCh);
/*---------------------------------------------------------------------------*/
/*--- 変更履歴 ---*/
// * Sun Sep 13 20:50:05 JST 2015 Naoyuki Sawa
// - 1st リリース。dSndSeqCをベースにしました。
// * 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()の動作を変更した事に伴い、当ツールをリビルドしました。
//   上記の関数の動作変更は、当ツールの使用方法では影響無いのですが、念のためにリビルドする事にしました。
// * 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のコメントを参照して下さい。
// - ゼロ除算エラーと、範囲外ビットシフトのハンドリングを追加しました。
//   これまでは前者はCPU例外で終了し、後者は無視してしまっていました。今後はエラーと見なします。
// - '%'演算子を対応しました。
// * Sun Nov 22 21:02:41 JST 2015 Naoyuki Sawa
// - 環境変数'プログラム名_OPTION'で指定されたオプション(有れば)を、コマンドライン引数にマージするようにしました。
//   詳細は、/clip/clipmisc.c の同日のコメントを参照して下さい。
// - GCに'-DLARGE_CONFIG'を付けてリビルドした事に伴い、当アプリケーションもリビルドしました。
//   詳細は、/clip/tool/gc/README.TXT の同日のコメントを参照して下さい。
// * 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の生成コードのみ警告レベルを元に戻しました。
// * 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のエラーにもならず、生成したプログラムの動作上も問題無く、これまで気付きませんでした。
//   しかし、間違った記述であった事には違い無いので、修正しておく事にしました。
// * 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'オプションは指定しなくて構いません。
// - 2016/09/16現在は、当ツールは進捗表示を行っていません。
//   従って、'-q'オプションを指定しても指定しなくても、動作に違いは有りません。
//   それにもかかわらず'-q'オプションを追加した理由は、dXxxXxxC.exeツールの種類によって'-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以外のツールについては、今すぐにマルチステートメント対応が必要な訳ではないのですが、上述の通り変更箇所は少ないので、他のツールも一緒に変更しておく事にしました。
// * Sat Feb 11 21:09:58 JST 2017 Naoyuki Sawa
// - ループ制御を追加しました。
//   これまでは、シーケンスデータでは、ループ制御を表現する事が出来ませんでした。
//   今回、repeat命令を追加した事により、全体ループ,又は,部分ループを表現する事が出来るようになりました。
// - 全体ループ,又は,部分ループの構造は、既存のdLedSeqC.exeのLEDシーケンサスクリプトの書式と同じです。
//   ただし、当ツール(dTapSeqC.exe)の実装は、dLedSeqC.exeよりも構文チェックが甘いので、LEDシーケンサスクリプトではエラーを検出するようなループ構造でも、当ツールではエラーを検出しないケースが有る事に注意して下さい。
//   例えば以下のようなスクリプトは、動作自体は問題無いものの、ループよりも下へ到達する事は無いので無意味であり、本来エラーとすべきです(実際にdLedSeqC.exeではエラーを検出します)が、当ツールではエラー検出しません。
//     ×正しくないがエラーを検出しない例
//     │Label1
//     │    play 0,1
//     │    wait 1000
//     │  repeat
//     │    play 0,2
//     │    wait 2000
//     │  end
//     │    play 0,3
//     │    wait 3000
//     │  end
//   なぜならば、当ツールはラベルを制御の区切りと認識しておらず、スクリプト全体を一連のコマンドの羅列としか認識していないからです。
//   動作上は問題無いものの、意図と違うスクリプトを書いた場合にエラーが検出されずに見つけ辛いバグになる恐れも有るので、注意して下さい。
//   もし今後、当ツール(dTapSeqC.exe)を作り直す機会が有ったら、dLedSeqC.exeと同様に厳密な構文チェックを行うようにしようと思います。
// - とは言え、現状では当ツールはラベルを制御の区切りと認識していない事を利用して、敢えて以下のようなスクリプトを書くことも可能ではあります。
//     ○ラベルを超えて戻りジャンプする例
//     │FromIntro
//     │    play 0,PhrNo_Intro1
//     │    wait 1000
//     │  repeat		←┐
//     │    play 0,PhrNo_Intro2　│
//     │    wait 2000		　│
//     │SkipIntro1		　│	このラベルから開始したとしても、ループ時はラベルよりも前へ戻ります。
//     │    play 0,PhrNo_Loop	　│
//     │    wait 3000		　│
//     │  end			─┘
// * Mon Feb 13 22:57:25 JST 2017 Naoyuki Sawa
// - 'play.w'命令を追加しました。
//   'play.w'命令を追加した理由は、以下の通りです。
// - イントロ・ループ制御を、論理チャネルではなく、シーケンサチャネルで行いたいケースが生じたからです。
//   具体的には、一種類のイントロフレーズから、条件によって、複数種類のループフレーズへ繋げたい場合に、論理チャネルの制御では実現出来ません。
//   論理チャネルでは制御せずに(=フレーズチェインは設定せずに)、シーケンスデータで明示的に次のフレーズへ繋げる事で、実現出来ます。
//   (厳密には、全く同じではありません。論理チャネル制御ならば既にイントロ又はループフレーズが再生中ならば鳴らし直さない制御が行われますが、シーケンサによる制御ではそのような気の利いた制御は行われません。今回は、そのような気の利いた制御は不要という前提で進めます。)
// - 既存の機能のまままでも、シーケンススクリプトを書くこと自体は可能だったのですが、スクリプト作成時に、イントロフレーズを再生開始した後ループフレーズを再生開始するまでの待ち時間を調べてシーケンサスクリプト上で明示的に指定するのが煩わしい、という問題が生じました。
//   そこで、シーケンスデータでフレーズを再生するのと同時に、そのフレーズの時間だけ自動的にウェイトも行うという、'play.w'命令を追加する事にしました。
//   例えば、以下の四つの例は同じ結果となります。(PhrNo_Introは1秒,PhrNo_Loopは3秒のフレーズとします。)
//   ①'play.w'を使わない例
//   │PlayWaitSample
//   │  play     0,PhrNo_Intro	#//PhrNo_Introには、フレーズチェインは設定しない。
//   │  wait     1000
//   │  play     0,PhrNo_Loop	#//PhrNo_Loopはループフレーズである事を、フレーズチェインで設定する。
//   │end
//   ②'play.w'を使う例Ａ
//   │PlayWaitSample
//   │  play.w   0,PhrNo_Intro	#//PhrNo_Introには、フレーズチェインは設定しない。
//   │  play     0,PhrNo_Loop	#//PhrNo_Loopはループフレーズである事を、フレーズチェインで設定する。
//   │end
//   ③'play.w'を使う例Ｂ
//   │PlayWaitSample
//   │  play.w   0,PhrNo_Intro	#//PhrNo_Introには、フレーズチェインは設定しない。
//   │  repeat
//   │    play   0,PhrNo_Loop	#//PhrNo_Loopにも、フレーズチェインを設定しない。
//   │    wait   3000
//   │  end
//   ④'play.w'を使う例Ｃ・・・この例が、シーケンサの機能を最大限利用した例です。
//   │PlayWaitSample
//   │  play.w   0,PhrNo_Intro	#//PhrNo_Introには、フレーズチェインは設定しない。
//   │  repeat
//   │    play.w 0,PhrNo_Loop	#//PhrNo_Loopにも、フレーズチェインを設定しない。
//   │  end
// - 今回、論理チャネル再生開始(ウェイト付き)のコードを、0x18～0x1Fに割り当てました。
//   そうした理由は、既存の論理チャネル再生開始が0x08～0x0Fなので、cliptaps.cの処理において、下位3ビットのマスクの意味を既存の0x08～0x0Fと同じにして、5ビット目の判定だけで処理を共通化出来るようにするためです。
//   今回、論理チャネル再生開始(ウェイト付き)のコードを、0x18～0x1Fに割り当てた事により、コード0x15～0x17が欠番となりました。
//   今後、新しい命令を追加する場合は、なるべくコード0x15～0x17に割り当てて、欠番を埋めて下さい。
//   しかし、今にして思えば、ウェイト付きのフラグを4ビット目にして、論理チャネル再生開始と論理チャネル再生開始(ウェイト付き)を連続した16個のコードに割り当てる事も可能だったかも知れません。
//   もし今後、大幅にコード割り当てを整理する機会が有れば、もう少しきれいな並びに割り当てたいです。(※TODO)
// * Tue Feb 28 21:46:05 JST 2017 Naoyuki Sawa
// - '-xc','-xcs'オプションを追加しました。
//   詳細は、/clip/tool/dRegTblC/winapp.hの2017/02/27のコメントを参照して下さい。
// * Thu Mar 16 23:39:55 JST 2017 Naoyuki Sawa
// - 複数の入力ファイルを指定した時に、最後以外のファイルでエラーが発生した場合、当ツールの終了ステータスが0になっていたバグを修正しました。
//   詳細は、/clip/tool/dEnmDefC/winapp.hの同日のコメントを参照して下さい。
/* バージョン定義 */
#define VERSION "20170316"
/*---------------------------------------------------------------------------*/
#endif/*__WINAPP_H__*/
