/*	
 *	clipmisc.h
 *
 *	エラー処理、その他いろいろです。
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2017 Naoyuki Sawa
 *
 *	* Wed Dec 12 21:51:29 JST 2001 Naoyuki Sawa
 *	- 作成開始。
 *	* Sun Jan 26 19:33:00 JST 2003 Naoyuki Sawa
 *	- die()関数に__attribute__((noreturn))属性を追加。
 *	  メモ:__attribute__((...))は関数宣言時のみ指定可能です。
 *	       関数実装時に指定するとコンパイルエラーとなります。
 *	* Sun May 4 18:05:00 JST 2003 Naoyuki Sawa
 *	- fpk_size()/fpk_load()を追加しました。
 *	* Wed Aug 20 06:00:00 JST 2003 Naoyuki Sawa
 *	- fpk_address()を追加しました。
 *	* Sat Nov 22 06:00:00 JST 2003 Naoyuki Sawa
 *	- トレース出力(TRACE_ON/TRACE/trace())を追加しました。
 *	* Sun Dec 28 13:49:00 JST 2003 Naoyuki Sawa
 *	- DDA構造体をcliprend.hから移動してきました。
 *	* Thu Jul 22 12:30:00 JST 2004 Naoyuki Sawa
 *	- RND8_RANGE()とRND16_RANGE()を追加しました。
 *	- COUNTOF()を追加しました。
 *	* Wed Sep 15 06:36:00 JST 2004 Naoyuki Sawa
 *	- コンパイラバグ回避のため、RND8/16,RND8/16_RANGEをマクロ→関数化しました。
 *	  過去のソースの互換性のため、関数を呼び出すマクロも定義してあります。
 *	* Sun Oct 31 13:19:00 JST 2004 Naoyuki Sawa
 *	- LEBYTE()/LEHALF()/LEWORD()/BEBYTE()/BEHALF()/BEWORD()マクロを
 *	  clippce.hからclipmisc.hへ移動してきました。
 *	- HIBYTE()/LOBYTE()/HIHALF()/LOHALF()マクロを追加しました。
 *	* Sun Dec 4 04:01:00 JST 2004 Naoyuki Sawa
 *	- Win32プロジェクトからのインクルードできるよう、
 *	  die()とtrace()の宣言をPIECEシンボル定義の有無によって場合分けしました。
 *	- DDA構造体にコメントを追加しました。(コメント追加のみ。定義変更は無し。)
 *	* Sun Dec 12 09:59:00 JST 2004 Naoyuki Sawa
 *	- BLOCKSIZE、SPEAKER_FREQUENCYはP/ECE特有の定数ですが、Win32版テストプログラムからも参照するために、
 *	  clippce.hからclipmisc.hへ移動しました。
 *	* Wed Feb 02 21:01:00 JST 2005 Naoyuki Sawa
 *	- mirror_table[]の宣言と、MIRROR()マクロを追加しました。
 *	  mirror_table[]の実体は、clipmirr.cにあります。
 *	* Wed Mar 31 06:00:00 JST 2005 Naoyuki Sawa
 *	- shuffle()関数を追加しました。
 *	* Wed Jun 01 19:58:00 JST 2005 Naoyuki Sawa
 *	- xsize2_table[]の宣言と、XSIZE2()マクロを追加しました。
 *	  xsize2_table[]の実体は、clipxsz2.cにあります。
 *	* Sun Jul 17 17:35:00 JST 2005 Naoyuki Sawa
 *	- COUNTOF()マクロの名称をARRAY_SIZE()に変更しました。
 *	- FIELD_OFFSET()マクロとCONTAINING_RECORD()を追加しました。
 *	* Sun Jul 31 08:07:00 JST 2005 Naoyuki Sawa
 *	- PUT_LEBYTE()/PUT_LEHALF()/PUT_LEWORD()/PUT_BEBYTE()/PUT_BEHALF()/PUT_BEWORD()を追加しました。
 *	- LEBYTE()/LEHALF()/LEWORD()/BEBYTE()/BEHALF()/BEWORD()を、GET_LEBYTE()/GET_LEHALF()/GET_LEWORD()/GET_BEBYTE()/GET_BEHALF()/GET_BEWORD()に改名しました。
 *	  LEBYTE()/LEHALF()/LEWORD()/BEBYTE()/BEHALF()/BEWORD()も、残しておくことにします。残しておくことにした理由は、次のとおりです。
 *	  1. これまでに、LEBYTE()/LEHALF()/LEWORD()/BEBYTE()/BEHALF()/BEWORD()を使って書いたソースコードの、互換性維持のため。
 *	  2. PUT_BEWORD()等よりも、GET_BEWORD()等の方が使う機会が多いと思うので、GET_BEWORD()等の省略記法として、BEWORD()等が使えると便利だから。
 *	* Fri Aug 05 18:19:00 JST 2005 Naoyuki Sawa
 *	- XCHG()マクロを追加しました。
 *	* Wed Aug 17 18:45:00 JST 2005 Naoyuki Sawa
 *	- 任意長パケットキュー(QUEUE)を追加しました。
 *	* Mon Aug 22 22:12:00 JST 2005 Naoyuki Sawa
 *	- ダブルリンクリストを追加しました。
 *	* Fri Aug 26 18:39:00 JST 2005 Naoyuki Sawa
 *	- リンクバッファ(BUFFER)を追加しました。
 *	  2005/08/26現在の実装は、実際にはリング構造でなく、メモリ移動を使った簡易実装となっています。
 *	  もしも今後、速度性能が問題となった場合は、実際にリング構造を使って再実装する予定です。
 *	  その際に、内部処理を変更しても、プログラムインターフェイスは変化しないはずです。
 *	* Thu Sep 15 23:00:00 JST 2005 Naoyuki Sawa
 *	- queue_space()、buffer_space()を追加しました。
 *	* Fri Sep 16 06:00:00 JST 2005 Naoyuki Sawa
 *	- read_queue()にて、packet=NULLが指定された場合に、読み出したパケットデータを破棄するようにしました。
 *	- read_buffer()にて、data=NULLが指定された場合に、読み出したデータを破棄するようにしました。
 *	- create_queue()にて、capacity引数“+sizeof(int)”のストレージを確保するように変更しました。
 *	  最大で、capacityバイトのパケットを一つ、キューに格納できるようにするためです。
 *	  これまでは、呼び出し側にてsizeof(int)を加算して、create_queue()を呼び出していました。
 *	- peek_queue()、peek_buffer()を追加しました。
 *	* Mon Oct 31 05:10:00 JST 2005 Naoyuki Sawa
 *	- shuffle()関数にて、seed引数を参照で受け取り、乱数シードを更新するよう変更しました。
 *	  これまでは、呼び出し側にて乱数シードを更新する必要がありましたが、今後は不要となります。
 *	  <変更前の使用例> shuffle(array, 10, sizeof(int), RND16(seed));
 *	  <変更後の使用例> shuffle(array, 10, sizeof(int), &seed);
 *	* Wed Nov 30 22:35:00 JST 2005 Naoyuki Sawa
 *	- Windowsヘッダファイルとの衝突回避を追加しました。
 *	  これまでは、clipmisc.hを使うWin32プロジェクトが、各々のextclip.hの中で個別に対策していました。
 *	- die()とtrace()をVisual C++でのコンパイルに対応し、実装をclipmisc.hからclipmisc.cへ移動しました。
 *	  これまでのWin32プロジェクトは、clipmisc.hのインクルードのみを行っていましたが、
 *	  今後は、clipmisc.cをプロジェクトに加えて、コンパイル・リンクするよう変更してください。
 *	- fpk_load()コンパイル時の、Visual C++の警告を抑制しました。
 *	- ファイルパック形式、オンメモリファイルパック形式は、利用頻度が低いので、
 *	  コードサイズ節約のために、実装をclipmisc.cからclipfpk.cへ分離しました。
 *	* Thu Dec 01 12:13:00 JST 2005 Naoyuki Sawa
 *	- ユーティリティ：マップを追加しました。
 *	* Thu Dec 02 04:53:00 JST 2005 Naoyuki Sawa
 *	- ユーティリティ：簡略版COMを追加しました。
 *	* Sun Dec 04 15:04:00 JST 2005 Naoyuki Sawa
 *	- query_interface_map()を追加しました。
 *	- safe_addref()、safe_release()、safe_assign()を追加しました。
 *	* Mon Dec 05 04:12:00 JST 2005 Naoyuki Sawa
 *	- safe_attach()、safe_detach()を追加しました。
 *	* Tue Dec 06 02:54:00 JST 2005 Naoyuki Sawa
 *	- Win32版die()に、__declspec(noreturn)の属性を追加しました。
 *	  この変更により、P/ECEとWin32のDIE()マクロを分けて定義する必要が無くなりました。
 *	* Wed Dec 07 04:39:00 JST 2005 Naoyuki Sawa
 *	- safe_query_interface()を追加しました。
 *	* Sat Dec 10 19:24:00 JST 2005 Naoyuki Sawa
 *	- safe_attach()の、(src)式の評価と、(dst)の参照カウント減少の順番を修正しました。
 *	* Sat Dec 10 22:58:00 JST 2005 Naoyuki Sawa
 *	- safe_addref(ptr)が、ptrを返すように変更しました。
 *	* Sun Dec 11 05:44:00 JST 2005 Naoyuki Sawa
 *	- unk_copy()、unk_delete()、unk_equals()を追加しました。
 *	* Sun Dec 11 20:47:00 JST 2005 Naoyuki Sawa
 *	- map_get()の仕様を変更し、値の複製を作って、戻り値とするようにしました。
 *	  これまでは、マップ要素が保持している値を、そのまま返していました。
 *	  このように変更した理由は、仕様の統一のためです。
 *	  特に、UNKNOWN_INTERFACEを値とするMAPにおいて、map_get()の特別扱いをしなくて済むようになりました。
 *	* Mon Dec 12 21:33:00 JST 2005 Naoyuki Sawa
 *	- safe_assign_interface()を追加しました。
 *	* Tue Dec 13 19:00:00 JST 2005 Naoyuki Sawa
 *	- reference_equals()を追加しました。
 *	* Tue Dec 20 05:00:00 JST 2005 Naoyuki Sawa
 *	- apply_interface_map()を追加しました。
 *	* Sun Dec 25 04:58:00 JST 2005 Naoyuki Sawa
 *	- map_remove()の仕様を変更し、削除した要素の値を返さず、自動的に削除するようにしました。
 *	  実際の利用において、削除した要素の値を使うことが少なく、自動的に削除される方が便利と判断したからです。
 *	  削除した要素の値が必要な場合は、あらかじめ、map_get()を用いて値を取得しておいてください。
 *	* Sun Dec 25 15:44:00 JST 2005 Naoyuki Sawa
 *	- map_clear()を追加しました。
 *	- ユーティリティ：可変長配列を追加しました。
 *	* Mon Dec 26 01:25:00 JST 2005 Naoyuki Sawa
 *	- コレクション関連の実装を、clipmisc.cからclipcoll.cへ分離しました。
 *	- インターフェイス関連の実装を、clipmisc.cからclipintf.cへ分離しました。
 *	* Fri Jan 06 21:27:00 JST 2006 Naoyuki Sawa
 *	- map_duplicate()、array_duplicate()を追加しました。
 *	* Wed Jan 18 19:00:00 JST 2006 Naoyuki Sawa
 *	- map_keys()を追加しました。
 *	* Mon Jan 30 08:44:00 JST 2006 Naoyuki Sawa
 *	- マクロの中で使っている変数名を、tmp→__tmp__に変更しました。
 *	  マクロの外で使っている変数名との衝突を避けるためです。
 *	* Fri Apr 14 21:09:00 JST 2006 Naoyuki Sawa
 *	- ARRAY_SIZE()の戻り値を(size_t)→(int)に変更しました。
 *	- これまでは、ARRAY_SIZE()の戻り値と(int)値の比較を行うと、符号無し比較が行われていました。
 *	  負値との比較を行う場合は、ARRAY_SIZE()の戻り値を明示的に(int)にキャストする必要がありました。
 *	    (変更前) if(i >      ARRAY_SIZE(array)) { ... } // iが-1の場合に、誤って「True」と判断されてしまう。
 *	    (変更前) if(i > (int)ARRAY_SIZE(array)) { ... } // 正しい判断のためには、明示的なキャストが必要だった。
 *	- 今回の変更により、ARRAY_SIZE()の戻り値は常に(int)になったので、利用側での明示的なキャストは不要になりました。
 *	    (変更後) if(i >      ARRAY_SIZE(array)) { ... } // iが-1の場合も、正しく「False」と判断します。
 *	* Sat Jun 17 05:11:45 JST 2006 Naoyuki Sawa
 *	- clipstd.hにてstddef.hのincludeを有効にしたので、offsetof()マクロが利用できるようになりました。
 *	  もう、FIELD_OFFSET()マクロは不要になったので、削除しました。
 *	  今後は、windows.h互換のFIELD_OFFSET()マクロではなく、ANSI標準のoffsetof()マクロを使ってください。
 *	* Thu Jul 06 12:09:17 JST 2006 Naoyuki Sawa
 *	- rnd32()、RND32()、rnd32_range()、RND32_RANGE()を追加しました。
 *	- shuffle()において、16bit乱数→32bit乱数を利用するよう変更しました。
 *	  この変更により、65536要素以上の配列をシャッフルできなかった制限が無くなりました。
 *	* Tue Nov 07 01:17:45 JST 2006 Naoyuki Sawa
 *	- map_empty()、array_empty()を追加しました。
 *	* Tue Nov 07 12:46:58 JST 2006 Naoyuki Sawa
 *	- ARRAY(可変長配列、array_*())をLIST(リスト、list_*())に変更しました。
 *	  プログラムの内容は変わらず、名前が変わっただけです。
 *	  これまでARRAYの処理内容はリストであったにもかかわらず、LIST_ENTRYとの名前衝突を避けるためにあえてARRAYと名付けていました。
 *	  しかし、やはり実態との一致を優先することにし、ARRAY_ENTRY構造体をLIST_NODEに改名して、LIST_ENTRYとの名前衝突を避けました。
 *	  この名前付けルールに合わせて、MAP_ENTRY構造体もMAP_NODEに改名しました。
 *	* Mon Dec 04 16:44:51 JST 2006 Naoyuki Sawa
 *	- ユーティリティ：プールを追加しました。
 *	* Wed Dec 06 03:36:51 JST 2006 Naoyuki Sawa
 *	- pool_free()から返却先プールの引数を不要としました。
 *	* Tue Jan 02 22:11:35 JST 2007 Naoyuki Sawa
 *	- プールに、参照カウント式ガーベージコレクションの機能を内包しました。
 *	* Sun Nov 04 14:59:39 JST 2007 Naoyuki Sawa
 *	- UPDOWN_MOTION()マクロを追加しました。
 *	* Tue Apr 01 12:10:19 JST 2008 Naoyuki Sawa
 *	- linux2.6 の include/linux/kernel.h を参考に、コンパイル時型検査のマクロを作成しました。
 *	* Sat Mar 14 21:13:42 JST 2009 Naoyuki Sawa
 *	- プールに、確保時コールバックと解放時コールバックを追加しました。
 *	* Thu Aug 13 17:02:32 JST 2009 Naoyuki Sawa
 *	- ユーティリティ：検索のセクションを追加しました。
 *	- quick_search()を追加しました。
 *	* Sat Jan 23 03:38:06 JST 2010 Naoyuki Sawa
 *	- match()を追加しました。
 *	* Wed Mar 17 01:31:08 JST 2010 Naoyuki Sawa
 *	- ユーティリティ：メルセンヌ・ツイスタ擬似乱数のセクションを追加しました。
 *	- MT_init()とMT_int32()を作成し、同時に、アセンブラ化しました。
 *	  オリジナル版のメルセンヌ・ツイスタ擬似乱数プログラムを元に、P/ECE用にアセンブラ化したものです。
 *	  また、元にしたオリジナル版プログラムを、keep/メルセンヌ・ツイスタ擬似乱数.7zに保存しました。
 *	  http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/mt.htmlのページから、ダウンロードしたものです。
 *	* Mon Oct 18 21:09:33 JST 2010 Naoyuki Sawa
 *	- ユーティリティ：ソートのセクションを追加しました。
 *	- msort()を追加しました。
 *	* Mon Jan 03 22:48:46 JST 2011 Naoyuki Sawa
 *	- match()→VERY_simple_RegEx_matching()に名前変更しました。
 *	* Tue Apr 19 17:31:57 JST 2011 Naoyuki Sawa
 *	- ユーティリティ：ユーティリティ：乱数生成アルゴリズムWELLのセクションを追加しました。
 *	- WELL_init()とWELL_next()を作成し、WELL_next()をアセンブラ化しました。
 *	- 乱数生成アルゴリズムWELLの資料を、keep/乱数生成アルゴリズムWELL.7zに保存しました。
 *	* Thu Aug 11 03:06:25 JST 2011 Naoyuki Sawa
 *	- BIT1_LOWEST_POSITION()、BIT1_SHIFT_TO_LSB()、BIT1_CONTINUATION_TEST()、BIT0_LOWEST_POSITION()、BIT0_SHIFT_TO_LSB()、BIT0_CONTINUATION_TEST()を追加しました。
 *	  BMPファイルのカラーマスクの操作等に利用できる、ビット演算マクロです。
 *	  利用頻度はあまり多くないと思いますが、マクロなので実行ファイルサイズに影響することは無いため、アルゴリズムの備忘録として定義しておくことにしました。
 *	* Sat Jan 14 00:03:29 JST 2012 Naoyuki Sawa
 *	- die2()とdie3()を追加しました。
 *	  die()の固定引数版で、die2()はDIEマクロで，die3()はASSERTマクロで使用します。
 *	  可変引数のdie()を使うよりも、固定引数のdie2()，die3()を使う方が、呼び出しコードが短くなります。
 *	  特にDIEマクロは使用箇所が多く、die2()とdie3()の増加分を相殺して、ライブラリ全体のコードサイズ節約に寄与します。
 *	- DIEマクロとASSERTマクロが、die()の代りに、die2()とdie3()を使用するように変更しました。
 *	* Thu Dec 06 17:08:54 JST 2012 Naoyuki Sawa
 *	- メルセンヌ・ツイスタ擬似乱数を、clipmt.hとclipmt.cへ分離しました。
 *	- 乱数生成アルゴリズムWELLを、clipwell.hとclipwell.cへ分離しました。
 *	* Sat Dec 08 22:01:35 JST 2012 Naoyuki Sawa
 *	- random_value_less_than_or_equal_to()とminimum_mask_greater_than_or_equal_to()を追加しました。
 *	* Sat Aug 24 00:14:18 JST 2013 Naoyuki Sawa
 *	- GCC拡張機能「__FUNCTION__」と「__PRETTY_FUNCTION__」を利用して、関数名と行番号を表示してエラー停止するマクロを作成しました。
 *	* Sun Sep 15 20:37:35 JST 2013 Naoyuki Sawa
 *	- min/maxマクロを追加しました。
 *	* Sat Feb 01 01:00:50 JST 2014 Naoyuki Sawa
 *	- 引数を文字列化するマクロPRESCAN_STRINGIFYを追加しました。
 *	* Wed Apr 09 00:15:54 JST 2014 Naoyuki Sawa
 *	- 2進数リテラルを定義するマクロ BIN8()、BIN16()、BIN32() を追加しました。
 *	* Tue Apr 15 19:07:53 JST 2014 Naoyuki Sawa
 *	- 変数の符号無し最大値,符号付き最大値,又は,最小値を求めるマクロ UVAR_MAX(),VAR_MAX(),VAR_MIN() を追加しました。
 *	- 変数の最大値,又は,最小値へ飽和する飽和加減算マクロ UVAR_ADD(),VAR_ADD(),UVAR_SUB(),VAR_SUB(),UVAR_INC(x),VAR_INC(x),UVAR_DEC(x),VAR_DEC(x) を追加しました。
 *	* Wed Apr 16 00:15:22 JST 2014 Naoyuki Sawa
 *	- GCC拡張機能を利用して、符号付きか符号無しかを自動的に判定するバージョンを追加しました。
 *	* Wed May 21 15:29:53 JST 2014 Naoyuki Sawa
 *	- 構造体メンバのサイズを返すマクロFIELD_SIZEOF()を追加しました。
 *	* Fri Oct 03 20:36:20 JST 2014 Naoyuki Sawa
 *	- ユーティリティ：文字列操作のセクションを追加しました。
 *	- strtrim()を追加しました。
 *	* Sat Oct 04 21:40:12 JST 2014 Naoyuki Sawa
 *	- strescape(),strcompress()を追加しました。
 *	* Sat Oct 11 12:29:17 JST 2014 Naoyuki Sawa
 *	- strtrim(),strescape(),strcompress()を、clipmisc.h,cからclipstr.h,cへ移動しました。今後は「ユーティリティ：文字列操作」はclipstr.h,cに追加してください。
 *	* Wed Dec 10 00:39:11 JST 2014 Naoyuki Sawa
 *	- die()が使用するフォントを切り替えられるようにしました。
 *	  詳細は、clip.mkの'Wed Dec 10 00:39:11 JST 2014'のコメントを参照してください。
 *	* Tue Dec 23 21:05:49 JST 2014 Naoyuki Sawa
 *	- Asm版die()を2命令節約しました。_diefontは0～2なのでxld.wでなくld.wで充分でした。
 *	* Tue Jan 06 21:26:41 JST 2015 Naoyuki Sawa
 *	- 乱数関連の宣言と実装を、clipmisc.*⇒cliprnd.*へ分離しました。
 *	  使用頻度は高いので、無駄なリンクを防ぐためと言うよりも、モジュール分けして分り易くするためです。
 *	- 「ユーティリティ：任意長パケットキュー」を、clipmisc.*⇒clipque.*へ分離しました。
 *	  使用頻度が低いので、無駄にリンクして容量が増加する事を防ぐためです。
 *	- 「ユーティリティ：リングバッファ」を、clipmisc.*⇒clipbuf.*へ分離しました。
 *	  使用頻度が低いので、無駄にリンクして容量が増加する事を防ぐためです。
 *	- 「ユーティリティ：ダブルリンクリスト」を、clipmisc.*⇒clipdlst.*へ分離しました。
 *	  使用頻度は高いので、無駄なリンクを防ぐためと言うよりも、モジュール分けして分り易くするためです。
 *	- 「ユーティリティ：検索」を、clipmisc.*⇒clipmatc.*へ分離しました。
 *	  使用頻度が低いので、無駄にリンクして容量が増加する事を防ぐためです。
 *	- 「ユーティリティ：ソート」の宣言を、clipmisc.hからclipsort.hへ分離しました。
 *	  「ユーティリティ：ソート」の実装は既に、clipsort.cで行っていたので、今回分離したのは宣言のみです。
 *	  宣言も分離することにした理由は、宣言と実装のファイルの対応付けを、分り易くするためです。
 *	- コレクション関連の宣言を、clipmisc.hからclipcoll.hへ分離しました。
 *	  コレクション関連の実装は既に、clipmisc.cからclipcoll.cへ分離してあったので、今回分離したのは宣言のみです。
 *	  宣言も分離することにした理由は、宣言と実装のファイルの対応付けを、分り易くするためです。
 *	- インターフェイス関連の宣言を、clipmisc.hからclipintf.hへ分離しました。
 *	  インターフェイス関連の実装は既に、clipmisc.cからclipintf.cへ分離してあったので、今回分離したのは宣言のみです。
 *	  宣言も分離することにした理由は、宣言と実装のファイルの対応付けを、分り易くするためです。
 *	- ファイルパック形式関連の宣言を、clipmisc.hからclipfpk.hへ分離しました。
 *	  ファイルパック形式関連の実装は既に、clipmisc.cからclipfpk.cへ分離してあったので、今回分離したのは宣言のみです。
 *	  宣言も分離することにした理由は、宣言と実装のファイルの対応付けを、分り易くするためです。
 *	* Wed Jan 07 21:18:08 JST 2015 Naoyuki Sawa
 *	- strcasecmp(),strncasecmp()の実装をclippce.c⇒cliplibc.cへ移動したことに伴い、
 *	  今後はWindowsプログラムにもcliplibc.cを含めてstrcasecmp(),strncasecmp()を利用できるので、stricmp(),strnicmp()への置き換えを廃止しました。
 *	* Tue Nov 17 21:10:26 JST 2015 Naoyuki Sawa
 *	- ENTER_CS,LEAVE_CSの定義をclippce.h⇒clipmisc.hへ移動しました。
 *	  clipmisc.hにVC++6.0プロジェクト用のENTER_CS,LEAVE_CSの定義を追加した事に伴い、P/ECE用のENTER_CS,LEAVE_CSもclipmisc.hの同じ場所で定義する方が管理し易いと思うからです。
 *	- VC++6.0プロジェクト用のENTER_CS,LEAVE_CSの定義を追加しました。
 *	* Wed Nov 18 21:37:53 JST 2015 Naoyuki Sawa
 *	- 'extern "C" {'～'}'で囲みました。.cppを含むWin32プロジェクトからもインクルード出来るようにするためです。
 *	* Sun Nov 22 21:02:41 JST 2015 Naoyuki Sawa
 *	- parse_cmdline()を追加しました。
 *	- 環境変数'プログラム名_OPTION'で指定されたオプション(有れば)を、コマンドライン引数にマージするようにしました。
 *	* Fri Jan 29 00:03:39 JST 2016 Naoyuki Sawa
 *	- min/maxマクロを変更しました。
 *	  異なる型に対してmin/maxマクロを使った場合、コンパイラが警告を出すようにしました。
 *	- clampマクロを追加しました。
 *	  min/maxマクロに依存しており、Visual C++では引数を二回評価する副作用が有る事に注意して下さい。
 *	  GCCならば安全です。
 *	- 上記二点は、Linuxのkernel.hを参考にしました。
 *	  (http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/linux/kernel.h)
 *	* Sat Feb 27 21:21:24 JST 2016 Naoyuki Sawa
 *	- FastCurv()とSlowCurv()を追加しました。
 *	  ゲームのエフェクト等で度々使う計算式なので、これまでは都度アプリケーション内に書いていましたが、今回当モジュール内でマクロ定義する事にしました。
 *	* Fri Apr 01 21:48:44 JST 2016 Naoyuki Sawa
 *	- ARRAY_SIZE()の引数に、誤ってポインタを渡した時に、コンパイルエラーとして検出出来るようにしました。
 *	  ただし、常に検出できる訳ではありません。詳細は、下記の例を参照して下さい。
 *	- ちなみに、Microsoftの最近のコンパイラ(Visual C++ 2015 等)では、_countof()というマクロが追加されており、ARRAY_SIZE()の代わりに_countof()を使う事も可能です。
 *	  ただし、_countof()の引数にポインタを渡した場合、C++ソースならばコンパイルエラーとして検出出来きますが、Cソースの場合は検出出来ずに間違った結果を生成します。
 *	  その点、今回変更したARRAY_SIZE()ならば、Cソースでも(常にではありませんが)コンパイルエラーとして検出出来るので、VC++でもARRAY_SIZE()を使う方が良いと思います。
 *	* Sat Apr 02 21:00:43 JST 2016 Naoyuki Sawa
 *	- ARRAY_SIZE()マクロを再度修正しました。
 *	  ARRAY_SIZE()マクロ定義個所の'Sat Apr 02 21:00:43 JST 2016 Naoyuki Sawa'のコメントを参照して下さい。
 *	* Sat Apr 02 23:34:06 JST 2016 Naoyuki Sawa
 *	- ARRAY_SIZE()マクロを再々度修正しました。
 *	  ARRAY_SIZE()マクロ定義個所の'Sat Apr 02 23:34:06 JST 2016 Naoyuki Sawa'のコメントを参照して下さい。
 *	* Fri Apr 15 21:07:28 JST 2016 Naoyuki Sawa
 *	- vdie()を追加しました。
 *	- P/ECE版の実装は、既存のdie()はそのままにして、新しくvdie()を追加しました。
 *	  P/ECE版の既存のdie()は、P/ECE APIのpceFontPrintf()を使用しているので、die()とvdie()に分割する事は出来ないからです。
 *	- P/ECE版の実装は、dief()と同様に、_def_vbuff[]の下端80～87ラインに、書式付き文字列を展開します。
 *	  詳細は、clipflt1.cの、dief()のコメントを参照して下さい。
 *	- Windows版の実装は、既存のdie()を、die()とvdie()に分割し、die()からvdie()を呼び出すように変更しました。
 *	  既存のdie()を利用しているアプリケーションの観点からは、die()の動作は変わっていないので、アプリケーションの変更は不要です。
 *	* Fri Apr 15 23:25:13 JST 2016 Naoyuki Sawa
 *	- Windows版のvdie()の動作を少し変更しました。
 *	  これまでは、常に、エラーメッセージをコンソールに出力していました。
 *	  変更後は、標準エラー出力がコンソールならば、これまで通りエラーメッセージをコンソールに出力しますが、
 *	  標準エラー出力がコンソールでなければ、エラーメッセージをメッセージボックスで表示するようにしました。
 *	- 標準エラー出力がコンソールでないケースとしては、以下のようなケースが考えられる。
 *	  ①明示的に標準エラー出力をファイル等へリダイレクトして実行した場合
 *	  ②VC++のアプリケーションの設定で、ウインドウアプリケーションとしてビルドした場合
 *	  ③VC++のアプリケーションの設定はコンソールアプリケーションだが、の中で'#pragma comment(linker, "/SUBSYSTEM:WINDOWS /ENTRY:mainCRTStartup")'を指定した場合
 *	  等が考えられる。
 *	  今回この対応を行った理由は、主に、②③のケースでもデバッグし易いようにするためです。
 *	* Sun May 29 21:54:56 JST 2016 Naoyuki Sawa
 *	- Visual C++ .NETで、main()が呼び出される前にプロセスが終了してしまう問題を修正しました。
 *	  詳細は、cliplibc.cの同日のコメントを参照して下さい。
 *	* Mon Jun 13 21:45:44 JST 2016 Naoyuki Sawa
 *	- P/ECE環境のENTER_CS,LEAVE_CSマクロのコードサイズを削減しました。
 *	  変更前は、直接pceSyncEnterCriticalSection(),pceSyncLeaveCriticalSection()APIを呼び出していましたが、変更後は、新たに作成したEnterCS(),LeaveCS()を経由するように変更しました。
 *	  そうした理由は、pceSyncEnterCriticalSection(),pceSyncLeaveCriticalSection()はスタックを介して値を受け渡しするので、必ずスタック操作が入ってしまっていたからです。
 *	  EnterCS(),LeaveCS()は、値返し,値渡しで値を受け渡すので、コンパイラは必要に応じてそれらの値をスタックでなくレジスタに保持する事が出来、コードサイズが削減出来ます。
 *	  CRITICAL_SECTIONは、P/ECE環境ではunsigned longなので、値返し,値渡しして、(可能ならば)レジスタに保持する方が効率が良いからです。
 *	  既に、ENTER_IL,LEAVE_ILマクロはそのような構造()になっているので、今回、ENTER_CS,LEAVE_CSマクロも同様の構造にして、コードサイズを節約する事にしました。
 *	- コードサイズの節約効果は、test.pce雛形プロジェクトをそのまま多数のモジュールを組み込んだ状態でビルドした場合の比較で、全体で72バイトの節約でした。
 *	  元々、ENTER_CS,LEAVE_CSマクロを使用している箇所はさほど多くは無いので、効果はさほど大きくは有りませんが、一応、コードサイズ削減にはなりました。
 *	- コードサイズ節約効果の他に、EnterCS(),LeaveCS()が値返しで有る事で、アセンブラコードからも呼び出し易くなったと思います。
 *	  今後、アセンブラコードの中で、ENTER_CS,LEAVE_CSの処理を行う必要が有る場合は、EnterCS(),LeaveCS()関数を呼び出して下さい。
 *	  これまで通りpceSyncEnterCriticalSection(),pceSyncLeaveCriticalSection()APIを使っても構いませんが、大抵の場合EnterCS(),LeaveCS()関数を使う方がコードサイズの節約になると思います。
 *	* Tue Aug 16 21:54:11 JST 2016 Naoyuki Sawa
 *	- エラー停止処理とトレース出力処理を、clipmisc.h,clipmisc.cから、clipdie.h,clipdie.cへ分離しました。
 *	* Tue Aug 16 22:54:46 JST 2016 Naoyuki Sawa
 *	- merge_env_option()が確実に実行されるように、「#pragma comment(linker, "/INCLUDE:_pmerge_env_option")」を追加しました。
 *	  具体的には、clipmisc.c内のpmerge_env_option変数をローカル変数からグローバル変数に変更し、その変数がアプリケーションに常にリンクされるように、clipmisc.h内に上記のプラグマを追加しました。
 *	  そうした理由は、以下の通りです。
 *	- 本日、エラー停止処理とトレース出力処理を、clipmisc.h,clipmisc.cから、clipdie.h,clipdie.cへ分離した事に伴い、当モジュールで定義されるグローバルシンボルが大分少なくなりました。
 *	  これまでは、当モジュールがdie()等の必ず参照されるグローバルシンボルを含んでいたので、当モジュールは必ずリンクされ、merge_env_option()もまず確実に呼び出されていたのですが、
 *	  本日の変更によって、die()等が別モジュールへ移動し、当モジュールで定義されるグローバルシンボルをアプリケーションが(直接,又は,間接的に)参照するか、やや心配になって来ました。
 *	  実験したところ、本日時点のモジュール構成で、最小限のアプリケーションでも、当モジュールはリンクされ、merge_env_option()は呼び出されるようです。(EnterCS等が参照されているためかと思います)
 *	  とは言え、偶然に依存するのも心許無いので、今のうちに、merge_env_option()が確実に実行されるようにしておく事にしました。
 *	  その方法としては、pmerge_env_optionを明示的に参照する事によって、merge_env_option()が確実に実行されるようにしました。
 *	  pmerge_env_optionを明示的に参照する方法は、下記のプラグマを利用しました。
 *	  □「MSDN ライブラリ Microsoft Visual Studio 6.0 - comment」より:
 *	  │linker
 *	  │オブジェクトファイルにリンカオプションを記録します。
 *	  │このコメント型を使うと、[プロジェクト設定]ダイアログボックスの[リンク]タブでオプションを指定する代わりにリンカオプションを指定できます。
 *	  │たとえば、次のように/includeオプションを指定して、強制的にシンボルを取り込むことができます。
 *	  │#pragma comment(linker, "/include:__mySymbol")
 *	- 「#pragma comment(linker, "/INCLUDE:pmerge_env_option")」ではなく、「#pragma comment(linker, "/INCLUDE:_pmerge_env_option")」とする必要が有る事に注意して下さい。
 *	  変数pmerge3_env_optionはCリンケージなので、リンカのシンボル名としては先頭に「_」が一つ付与されるからです。
 *	  例えば上のMSDN ライブラリの例の場合、元の変数名は「_mySymbol」で、シンボル名としては「_」を一つ付与して「__mySymbol」になったのだろうと推測されます。
 *	* Wed Aug 17 21:19:23 JST 2016 Naoyuki Sawa
 *	- Windows用のARRAY_SIZE()マクロを修正しました。
 *	  ARRAY_SIZE()マクロ定義個所の'Wed Aug 17 21:19:23 JST 2016 Naoyuki Sawa'のコメントを参照して下さい。
 *	* Sat Sep 03 14:13:50 JST 2016 Naoyuki Sawa
 *	- CONTAINING_RECORD()が、(int)でアドレス演算を行っていたのを、(char*)で行うように修正しました。
 *	  64ビット対応のための準備ですが、32ビットでも(char*)で行う方が本当は正しいからです。
 *	  とは言え、32ビットではどちらでも同じ結果になるので、既存の32ビットコードには影響有りません。
 *	* Wed Sep 07 21:52:10 JST 2016 Naoyuki Sawa
 *	- 64ビット版では、「#pragma comment(linker, "/INCLUDE:_pmerge_env_option")」を「#pragma comment(linker, "/INCLUDE:pmerge_env_option")」に変更しました。
 *	  関数シンボルならば、32ビットは__stdcall('_'が付く)がデフォルトで、64ビットは__fastcall('_'が付かない)がデフォルトという違いで理解出来るのですが、変数も同様の違いが生じる理由が、まだ理解出来ていません。
 *	  実際に試してみて、こうしないとリンクエラーになるので、こうしました。
 *	  しかし、上記の理由をきちんと理解するためには、要調査です。(※TODO:)
 *	* Thu Sep 08 22:20:43 JST 2016 Naoyuki Sawa
 *	- init_cs()が確実に実行されるように、「#pragma comment(linker, "/INCLUDE:_pinit_cs")」及び「#pragma comment(linker, "/INCLUDE:pinit_cs")」を追加しました。
 *	  詳細は、cliplibc.h の同日のコメントを参照して下さい。
 *	* Tue Sep 27 21:08:22 JST 2016 Naoyuki Sawa
 *	- BIN8()等をC++ソース内で使用した時に、「warning C4804:'/':演算中の'bool'型の使用方法が安全ではありません」が出る問題を修正しました。
 *	  修正方法は、!!,及び,!演算子の結果を、明示的に(int)にキャストした事です。
 *	  この修正は、C++ソースに限らずCソース内で使用する場合にも適用しても構わないのですが、敢えてC++ソースの場合だけ適用する事にしました。
 *	  Cソース内では上記の警告は出ない事と、これまでCソースでは2年間以上問題無く動作していたので極力変更の影響範囲を少なくしたいからです。
 *	- VS2015では、CソースでもC++ソースでも、BIN8()の引数に8桁を超える値を指定した時の、エラー検出が働かない事に気付きました。
 *	  VC++6.0ならば、CソースでもC++ソースでもちゃんと「error C2124:除算、剰余演算が0で行われています。」というエラーになるので、VS2015のバグのような気がします。
 *	  試してみたところ、VS2015は「int x = 1|(0/0);」という式を、エラー無く通してしまうのが原因のようです。
 *	  式をいろいろ変えてみたのですが、どうやってもVS2015で上記のエラーを検出する事が出来なかったので、この点はこのままとする事にしました。
 *	  引数が正しければ問題無いので、正しいプログラムには支障無いはずです。
 *	* Sun Jan 15 09:21:07 JST 2017 Naoyuki Sawa
 *	- XCHG()マクロの、gcc拡張機能を使わないバージョンも定義しました。
 *	* Sun Mar 19 22:19:43 JST 2017 Naoyuki Sawa
 *	- 「Direct3D互換のD3DCOLOR形式マクロ」をDxlibHelper.h⇒clipmisc.hへ移動しました。
 *	  clipsprf.cモジュールでこれらのマクロを使用するようになったので、Windows環境に限らずP/ECE環境でもこれらのマクロが必要になったからです。
 *	  実際の所、P/ECE環境でこれらのマクロを使用している関数(SprFnt_PrintXF_subr())を呼び出すとは思えないのですが、ソースの共通化のためだけに必要になっています。
 *	* Tue Mar 21 21:23:37 JST 2017 Naoyuki Sawa
 *	- D3DRGB()マクロでD3DCOLOR値を作成した場合、α成分が1.0になるように修正しました。
 *	  これまでは間違って、D3DRGB()マクロでD3DCOLOR値を作成した場合、α成分を0.0にしてしまっていました。
 *	  なぜこれまでは間違っていたかと言うと、RGB_MAKE()でRGB値を作成した場合はα成分が0.0になるので、D3DRGB()も同様だろうと思い込んでしまっていたからです。
 *	  しかし実際には、D3DRGB()でD3DCOLOR値を作成した場合は、α成分が1.0になるというのが、本物のDirect3Dのヘッダファイルで定義されているマクロの仕様でした。
 *	  直観的にも、D3DRGB()でD3DCOLOR値を作成した場合も、α成分が1.0になるのが自然だと思うし、既存のプログラムへの影響も無さそうなので、本日、修正しました。
 *	  これまでは、透明度を意識しないプログラムでも、α成分を1.0にするためだけに'D3DRGBA(r,g,b,1)'等と書いていたのですが、今後は'D3DRGB(r,g,b)'と書けます。
 *	- D3DRGB()でD3DCOLOR値を作成した場合はα成分が1.0になるが、RGB_MAKE()でRGB値を作成した場合はα成分が0.0になるという点に注意して下さい。
 *	  なぜそんな仕様になっているのか不思議なのですが、これが本物のDirect3Dのヘッダファイルで定義されているマクロの仕様です。
 *	  推測ですが、Direct3Dの意図としては、D3DRGBA()とD3DRGB()で作成するのはα成分に意味の有るD3DCOLOR形式であり、RGBA_MAKE()で作成するのもα成分に意味のあるRGBA形式、RGB_MAKE()で作成するのはα成分を0固定とするRGB形式、という概念のなのではないかと思います。
 *	  実際の所はどれも整数値なので、あまり意識して使い分ける事は無いのですが…(と言うか、α成分が0固定でなければいけない場面があまり無いので…)
 */
#ifndef __CLIP_MISC_H__
#define __CLIP_MISC_H__

#ifdef  __cplusplus
extern "C" {
#endif//__cplusplus

/*****************************************************************************
 *	Windowsヘッダファイルとの衝突回避
 *****************************************************************************/

#ifdef WIN32

#undef HIBYTE
#undef LOBYTE

//#undef FIELD_OFFSET → 2006/06/17 FIELD_OFFSET()の定義を削除したので、もう、windows.hとの衝突回避は不要になりました。
#undef CONTAINING_RECORD

//{{2015/01/06削除:「ユーティリティ：ダブルリンクリスト」を、clipmisc.*⇒clipdlst.*へ分離しました。
//#define _LIST_ENTRY _xLIST_ENTRY
//#define  LIST_ENTRY  xLIST_ENTRY
//}}2015/01/06削除:「ユーティリティ：ダブルリンクリスト」を、clipmisc.*⇒clipdlst.*へ分離しました。

//{{2015/01/07削除:strcasecmp(),strncasecmp()の実装をclippce.c⇒cliplibc.cへ移動したことに伴い、今後はWindowsプログラムにもcliplibc.cを含めてstrcasecmp(),strncasecmp()を利用できるので、stricmp(),strnicmp()への置き換えを廃止しました。
//#define strcasecmp  stricmp
//#define strncasecmp strnicmp
//}}2015/01/07削除:strcasecmp(),strncasecmp()の実装をclippce.c⇒cliplibc.cへ移動したことに伴い、今後はWindowsプログラムにもcliplibc.cを含めてstrcasecmp(),strncasecmp()を利用できるので、stricmp(),strnicmp()への置き換えを廃止しました。

#endif /*WIN32*/

/*****************************************************************************
 *	汎用マクロ・関数
 *****************************************************************************/

//{{2015/11/17追加:ENTER_CS,LEAVE_CSの定義をclippce.h⇒clipmisc.hへ移動しました。
#ifdef  PIECE
/* /usr/PIECE/sysdev/pcekn/pcekn.hより宣言のみコピー。
 * 実体はpceapi.libに含まれているので、ユーザーアプリケーションからも利用できます。
 * [使い方]
 *	ENTER_CS; // “__cs__ = PSR; PSR(IE) = 0;”に相当
 *	// 割り込み禁止が必要な処理を行う
 *	LEAVE_CS; // “PSR = __cs__;”に相当
 */
typedef unsigned long CRITICAL_SECTION;
void pceSyncEnterCriticalSection(CRITICAL_SECTION* pcs); /* 割り込み許可状態を保存→割り込み禁止 */
void pceSyncLeaveCriticalSection(CRITICAL_SECTION* pcs); /* 割り込み許可状態を復元 */
//{{2016/06/13変更:P/ECE環境のENTER_CS,LEAVE_CSマクロのコードサイズを削減しました。
//#define ENTER_CS do { CRITICAL_SECTION __cs__; pceSyncEnterCriticalSection(&__cs__)
//#define LEAVE_CS pceSyncLeaveCriticalSection(&__cs__); } while(0)
//↓2016/06/13変更:P/ECE環境のENTER_CS,LEAVE_CSマクロのコードサイズを削減しました。
// * Mon Jun 13 21:45:44 JST 2016 Naoyuki Sawa
// - P/ECE環境のENTER_CS,LEAVE_CSマクロのコードサイズを削減しました。
//   変更前は、直接pceSyncEnterCriticalSection(),pceSyncLeaveCriticalSection()APIを呼び出していましたが、変更後は、新たに作成したEnterCS(),LeaveCS()を経由するように変更しました。
//   そうした理由は、pceSyncEnterCriticalSection(),pceSyncLeaveCriticalSection()はスタックを介して値を受け渡しするので、必ずスタック操作が入ってしまっていたからです。
//   EnterCS(),LeaveCS()は、値返し,値渡しで値を受け渡すので、コンパイラは必要に応じてそれらの値をスタックでなくレジスタに保持する事が出来、コードサイズが削減出来ます。
//   CRITICAL_SECTIONは、P/ECE環境ではunsigned longなので、値返し,値渡しして、(可能ならば)レジスタに保持する方が効率が良いからです。
//   既に、ENTER_IL,LEAVE_ILマクロはそのような構造()になっているので、今回、ENTER_CS,LEAVE_CSマクロも同様の構造にして、コードサイズを節約する事にしました。
// - コードサイズの節約効果は、test.pce雛形プロジェクトをそのまま多数のモジュールを組み込んだ状態でビルドした場合の比較で、全体で72バイトの節約でした。
//   元々、ENTER_CS,LEAVE_CSマクロを使用している箇所はさほど多くは無いので、効果はさほど大きくは有りませんが、一応、コードサイズ削減にはなりました。
// - コードサイズ節約効果の他に、EnterCS(),LeaveCS()が値返しで有る事で、アセンブラコードからも呼び出し易くなったと思います。
//   今後、アセンブラコードの中で、ENTER_CS,LEAVE_CSの処理を行う必要が有る場合は、EnterCS(),LeaveCS()関数を呼び出して下さい。
//   これまで通りpceSyncEnterCriticalSection(),pceSyncLeaveCriticalSection()APIを使っても構いませんが、大抵の場合EnterCS(),LeaveCS()関数を使う方がコードサイズの節約になると思います。
CRITICAL_SECTION EnterCS();
void LeaveCS(CRITICAL_SECTION cs);
#define ENTER_CS do { CRITICAL_SECTION __cs__ = EnterCS()
#define LEAVE_CS LeaveCS(__cs__); } while(0)
//}}2016/06/13変更:P/ECE環境のENTER_CS,LEAVE_CSマクロのコードサイズを削減しました。
#endif//PIECE
//}}2015/11/17追加:ENTER_CS,LEAVE_CSの定義をclippce.h⇒clipmisc.hへ移動しました。
//{{2015/11/17追加:VC++6.0プロジェクト用のENTER_CS,LEAVE_CSの定義を追加しました。
#ifdef  _MSC_VER
extern CRITICAL_SECTION __cs__;//clipmisc.cのinit_cs()にて、main()が呼び出される前に初期化される。
#define ENTER_CS do { EnterCriticalSection(&__cs__)
#define LEAVE_CS LeaveCriticalSection(&__cs__); } while(0)
//{{2016/09/08追加:init_cs()が確実に実行されるように、「#pragma comment(linker, "/INCLUDE:_pinit_cs")」及び「#pragma comment(linker, "/INCLUDE:pinit_cs")」を追加しました。
#ifndef _WIN64
#pragma comment(linker, "/INCLUDE:_pinit_cs")	//32ビットでは、シンボル名の先頭に'_'が付きます。
#else //_WIN64
#pragma comment(linker, "/INCLUDE:pinit_cs")	//64ビットでは、シンボル名の先頭に'_'が付きません。
#endif//_WIN64
//}}2016/09/08追加:init_cs()が確実に実行されるように、「#pragma comment(linker, "/INCLUDE:_pinit_cs")」及び「#pragma comment(linker, "/INCLUDE:pinit_cs")」を追加しました。
#endif//_MSC_VER
//}}2015/11/17追加:VC++6.0プロジェクト用のENTER_CS,LEAVE_CSの定義を追加しました。

/* * Tue Apr 01 12:10:19 JST 2008 Naoyuki Sawa
 * - linux2.6 の include/linux/kernel.h を参考に、コンパイル時型検査のマクロを作成しました。
 *   typecheck()は常に1と評価されるので、タイプセーフなマクロからの利用が容易です。
 *   <例> #define less_than(a,b) (typecheck(fixed,a)&&typecheck(fixed,b)&&(int)(a)<(int)(b))
 * - Check at compile time that something is of a particular type.
 *   Always evaluates to 1 so you may use it easily in comparisons.
 */
#ifdef  __GNUC__
#define typecheck(type, x) ({			\
	type      __dummy1__;			\
	typeof(x) __dummy2__;			\
	(void)(&__dummy1__ == &__dummy2__);	\
	1; })
#endif//__GNUC__

//{{2016/08/16削除:エラー停止処理とトレース出力処理を、clipmisc.h,clipmisc.cから、clipdie.h,clipdie.cへ分離しました。
////{{2012/01/14:変更
////#define DIE()		die(__FILE__ "(%d)", __LINE__)
////↓2012/01/14:変更
//#define DIE()		die2(__FILE__, __LINE__)
////}}2012/01/14:変更
//
///* * Sat Aug 24 00:14:18 JST 2013 Naoyuki Sawa
// * - GCC拡張機能「__FUNCTION__」と「__PRETTY_FUNCTION__」を利用して、関数名と行番号を表示してエラー停止するマクロを作成しました。
// *   C言語においては、「__FUNCTION__」と「__PRETTY_FUNCTION__」は同一なので、下記「DIEFN()」と「DIEPF()」は同じ結果が得られます。
// * - 作成しては見たものの、多分、実際にこれらを利用することは無いと思います。なぜならば、既存の「DIE()」に比べて、「DIEFN()」と「DIEPF()」は以下の欠点があるからです：
// *   ・DIE()よりも、却ってエラー箇所を特定しづらくなる場合があります。複数のファイルに同じ名前のローカル関数があった場合に、同じエラーメッセージが生成される可能性があるからです。
// *   ・DIE()よりも、コードサイズが大きくなります。同一ファイル内で複数回使用した時に、DIE()ならばファイル名を共有できますが、DIEFN()は個々に関数名を展開するからです。
// *   ・VisualC++ 6.0では使用できません。新しいVisualC++ならばC99標準の__func__を使って作成できそうですが、自分はVisualC++ 6.0使いなので考慮していません。
// * - そんなわけで、DIEFN()とDIEPF()を実際に利用することは無いと思います。
// *   今回、DIEFN()とDIEPF()を作成した理由は、P/ECE開発環境のgcc33でも、__FUNCTION__や__PRETTY_FUNCTION__が利用できることの確認と、備忘録代わりです。
// */
//#ifdef  __GNUC__
//#define DIEFN()		die2(__FUNCTION__, __LINE__)
//#define DIEPF()		die2(__PRETTY_FUNCTION__, __LINE__)
//#endif/*__GNUC__*/
//
//#ifdef DEBUG
////{{2012/01/14:変更
////#define ASSERT(f)	((void)((f) || (die(__FILE__ "(%d): %s", __LINE__, #f), 0)))
////↓2012/01/14:変更
//#define ASSERT(f)	((void)((f) || (die3(__FILE__, __LINE__, #f), 0)))
////}}2012/01/14:変更
//#define VERIFY(f)	ASSERT(f)
//#else /*DEBUG*/
//#define ASSERT(f)	((void)0)
//#define VERIFY(f)	((void)(f))
//#endif /*DEBUG*/
//}}2016/08/16削除:エラー停止処理とトレース出力処理を、clipmisc.h,clipmisc.cから、clipdie.h,clipdie.cへ分離しました。

/* ビット操作 */
#define BTST(a, b)	(((char*)(a))[(b) / 8] &    1 << ((b) & 7) )
#define BCLR(a, b)	(((char*)(a))[(b) / 8] &= ~(1 << ((b) & 7)))
#define BSET(a, b)	(((char*)(a))[(b) / 8] |=   1 << ((b) & 7) )
#define BNOT(a, b)	(((char*)(a))[(b) / 8] ^=   1 << ((b) & 7) )

/* 16ビット整数値のバイトスワップ */
#define SWAPH(a) \
	(((a) >> 8 & 0x00ff) | \
	 ((a) << 8 & 0xff00))
/* 32ビット整数値のバイトスワップ */
#define SWAPW(a) \
	(((a) >> 24 & 0x000000ff) | \
	 ((a) >>  8 & 0x0000ff00) | \
	 ((a) <<  8 & 0x00ff0000) | \
	 ((a) << 24 & 0xff000000))

/* 任意の型の二つの変数を入れ替えます。(gcc拡張機能を使っているので、VC++では使えません。) */	//{{2017/01/15コメント追記:XCHG()マクロの、gcc拡張機能を使わないバージョンも定義しました。}}
#ifdef  __GNUC__
    //gcc拡張機能を使うバージョン
    #define XCHG(a, b) do {	\
	typeof(a) __a__ = (a);	\
	typeof(b) __b__ = (b);	\
	(a) = __b__;		\
	(b) = __a__;		\
    } while(0)
#else //__GNUC__
    //gcc拡張機能を使わないバージョン
    #define XCHG(a, b) do {	\
	static_assert(sizeof(a) == sizeof(b), "XCHG()マクロの引数が不正です。");	\
	unsigned char __a__[sizeof(a)];	\
	memcpy(__a__, &(a), sizeof(a));	\
	memcpy(&(a),  &(b), sizeof(a));	\
	memcpy(&(b), __a__, sizeof(a));	\
    } while(0);
#endif//__GNUC__

/* GET_LEBYTE()/GET_LEHALF()/GET_LEWORD()/GET_BEBYTE()/GET_BEHALF()/GET_BEWORD()の省略記法 */
#define LEBYTE(p)	GET_LEBYTE(p)
#define LEHALF(p)	GET_LEHALF(p)
#define LEWORD(p)	GET_LEWORD(p)
#define BEBYTE(p)	GET_BEBYTE(p)
#define BEHALF(p)	GET_BEHALF(p)
#define BEWORD(p)	GET_BEWORD(p)

/* リトルエンディアンのバイトオーダーでバイト値、ハーフワード値、ワード値を読み出します。
 * ポインタpはハーフワード境界やワード境界に整列されていなくても構いません。
 */
#define GET_LEBYTE(p)	((unsigned char )(((unsigned char*)(p))[0]<< 0))
#define GET_LEHALF(p)	((unsigned short)(((unsigned char*)(p))[0]<< 0|((unsigned char*)(p))[1]<< 8))
#define GET_LEWORD(p)	((unsigned int  )(((unsigned char*)(p))[0]<< 0|((unsigned char*)(p))[1]<< 8|((unsigned char*)(p))[2]<<16|((unsigned char*)(p))[3]<<24))

/* ビッグエンディアンのバイトオーダーでバイト値、ハーフワード値、ワード値を読み出します。
 * ポインタpはハーフワード境界やワード境界に整列されていなくても構いません。
 */
#define GET_BEBYTE(p)	((unsigned char )(((unsigned char*)(p))[0]<< 0))
#define GET_BEHALF(p)	((unsigned short)(((unsigned char*)(p))[0]<< 8|((unsigned char*)(p))[1]<< 0))
#define GET_BEWORD(p)	((unsigned int  )(((unsigned char*)(p))[0]<<24|((unsigned char*)(p))[1]<<16|((unsigned char*)(p))[2]<< 8|((unsigned char*)(p))[3]<< 0))

/* リトルエンディアンのバイトオーダーでバイト値、ハーフワード値、ワード値を書き込みます。
 * ポインタpはハーフワード境界やワード境界に整列されていなくても構いません。
 */
#define PUT_LEBYTE(p,v)	do { ((unsigned char*)(p))[0]=(unsigned char)((v)>> 0); } while(0)
#define PUT_LEHALF(p,v)	do { ((unsigned char*)(p))[0]=(unsigned char)((v)>> 0); ((unsigned char*)(p))[1]=(unsigned char)((v)>> 8); } while(0)
#define PUT_LEWORD(p,v)	do { ((unsigned char*)(p))[0]=(unsigned char)((v)>> 0); ((unsigned char*)(p))[1]=(unsigned char)((v)>> 8); ((unsigned char*)(p))[2]=(unsigned char)((v)>>16); ((unsigned char*)(p))[3]=(unsigned char)((v)>>24); } while(0)

/* ビッグエンディアンのバイトオーダーでバイト値、ハーフワード値、ワード値を書き込みます。
 * ポインタpはハーフワード境界やワード境界に整列されていなくても構いません。
 */
#define PUT_BEBYTE(p,v)	do { ((unsigned char*)(p))[0]=(unsigned char)((v)>> 0); } while(0)
#define PUT_BEHALF(p,v)	do { ((unsigned char*)(p))[0]=(unsigned char)((v)>> 8); ((unsigned char*)(p))[1]=(unsigned char)((v)>> 0); } while(0)
#define PUT_BEWORD(p,v)	do { ((unsigned char*)(p))[0]=(unsigned char)((v)>>24); ((unsigned char*)(p))[1]=(unsigned char)((v)>>16); ((unsigned char*)(p))[2]=(unsigned char)((v)>> 8); ((unsigned char*)(p))[3]=(unsigned char)((v)>> 0); } while(0)

/* ハーフワード値の上位バイト、下位バイトを取得します。 */
#define HIBYTE(h)	((unsigned char)((h) >> 8))
#define LOBYTE(h)	((unsigned char)((h) >> 0))

/* ワード値の上位ハーフワード、下位ハーフワードを取得します。 */
#define HIHALF(w)	((unsigned short)((w) >> 16))
#define LOHALF(w)	((unsigned short)((w) >>  0))

//{{2015/01/06削除:乱数関連の宣言と実装を、clipmisc.*⇒cliprnd.*へ分離しました。
/////* 8ビット乱数(『Z80マシン語秘伝の書』より) */
////#define RND8(s)	(((s) = (s) * 5 + 0x3711) >> 8 & 0xff)
/////* 16ビット乱数(VisualC++ 6.0 \VC98\CRT\SRC\RAND.C を参考にしました) */
////#define RND16(s)	(((s) = (s) * 214013 + 2531011) >> 16 & 0xffff)
////↓2004/09/15 コンパイラバグ(?)で負値になってしまう場合があったので、本体処理を関数化しました。
////↓           過去のソースの互換性のため、関数を呼び出すマクロも定義してあります。
///* 8ビット乱数 */
//int rnd8(int* seed);			/* 戻り値の型は符号付き(int)で、範囲は+0x00000000～+0x000000FFです。 */
//#define RND8(s)		(rnd8(&(s)))
///* 16ビット乱数 */
//int rnd16(int* seed);			/* 戻り値の型は符号付き(int)で、範囲は+0x00000000～+0x0000FFFFです。 */
//#define RND16(s)	(rnd16(&(s)))
///* 32ビット乱数 */
//int rnd32(int* seed);			/* 戻り値の型は符号付き(int)で、範囲は-0x80000000～+0x7FFFFFFFです。要注意!! */
//#define RND32(s)	(rnd32(&(s)))
//
///* (a)以上(b)★未満★の乱数を生成 */
////#define RND8_RANGE(s, a, b)	(RND8(s) % ((b) - (a)) + (a))
////#define RND16_RANGE(s, a, b)	(RND16(s) % ((b) - (a)) + (a))
////↓2004/09/15 コンパイラバグ(?)で負値になってしまう場合があったので、本体処理を関数化しました。
////↓           過去のソースの互換性のため、関数を呼び出すマクロも定義してあります。
///* (a)以上(b)★未満★の乱数を生成 */
//int rnd8_range(int* seed, int a, int b);
//#define RND8_RANGE(s, a, b)	(rnd8_range(&(s), (a), (b)))
//int rnd16_range(int* seed, int a, int b);
//#define RND16_RANGE(s, a, b)	(rnd16_range(&(s), (a), (b)))
//int rnd32_range(int* seed, int a, int b);
//#define RND32_RANGE(s, a, b)	(rnd32_range(&(s), (a), (b)))
//}}2015/01/06削除:乱数関連の宣言と実装を、clipmisc.*⇒cliprnd.*へ分離しました。

/* 配列(array)の要素数を求めます。 */
//#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
//↓2006/04/14 ARRAY_SIZE()の戻り値を(size_t)→(int)に変更しました。
//↓これまでは、ARRAY_SIZE()の戻り値と(int)値の比較を行うと、符号無し比較が行われていました。
//↓負値との比較を行う場合は、ARRAY_SIZE()の戻り値を明示的に(int)にキャストする必要がありました。
//↓  (変更前) if(i >      ARRAY_SIZE(array)) { ... } // iが-1の場合に、誤って「True」と判断されてしまう。
//↓  (変更前) if(i > (int)ARRAY_SIZE(array)) { ... } // 正しい判断のためには、明示的なキャストが必要だった。
//↓今回の変更により、ARRAY_SIZE()の戻り値は常に(int)になったので、利用側での明示的なキャストは不要になりました。
//↓  (変更後) if(i > ARRAY_SIZE(array)) { ... } // iが-1であっても、正しく「False」と判断します。
//#define ARRAY_SIZE(array) ((int)(sizeof(array) / sizeof((array)[0])))
// * Fri Apr 01 21:48:44 JST 2016 Naoyuki Sawa
// - ARRAY_SIZE()の引数に、誤ってポインタを渡した時に、コンパイルエラーとして検出出来るようにしました。
//   ただし、常に検出できる訳ではありません。詳細は、下記の例を参照して下さい。
// - ちなみに、Microsoftの最近のコンパイラ(Visual C++ 2015 等)では、_countof()というマクロが追加されており、ARRAY_SIZE()の代わりに_countof()を使う事も可能です。
//   ただし、_countof()の引数にポインタを渡した場合、C++ソースならばコンパイルエラーとして検出出来きますが、Cソースの場合は検出出来ずに間違った結果を生成します。
//   その点、今回変更したARRAY_SIZE()ならば、Cソースでも(常にではありませんが)コンパイルエラーとして検出出来るので、VC++でもARRAY_SIZE()を使う方が良いと思います。
//□「Stack Overflow - Common array length macro for C?」(http://stackoverflow.com/questions/4415524/common-array-length-macro-for-c)より:
//│It improves on the array[0] or *array version by using 0[array], which is equivalent to array[0] on plain arrays, but will fail to compile if array happens to be a C++ type that overloads operator[]().
//│The division causes a divide-by-zero operation (that should be caught at compile time since it's a compile-time constant expression) for many (but not all) situations where a pointer is passed as the array parameter.
//#define ARRAY_SIZE(array) (((int)(sizeof(array)/sizeof(0[array])))/((int)(!(sizeof(array)%sizeof(0[array])))))
////                                                                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ARRAY_SIZE()の引数にポインタを渡すのは誤りである。もしARRAY_SIZE()の引数にポインタを渡した場合、この部分がゼロ除算の定数式となり、コンパイルエラーとして検出出来る。
////                                                                                                           ただし、1,2,4バイトの値に対するポインタの場合(char* p,short* p,int* p等)は検出出来ない。それらを簡単に検出する方法は無いので、変更前と同様に目視で見付けるしか無い。
//□コンパイル時に検出出来るバグと、検出出来ないバグについて
//│struct { char  a,b,c; } a1[3], *p1 = a1;
//│struct { short a,b,c; } a2[3], *p2 = a2;
//│struct { int   a,b,c; } a3[3], *p3 = a3;
//│char  a4[3], *p4 = a4;
//│short a5[3], *p5 = a5;
//│int   a6[3], *p6 = a6;
//│printf("%d\n", ARRAY_SIZE(a1)); //○正しい使い方。結果は3になる。
//│printf("%d\n", ARRAY_SIZE(p1)); //×不正な使い方。コンパイルエラーで検出出来る。	⇒{{2016/04/02追記:P/ECE開発環境のgcc33ではコンパイルエラーにならずランタイムエラーになる事に気付きました。詳細は下記の2016/04/02のコメントを参照して下さい。}}
//│printf("%d\n", ARRAY_SIZE(a2)); //○正しい使い方。結果は3になる。
//│printf("%d\n", ARRAY_SIZE(p2)); //×不正な使い方。コンパイルエラーで検出出来る。	⇒{{2016/04/02追記:P/ECE開発環境のgcc33ではコンパイルエラーにならずランタイムエラーになる事に気付きました。詳細は下記の2016/04/02のコメントを参照して下さい。}}
//│printf("%d\n", ARRAY_SIZE(a3)); //○正しい使い方。結果は3になる。
//│printf("%d\n", ARRAY_SIZE(p3)); //×不正な使い方。コンパイルエラーで検出出来る。	⇒{{2016/04/02追記:P/ECE開発環境のgcc33ではコンパイルエラーにならずランタイムエラーになる事に気付きました。詳細は下記の2016/04/02のコメントを参照して下さい。}}
//│printf("%d\n", ARRAY_SIZE(a4)); //○正しい使い方。結果は3になる。
//│printf("%d\n", ARRAY_SIZE(p4)); //!!不正な使い方だが、コンパイルエラーにならず、間違った結果(4)になる。この不正な使い方によるバグは、これまでと同様に目視で見付けるしか無い。	←←←←←要注意!!
//│printf("%d\n", ARRAY_SIZE(a5)); //○正しい使い方。結果は3になる。
//│printf("%d\n", ARRAY_SIZE(p5)); //!!不正な使い方だが、コンパイルエラーにならず、間違った結果(2)になる。この不正な使い方によるバグは、これまでと同様に目視で見付けるしか無い。	←←←←←要注意!!
//│printf("%d\n", ARRAY_SIZE(a6)); //○正しい使い方。結果は3になる。
//│printf("%d\n", ARRAY_SIZE(p6)); //!!不正な使い方だが、コンパイルエラーにならず、間違った結果(1)になる。この不正な使い方によるバグは、これまでと同様に目視で見付けるしか無い。	←←←←←要注意!!
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
// * Sat Apr 02 21:00:43 JST 2016 Naoyuki Sawa
// - ARRAY_SIZE()マクロを再度修正しました。
//   2016/04/01の方法には問題が有る事に気付いたからです。
//   2016/04/01の方法だと、P/ECE開発環境のgcc33では、ARRAY_SIZE()の引数にポインタを渡した時に、コンパイルエラーにならず、ゼロ除算を行うコードが生成されてしまうようです。
//   │struct S { char a,b,c; };
//   │struct S a1[3], *p1 = a1;
//   │int f1() { return ARRAY_SIZE(a1); }	⇒	○問題無し。							ld.w %r10,0 ; ret
//   │int g1() { return ARRAY_SIZE(p1); }	⇒	×問題有り。							ld.w %r12,0 ; ld.w %r13,0 ; xcall __divsi3 ; ret
//   実行時にゼロ除算エラーが発生して検出出来るので、単に間違った値が返されるよりはマシではあるのですが、その箇所が実行されるまで発見出来ないという問題が有ります。
//   そんな訳で、2016/04/01の方法は良くなかったので、ARRAY_SIZE()マクロを再検討する事にしました。
// - 下記のページに、色々な定義方法が載っているので、参考にさせて頂きました。
//   「Stack Overflow - Array-size macro that rejects pointers」(http://stackoverflow.com/questions/19452971/array-size-macro-that-rejects-pointers)
//   ただし、載っている方法をそのまま使う事は出来ませんでした。
//   P/ECE開発環境のgcc33が古いためか、上記のページの方法では定数式になる事を期待している部分が、コンパイルエラーでなくプログラムコードが生成されていまうケースが多いからです。
//   色々実験して、P/ECE用とWindows用で、それぞれに最適な方法を決定しました。
// - P/ECE用としては、前述のページに載っていた下記の案をベースにさせて頂きました。
//   │#define ARRAYSIZE(arr) ({typeof(arr) arr##_is_a_pointer __attribute__((unused))={}; sizeof(arr)/sizeof(arr[0]);})
//   ただし、そのままでは使用出来ませんでした。
//   P/ECE開発環境のgcc33では、上記の書き方では、'unused'な変数もスタック上に確保されてしまい、無駄なコードが生成されるからです。
//   │#define ARRAY_SIZE(array) ({typeof(array) array##_is_a_pointer __attribute__((unused))={}; (int)(sizeof(array)/sizeof(0[array]));})
//   │struct S { char a,b,c; };
//   │struct S a1[3], *p1 = a1;
//   │int f1() { return ARRAY_SIZE(a1); }	⇒	×問題有り。動作上は問題無いが無駄なコードが生成される。	__LC0: ; .space 9 ; f1: ; xsub %sp,%sp,12 ; ld.w %r12,%sp ; xld.w %r13,__LC0 ; ld.w %r14,9 ; xcall memcpy ; ld.w %r10,3 ; xadd %sp,%sp,12 ; ret
//   │int g1() { return ARRAY_SIZE(p1); }	⇒	○問題無し。期待通りコンパイルエラーとして検出されます。
//   さらに実験したところ、無名変数として定義すれば、使わない無名変数はスタック上に確保されず、無駄なコードが生成されない事が判りました。
//   │#define ARRAY_SIZE(array) (((void)((typeof(array)){})),((int)(sizeof(array)/sizeof(0[array]))))
//   │struct S { char a,b,c; };
//   │struct S a1[3], *p1 = a1;
//   │int f1() { return ARRAY_SIZE(a1); }	⇒	○問題無し。無駄なコードは生成されなくなりました。		f1: ; ld.w %r10,3 ; ret
//   │int g1() { return ARRAY_SIZE(p1); }	⇒	○問題無し。期待通りコンパイルエラーとして検出されます。
//   ちなみに、2016/04/01の方法では、ARRAY_SIZE()に誤って(char*)や(short*)や(int*)を渡した場合にコンパイルエラーが検出出来ない欠点が有ったのですが、今回の方法ならばそれらも検出出来るようになりました。
//   │#define ARRAY_SIZE(array) (((void)((typeof(array)){})),((int)(sizeof(array)/sizeof(0[array]))))
//   │int a1[3], *p1 = a1;
//   │int f1() { return ARRAY_SIZE(a1); }	⇒	○問題無し。							f1: ; ld.w %r10,3 ; ret
//   │int g1() { return ARRAY_SIZE(p1); }	⇒	○問題無し。期待通りコンパイルエラーとして検出されます。
//   今回の方法の欠点としては、GCC拡張機能を利用しているので、Visual C++では使用出来ない事です。
//   そこで、P/ECE用とWindows用で、ARRAY_SIZE()の定義を分けるようにしました。
// - Windows用としては、2016/04/01版の方法のままでも構いません。
//   VC++6.0は、ゼロ除算の定数式を正しく認識し、コンパイルエラーとして検出するからです。
//   しかし、処理系によってゼロ除算の定数式をどのように処理するかどうかに依存した定義方法は良くないと思ったので、やっぱりWindows用のARRAY_SIZE()の定義も修正する事にしました。
//   Windows用としては、前述のページに載っていた下記の案をベースにさせて頂きました。
//   │#define ARRAY_SIZE(arr)  (sizeof(arr)/sizeof((arr)[0])+STATIC_EXP(IS_ARRAY(arr)))
//   │#define IS_ARRAY(arr)    ((void*)&(arr)==&(arr)[0])
//   │#define STATIC_EXP(e)    (0*sizeof(struct{int ARRAY_SIZE_FAILED:(2*(e)-1);}))
//   ただし、そのままでは使用出来ませんでした。
//   VC++6.0では、arrが配列かポインタかに関係無く、'((void*)&(arr)==&(arr)[0])'が定数式として評価されないようだからです。(ちなみにgcc33でも同様です)
//   上記の方法は、arrが配列ならば'((void*)&(arr)==&(arr)[0])'が定数式として評価され、arrがポインタならば実行時に評価される事に依存した方法なのですが、VC++6.0やgcc33ではそうはなりませんでした。
//   │#define ARRAY_SIZE(arr)  (sizeof(arr)/sizeof((arr)[0])+STATIC_EXP(IS_ARRAY(arr)))
//   │#define IS_ARRAY(arr)    ((void*)&(arr)==&(arr)[0])
//   │#define STATIC_EXP(e)    (0*sizeof(struct{int ARRAY_SIZE_FAILED:(2*(e)-1);}))
//   │struct S { char a,b,c; };
//   │struct S a1[3], *p1 = a1;
//   │int f1() { return ARRAY_SIZE(a1); }	⇒	×問題有り。これはコンパイル成功して欲しいのだが、'定数式が必要です'というコンパイルエラーになってしまう。
//   │int g1() { return ARRAY_SIZE(p1); }	⇒	○問題無し。期待通り'定数式が必要です'というコンパイルエラーとして検出されます。
//   そもそも、処理系依存の評価方法に依存しないようにするために修正する事にしたのだから、'((void*)&(arr)==&(arr)[0])'が定数式として評価されるかどうかに依存した方法は良くありません。
//   そこで、2016/04/01の方法との折衷案で、下記のような方法にしました。
//   │#define ARRAY_SIZE(arr)  (sizeof(arr)/sizeof((arr)[0])+STATIC_EXP(IS_ARRAY(arr)))
//   │#define IS_ARRAY(arr)    (!(sizeof(arr)%sizeof(0[arr])))
//   │#define STATIC_EXP(e)    (0*sizeof(struct{int ARRAY_SIZE_FAILED:(2*(e)-1);}))
//   │struct S { char a,b,c; };
//   │struct S a1[3], *p1 = a1;
//   │int f1() { return ARRAY_SIZE(a1); }	⇒	○問題無し。
//   │int g1() { return ARRAY_SIZE(p1); }	⇒	○問題無し。期待通り'定数式が必要です'というコンパイルエラーとして検出されます。
//   さらに変更して、三つのマクロを一つにまとめました。
//   また、上記の方法はビットフィールドの幅が1(正常)か-1(エラー)になるようになっていたのですが、名前付きビットフィールドの幅は0もエラーになる事を利用して、式を単純化出来ました。
//   │#define ARRAY_SIZE(array) (((void)(sizeof(struct{int ARRAY_SIZE_FAILED:!(sizeof(array)%sizeof(0[array]));}))),((int)(sizeof(array)/sizeof(0[array]))))
//   │struct S { char a,b,c; };
//   │struct S a1[3], *p1 = a1;
//   │int f1() { return ARRAY_SIZE(a1); }	⇒	○問題無し。
//   │int g1() { return ARRAY_SIZE(p1); }	⇒	○問題無し。期待通り'定数式が必要です'というコンパイルエラーとして検出されます。
//   ちなみに、今回のWindows版の方法でも、2016/04/01の方法と同様に、ARRAY_SIZE()に誤って(char*)や(short*)や(int*)を渡した場合に、コンパイルエラとして検出出来ない欠点が有ります。
//   │#define ARRAY_SIZE(array) (((void)(sizeof(struct{int ARRAY_SIZE_FAILED:!(sizeof(array)%sizeof(0[array]));}))),((int)(sizeof(array)/sizeof(0[array]))))
//   │int a1[3], *p1 = a1;
//   │int f1() { return ARRAY_SIZE(a1); }	⇒	○問題無し。
//   │int g1() { return ARRAY_SIZE(p1); }	⇒	!!要注意。ARRAY_SIZE()にポインタを渡すのは誤りなのだが、(char*)や(short*)や(int*)の場合はコンパイルエラーとして検出出来ず、これらのバグは目視で発見する必要が有る。
//   もっとも、Windows専用ではないモジュールは、P/ECEでもコンパイルしますから、P/ECEでのコンパイル時に前述のP/ECE用ARRAY_SIZE()マクロで検出出来ると思います。
//#ifndef PIECE
//#define ARRAY_SIZE(array) (((void)(sizeof(struct{int ARRAY_SIZE_FAILED:!(sizeof(array)%sizeof(0[array]));}))),((int)(sizeof(array)/sizeof(0[array]))))	//Windows用。VC++特有の機能は使っていないので汎用としても使用出来ます。ARRAY_SIZE()の引数に誤って(char*)や(short*)や(int*)を渡した場合は、コンパイルエラーとして検出出来ない事に注意して下さい。
//#else //PIECE
//#define ARRAY_SIZE(array) (((void)((typeof(array)){})),((int)(sizeof(array)/sizeof(0[array]))))								//P/ECE用。GCC拡張機能を使用しています。ARRAY_SIZE()の引数に誤って(char*)や(short*)や(int*)を渡した場合も、誤って構造体のポンイタを渡した場合と同様に、コンパイルエラーとして検出出来ます。
//#endif//PIECE
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
// * Sat Apr 02 23:34:06 JST 2016 Naoyuki Sawa
// - ARRAY_SIZE()マクロを再々度修正しました。
//   Windows用の定義'(((void)(sizeof(struct{int ARRAY_SIZE_FAILED:!(sizeof(array)%sizeof(0[array]));}))),((int)(sizeof(array)/sizeof(0[array]))))'には問題が有りました。
//   VC++6.0でC++ソースをコンパイルする時にエラーになるのです。
//   VC++6.0でCソースをコンパイルする時は大丈夫なのですが、C++ソースではエラーになります。
//   どうやら、VC++6.0のC++では、条件式の中に無名のstruct定義が有ると、エラーになるようです。
//   仕方が無いので、少し変更する事にしました。下記の書き方ならば、C++ソースでもエラー無くコンパイル出来ます。
//   │#define ARRAY_SIZE(array) (((void)(sizeof(char[1-2*(sizeof(array)%sizeof(0[array]))]))),((int)(sizeof(array)/sizeof(0[array]))))
//   │struct S { char a,b,c; };
//   │struct S a1[3], *p1 = a1;
//   │int f1() { return ARRAY_SIZE(a1); }	⇒	○問題無し。
//   │int g1() { return ARRAY_SIZE(p1); }	⇒	○問題無し。期待通り'定数式が必要です'というコンパイルエラーとして検出されます。
//   前回のマクロは、名前付きビットフィールドの幅が0ならばコンパイルエラーになる事を利用していました。
//   今回のマクロは、負の要素数の配列はコンパイルエラーになる事を利用するように変更しました。
//   尚、VC++6.0では0の要素数の配列のsizeofはコンパイルエラーになるので'1-2*(～'の部分は'1-(～'でも良いのですが、処理系によっては(例えばGCCだと)0の要素数の配列のsizeofはエラーにならないので、今後のために要素数1,又は,マイナスになるようにしておく事にしました。
// - 本題から外れますが、今回の変更を行っていて少し気付いた事が有り、メモとして残しておきます。
//   計算式が単純ならば、明示的に(int)キャストしているにもかかわらず、(int)と(unsigned)の比較を行っても警告が出ません。
//   計算式を少し複雑にすると、実際の処理内容は同じであるのに、(int)と(unsigned)の比較で警告が出るようになるという違いが生じます。
//   │VC++6.0にて確認:
//   │#define FOO(x) (        (int)(sizeof(x)/sizeof(0[x])))
//   │#define BAR(x) ((void)0,(int)(sizeof(x)/sizeof(0[x])))
//   │static int t1(int i) { return (unsigned)i < FOO(a1); }	//警告無し。
//   │static int t2(int i) { return (unsigned)i < BAR(a1); }	//警告有り。'signedとunsignedの数値を比較しようとしました。'
//   2016/03/31までのARRAY_SIZE()は上記のFOO()に相当するため、(int)と(unsigned)の比較で警告が出ていない箇所が有りました。(動作自体は問題有りません)
//   2016/04/01以降のARRAY_SIZE()は上記のBAR()に相当するため、'if((unsigned)i>ARRAY_SIZE(a)){DIE();}'のような使い方をしてた部分で警告が出るようになりました。
//   うっかりミスを防げるという観点では、2016/04/01以降のARRAY_SIZE()で警告が出るようになって、良くなったと思います。
//   この警告を回避するために、明示的に'if((unsigned)i>(unsigned)ARRAY_SIZE(a)){DIE();}'のように書くように、幾つかのモジュールを修正しました。
//   尚、元々ほとんどは(unsigned)比較ではなく(int)比較なので、上記の修正が必要になる箇所は少なかったです。
//#ifndef PIECE
//#define ARRAY_SIZE(array) (((void)(sizeof(char[1-2*(sizeof(array)%sizeof(0[array]))]))),((int)(sizeof(array)/sizeof(0[array]))))	//Windows用。VC++特有の機能は使っていないので汎用としても使用出来ます。ARRAY_SIZE()の引数に誤って(char*)や(short*)や(int*)を渡した場合は、コンパイルエラーとして検出出来ない事に注意して下さい。	P/ECE用としても使う事は可能ですが、P/ECEでは下記の別バージョンを使う事にしました。P/ECEではGCC拡張機能を使って、(char*)や(short*)や(int*)も検出出来るからです。
//#else //PIECE
//#define ARRAY_SIZE(array) (((void)((typeof(array)){})),((int)(sizeof(array)/sizeof(0[array]))))						//P/ECE用。GCC拡張機能を使用しています。ARRAY_SIZE()の引数に誤って(char*)や(short*)や(int*)を渡した場合も、誤って構造体のポンイタを渡した場合と同様に、コンパイルエラーとして検出出来ます。
//#endif//PIECE
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
// * Wed Aug 17 21:19:23 JST 2016 Naoyuki Sawa
// - Windows用のARRAY_SIZE()マクロを修正しました。
//     #define ARRAY_SIZE(array) (((void)(sizeof(char[1-2*((int)(sizeof(array)%sizeof(0[array])))]))),((int)(sizeof(array)/sizeof(0[array]))))
//                                                         ~~~~~このキャストを追加しました。
//   変更した理由は、以下の通りです。
// - 上記のマクロの動作は、マクロ引数にポインタを渡した時に、char[～]の～がマイナスになり、コンパイルエラーとして検出される事を利用したものです。
//   しかし、(sizeof(array)%sizeof(0[array]))が(unsigned%unsigned)であるため、(1-2*unsigned値)全体の結果がunsignedと見なされ、最上位ビットが1でもマイナスと見なされず、コンパイルエラーとして検出されないケースが有る事に気付きました。
//   実際の所、VC++6.0ならば、修正前のマクロ定義でも問題なくコンパイルエラーとして検出されるのですが、Hewだと、コンパイルエラーとして検出されませんでした。
//   コンパイラの動作としては、Hewの挙動の方が理解出来るので、VC++6.0の方が何か不思議な動作をしているのだと思います。((1-2*unsigned値)が符号付きとして判断されている?)
//   いずれにせよ、上記のキャストは追加するのが正しいので、追加しておく事にしました。
//   この修正により、Hewでも、マクロ引数にポインタを渡した時に、コンパイルエラーとして検出出来るようになりました。
//   VC++6.0では、上述の通り、修正前も(何故か)コンパイルエラーとして検出出来ていたのですが、今回の修正後の定義でも、もちろん問題なく検出出来ます。
// - 今回は、PIECE用のARRAY_SIZE()マクロは、変更していません。
#ifndef PIECE
#define ARRAY_SIZE(array) (((void)(sizeof(char[1-2*((int)(sizeof(array)%sizeof(0[array])))]))),((int)(sizeof(array)/sizeof(0[array]))))	//Windows用。VC++特有の機能は使っていないので汎用としても使用出来ます。ARRAY_SIZE()の引数に誤って(char*)や(short*)や(int*)を渡した場合は、コンパイルエラーとして検出出来ない事に注意して下さい。	P/ECE用としても使う事は可能ですが、P/ECEでは下記の別バージョンを使う事にしました。P/ECEではGCC拡張機能を使って、(char*)や(short*)や(int*)も検出出来るからです。		//{{2016/08/17コメント追記:本日の修正によってHewでも使えるようになりました。}}
#else //PIECE
#define ARRAY_SIZE(array) (((void)((typeof(array)){})),((int)(sizeof(array)/sizeof(0[array]))))						//P/ECE用。GCC拡張機能を使用しています。ARRAY_SIZE()の引数に誤って(char*)や(short*)や(int*)を渡した場合も、誤って構造体のポンイタを渡した場合と同様に、コンパイルエラーとして検出出来ます。
#endif//PIECE

/* 構造体メンバのサイズを返します。(linux/include/linux/kernel.h から借用しました) */
#define FIELD_SIZEOF(t,f) (sizeof(((t*)0)->f))

///* 構造体(type)の先頭から、フィールド(field)までのオフセットバイト数を求めます。 */
//#define FIELD_OFFSET(type,field) ((int)&(((type*)0)->field))
//↓削除しました。
// * Sat Jun 17 05:11:45 JST 2006 Naoyuki Sawa
// - clipstd.hにてstddef.hのincludeを有効にしたので、offsetof()マクロが利用できるようになりました。
//   もう、FIELD_OFFSET()マクロは不要になったので、削除しました。
//   今後は、windows.h互換のFIELD_OFFSET()マクロではなく、ANSI標準のoffsetof()マクロを使ってください。

/* 構造体(type)のフィールド(field)のアドレスから、構造体(type)の先頭アドレスを求めます。 */
//#define CONTAINING_RECORD(address,type,field)	((type*)((int)(address) - FIELD_OFFSET(type,field)))
//↓Sat Jun 17 05:11:45 JST 2006 Naoyuki Sawa FIELD_OFFSET()→offsetof()を使うように変更しました。
//#define CONTAINING_RECORD(address,type,field)	((type*)((int)(address) - offsetof(type,field)))
//↓Sat Sep 03 14:13:50 JST 2016 Naoyuki Sawa CONTAINING_RECORD()が、(int)でアドレス演算を行っていたのを、(char*)で行うように修正しました。
#define CONTAINING_RECORD(address,type,field)	((type*)((char*)(address) - offsetof(type,field)))

/* 1バイト値をビット反転します。
 * 注意!! 引数は、0x00～0xffの範囲でなければいけません。
 *        範囲外の値を指定すると、誤った結果となります。
 */
#define MIRROR(a)	(mirror_table[(a)])
extern const unsigned char mirror_table[0x100]; /* -> clipmirr.c */

/* 1バイト値(1ビット×8ピクセル)を水平に二倍拡大します。
 * 注意!! 引数は、0x00～0xffの範囲でなければいけません。
 *        範囲外の値を指定すると、誤った結果となります。
 */
#define XSIZE2(a)	(xsize2_table[(a)])
extern const unsigned short xsize2_table[0x100]; /* -> clipxsz2.c */

/* 往復運動カウンタを生成します。
 * - あまり頻繁に使うものでもないと思ったので、clipmiscモジュールのサイズが無駄に増えないよう、マクロにしました。
 *   もし、頻繁に使う場合は、アプリケーション内で関数化してください。
 * <使用例>
 *	UPDOWN_MOTION(now,5) → 0,1,2,3,4,3,2,1,0,1,2,...
 */
#define UPDOWN_MOTION(i,n)	(abs(((i)+((n)-2))%(((n)-1)*2)-((n)-2)))

/* 整数カウンタ(x=0→y)を、実数値(0.0→1.0)に変換します。
 * - 出力値のカーブは、90度分の円弧に相当します。
 *   詳細は、各マクロのコメントを参照して下さい。
 */
#define FastCurv(x,y)	(    sin(M_PI_2/(y)*(x)))	//(x=0→y)に対して、0.0→1.0の値を返す。大きな変化で開始し、小さな変化に移行する。	<例> 爆発エフェクトの拡大率 = 1.0+FastCurv(cnt,SEC(1.0)), 爆発エフェクトの透明度 = 1.0-FastCurv(cnt,SEC(1.0))
#define SlowCurv(x,y)	(1.0-cos(M_PI_2/(y)*(x)))	//(x=0→y)に対して、0.0→1.0の値を返す。小さな変化で開始し、大きな変化に移行する。	FastCurv()に比べると、SlowCurv()を使う事は少ないと思います。場面転換でアイキャッチ等のズームアップを簡易3D風に見せる時に使えるかも知れません。

/* * Thu Aug 11 03:06:25 JST 2011 Naoyuki Sawa
 * - BIT1_LOWEST_POSITION()、BIT1_SHIFT_TO_LSB()、BIT1_CONTINUATION_TEST()、BIT0_LOWEST_POSITION()、BIT0_SHIFT_TO_LSB()、BIT0_CONTINUATION_TEST()を追加しました。
 *   BMPファイルのカラーマスクの操作等に利用できる、ビット演算マクロです。
 *   利用頻度はあまり多くないと思いますが、マクロなので実行ファイルサイズに影響することは無いため、アルゴリズムの備忘録として定義しておくことにしました。
 * - 以下のWebサイトを参考にしました。
 *	「ルーチェ's Homepage」さんの、「Home/プログラミング/BMPファイル仕様/ビットフィールド」(http://www.ruche-home.net/?プログラミング/BMPファイル仕様/ビットフィールド)のページ
 *	「ウィキペディア」の、「2の補数」(http://ja.wikipedia.org/wiki/2の補数)のページの、「テクニック ビットの立っている最下位ビットだけを残して残りを0にする方法」のページ
 *	「stephan-brumme.com」さんの、「Position of lowest bit set」(http://bits.stephan-brumme.com/lowestBitSet.html)、及び、「Bit mask of lowest bit not set」(http://bits.stephan-brumme.com/lowestBitNotSet.html)のページ
 */
/* 整数値xについて、値が1の最下位ビットだけが、セットされた値を求める。
 * <例1>
 *	                     x    = 11111111 01111110 00111100 00011000
 *	BIT1_LOWEST_POSITION(x)   = 00000000 00000000 00000000 00001000
 * <例2>
 *	                     x    = 00000000 00000000 00000000 00000000
 *	BIT1_LOWEST_POSITION(x)   = 00000000 00000000 00000000 00000000
 *	(xのビットが全て0である場合のみ、結果が0となる。)
 */
#define BIT1_LOWEST_POSITION(x)		((x) & -(x))
/* 整数値xについて、値が1の最下位ビットが、右端となるよう右シフトする。
 * <例1>
 *	                  x       = 11111111 01111110 00111100 00011000
 *	BIT1_SHIFT_TO_LSB(x)      = 00011111 11101111 11000111 10000011
 * <例2>
 *	                  x       = 00000000 00000000 00000000 00000000
 *	BIT1_SHIFT_TO_LSB(x)      = 00000000 00000000 00000000 00000000
 *	(xのビットが全て0である場合は、xをそのまま返す。)
 */
#define BIT1_SHIFT_TO_LSB(x)		((x) ? (unsigned)(x) / (unsigned)BIT1_LOWEST_POSITION(x) : (x))
/* 整数値xについて、値が1のビットが、連続しているか調べる。
 * <例1>
 *	                       x  = 11111111 01111110 00111100 00011000
 *	BIT1_CONTINUATION_TEST(x) = 0 (連続していない)
 * <例2>
 *	                       x  = 00000000 00001111 11110000 00000000
 *	BIT1_CONTINUATION_TEST(x) = 1 (連続している)
 * <例3>
 *	                       x  = 00000000 00000000 00000000 00000000
 *	BIT1_CONTINUATION_TEST(x) = 1 (連続している)
 *	(xのビットが全て0である場合、「値が1のビットが0個連続している」と解釈する。)
 */
#define BIT1_CONTINUATION_TEST(x)	(!(BIT1_SHIFT_TO_LSB(x) & (BIT1_SHIFT_TO_LSB(x) + 1)))
/* 整数値xについて、値が0の最下位ビットだけが、セットされた値を求める。
 * <例1>
 *	                     x    = 00000000 10000001 11000011 11100111
 *	BIT0_LOWEST_POSITION(x)   = 00000000 00000000 00000000 00001000
 * <例2>
 *	                     x    = 11111111 11111111 11111111 11111111
 *	BIT0_LOWEST_POSITION(x)   = 00000000 00000000 00000000 00000000
 *	(xのビットが全て1である場合のみ、結果が0となる。)
 */
#define BIT0_LOWEST_POSITION(x)		BIT1_LOWEST_POSITION(~(x))
/* 整数値xについて、値が0の最下位ビットが、右端となるよう右シフトする。
 * <例1>
 *	                  x       = 00000000 10000001 11000011 11100111
 *	BIT0_SHIFT_TO_LSB(x)      = 11100000 00010000 00111000 01111100
 * <例2>
 *	                  x       = 11111111 11111111 11111111 11111111
 *	BIT0_SHIFT_TO_LSB(x)      = 11111111 11111111 11111111 11111111
 *	(xのビットが全て1である場合は、xをそのまま返す。)
 */
#define BIT0_SHIFT_TO_LSB(x)		(~BIT1_SHIFT_TO_LSB(~(x)))
/* 整数値xについて、値が0のビットが、連続しているか調べる。
 * <例1>
 *	                  x       = 00000000 10000001 11000011 11100111
 *	BIT0_CONTINUATION_TEST(x) = 0 (連続していない)
 * <例2>
 *	                       x  = 11111111 11110000 00001111 11111111
 *	BIT0_CONTINUATION_TEST(x) = 1 (連続している)
 * <例3>
 *	                       x  = 11111111 11111111 11111111 11111111
 *	BIT0_CONTINUATION_TEST(x) = 1 (連続している)
 *	(xのビットが全て1である場合、「値が0のビットが0個連続している」と解釈する。)
 */
#define BIT0_CONTINUATION_TEST(x)	BIT1_CONTINUATION_TEST(~(x))

//{{2015/01/06削除:乱数関連の宣言と実装を、clipmisc.*⇒cliprnd.*へ分離しました。
///* 配列要素をシャッフルします。
// * [in]
// *	base		配列の先頭アドレス。
// *	num		配列の要素数。
// *	width		配列要素ひとつ当りのバイト数。
// *	seed		シャッフル用乱数シード。
// * [note]
// *	* 引数の並びは、最後のseed以外、標準Cライブラリのqsort()関数に互換です。
// *	* numが0未満ならば、不正な配列と見なしてアサートします。
// *	// * 2005/03/31現在の実装は、16bit乱数を利用しているために、65536要素以上の配列をシャッフルできません。
// *	//   numが65536よりも大きいと、アサートします。
// *	↓2006/07/06 追記
// *	* Thu Jul 06 11:48:53 JST 2006 Naoyuki Sawa
// *	- rnd32()の新設に伴い、16bit乱数→32bit乱数を利用するよう変更しました。
// *	  この変更により、65536要素以上の配列をシャッフルできなかった制限が無くなりました。
// */
////void shuffle(void* base, int num, int width, int seed);
////↓* Mon Oct 31 05:10:00 JST 2005 Naoyuki Sawa
////↓- shuffle()関数にて、seed引数を参照で受け取り、乱数シードを更新するよう変更しました。
////↓  これまでは、呼び出し側にて乱数シードを更新する必要がありましたが、今後は不要となります。
////↓  <変更前の使用例> shuffle(array, 10, sizeof(int), RND16(seed));
////↓  <変更後の使用例> shuffle(array, 10, sizeof(int), &seed);
//void shuffle(void* base, int num, int width, int* seed);
//}}2015/01/06削除:乱数関連の宣言と実装を、clipmisc.*⇒cliprnd.*へ分離しました。

/* DDA(Digital Differential Analysis)構造体
 * * Sun Dec 4 04:01:00 JST 2004 Naoyuki Sawa (コメント追加のみ)
 * - 現在値を保持するフィールドはありません。
 *   現在値はDDA構造体とは別に保持してください。
 *   ただし、DDA構造体の一部のフィールドが不要となる場合は、そこに保持することもできます。
 *   詳しくは、次のコメントを参照してください。
 * - DDA構造体を汎用にサポートする関数はないので、各フィールドは任意に利用して構いません。
 *   たとえば、進行方向が＋方向固定ならば、多くの場合、繰上げ時の変化量は1固定となります。
 *   その場合、vを使う必要がなくなるので、代りに現在値をvに保持することができます。
 */
typedef struct _DDA {
	int n;			/* + 0,4 端数の増加量     */
	int d;			/* + 4,4 端数             */
	int u;			/* + 8,4 毎回の変化量     */
	int v;			/* +12,4 繰上げ時の変化量 */
				/* =16                    */
} DDA;

/* * Sun Dec 12 09:59:00 JST 2004 Naoyuki Sawa
 * - BLOCKSIZE、SPEAKER_FREQUENCYはP/ECE特有の定数ですが、Win32版テストプログラムからも参照するために、
 *   clippce.hからclipmisc.hへ移動しました。
 */
#define BLOCKSIZE		4096	/* フラッシュメモリのセクタサイズ */
#define SPEAKER_FREQUENCY	16000	/* P/ECEスピーカー出力周波数[Hz] */

/* * Sun Sep 15 20:37:35 JST 2013 Naoyuki Sawa
 * - min/maxマクロを追加しました。
 *   GCC拡張機能を利用しているので、Visual C++では使用できません。
 *   Visual C++では、windows.h(からインクルードされるwindef.h)で、同等のマクロが定義されています。
 *   Visual C++では、windows.hをインクルードして定義してください。
 *   ただし、下記のマクロはGCC拡張機能を利用しているので、引数を二回評価する副作用が有りませんが、
 *   windows.hで定義されているマクロは、引数を二回評価する副作用が【有る】ことに注意してください。
 * * Fri Jan 29 00:03:39 JST 2016 Naoyuki Sawa
 * - min/maxマクロを変更しました。
 *   異なる型に対してmin/maxマクロを使った場合、コンパイラが警告を出すようにしました。
 * - clampマクロを追加しました。
 *   min/maxマクロに依存しており、Visual C++では引数を二回評価する副作用が有る事に注意して下さい。
 *   GCCならば安全です。
 * - 上記二点は、Linuxのkernel.hを参考にしました。
 *   (http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/linux/kernel.h)
 */
#ifdef  __GNUC__
//{{2016/01/29変更:min/maxマクロを変更しました。異なる型に対してmin/maxマクロを使った場合、コンパイラが警告を出すようにしました。
//#define min(a,b) ({typeof(a) _a=(a); typeof(b) _b=(b); _a<=_b?_a:_b;})
//#define max(a,b) ({typeof(a) _a=(a); typeof(b) _b=(b); _a>=_b?_a:_b;})
//↓2016/01/29変更:min/maxマクロを変更しました。異なる型に対してmin/maxマクロを使った場合、コンパイラが警告を出すようにしました。
#define min(x,y) ({typeof(x) _x=(x); typeof(y) _y=(y); (void)(&_x==&_y); _x<=_y?_x:_y;})
#define max(x,y) ({typeof(x) _x=(x); typeof(y) _y=(y); (void)(&_x==&_y); _x>=_y?_x:_y;})
//}}2016/01/29変更:min/maxマクロを変更しました。異なる型に対してmin/maxマクロを使った場合、コンパイラが警告を出すようにしました。
#endif/*__GNUC__*/
//{{2016/01/29追加:clampマクロを追加しました。min/maxマクロに依存しており、Visual C++では引数を二回評価する副作用が有る事に注意して下さい。GCCならば安全です。
#define clamp(val,lo,hi) min(max(val,lo),hi)
//}}2016/01/29追加:clampマクロを追加しました。min/maxマクロに依存しており、Visual C++では引数を二回評価する副作用が有る事に注意して下さい。GCCならば安全です。

/* * Sat Feb 01 01:00:50 JST 2014 Naoyuki Sawa
 * - 引数を文字列化するマクロPRESCAN_STRINGIFYを追加しました。
 * - もし引数がマクロだった場合は、展開後に文字列化するよう、このように二重に定義する必要があります。
 *   ＜例＞
 *   コンパイル時に「-DPROJECT=test」と指定しておくと、ソースの中で:
 *   const char* fname = PRESCAN_STRINGIFY(PROJECT) ".pex"; //⇒"test" ".pex"⇒"test.pex"になります。
 * - 引数がマクロでない場合も、問題なく使用可能です。(あまり有用ではありませんが)
 *   ＜例＞
 *   const char* fname = PRESCAN_STRINGIFY(test) ".pex"; //⇒"test" ".pex"⇒"test.pex"になります。
 * - マクロの名称「PRESCAN_STRINGIFY」は、下記参考資料の説明文の中の用語から取って、名付けました。
 * - 下記の【参考資料】はGCCの資料ですが、試したところ、Visual C++ 6.0のプリプロセッサも同じ挙動のようでした。
 *   従って、このマクロ「PRESCAN_STRINGIFY」は、Visual C++ 6.0でも利用できます。
 */
#define  PRESCAN_STRINGIFY(s) _PRESCAN_STRINGIFY(s)
#define _PRESCAN_STRINGIFY(s) #s /* これは、二重化のためのマクロです。直接、使用しないでください。 */
//【参考資料】
//http://gcc.gnu.org/onlinedocs/cpp/Macro-Arguments.html
//http://www.sra.co.jp/public/sra/product/wingnut/gcc/cpp-j.html
//■The C Preprocessor
//□Separate Expansion of Macro Arguments
//┃実引数の置き換えを含むマクロ展開は、さらに展開すべきマクロ呼出しがないか再走査されるということを説明した。
//┃実際に起きていることはもっと巧妙である。
//┃最初に各実引数テキストが独立にマクロ呼出しがないかどうか走査される。
//┃次に、その結果がマクロ本体に代入されマクロ展開を生成する。
//┃そして、そのマクロ展開に展開すべきマクロがないかどうか再走査されるのである。
//┃この結果、実引数はその中にあるマクロ呼出しを展開するために二回走査されるのである。
//┃ほとんどの場合は、何も影響がない。
//┃実引数が任意のマクロ呼出しに含まれていれば、最初の走査の時に展開される。
//┃その結果、マクロ呼出しがなくなるので、二回目の走査では変更を行わない。
//┃実引数が与えられたように代入され、事前走査が行われないのなら、残り一回の走査で同じマクロ呼出しを見つけて同じ結果を生成する。
//┃読者は、自己参照マクロが別のマクロの実引数の中で使われているときは、二重に走査を行うと結果が変わると期待するかもしれない。
//┃自己参照マクロが最初の走査で一回展開され、二回目の走査でもう一度展開されると。
//┃だが、こうはならないのである。
//┃最初の走査で展開されない自己参照は、印が付けられ、二回目の走査でも展開されないのである。
//┃事前走査は、引数が文字列化されたり連結されたりする場合には行われない。							←注目
//┃すなわち、															←注目
//┃│#define str(s) #s														←注目
//┃│#define foo 4														←注目
//┃│str(foo)															←注目
//┃は"foo"に展開される。													←注目
//┃再び、事前走査による意味のある影響は防がれる。
//┃もっと正確に言うなら、文字列化と連結では、書かれた通りの引数を事前走査無しに使うのである。
//┃同じ実引数が、文字列化や連結を受けることなくどこか他の場所で置換されるなら、事前走査を受けた形で使われる。
//┃│#define str(s) #s lose(s)
//┃│#define foo 4
//┃│str(foo)
//┃は"foo" lose(4)に展開される。
//┃さて読者はこう聞きたくなるだろう。
//┃「何で事前走査の話を持ちだしたんだい?なんの違いもないんだろ?それに、どうして事前走査を飛ばしてプリプロセッサをもっと速くするようにしないの?」
//┃答えは、事前走査は、三つの特別な場合には違いが生じるからである。
//┃・マクロの入れ子呼出し
//┃・他の文字列化や連結を行うマクロを呼び出すマクロ
//┃・保護されていないカンマが展開に含まれるマクロ
//┃あるマクロの実引数にそのマクロそのものへの呼出しが含まれる場合、入れ子のマクロ呼出しが起きたと言う。
//┃例えば、fが引数を一つ取るマクロの場合、f(f(1))は、入れ子になったfの呼出しの対である。
//┃望ましい展開は、f(1)を展開し、それをfの定義の中に代入することである。
//┃事前走査があるので、期待どおりの結果になる。
//┃事前走査がないと、f(1)自身が実引数として代入されるので、内側のfは本番の走査のときに間接的な自己参照と見なされ、展開されないのである。
//┃ここでは、事前走査により、自己参照マクロの特別な規則の望ましくない副作用(この場合、医学的な意味で言っており、計算機学的なものではない)が打ち消されるのである。
//┃だが、事前走査は、入れ子マクロ呼出しの他の場合に問題を起こすことがある。
//┃以下に例を示す。
//┃│#define foo a,b
//┃│#define bar(x) lose(x)
//┃│#define lose(x) (1+(x))
//┃│bar(foo)
//┃bar(foo)は(1+(foo))に展開して欲しくて、次には(1+(a,b))に展開して欲しいと思う。
//┃だが、代わりに、bar(foo)はlose(a,b)に展開され、loseの引数は一個なのでエラーになる。
//┃この場合は、算術演算の入れ子の間違いを防ぐのに使うように括弧を使えば、簡単に解決できる。
//┃│#define foo (a,b)
//┃│#define bar(x) lose((x))
//┃マクロの引数が式でない場合は問題はもっと深刻になる。
//┃その場合は、括弧を付けると正しくないCのコードになってしまうからである。
//┃│#define foo {int a,b;...}
//┃GNU C では、({...}) 構文を使ってカンマを保護することができる。
//┃この構文は、複文を式に変える。
//┃│#define foo ({int a,b;...})
//┃あるいは、マクロ定義を書き直してこのようなカンマを避けることもできる。
//┃│#define foo {int a;int b;...}
//┃もう一つ、事前走査が役に立つ場合がある。
//┃事前走査で引数を展開してからそれを文字列化することが、二段階のマクロを使うことで可能になる。				←注目
//┃上に出てきた例に新しいマクロxstrを追加しよう。										←注目
//┃│#define xstr(s) str(s)													←注目
//┃│#define str(s) #s														←注目
//┃│#define foo 4														←注目
//┃│xstr(foo)															←注目
//┃これは"foo"ではなく"4"に展開される。											←注目
//┃この違いの理由は、xstrの引数は事前走査で展開されるからである。(なぜなら、xstrは引数の文字列化や連結を行わないから。)	←注目
//┃そして、事前走査の結果が、strの引数となる。											←注目
//┃strは、それ自身への引数を事前走査無しで使用する。(なぜなら、strは引数の文字列化を行うから。)				←注目
//┃しかしそれは、xstrによって既に行われた事前走査を、妨げたり無効化したりはしない。						←注目

/* * Wed Apr 09 00:15:54 JST 2014 Naoyuki Sawa
 * - 2進数リテラルを定義するマクロ BIN8()、BIN16()、BIN32() を追加しました。
 * * Tue Sep 27 21:08:22 JST 2016 Naoyuki Sawa
 * - BIN8()等をC++ソース内で使用した時に、「warning C4804:'/':演算中の'bool'型の使用方法が安全ではありません」が出る問題を修正しました。
 *   修正方法は、!!,及び,!演算子の結果を、明示的に(int)にキャストした事です。
 *   この修正は、C++ソースに限らずCソース内で使用する場合にも適用しても構わないのですが、敢えてC++ソースの場合だけ適用する事にしました。
 *   Cソース内では上記の警告は出ない事と、これまでCソースでは2年間以上問題無く動作していたので極力変更の影響範囲を少なくしたいからです。
 * - VS2015では、CソースでもC++ソースでも、BIN8()の引数に8桁を超える値を指定した時の、エラー検出が働かない事に気付きました。
 *   VC++6.0ならば、CソースでもC++ソースでもちゃんと「error C2124:除算、剰余演算が0で行われています。」というエラーになるので、VS2015のバグのような気がします。
 *   試してみたところ、VS2015は「int x = 1|(0/0);」という式を、エラー無く通してしまうのが原因のようです。
 *   式をいろいろ変えてみたのですが、どうやってもVS2015で上記のエラーを検出する事が出来なかったので、この点はこのままとする事にしました。
 *   引数が正しければ問題無いので、正しいプログラムには支障無いはずです。
 */
#ifndef __cplusplus
//Cソース用
#define BIN8(a) (((!!((0##a)& 000000001))<<0)|\
                 ((!!((0##a)& 000000010))<<1)|\
                 ((!!((0##a)& 000000100))<<2)|\
                 ((!!((0##a)& 000001000))<<3)|\
                 ((!!((0##a)& 000010000))<<4)|\
                 ((!!((0##a)& 000100000))<<5)|\
                 ((!!((0##a)& 001000000))<<6)|\
                 ((!!((0##a)& 010000000))<<7)|\
                 (0/!((0##a)&~011111111))|\
                 (0&sizeof&(a[(char*)0])))
#else //__cplusplus
//C++ソース用
#define BIN8(a) ((((int)(!!((0##a)& 000000001)))<<0)|\
                 (((int)(!!((0##a)& 000000010)))<<1)|\
                 (((int)(!!((0##a)& 000000100)))<<2)|\
                 (((int)(!!((0##a)& 000001000)))<<3)|\
                 (((int)(!!((0##a)& 000010000)))<<4)|\
                 (((int)(!!((0##a)& 000100000)))<<5)|\
                 (((int)(!!((0##a)& 001000000)))<<6)|\
                 (((int)(!!((0##a)& 010000000)))<<7)|\
                 (0/((int)!((0##a)&~011111111)))|\
                 (0&sizeof&(a[(char*)0])))
#endif//__cplusplus
#define BIN16(a,b)     ((BIN8(a)<<8)|BIN8(b))
#define BIN32(a,b,c,d) ((BIN16(a,b)<<16)|BIN16(c,d))
//□使用例:
//const int a=BIN8(01011010);                             //⇒0x5A             ８ビットの定義例
//const int b=BIN16(00010010,00110100);                   //⇒0x1234           16ビットの定義例
//const int c=BIN32(00010010,00110100,01010110,01111000); //⇒0x12345678       32ビットの定義例
//const int d=BIN32(10010,110100,1010110,1111000);        //⇒0x12345678       各桁の上位0は省略可能
//const int e=BIN8(101011010);                            //⇒コンパイルエラー 9桁以上はエラー      (マクロの下から2行目で検出する)
//const int f=BIN8(02022020);                             //⇒コンパイルエラー 0,1以外を含むとエラー(マクロの下から2行目で検出する)
//const int g=BIN8(0+1);                                  //⇒コンパイルエラー 式を含むとエラー     (マクロの最後の行で検出する)
//マクロの最後二行のエラー検出方法は、下記の記事を参考にさせて頂きました:
//⇒Qiita - プログラマの技術情報共有サービス「C言語の2進数マクロ」(http://qiita.com/Nabetani/items/6514689ca42bbfef5602)

/* * Tue Apr 15 19:07:53 JST 2014 Naoyuki Sawa
 * - 変数の符号無し最大値,符号付き最大値,又は,最小値を求めるマクロ UVAR_MAX(),VAR_MAX(),VAR_MIN() を追加しました。
 * - 変数xの変数型が、符号付きか符号無しかは、自動的に判定できません。			┬Wed Apr 16 00:15:22 JST 2014 Naoyuki Sawa
 *   変数xの変数型が、符号付きか符号無しかに対応した、適切なマクロを使用してください。	┘符号付きか符号無しかを自動的に判定するバージョンを追加しました。下のGVAR_MIN()等を参照してください。
 */
#define UVAR_MAX(x) (  4294967295U  >>((4-sizeof(x))*8)) //変数xの符号無し最大値を求める。結果の型は符号無し。
#define  VAR_MAX(x) (  2147483647   >>((4-sizeof(x))*8)) //変数xの符号付き最大値を求める。結果の型は符号付き。	//VC++6.0は、当マクロの結果の型が'符号無し'になるバグ(?)がある。このバグ(?)を回避するため、すぐ下で定義し直す。
#define  VAR_MIN(x) ((-2147483647-1)>>((4-sizeof(x))*8)) //変数xの符号付き最小値を求める。結果の型は符号付き。	//VC++6.0は、当マクロの結果の型が'符号無し'になるバグ(?)がある。このバグ(?)を回避するため、すぐ下で定義し直す。
#ifdef  _MSC_VER
#undef   VAR_MAX
#define  VAR_MAX(x) ((int)( 2147483647 >>( (4-sizeof(x))*8)   ))						//VC++6.0のバグ(?)回避
#undef   VAR_MIN
#define  VAR_MIN(x) ((int)((        -1)<<((   sizeof(x) *8)-1)))						//VC++6.0のバグ(?)回避
#endif//_MSC_VER
/* * Tue Apr 15 19:07:53 JST 2014 Naoyuki Sawa
 * - 変数の最大値,又は,最小値へ飽和する飽和加減算マクロ UVAR_ADD(),VAR_ADD(),UVAR_SUB(),VAR_SUB(),UVAR_INC(x),VAR_INC(x),UVAR_DEC(x),VAR_DEC(x) を追加しました。
 * - 引数xは、二回以上評価されることに注意してください。
 *   引数yは、一回しか評価されませんので、副作用のある式や関数を渡しても安全です。
 */
#define UVAR_ADD(x,y) do{unsigned __tmp__=(y);(x)=((((unsigned)(UVAR_MAX(x)-(x)))>=__tmp__)?((x)+__tmp__):UVAR_MAX(x));}while(0) //符号無し飽和加算。x=被加算変数(符号無し),y=加算値(符号無し)
#define  VAR_ADD(x,y) do{unsigned __tmp__=(y);(x)=((((unsigned)( VAR_MAX(x)-(x)))>=__tmp__)?((x)+__tmp__): VAR_MAX(x));}while(0) //符号付き飽和加算。x=被加算変数(符号付き),y=加算値(符号無し)
#define UVAR_SUB(x,y) do{unsigned __tmp__=(y);(x)=((((unsigned)((x)-         0 ))>=__tmp__)?((x)-__tmp__):         0 );}while(0) //符号無し飽和減算。x=被減算変数(符号無し),y=減算値(符号無し)
#define  VAR_SUB(x,y) do{unsigned __tmp__=(y);(x)=((((unsigned)((x)- VAR_MIN(x)))>=__tmp__)?((x)-__tmp__): VAR_MIN(x));}while(0) //符号付き飽和減算。x=被減算変数(符号付き),y=減算値(符号無し)
#define UVAR_INC(x) UVAR_ADD((x),1) //ユーティリティ
#define  VAR_INC(x)  VAR_ADD((x),1) //ユーティリティ
#define UVAR_DEC(x) UVAR_SUB((x),1) //ユーティリティ
#define  VAR_DEC(x)  VAR_SUB((x),1) //ユーティリティ
//□テストスイート:
//void TestSuite1() {
// {//UVAR_MAX(),VAR_MAX(),VAR_MIN()が正しい値を返すこと、及び、UVAR_MAX()が返す値の型が符号無し，VAR_MAX(),VAR_MIN()が返す値の型が符号付であることを確認する。
//  char c; short s; int i;
//  printf("%12u%12d%12d %d %d %d\n",UVAR_MAX(c),VAR_MAX(c),VAR_MIN(c),UVAR_MAX(c)<=-1,VAR_MAX(c)>=-1,VAR_MIN(c)<=0);//         255         127        -128 1 1 1
//  printf("%12u%12d%12d %d %d %d\n",UVAR_MAX(s),VAR_MAX(s),VAR_MIN(s),UVAR_MAX(s)<=-1,VAR_MAX(s)>=-1,VAR_MIN(s)<=0);//       65535       32767      -32768 1 1 1
//  printf("%12u%12d%12d %d %d %d\n",UVAR_MAX(i),VAR_MAX(i),VAR_MIN(i),UVAR_MAX(i)<=-1,VAR_MAX(i)>=-1,VAR_MIN(i)<=0);//  4294967295  2147483647 -2147483648 1 1 1
// }//                                                                  符号無比較~~   符号付比較~~   符号付比較~~
// {//引数の変数型が符号付きか符号無しかを判断することはできず、マクロの種類によってのみ判断する。従って、以下の例は上の例と同じ結果になる。
//  //本当は、引数の変数型が符号付きか符号無しかを自動的に判断できれば良かったのだが、C89では無理(又は極端に複雑?)になると思うので、諦めた。
//  unsigned char c; unsigned short s; unsigned int i;
//  printf("%12u%12d%12d %d %d %d\n",UVAR_MAX(c),VAR_MAX(c),VAR_MIN(c),UVAR_MAX(c)<=-1,VAR_MAX(c)>=-1,VAR_MIN(c)<=0);//         255         127        -128 1 1 1
//  printf("%12u%12d%12d %d %d %d\n",UVAR_MAX(s),VAR_MAX(s),VAR_MIN(s),UVAR_MAX(s)<=-1,VAR_MAX(s)>=-1,VAR_MIN(s)<=0);//       65535       32767      -32768 1 1 1
//  printf("%12u%12d%12d %d %d %d\n",UVAR_MAX(i),VAR_MAX(i),VAR_MIN(i),UVAR_MAX(i)<=-1,VAR_MAX(i)>=-1,VAR_MIN(i)<=0);//  4294967295  2147483647 -2147483648 1 1 1
// }//                                                                  符号無比較~~   符号付比較~~   符号付比較~~
//#if 0
// {//VC++6.0で、'定義し直す前'のバージョンを使うと、VC++6.0のバグ(?)のために、以下のように間違った結果になる。
//  char c; short s; int i;
//  printf("%12u%12d%12d %d %d %d\n",UVAR_MAX(c),VAR_MAX(c),VAR_MIN(c),UVAR_MAX(c)<=-1,VAR_MAX(c)>=-1,VAR_MIN(c)<=0);//         255         127         128 1 0 0
//  printf("%12u%12d%12d %d %d %d\n",UVAR_MAX(s),VAR_MAX(s),VAR_MIN(s),UVAR_MAX(s)<=-1,VAR_MAX(s)>=-1,VAR_MIN(s)<=0);//       65535       32767       32768 1 0 0
//  printf("%12u%12d%12d %d %d %d\n",UVAR_MAX(i),VAR_MAX(i),VAR_MIN(i),UVAR_MAX(i)<=-1,VAR_MAX(i)>=-1,VAR_MIN(i)<=0);//  4294967295  2147483647 -2147483648 1 0 0
// }//                                                                  符号無比較~~   符号無比較~~   符号無比較~~                              ~~~~~~~~~~~   ~ ~
//#endif
//{//飽和加減算マクロのテスト
//  unsigned  char uc=UCHAR_MAX-5;
//  unsigned short us=          5;
//  unsigned       ui= UINT_MAX-5;
//            char  c= CHAR_MAX-5;
//           short  s= SHRT_MIN+5;
//             int  i=  INT_MIN+5;
//  printf("%3d %3d %#x %3d %6d %#x\n",uc,us,ui,c,s,i);//250   5 0xfffffffa 122 -32763 0x80000005
//  UVAR_ADD(uc, 10);// 8bit符号無し飽和加算⇒飽和する場合
//  UVAR_SUB(us, 10);//16bit符号無し飽和減算⇒飽和する場合
//  UVAR_ADD(ui, 10);//32bit符号無し飽和加算⇒飽和する場合
//   VAR_ADD( c, 10);// 8bit符号付き飽和加算⇒飽和する場合
//   VAR_SUB( s, 10);//16bit符号付き飽和減算⇒飽和する場合
//   VAR_SUB( i, 10);//32bit符号付き飽和減算⇒飽和する場合
//  printf("%3d %3d %#x %3d %6d %#x\n",uc,us,ui,c,s,i);//255   0 0xffffffff 127 -32768 0x80000000
//  UVAR_SUB(uc,200);// 8bit符号無し飽和減算⇒飽和しない場合
//  UVAR_ADD(us,200);//16bit符号無し飽和加算⇒飽和しない場合
//  UVAR_SUB(ui,200);//32bit符号無し飽和減算⇒飽和しない場合
//   VAR_SUB( c,200);// 8bit符号付き飽和減算⇒飽和しない場合
//   VAR_ADD( s,200);//16bit符号付き飽和加算⇒飽和しない場合
//   VAR_ADD( i,200);//32bit符号付き飽和加算⇒飽和しない場合
//  printf("%3d %3d %#x %3d %6d %#x\n",uc,us,ui,c,s,i);// 55 200 0xffffff37 -73 -32568 0x800000c8
//}}
/* * Wed Apr 16 00:15:22 JST 2014 Naoyuki Sawa
 * - GCC拡張機能を利用して、符号付きか符号無しかを自動的に判定するバージョンを追加しました。
 *   GccとGeneric(汎用)の意味を掛けて、マクロ名の先頭に「G」の文字を付与しました。
 */
#define IS_TYPE_SIGNED(t) (((t)(-1))<0)			//型tが、符号付きか符号無しかを判定します。このマクロは、GCC以外でも使用できます。
#ifdef  __GNUC__
#define IS_VAR_SIGNED(x)  (IS_TYPE_SIGNED(typeof(x)))	//変数xが、符号付きか符号無しかを判定します。このマクロは、GCCでのみ使用できます。
#define GVAR_MIN(x  )      (IS_VAR_SIGNED(x) ?VAR_MIN(x  ):               0     )	//┬真式と偽式の型を、符号付きに揃えることにした。
#define GVAR_MAX(x  )      (IS_VAR_SIGNED(x) ?VAR_MAX(x  ):((int)UVAR_MAX(x  ) ))	//┘従って、マクロ全体の戻り値は、符号付きとなる。
#define GVAR_ADD(x,y) do{if(IS_VAR_SIGNED(x)){VAR_ADD(x,y);}else{UVAR_ADD(x,y);}}while(0)
#define GVAR_SUB(x,y) do{if(IS_VAR_SIGNED(x)){VAR_SUB(x,y);}else{UVAR_SUB(x,y);}}while(0)
#define GVAR_INC(x  ) do{if(IS_VAR_SIGNED(x)){VAR_INC(x  );}else{UVAR_INC(x  );}}while(0)
#define GVAR_DEC(x  ) do{if(IS_VAR_SIGNED(x)){VAR_DEC(x  );}else{UVAR_DEC(x  );}}while(0)
#endif//__GNUC__
//□テストスイート:
//#ifdef  __GNUC__
//void TestSuite2() {
// {//符号付き変数に対して、GVAR_MAX(),GVAR_MIN()が正しい値を返すこと、及び、戻り値の型が符号付きであることを確認する。
//  char c; short s; int i;
//  printf("%12d%12d %d %d\n",GVAR_MAX(c),GVAR_MIN(c),GVAR_MAX(c)>=-1,GVAR_MIN(c)<=0);//         127        -128 1 1
//  printf("%12d%12d %d %d\n",GVAR_MAX(s),GVAR_MIN(s),GVAR_MAX(s)>=-1,GVAR_MIN(s)<=0);//       32767      -32768 1 1
//  printf("%12d%12d %d %d\n",GVAR_MAX(i),GVAR_MIN(i),GVAR_MAX(i)>=-1,GVAR_MIN(i)<=0);//  2147483647 -2147483648 1 1
// }//                                                 符号付比較~~    符号付比較~~
// {//符号無し変数に対して、GVAR_MAX(),GVAR_MIN()が正しい値を返すこと、及び、戻り値の型が符号付きであることを確認する。
//  unsigned char c; unsigned short s; unsigned int i;
//  printf("%12u%12u %d %d\n",GVAR_MAX(c),GVAR_MIN(c),GVAR_MAX(c)>=-1,GVAR_MIN(c)<=0);//         255           0 1 1
//  printf("%12u%12u %d %d\n",GVAR_MAX(s),GVAR_MIN(s),GVAR_MAX(s)>=-1,GVAR_MIN(s)<=0);//       65535           0 1 1
//  printf("%12u%12u %d %d\n",GVAR_MAX(i),GVAR_MIN(i),GVAR_MAX(i)>=-1,GVAR_MIN(i)<=0);//  4294967295           0 1 1
// }//                                                 符号付比較~~    符号付比較~~
//{//飽和加減算マクロのテスト
//  unsigned  char uc=UCHAR_MAX-5;
//  unsigned short us=          5;
//  unsigned       ui= UINT_MAX-5;
//            char  c= CHAR_MAX-5;
//           short  s= SHRT_MIN+5;
//             int  i=  INT_MIN+5;
//  printf("%3d %3d %#x %3d %6d %#x\n",uc,us,ui,c,s,i);//250   5 0xfffffffa 122 -32763 0x80000005
//  GVAR_ADD(uc, 10);// 8bit符号無し飽和加算⇒飽和する場合
//  GVAR_SUB(us, 10);//16bit符号無し飽和減算⇒飽和する場合
//  GVAR_ADD(ui, 10);//32bit符号無し飽和加算⇒飽和する場合
//  GVAR_ADD( c, 10);// 8bit符号付き飽和加算⇒飽和する場合
//  GVAR_SUB( s, 10);//16bit符号付き飽和減算⇒飽和する場合
//  GVAR_SUB( i, 10);//32bit符号付き飽和減算⇒飽和する場合
//  printf("%3d %3d %#x %3d %6d %#x\n",uc,us,ui,c,s,i);//255   0 0xffffffff 127 -32768 0x80000000
//  GVAR_SUB(uc,200);// 8bit符号無し飽和減算⇒飽和しない場合
//  GVAR_ADD(us,200);//16bit符号無し飽和加算⇒飽和しない場合
//  GVAR_SUB(ui,200);//32bit符号無し飽和減算⇒飽和しない場合
//  GVAR_SUB( c,200);// 8bit符号付き飽和減算⇒飽和しない場合
//  GVAR_ADD( s,200);//16bit符号付き飽和加算⇒飽和しない場合
//  GVAR_ADD( i,200);//32bit符号付き飽和加算⇒飽和しない場合
//  printf("%3d %3d %#x %3d %6d %#x\n",uc,us,ui,c,s,i);// 55 200 0xffffff37 -73 -32568 0x800000c8
//}}
//#endif//__GNUC__

//{{2017/03/19追加:「Direct3D互換のD3DCOLOR形式マクロ」をDxlibHelper.h⇒clipmisc.hへ移動しました。
/****************************************************************************
 *	Direct3D互換のD3DCOLOR形式マクロ
 ****************************************************************************/
//□参照資料:/Program Files/Microsoft Visual Studio/VC98/Include/D3DTYPES.H
#ifndef _D3DTYPES_H_
//┌────┬────┬────┬────┐
//│alpha   │red     │green   │blue    │
//└────┴────┴────┴────┘
#define D3DRGBA(r,g,b,a)	RGBA_MAKE((r)*255,(g)*255,(b)*255,(a)*255)	//これだけ[0.0～1.0]。これ以外は[0～255]。
#define RGBA_MAKE(r,g,b,a)	((((uint8_t)(a))<<24)|(((uint8_t)(r))<<16)|(((uint8_t)(g))<<8)|((uint8_t)(b)))
#define RGBA_GETBLUE(rgba)	((uint8_t)(((int)(rgba))    ))
#define RGBA_GETGREEN(rgba)	((uint8_t)(((int)(rgba))>> 8))
#define RGBA_GETRED(rgba)	((uint8_t)(((int)(rgba))>>16))
#define RGBA_GETALPHA(rgba)	((uint8_t)(((int)(rgba))>>24))
#define RGBA_SETALPHA(rgba,a)	((((uint8_t)(a))<<24)|(((int)(rgba))&0xFFFFFF))
#define RGBA_TORGB(rgba)	RGBA_SETALPHA(rgba,0)
//┌────┬────┬────┬────┐
//│ignored │red     │green   │blue    │
//└────┴────┴────┴────┘
//{{2017/03/21変更:D3DRGB()マクロでD3DCOLOR値を作成した場合、α成分が1.0になるように修正しました。
//#define D3DRGB(r,g,b)		D3DRGBA(r,g,b,0)				//これだけ[0.0～1.0]。これ以外は[0～255]。
//↓2017/03/21変更:D3DRGB()マクロでD3DCOLOR値を作成した場合、α成分が1.0になるように修正しました。
#define D3DRGB(r,g,b)		D3DRGBA(r,g,b,1)				//これだけ[0.0～1.0]。これ以外は[0～255]。	//┐2017/03/21コメント追記:
//}}2017/03/21変更:D3DRGB()マクロでD3DCOLOR値を作成した場合、α成分が1.0になるように修正しました。				//│RGB_MAKE()はα成分を0.0にするが、D3DRGB()はα成分を1.0にするという、Direct3Dの仕様に合わせました。
#define RGB_MAKE(r,g,b)		RGBA_MAKE(r,g,b,0)										//┘なぜそういう判り辛い仕様になっているのか理解出来ないのですが、ともかく、合わせておく事にしました。
#define RGB_GETBLUE(rgb)	RGBA_GETBLUE(rgb)
#define RGB_GETGREEN(rgb)	RGBA_GETGREEN(rgb)
#define RGB_GETRED(rgb)		RGBA_GETRED(rgb)
#define RGB_TORGBA(rgb)		RGBA_SETALPHA(rgb,255)
#endif//_D3DTYPES_H_
//}}2017/03/19追加:「Direct3D互換のD3DCOLOR形式マクロ」をDxlibHelper.h⇒clipmisc.hへ移動しました。

//{{2016/08/16削除:エラー停止処理とトレース出力処理を、clipmisc.h,clipmisc.cから、clipdie.h,clipdie.cへ分離しました。
///*****************************************************************************
// *	エラー処理
// *****************************************************************************/
//
///* エラーメッセージを表示し、プログラムを強制終了します。
// * [in]
// *	fmt,...		printf()の引数と同様です。
// * [note]
// *	* この関数は処理を返しません。
// */
//#ifdef PIECE
//void die(const char* fmt, ...) __attribute__((noreturn));
////{{2016/04/15追加:vdie()を追加しました。
//void vdie(const char* fmt, va_list ap) __attribute__((noreturn));
////}}2016/04/15追加:vdie()を追加しました。
////{{2012/01/14:追加
//void die2(const char* file, int line) __attribute__((noreturn));
//void die3(const char* file, int line, const char* f) __attribute__((noreturn));
////}}2012/01/14:追加
//#else /*PIECE*/
//__declspec(noreturn) void die(const char* fmt, ...);
////{{2016/04/15追加:vdie()を追加しました。
//__declspec(noreturn) void vdie(const char* fmt, va_list ap);
////}}2016/04/15追加:vdie()を追加しました。
////{{2012/01/14:追加
//__declspec(noreturn) void die2(const char* file, int line);
//__declspec(noreturn) void die3(const char* file, int line, const char* f);
////}}2012/01/14:追加
//#endif /*PIECE*/
//
///*****************************************************************************
// *	トレース出力
// *****************************************************************************/
//
///* !!要注意!! TRACE()マクロはアプリケーション専用です。CLiPライブラリの中で使わないように!!
// *            (TRACE()マクロはTRACE_ONシンボルの定義によって振る舞いが変わるので、
// *             あらかじめコンパイルされるライブラリの中ではTRACE_ONによる振る舞いの切り替えが効かないから)
// *
// * * トレース出力を利用する場合は、  clip.hをインクルードする前に「#define TRACE_ON 1」を定義してください。
// *   トレース出力を利用しない場合は、clip.hをインクルードする前に「#define TRACE_ON 0」を定義するか、
// *   またはTRACE_ONシンボルを定義しないでください。
// * * トレース出力を利用しない場合は、トレース文字列はCコンパイラの最適化によって削除されます。
// *   TRACE()呼び出しを削除しなくても、トレース文字列がメモリを圧迫することはありません。
// */
//#if defined(TRACE_ON) && (TRACE_ON)
//#define TRACE	trace
//#else
//#define TRACE	1 ? (void)0 : trace
//#endif
//
///* 標準エラー出力へのfprintfです。
// * [in]
// *	fmt,...		printf()の引数と同様です。
// * [note]
// *	* TRACEマクロ経由で利用します。
// */
//void trace(const char* fmt, ...);
//}}2016/08/16削除:エラー停止処理とトレース出力処理を、clipmisc.h,clipmisc.cから、clipdie.h,clipdie.cへ分離しました。

//{{2015/01/06削除:「ユーティリティ：任意長パケットキュー」を、clipmisc.*⇒clipque.*へ分離しました。
///*****************************************************************************
// *	ユーティリティ：任意長パケットキュー
// *****************************************************************************/
//
///* * 任意長パケットのFIFOキューを表します。キューの構造は下図のとおりです。
// *
// *	+==================+･･････････････････････････････････････････････
// *	|     capacity     |　↑　　　　　　　　　　　　　　　　　　　　　
// *	+------------------+　│QUEUE 　　　　　　　　　　　　　　　　　　
// *	|       size       |　↓　　　　　　　　　　　　　　　　　　　　　
// *	+==================+･･････････････････････････････････････････････
// *	| 1個目のﾊﾟｹｯﾄｻｲｽﾞ |　　word　　　　　　　　　　↑　　　↑　　　　
// *	+------------------+･･････････････････････････　│　　　│　　　　
// *	|                  |　↑　　　　　　　　　　　　│　　　│　　　　
// *	| 1個目のﾊﾟｹｯﾄﾃﾞｰﾀ |　│byte[1個目のﾊﾟｹｯﾄｻｲｽﾞ]　│　　　│　　　　
// *	|                  |　↓　　　　　　　　　　　　│　　　│　　　　
// *	+------------------+･･････････････････････････　│　　　│　　　　
// *	| 2個目のﾊﾟｹｯﾄｻｲｽﾞ |　　word　　　　　　　　　　│　　　│　　　　
// *	+------------------+･･････････････････････････　│　　　│　　　　
// *	|                  |　↑　　　　　　　　　　　　│　　　│　　　　
// *	| 2個目のﾊﾟｹｯﾄﾃﾞｰﾀ |　│byte[2個目のﾊﾟｹｯﾄｻｲｽﾞ]　│　　　│　　　　
// *	|                  |　↓　　　　　　　　　　　　│　　　│　　　　
// *	+------------------+･･････････････････････････　│　　　│　　　　
// *	|        ・        |　　　　　　　　　　　　　　│size　│capacity
// *	|        ・        |　　　　　　　　　　　　　　│　　　│　　　　
// *	|        ・        |　　　　　　　　　　　　　　│　　　│　　　　
// *	+------------------+･･････････････････････････　│　　　│　　　　
// *	| N個目のﾊﾟｹｯﾄｻｲｽﾞ |　　word　　　　　　　　　　│　　　│　　　　
// *	+------------------+･･････････････････････････　│　　　│　　　　
// *	|                  |　↑　　　　　　　　　　　　│　　　│　　　　
// *	| N個目のﾊﾟｹｯﾄﾃﾞｰﾀ |　│byte[N個目のﾊﾟｹｯﾄｻｲｽﾞ]　│　　　│　　　　
// *	|                  |　↓　　　　　　　　　　　　↓　　　│　　　　
// *	+------------------+･･････････････････････････････････　│　　　　
// *	|                  |　　　　　　　　　　　　　　　　　　│　　　　
// *	|    (空き領域)    |　　　　　　　　　　　　　　　　　　│　　　　
// *	|                  |　　　　　　　　　　　　　　　　　　↓　　　　
// *	+==================+･･････････････････････････････････････････････
// */
//typedef struct _QUEUE {
//	int capacity;	/* ストレージの総容量 */
//	int size;	/* ストレージの使用量 */
//	/*unsigned char storage[capacity]*/
//} QUEUE;
//
///* キューを作成します。
// * [in]
// *	capacity	ストレージサイズ。
// *			実際に確保するストレージサイズは、capacity+sizeof(int)となります。
// *			[note]を参照してください。
// * [out]
// *	戻り値		作成したキュー。
// * [note]
// *	* キューの使用が終わったら、delete_queue()で削除してください。
// *	* create_queue()が実際に確保するストレージサイズは、(capacity+sizeof(int))です。
// *	  最大で、capacityバイトのパケットを一つ、キューに格納できるようにするためです。
// *	  呼び出し側にて、パケットサイズ格納用のsizeof(int)を加算して指定する必要はありません。
// */
//QUEUE* create_queue(int capacity);
//
///* キューを削除します。
// * [in]
// *	queue		削除するキュー。
// */
//void delete_queue(QUEUE* queue);
//
///* キューを空にします。
// * [in]
// *	queue		空にするキュー。
// */
//void clear_queue(QUEUE* queue);
//
///* キューにパケットを追加します。
// * [in]
// *	queue		キュー。
// *	packet		追加するパケットデータ。
// *	length		追加するパケットサイズ。(0、または、正数)
// * [out]
// *	戻り値		成功ならば、パケットサイズをそのまま返します。
// *			失敗ならば、負数を返します。
// * [note]
// *	* 0バイトのパケットを追加することも可能です。
// *	  戻り値「0」は、成功を意味することに注意してください。
// */
//int write_queue(QUEUE* queue, const void* packet/*[length]*/, int length);
//
///* キューからパケットを取り出します。
// * [in]
// *	queue		キュー。
// *	packet		取り出したパケットデータを格納するメモリ領域。
// *			NULLを指定すると、読み出したパケットデータを破棄します。
// *	length		取り出したパケットサイズ。(0、または、正数)
// * [out]
// *	戻り値		成功ならば、取り出したパケットサイズを返します。
// *			失敗ならば、負数を返します。
// * [note]
// *	* 0バイトのパケットを取り出すことも有り得ます。
// *	  戻り値「0」は、成功を意味することに注意してください。
// *	* packet=NULLを指定した場合、読み出したパケットデータを破棄します。
// *	  その際も、length引数は意味を持つことに注意してください。
// *	  キューの先頭にある任意長のパケットを破棄するには、次のように呼び出してください。
// *		read_queue(queue, NULL, INT_MAX);
// */
//int read_queue(QUEUE* queue, void* packet/*[maxlength]*/, int maxlength);
//
///* キューの先頭のパケットを参照します。
// * [in]
// *	queue		キュー。
// *	length		パケットサイズを格納する変数へのポインタ。
// *			NULLを指定すると、パケットサイズを格納しません。
// * [out]
// *	戻り値		パケットデータの先頭アドレス。
// *			キューが空の場合、NULLを返し、パケットサイズを格納しません。
// * [note]
// *	* キューが空の場合と、先頭のパケットが0バイトの場合の違いに注意してください。
// *	  キューが空の場合は、NULLを返し、パケットサイズを格納しません。
// *	  先頭のパケットが0バイトの場合は、NULL以外のポインタを返し、パケットサイズに0を格納します。
// */
//const void* peek_queue(QUEUE* queue, int* length);
//
///* キューに追加可能な、最大パケットサイズを求めます。
// * [in]
// *	queue		キュー。
// * [out]
// *	戻り値		最大パケットサイズ。
// */
//int queue_space(QUEUE* queue);
//}}2015/01/06削除:「ユーティリティ：任意長パケットキュー」を、clipmisc.*⇒clipque.*へ分離しました。

//{{2015/01/06削除:「ユーティリティ：リングバッファ」を、clipmisc.*⇒clipbuf.*へ分離しました。
///*****************************************************************************
// *	ユーティリティ：リングバッファ
// *****************************************************************************/
//
///* 2005/08/26現在の実装は、実際にはリング構造でなく、メモリ移動を使った簡易実装となっています。
// * もしも今後、速度性能が問題となった場合は、実際にリング構造を使って再実装する予定です。
// * その際に、内部処理を変更しても、プログラムインターフェイスは変化しないはずです。
// */
//typedef struct _BUFFER {
//	int capacity;	/* ストレージの総容量 */
//	int size;	/* ストレージの使用量 */
//	/*unsigned char storage[capacity]*/
//} BUFFER;
//
///* バッファを作成します。
// * [in]
// *	capacity	ストレージサイズ。
// * [out]
// *	戻り値		作成したバッファ。
// * [note]
// *	* バッファの使用が終わったら、delete_buffer()で削除してください。
// */
//BUFFER* create_buffer(int capacity);
//
///* バッファを削除します。
// * [in]
// *	buffer		削除するバッファ。
// */
//void delete_buffer(BUFFER* buffer);
//
///* バッファを空にします。
// * [in]
// *	queue		空にするバッファ。
// */
//void clear_buffer(BUFFER* buffer);
//
///* バッファにデータを書き込みます。
// * [in]
// *	buffer		バッファ。
// *	data		書き込むデータ。
// *	length		書き込むデータ長。
// * [out]
// *	戻り値		実際に書き込んだデータ長を返します。(0≦戻り値≦length)
// *			ストレージの空き容量が不足している場合、部分的な書き込みとなります。
// *			部分的な書き込みを行った場合、戻り値は、lengthよりも小さくなります。
// */
//int write_buffer(BUFFER* buffer, const void* data/*[length]*/, int length);
//
///* バッファからデータを読み出します。
// * [in]
// *	buffer		バッファ。
// *	data		読み出したデータを格納するメモリ領域。
// *			NULLを指定すると、読み出したデータを破棄します。
// *	maxlength	読み出すデータの最大長。
// * [out]
// *	戻り値		実際に読み出したデータ長を返します。(0≦戻り値≦length)
// */
//int read_buffer(BUFFER* buffer, void* data/*[maxlength]*/, int maxlength);
//
///* バッファのデータを参照します。
// * [in]
// *	buffer		バッファ。
// *	length		データ長を格納する変数へのポインタ。
// *			NULLを指定すると、データ長を格納しません。
// * [out]
// *	戻り値		ストレージの先頭アドレス。
// * [note]
// *	* この関数は、必ず成功します。
// *	  バッファが空の場合も、ストレージの先頭アドレスを返し、データ長に0を格納します。
// */
//const void* peek_buffer(BUFFER* buffer, int* length);
//
///* バッファに書き込み可能な、最大データ長を求めます。
// * [in]
// *	buffer		バッファ。
// * [out]
// *	戻り値		最大データ長。
// */
//int buffer_space(BUFFER* buffer);
//}}2015/01/06削除:「ユーティリティ：リングバッファ」を、clipmisc.*⇒clipbuf.*へ分離しました。

//{{2015/01/06削除:「ユーティリティ：ダブルリンクリスト」を、clipmisc.*⇒clipdlst.*へ分離しました。
///*****************************************************************************
// *	ユーティリティ：ダブルリンクリスト
// *****************************************************************************/
//
///* Windows DDK互換の、ダブルリンクリスト操作関数群です。
// * CONTAINING_RECORD()マクロと併せて、使用してください。
// */
//typedef struct _LIST_ENTRY {
//	struct _LIST_ENTRY *Flink;	/* 前方リンク */
//	struct _LIST_ENTRY *Blink;	/* 後方リンク */
//} LIST_ENTRY;
//
///* ダブルリンクリストを初期化します。 */
//void InitializeListHead(LIST_ENTRY* ListHead);
//
///* ダブルリンクリストが空か否か、判定します。 */
//int IsListEmpty(LIST_ENTRY* ListHead);
//
///* ダブルリンクリストから、先頭の要素を取り除きます。 */
//LIST_ENTRY* RemoveHeadList(LIST_ENTRY* ListHead);
//
///* ダブルリンクリストから、末尾の要素を取り除きます。 */
//LIST_ENTRY* RemoveTailList(LIST_ENTRY* ListHead);
//
///* ダブルリンクリストから、指定した要素を取り除きます。 */
//void RemoveEntryList(LIST_ENTRY* Entry);
//
///* ダブルリンクリストの先頭に、指定した要素を追加します。 */
//void InsertHeadList(LIST_ENTRY* ListHead, LIST_ENTRY* Entry);
//
///* ダブルリンクリストの末尾に、指定した要素を追加します。 */
//void InsertTailList(LIST_ENTRY* ListHead, LIST_ENTRY* Entry);
//}}2015/01/06削除:「ユーティリティ：ダブルリンクリスト」を、clipmisc.*⇒clipdlst.*へ分離しました。

//{{2015/01/06削除:「ユーティリティ：検索」を、clipmisc.*⇒clipmatc.*へ分離しました。
///*****************************************************************************
// *	ユーティリティ：検索
// *****************************************************************************/
//
///* クイックサーチ法を使って、バイナリパターン検索を行います。
// * [in]
// *	mem1		検索されるバイナリデータ
// *	len1		検索されるバイナリデータのバイト数
// *	mem2		検索するバイナリパターン
// *	len2		検索するバイナリパターンのバイト数
// * [out]
// *	戻り値		mem2がmem1内に最初に現れた位置へのポインタを返します。
// *			mem2がmem1内に見つからない場合は、NULLポインタを返します。
// *			len2が0の場合は、mem1を返します。
// * [note]
// * - ★重要!! 本関数は、スタックを1KB消費します。
// *   ★スタックオーバーフローに注意してください。
// * - 戻り値の仕様は、strstr()と互換性があります。
// *   strstr()の代わりに使う場合は、以下のように呼び出してください。
// *      ptr = strstr(str1, str2);
// *   → ptr = quick_search(str1, strlen(str1), str2, strlen(str2));
// * - クイックサーチ法は、Sunday法、BMS法とも呼ばれます。
// *   解説 http://www.inf.fh-flensburg.de/lang/algorithmen/pattern/sundayen.htm
// */
//void* quick_search(const void* _mem1/*[len1]*/, int len1, const void* _mem2/*[len2]*/, int len2);
//
///* O'Reilly Japan「ビューティフルコード」に掲載されている、シンプルな正規表現マッチャです。
// * [in]
// *	regexp		正規表現。
// *	text		テキスト。
// * [out]
// *	戻り値		テキストの中に正規表現が"部分一致"したら1、そうでなければ0を返します。
// *			マッチ条件が、"部分一致"であることに要注意です。
// *			"完全一致"で判断する場合は、'^'と'$'を使います。
// * [note]
// * 	* 僕はこの本を持っていなくて、以下のサイトの記事に引用されていたソースコードを参照しました。
// *
// *	  http://weblogs.asp.net/meligy/archive/2008/04/27/beautiful-code-back-to-basics-please-read-this-c-code-quickly.aspx
// *
// *	  The code is a VERY simple RegEx (Regular Expression) matching.
// *	  Some code that you send a pattern and text to match.
// *	  It returns 1 if the text matches the pattern and 0 otherwise.
// *	  The pattern domain is a very stripped version of RegEx than only includes:
// *
// *	  c => (Any character) matches any literal character c
// *	  . => (Period) matches any single character
// *	  ^ => matches the beginning of the string (meaning there must be beginning, not empty string)
// *	  $ => matches the end of the string (meaning when tested, there should be no more characters in the string)
// *	  * => (appearing after a character) matches zero or more occurrences of the previous character in the string
// */
////int match(const char* regexp, const char* text);
////↓ * Mon Jan 03 22:48:46 JST 2011 Naoyuki Sawa
////↓ - match()→VERY_simple_RegEx_matching()に名前変更しました。
////↓   「match」では単純すぎて、オープンソースソフトのコンパイル時に、名前が衝突することがあるためです。
////↓   具体的には、「Lua 5.1.4」をコンパイルしようとすると、同名のローカル関数があり、名前衝突しました。
////↓ - 本関数は、シンプルな正規表現マッチャの実装方法を覚えておく程度の役割であり、実際に使うことはほとんど無いと思います。
////↓   従って、極端に長い名前で、使いづらくても、さほど問題にはならないと思います。
////↓   上記サイトの説明文から取って、「VERY_simple_RegEx_matching」という極端に長い関数名にすることにしました。
//int VERY_simple_RegEx_matching(const char* regexp, const char* text);
//}}2015/01/06削除:「ユーティリティ：検索」を、clipmisc.*⇒clipmatc.*へ分離しました。

//{{2015/01/06削除:「ユーティリティ：ソート」の宣言を、clipmisc.hからclipsort.hへ分離しました。
///*****************************************************************************
// *	ユーティリティ：ソート
// *****************************************************************************/
//
///* マージソートを実行します。
// * [in]
// *	base		ソートする配列の先頭
// *	num		配列の要素数
// *	width		配列要素のサイズ(バイト数)
// *	compare		比較関数
// * [note]
// *	- 引数の仕様は、qsort()関数と同じです。
// *	- クイックソートに対する、マージソートの利点：
// *	  ・安定ソートである。
// *	  ・あらかじめほとんど整列されている配列に対しては、クイックソートよりも高速である。
// *	- クイックソートに対する、マージソートの欠点：
// *	  ・ソートする配列と同じサイズの、一時的な作業用メモリが必要である。
// *	  ・あまり整列されていないばらばらの配列に対しては、クイックソートよりも低速である。
// *	- 以上の利点と欠点を勘案して、ソート方法を選択してください。
// *	  通常はクイックソートを使い、安定ソートが必要な場合のみマージソートを使うのが適切です。
// */
//void msort(void* a, size_t length, size_t width, int (*compare)(const void*, const void*)); /* -> clipsort.c */
//}}2015/01/06削除:「ユーティリティ：ソート」の宣言を、clipmisc.hからclipsort.hへ分離しました。

//{{2015/01/06削除:コレクション関連の宣言を、clipmisc.hからclipcoll.hへ分離しました。
///*****************************************************************************
// *	ユーティリティ：コレクションのヘルパ関数
// *****************************************************************************/
//
///* ヘルパ関数の実装例: コレクションがメモリ管理を行わないポインタ、または、数値
// */
//void* ptr_copy(void* a);
//void  ptr_delete(void* a);
//int   ptr_equals(void* a, void* b);
//
///* ヘルパ関数の実装例: コレクションがメモリ管理を行う文字列
// * * map_put()は、渡された文字列をコピーして、コレクションに保持します。
// * // * map_get()は、文字列をコピーせず、保持している文字列のポインタをそのまま返します。
// * //   必要に応じて、map_get()の呼び出し元が、文字列のコピーを作成してください。
// * ↓2005/12/11 仕様変更
// * * map_get()は、保持している文字列のコピーを作成して、呼び出し元に返します。
// *   map_get()の呼び出し元は、文字列の使用が終了したら、str_delete()を使って文字列を解放してください。
// *   str_delete()の実装は、単にfree()を行っているだけなので、直接free()を使って解放しても構いません。
// */
//void* str_copy(void* a);
//void  str_delete(void* a);
//int   str_equals(void* a, void* b);
//
///* ヘルパ関数の実装例: インターフェイスポインタ (UNKNOWN_INTERFACE**)
// * * キーとして用いた場合の等価判定は、オブジェクト比較です。
// *   オブジェクトが複数のインターフェイスをサポートしている場合、
// *   そのオブジェクトに対するUNKNOWNインターフェイスポインタは、複数存在します。
// *   unk_equals()は、それらの異なるインターフェイスポインタを等価と見なします。
// *   このような挙動が必要ない場合(単なるポインタ比較で良い場合)は、
// *   unk_equals()の代りに、ptr_equals()を使ってください。
// * * map_put()は、渡されたインターフェイスポインタをaddref()して、コレクションに保持します。
// * // * map_get()は、インターフェイスポインタをaddref()せず、そのまま返します。
// * //   この挙動は、参照カウントの増減ルール[ルール1-1]に反する、特例です。
// * //   必要に応じて、map_get()の呼び出し元が、addref()を行ってください。
// * //   呼び出し元が、addref()を行わなかった場合は、release()も不要です。
// * ↓2005/12/11 仕様変更
// * * map_get()が、インターフェイスポインタをaddref()して、呼び出し元に返すようになりました。
// *   呼び出し元が、map_get()から返されたインターフェイスポインタに対し、addref()する必要はありません。
// *   呼び出し元は、返されたインターフェイスポインタの使用が終了したら、release()を行う必要があります。
// *   以上の挙動は、参照カウントの増減ルール[ルール1-1]に準拠しています。
// *   すなわち、2005/12/11の仕様変更により、map_get()の挙動だけを特別扱いする必要が無くなりました。
// */
//void* unk_copy(void* a);
//void  unk_delete(void* a);
//int   unk_equals(void* a, void* b);
//
///*****************************************************************************
// *	ユーティリティ：マップ (コレクション)
// *****************************************************************************/
//
///* マップ情報 */
//typedef struct _MAP_INFO {
//	void* (*key_copy)(void* key);			/* キーを複製する、ヘルパ関数 */
//	void  (*key_delete)(void* key);			/* キーを削除する、ヘルパ関数 */
//	int   (*key_equals)(void* key1, void* key2);	/* キーを比較する、ヘルパ関数 */
//	void* (*val_copy)(void* val);			/* 値  を複製する、ヘルパ関数 */
//	void  (*val_delete)(void* val);			/* 値  を削除する、ヘルパ関数 */
//} MAP_INFO;
//
///* マップ */
//typedef struct _MAP {
//	LIST_ENTRY list_head;	/* MAP_NODEのリストヘッダ */
//	MAP_INFO map_info;	/* マップ情報 */
//} MAP;
//
///* マップ要素
// * * ガベージコレクションを使用可能とするために、マップ要素とリストエントリの先頭アドレスを揃えてあります。
// *   両者のアドレスが違っていると、ガベージコレクタが未開放のマップ要素を誤って開放してしまうためです。
// * - ガベージコレクションの使用は必須ではありません。
// *   MAP構造体やMAP_NODE構造体のメモリ開放は、ライブラリが明示的に行っています。
// *   キーと値のメモリ管理は、アプリケーション定義のヘルパ関数にて、明示的に行うことが可能です。
// * - ガベージコレクションを使うと、明示的な、キーと値のメモリ解放を省略し、ヘルパ関数を簡略化できます。
// */
//typedef struct _MAP_NODE {
//	LIST_ENTRY list_entry;	/* MAP_NODEのリストエントリ */
//	void* key;		/* キー (実際の型はアプリケーション定義) */
//	void* val;		/* 値   (実際の型はアプリケーション定義) */
//} MAP_NODE;
//
///* マップを作成します。
// * [in]
// *	map_info	マップ情報。
// * [out]
// *	戻り値		マップ。
// */
//MAP* map_create(const MAP_INFO* map_info);
//
///* マップを削除します。
// * [in]
// *	map		マップ。
// * [note]
// *	* 自動的にmap_clear()を呼び、残っているマップ要素をすべて削除します。
// *	  明示的にmap_clear()を呼んでおく必要はありません。
// */
//void map_delete(MAP* map);
//
///* マップの全要素を削除します。
// * [in]
// *	map		マップ。
// * [note]
// *	* 各マップ要素について、key_delete()ヘルパ関数を用いて、キーを削除します。
// *	                        val_delete()ヘルパ関数を用いて、値  を削除します。
// */
//void map_clear(MAP* map);
//
///* 指定されたキーに対応するマップ要素が有るか、判定します。
// * [in]
// *	map		マップ。
// *	key		キー。
// * [out]
// *	戻り値		マップ要素が有れば、  0以外の値を返します。
// *			マップ要素が無ければ、0を返します。
// */
//int map_contains(MAP* map, void* key);
//
///* 指定されたキーに対応するマップ要素を作成し、値を格納します。
// * [in]
// *	map		マップ。
// *	key		キー。
// *	val		値。
// * [note]
// *	* key_copy()ヘルパ関数を用いて、キーを複製し、マップ要素に格納します。
// *	  アプリケーションは、呼び出し時に指定したkeyを維持する必要はありません。
// *	  ただし、key_copy()ヘルパ関数が複製を行わない場合は、この限りではありません。
// *	* val_copy()ヘルパ関数を用いて、値を複製し、マップ要素に格納します。
// *	  アプリケーションは、呼び出し時に指定したvalを維持する必要はありません。
// *	  ただし、val_copy()ヘルパ関数が複製を行わない場合は、この限りではありません。
// *	* 既に、指定されたキーに対応する値が存在する場合は、既存の値を削除します。
// *	  既存の値の削除には、val_delete()ヘルパ関数が利用されます。
// */
//void map_put(MAP* map, void* key, void* val);
//
///* 指定されたキーに対応するマップ要素の、値を取得します。
// * [in]
// *	map		マップ。
// *	key		キー。
// * [out]
// *	戻り値		値。
// * [note]
// *	* 指定されたキーに対応するマップ要素が存在しない場合は、アサートします。
// *	  先にmap_contains()を用いて、キーに対応するマップ要素が存在することを確認してください。
// *	  <例>	if(map_contains(map, key)) {
// *			val = map_get(map, key);
// *			...
// *			free(val); // 2005/12/11の仕様変更により、値の解放が必要となりました。
// *		}
// *	// * 返される値は、複製ではなく、マップ要素が保持している値をそのまま返します。
// *	//   呼び出し側アプリケーションにて、返された値を削除してはいけません。
// *	//↓2005/12/11 仕様変更
// *	* map_get()は、val_copy()ヘルパ関数を用いて値の複製を作成し、その複製を返します。
// *	  返された値の所有権は、map_get()を呼び出した側のみに有ります。
// *	  map_get()を呼び出した側は、返された値を適切に解放することを忘れないでください。
// */
//void* map_get(MAP* map, void* key);
//
///* 指定されたキーに対応するマップ要素を削除します。
// * [in]
// *	map		マップ。
// *	key		キー。
// * [note]
// *	* 指定されたキーに対応するマップ要素が存在しない場合は、アサートします。
// *	  先にmap_contains()を用いて、キーに対応するマップ要素が存在することを確認してください。
// *	  <例>	if(map_contains(map, key)) {
// *			map_remove(map, key);
// *		}
// *	* 削除するマップ要素のキーは、key_delete()ヘルパ関数を用いて、自動的に削除されます。
// *	  削除するマップ要素の値  は、val_delete()ヘルパ関数を用いて、自動的に削除されます。
// */
//void map_remove(MAP* map, void* key);
//
///* マップを複製します。
// * [in]
// *	map		複製元のマップ。
// * [out]
// *	戻り値		複製したマップ。
// * [note]
// *	* この関数が行う処理は、以下のとおりです。
// *	  1. 複製元のマップと同じマップ情報を持つ、空のマップを作成します。
// *	     これが、複製先のマップとなります。
// *	  2. 複製元のマップの各要素のキーと値について、key_copyとval_copy()ヘルパ関数を用いて複製し、
// *	     複製先のマップへ追加します。
// *	  3. 複製先のマップを返します。
// */
//MAP* map_duplicate(MAP* map);
//
///* マップ要素に含まれている、すべてのキーから成る、リストを作成します。
// * [in]
// *	map		マップ。
// * [out]
// *	戻り値		リスト。
// * [note]
// *	* 作成されたリストのヘルパ関数は、作成元のマップのヘルパ関数の一部と同一となります。
// *	  リスト情報のヘルパ関数と、マップのヘルパ関数との対応は、以下のとおりです。
// *		==== 作成元のマップ ====    ==== 作成されたリスト ====
// *		map->map_info.key_copy   → list->list_info.val_copy  
// *		map->map_info.key_delete → list->list_info.val_delete
// *		map->map_info.key_equals → 使いません
// *		map->map_info.val_copy   → 使いません
// *		map->map_info.val_delete → 使いません
// *	* 返されたリストが不要になったら、呼び出し元にてlist_delete()を実行し、リストを削除してください。
// */
//struct _LIST* map_keys(MAP* map);
//
///* マップが空か否か調べます。
// * [in]
// *	map		マップ。
// * [out]
// *	戻り値		空ならば0以外を返します。
// *			空でなければ0を返します。
// */
//int map_empty(MAP* map);
//
///*****************************************************************************
// *	ユーティリティ：リスト (コレクション)
// *****************************************************************************/
//
///* リスト情報 */
//typedef struct _LIST_INFO {
//	void* (*val_copy)(void* val);	/* 値を複製する、ヘルパ関数 */
//	void  (*val_delete)(void* val);	/* 値を削除する、ヘルパ関数 */
//} LIST_INFO;
//
///* リスト */
//typedef struct _LIST {
//	LIST_ENTRY list_head;	/* LIST_NODEのリストヘッダ */
//	LIST_INFO list_info;	/* リスト情報 */
//} LIST;
//
///* リスト要素
// * * ガベージコレクションを使用可能とするために、リスト要素とリストエントリの先頭アドレスを揃えてあります。
// *   両者のアドレスが違っていると、ガベージコレクタが未開放のリスト要素を誤って開放してしまうためです。
// * - ガベージコレクションの使用は必須ではありません。
// *   LIST構造体やLIST_NODE構造体のメモリ開放は、ライブラリが明示的に行っています。
// *   値のメモリ管理は、アプリケーション定義のヘルパ関数にて、明示的に行うことが可能です。
// * - ガベージコレクションを使うと、明示的な、値のメモリ解放を省略し、ヘルパ関数を簡略化できます。
// */
//typedef struct _LIST_NODE {
//	LIST_ENTRY list_entry;	/* LIST_NODEのリストエントリ */
//	void* val;		/* 値 (実際の型はアプリケーション定義) */
//} LIST_NODE;
//
///* リストを作成します。
// * [in]
// *	list_info	リスト情報。
// * [out]
// *	戻り値		リスト。
// */
//LIST* list_create(const LIST_INFO* list_info);
//
///* リストを削除します。
// * [in]
// *	list		リスト。
// * [note]
// *	* 自動的にlist_clear()を呼び、残っているマップ要素をすべて削除します。
// *	  明示的にlist_clear()を呼んでおく必要はありません。
// */
//void list_delete(LIST* list);
//
///* リストの全要素を削除します。
// * [in]
// *	list		リスト。
// * [note]
// *	* 各リスト要素について、val_delete()ヘルパ関数を用いて、値を削除します。
// */
//void list_clear(LIST* list);
//
///* リストの要素数を取得します。
// * [in]
// *	list		リスト。
// * [out]
// *	戻り値		要素数。
// */
//int list_size(LIST* list);
//
///* インデクスにて指定された位置に、値を格納します。
// * [in]
// *	list		リスト。
// *	index		インデクス。(0～size-1)
// *	val		値。
// * [note]
// *	* インデクスは、有効な位置(0以上、配列サイズ未満)でなければなりません。
// *	  この範囲外のインデクスが指定された場合は、アサートします。
// *	  空のリストに対してこの関数を呼び出した場合は、常にアサートします。
// *	* val_copy()ヘルパ関数を用いて、値を複製し、リスト要素に格納します。
// *	  アプリケーションは、呼び出し時に指定したvalを維持する必要はありません。
// *	  ただし、val_copy()ヘルパ関数が複製を行わない場合は、この限りではありません。
// *	* 指定された位置に存在する既存の値は、自動的に削除されます。
// *	  既存の値の削除には、val_delete()ヘルパ関数が利用されます。
// */
//void list_set(LIST* list, int index, void* val);
//
///* インデクスにて指定された位置の、値を取得します。
// * [in]
// *	list		リスト。
// *	index		インデクス。(0～size-1)
// * [out]
// *	戻り値		値。
// * [note]
// *	* インデクスは、有効な位置(0以上、配列サイズ未満)でなければなりません。
// *	  この範囲外のインデクスが指定された場合は、アサートします。
// *	  空のリストに対してこの関数を呼び出した場合は、常にアサートします。
// *	* list_get()は、val_copy()ヘルパ関数を用いて値の複製を作成し、その複製を返します。
// *	  返された値の所有権は、list_get()を呼び出した側のみに有ります。
// *	  list_get()を呼び出した側は、返された値を適切に解放することを忘れないでください。
// */
//void* list_get(LIST* list, int index);
//
///* リストの末尾に、値を追加します。
// * [in]
// *	list		リスト。
// *	val		値。
// * [note]
// *	* "list_insert(list, list_size(list), val)"と等価です。
// */
//void list_add(LIST* list, void* val);
//
///* インデクスにて指定された位置に、値を追加します。
// * [in]
// *	list		リスト。
// *	index		インデクス。(0～size)
// *	val		値。
// * [note]
// *	* インデクスは、有効な位置(0以上、配列サイズ未満)、または、末尾(=配列サイズ)でなければなりません。
// *	  この範囲外のインデクスが指定された場合は、アサートします。
// *	* val_copy()ヘルパ関数を用いて、値を複製し、リスト要素に格納します。
// *	  アプリケーションは、呼び出し時に指定したvalを維持する必要はありません。
// *	  ただし、val_copy()ヘルパ関数が複製を行わない場合は、この限りではありません。
// *	* インデクスに、配列サイズ未満を指定した場合、追加した位置よりも後の要素は、ひとつづつ、後へ移動します。
// */
//void list_insert(LIST* list, int index, void* val);
//
///* インデクスにて指定された位置の、値を削除します。
// * [in]
// *	list		リスト。
// *	index		インデクス。(0～size-1)
// * [note]
// *	* インデクスは、有効な位置(0以上、配列サイズ未満)でなければなりません。
// *	  この範囲外のインデクスが指定された場合は、アサートします。
// *	  空のリストに対してこの関数を呼び出した場合は、常にアサートします。
// *	* 指定された位置に存在する既存の値は、自動的に削除されます。
// *	  既存の値の削除には、val_delete()ヘルパ関数が利用されます。
// *	* 削除した位置よりも後の要素は、ひとつづつ、前へ移動します。
// */
//void list_remove(LIST* list, int index);
//
///* リストを複製します。
// * [in]
// *	list		複製元のリスト。
// * [out]
// *	戻り値		複製したリスト。
// * [note]
// *	* この関数が行う処理は、以下のとおりです。
// *	  1. 複製元のリストと同じリスト情報を持つ、空のリストを作成します。
// *	     これが、複製先のリストとなります。
// *	  2. 複製元のリストの各要素の値について、val_copy()ヘルパ関数を用いて複製し、
// *	     複製先のリストへ追加します。
// *	  3. 複製先のリストを返します。
// */
//LIST* list_duplicate(LIST* list);
//
///* リストが空か否か調べます。
// * [in]
// *	list		リスト。
// * [out]
// *	戻り値		空ならば0以外を返します。
// *			空でなければ0を返します。
// * [note]
// *	* リストが空か否かを調べるだけならば、
// *		if(!list_size(list)) { 空の場合の処理 } else { 空でない場合の処理 }
// *	  とするよりも、
// *		if(list_empty(list)) { 空の場合の処理 } else { 空でない場合の処理 }
// *	  とする方が高速です。
// */
//int list_empty(LIST* list);
//
///*****************************************************************************
// *	ユーティリティ：プール (コレクション)
// *****************************************************************************/
//
//#if 0 /*{{2006/12/06:pool_free()から返却先プールの引数を不要とする変更により削除*/
/////* * Mon Dec 04 16:24:06 JST 2006 Naoyuki Sawa
//// * - malloc()、free()のオーバーヘッドを避けるための、メモリブロックプールです。
//// *   明示的な、プールの初期化とクリーンアップを行わなくて良いのが特徴です。
//// * - 以下のように利用してください。
//// *
//// * ①POOL構造体を、グローバル変数(またはstatic変数)として定義してください。
//// *   定義と同時に、sizeメンバをメモリブロック単位のサイズに初期化してください。
//// *
//// *	POOL foo_pool = { sizeof(FOO) };
//// *
//// * ②pool_alloc()を呼び出して、メモリブロックを確保してください。
//// *   適切に、ヒープまたはプールからメモリブロックが割り当てられます。
//// *   割り当てに失敗した場合は、pool_alloc()内部でアサートするので、戻り値を検査する必要はありません。
//// *   返されたメモリブロックは、pool_alloc()によってゼロクリアされています。
//// *
//// *	int main(int argc, char* argv[]) {
//// *		FOO* foo1 = pool_alloc(&foo_pool);
//// *
//// * ③pool_free()を呼び出して、不要になったメモリブロックをプールに返してください。
//// *
//// *		pool_free(&foo_pool, foo1);
//// *
//// * ④最終的な、プールのクリーンアップは不要です。
//// *   割り当てたメモリブロックが全てプールに返されたタイミングで、自動的に全てヒープに返されます。
//// *
//// *		foo1 = pool_alloc(&foo_pool);	// 割り当て数1、プール数0 (ヒープから確保)
//// *		foo2 = pool_alloc(&foo_pool);	// 割り当て数2、プール数0 (ヒープから確保)
//// *		pool_free(&foo_pool, foo1);	// 割り当て数1、プール数1 (プールへ返す)
//// *		foo3 = pool_alloc(&foo_pool);	// 割り当て数2、プール数0 (プールから確保)
//// *		pool_free(&foo_pool, foo2);	// 割り当て数1、プール数1 (プールへ返す)
//// *		pool_free(&foo_pool, foo3);	// 割り当て数0、プール数2 (プールへ返す)→(ヒープへ返す)→プール数0
//// *
//// * - 上では構造体FOOだけのためにfoo_poolを用意していますが、複数の構造体で一つのプールを共有することも可能です。
//// *   たとえば、構造体FOOとBARで一つのプールを共有する場合、大きい方の構造体サイズをPOOL.sizeに設定してください。
//// * - 割り当て数がひんぱんに0に戻るような割り当て/開放パターンの場合、オーバーヘッドが低減されない場合があります。
//// *
//// *		foo1 = pool_alloc(&foo_pool);	// 割り当て数1、プール数0 (ヒープから確保)
//// *		pool_free(&foo_pool, foo1);	// 割り当て数0、プール数1 (プールへ返す)→(ヒープへ返す)→プール数0
//// *		foo2 = pool_alloc(&foo_pool);	// 割り当て数1、プール数0 (ヒープから確保)
//// *		pool_free(&foo_pool, foo2);	// 割り当て数0、プール数1 (プールへ返す)→(ヒープへ返す)→プール数0
//// *		foo3 = pool_alloc(&foo_pool);	// 割り当て数1、プール数0 (ヒープから確保)
//// *		pool_free(&foo_pool, foo3);	// 割り当て数0、プール数1 (プールへ返す)→(ヒープへ返す)→プール数0
//// *
//// * - 4バイト余計に割り当てて先頭に返却先プールへのポインタを格納し、ユーザーには+4の位置を示す方法もあります。
//// *   そのようにすれば、pool_free()から返却先プールの引数が不要になり便利なのですが、今回は採用しませんでした。
//// *   ユーザーが保持するポインタがメモリブロック先頭を指していないと、ガーベージコレクタと併用できなくなるからです。
//// */
////typedef struct _POOL {
////	int size;			/* 割り当てるメモリブロック単位のバイト数 */
////	int cnt;			/* (割り当て回数 - 開放回数) */
////	struct _POOL_NODE* first;	/* プール内の最初のメモリブロックへのリンク (NULL=空) */
////} POOL;
////
////typedef struct _POOL_NODE {
////	struct _POOL_NODE* next;	/* プール内の次のメモリブロックへのリンク (NULL=終端) */
////} POOL_NODE;
////
/////* メモリブロックを確保します。
//// * [in]
//// *	pool		プール。
//// * [out]
//// *	戻り値		メモリブロック。
//// */
////void* pool_alloc(POOL* pool);
////
/////* メモリブロックを開放します。
//// * [in]
//// *	pool		プール。
//// *	ptr		メモリブロック。
//// */
////void pool_free(POOL* pool, void* ptr);
//#endif /*}}2006/12/06:pool_free()から返却先プールの引数を不要とする変更により削除*/
////↓ * Wed Dec 06 03:36:51 JST 2006 Naoyuki Sawa
////↓ - pool_free()から返却先プールの引数を不要としました。
////↓   メモリブロック当り12バイトのオーバーヘッドが増えましたが、使い易さを優先してこのような仕様に変更しました。
////↓ - 割り当て中のメモリブロック先頭をチェインすることで、ガーベージコレクションの対象となることを防いでいます。
////↓   なぜこのような対策が必要かは、上のコメントアウトしたブロック内のコメントの、最後の部分を参照してください。
////↓ - pool_free()から返却先プールの引数を不要としたこと以外は、使用方法は変わっていません。
////↓   上のコメントアウトしたブロック内のコメントを参照してください。
//
///* * Tue Jan 02 22:11:35 JST 2007 Naoyuki Sawa
// * - プールに、参照カウント式ガーベージコレクションの機能を内包しました。
// * - プールから確保したメモリブロックは、常にプールにチェインにされているため、不要になったブロックを判断できず、通常のGCで回収できません。
// *   そこで、参照カウント式ガーベージコレクションの機能を内包することにしました。
// * - この機能はプールに直接関係のある機能ではなく、単純な確保と解放だけの管理ならば、ガーベージコレクションの仕組みは不要です。
// *   しかし、複数の箇所からメモリブロックを共有するような使い方をする場合、いずれ必要になる機能でもあります。
// *   必要な場合だけ、アプリケーション側で参照カウントの管理を行う方法もありますが、簡単のため、プールの機能に内包してしまうことにしました。
// * - この機能追加によるアプリケーションインターフェイスの変化は、pool_lock()が増えたことだけです。
// *   pool_alloc()直後の参照カウントは1であり、pool_free()すれば0になって解放されるので、既存のアプリケーションへの影響はありません。
// *   メモリブロック毎に4バイトのオーバーヘッド(参照カウントの分)が増えてしまいましたが、まあ、許容範囲だと思います。
// * - NULLポインタに対するpool_lock()とpool_free()は何も行わないようにしました。
// *   従って、あるメモリブロックpの参照カウントを増やす場合に、pがNULLであるか否かを判断する必要はありません。
// *   pがNULLならば、何も行いません。
// *
// *	<例>
// *		void MyClass_constructor(MyClass* This, void* p) {
// *			This->p = p;
// *			pool_lock(This->p); // pがNULLでも大丈夫
// *		}
// *		void MyClass_destructor(MyClass* This) {
// *			pool_free(This->p); // pがNULLでも大丈夫
// *		}
// *
// * - 通常のGCとの併用も可能です。
// *   その場合、malloc()/free()で確保・解放するオブジェクトはマーク&スイープ方式のGC、
// *   pool_alloc()/pool_free()/pool_lock()で確保・解放するオブジェクトは参照カウント式のGC、と、二方式のGCが混在することに注意してください。
// * - 以下に、使用例を示します。
// *
// *	void main() {
// *		void* p;
// *		p = pool_alloc(&pool);	// 参照カウント=1
// *		foo1(p);		// 参照カウント=2
// *		foo2(p);		// 参照カウント=3
// *		pool_free(p);		// 参照カウント=2
// *		bar1(p);		// 参照カウント=1
// *		bar2(p);		// 参照カウント=0 -> 解放
// *	}
// *
// *	void* g_ptr1;
// *	void foo1(void* p) {
// *		g_ptr1 = p;
// *		pool_lock(g_ptr1);	// 参照カウント+1
// *	}
// *	void bar1() {
// *		pool_free(g_ptr1);	// 参照カウント-1
// *		g_ptr1 = NULL;
// *	}
// *
// *	void* g_ptr2;
// *	void foo2(void* p) {
// *		g_ptr2 = p;
// *		pool_lock(g_ptr2);	// 参照カウント+1
// *	}
// *	void bar2() {
// *		pool_free(g_ptr2);	// 参照カウント-1
// *		g_ptr2 = NULL;
// *	}
// *
// */
//
///* * Sat Mar 14 21:13:42 JST 2009 Naoyuki Sawa
// * - プールに、確保時コールバックと解放時コールバックを追加しました。
// * - 以下に、使用例を示します。
// *
// *	void foo_init_proc(void* data) {
// *		// 確保したメモリブロックの、共通初期化処理など
// *	}
// *	void foo_free_proc(void* data) {
// *		// 解放するメモリブロックの、共通クリーンアップ処理など
// *	}
// *	POOL foo_pool = { sizeof(FOO), foo_init_proc, foo_free_proc };
// *	void main() {
// *		FOO* foo = pool_alloc(&foo_pool);	// foo_init_proc()が呼び出されます。
// *		pool_lock(foo);		// 参照カウント=2
// *		pool_free(foo);		// 参照カウント=1
// *		pool_free(foo);		// 参照カウント=0。foo_free_proc()が呼び出されます。
// *	}
// */
//
////{{2009/03/14:確保時コールバックと解放時コールバックを追加するために変更
////typedef struct _POOL {
////	int size;		/* このフィールドだけ、ユーザーが設定してください */
////	int init;		/* (内部使用: 初期化済み or 未初期化の判断用) */
////	LIST_ENTRY alloc_list;	/* (内部使用: 割り当て中メモリブロックの先頭をチェインし、GCを防ぐ) */
////	LIST_ENTRY free_list;	/* (内部使用: 解放されたメモリブロックの先頭をチェインして保持する) */
////} POOL;
////↓2009/03/14:確保時コールバックと解放時コールバックを追加するために変更
//typedef struct _POOL {
//	int size;			/* 割り当てるメモリブロックのバイト数。(ユーザーが設定してください) */
//	void (*init)(void* data);	/* 確保時コールバック。(ユーザーが設定してください。不要ならばNULL) */
//	void (*free)(void* data);	/* 解放時コールバック。(ユーザーが設定してください。不要ならばNULL) */
//	int mark;			/* (内部使用: 初期化済み or 未初期化の判断用) */
//	LIST_ENTRY alloc_list;		/* (内部使用: 割り当て中メモリブロックの先頭をチェインし、GCを防ぐ) */
//	LIST_ENTRY free_list;		/* (内部使用: 解放されたメモリブロックの先頭をチェインして保持する) */
//} POOL;
////}}2009/03/14:確保時コールバックと解放時コールバックを追加するために変更
//
//typedef struct _POOL_NODE {			/* (内部使用) */
//	LIST_ENTRY list_entry;			/* POOL.alloc_list、または、POOL.free_listにチェインする */
//	POOL* pool;				/* このメモリブロックの割り当て元プールへのポインタ */
//	/*{{2007/01/02追加: 参照カウント式ガーベージコレクションの機能を内包*/
//	int ref_cnt;				/* 参照カウント */
//	/*}}2007/01/02追加: 参照カウント式ガーベージコレクションの機能を内包*/
//	/*unsigned char data[pool->size];*/	/* ユーザーには、この領域の先頭アドレスが返されます */
//} POOL_NODE;
//
///* メモリブロックを確保します。
// * [in]
// *	pool		プール。
// * [out]
// *	戻り値		メモリブロック。
// * [note]
// *	{{2007/01/02追加: 参照カウント式ガーベージコレクションの機能を内包
// *	- メモリブロックを確保した直後の、参照カウントの初期値は1です。
// *	}}2007/01/02追加: 参照カウント式ガーベージコレクションの機能を内包
// */
//void* pool_alloc(POOL* pool);
//
///* メモリブロックを開放します。
// * [in]
// *	data		メモリブロック。
// *			NULLならば、何も行いません。
// * [note]
// *	{{2007/01/02追加: 参照カウント式ガーベージコレクションの機能を内包
// *	- 参照カウントを減らし、参照カウントが残っていたら解放しません。
// *	}}2007/01/02追加: 参照カウント式ガーベージコレクションの機能を内包
// */
//void pool_free(void* data/*NULLOK*/);
//
///*{{2007/01/02追加: 参照カウント式ガーベージコレクションの機能を内包*/
///* 参照カウントを増やします。
// * [in]
// *	data		メモリブロック。
// *			NULLならば、何も行いません。
// */
//void pool_lock(void* data/*NULLOK*/);
///*}}2007/01/02追加: 参照カウント式ガーベージコレクションの機能を内包*/
//}}2015/01/06削除:コレクション関連の宣言を、clipmisc.hからclipcoll.hへ分離しました。

//{{2015/01/06削除:インターフェイス関連の宣言を、clipmisc.hからclipintf.hへ分離しました。
///*****************************************************************************
// *	ユーティリティ：簡略版COM (Component Object Model)
// *****************************************************************************/
//
///* 参照カウントの増減ルール (暫定版。※TODO:あとで詳しく書く。)
// *
// *	以下、呼び出す側(A)、呼び出される側(B、C)とする。
// *
// *	[ルール1-1]
// *	Bの戻り値としてインターフェイスを返す場合、Aのために、参照カウントを+1しておく。
// *	Aは、インターフェイスの使用が終わったら、参照カウントを-1する。
// *
// *		INTERFACE** B() {
// *			safe_addref(g_intf);	// refcnt+1
// *			return g_intf;
// *		}
// *
// *		void A() {
// *			INTERFACE** intf = B();
// *			...
// *			safe_release(intf);	// refcnt-1
// *		}
// *
// *	[ルール1-2]
// *	Bがオブジェクト生成関数である場合も、[ルール1-1]に従う。
// *	つまり、Bは参照カウント1のオブジェクトを作成し、そのインターフェイスをAに返す。
// *	Aは、返されたインターフェイスが、新規作成されたものか、既存のものか、判断する必要が無い。
// *
// *		INTERFACE** B() {
// *			OBJECT** obj = calloc(1, OBJECT);
// *			obj->refcnt = 1;		// refcnt=1
// *			obj->interface = &interface;	// VTBL設定
// *			...
// *			return &obj->interface;
// *		}
// *
// *		void A() {
// *			INTERFACE** intf = B();
// *			...
// *			safe_release(intf);		// refcnt-1
// *		}
// *
// *	[ルール2-1]
// *	AがBへの入力引数としてインターフェイスを渡す場合、Aは参照カウントを増減しない。
// *	Bは、インターフェイスの使用が関数内のみならば、参照カウントを増減しない。
// *
// *		void A() {
// *			B(g_intf);
// *		}
// *
// *		void B(INTERFACE** intf) {
// *			...
// *		}
// *
// *	[ルール2-2]
// *	Bが、グローバル変数等にインターフェイスを保持するならば、参照カウントを+1する。
// *	グローバル変数等への保持が終了したら、参照カウントを-1する。
// *
// *		void A() {
// *			B(g_intf);
// *			...
// *			C();
// *		}
// *
// *		void B(INTERFACE** intf) {
// *			g_intf = intf;
// *			safe_addref(g_intf);		// refcnt+1
// *		}
// *
// *		void C(INTERFACE** intf) {
// *			safe_release(g_intf);		// refcnt-1
// *		}
// */
//
///*---------------------------------------------------------------------------*/
//
///* インターフェイスを定義するためのマクロです。
// * * 簡易UUIDとして、万国標準時1970/1/1 00:00:00からの経過秒数を利用します。
// *   clip/tool/timestmp.exeコマンドを使って、生成できます。
// */
//#define DEFINE_INTERFACE(intfname, timestmp, method_list)		\
//	enum { intfname##_ID = timestmp };				\
//	typedef struct _##intfname intfname;				\
//	struct _##intfname {						\
//		void* (*query_interface)(intfname** intf, int id);	\
//		void  (*addref)(intfname** intf);			\
//		void  (*release)(intfname** intf);			\
//		method_list						\
//	};
//
///* 基底インターフェイス(UNKNOWN_INTERFACE)を定義します。
// * * method_listが空であるために、DEFINE_INTERFACEマクロが利用できません。
// *   止むを得ず、UNKNOWN_INTERFACEだけは、マクロを使わずに定義しています。
// */
//enum { UNKNOWN_INTERFACE_ID = 0/*1970/01/01 09:00:00*/ };
//typedef struct _UNKNOWN_INTERFACE UNKNOWN_INTERFACE;
//struct _UNKNOWN_INTERFACE {
//	void* (*query_interface)(UNKNOWN_INTERFACE** intf, int id);
//	void  (*addref)(UNKNOWN_INTERFACE** intf);
//	void  (*release)(UNKNOWN_INTERFACE** intf);
//};
//
////----------------------------------------------------------------------------
////				実装例
////----------------------------------------------------------------------------
////	
////	/*----- *.hファイルに記述し、公開する部分 -----*/
////	
////	DEFINE_INTERFACE(SAMPLE_INTERFACE, 1133444760/*2005/12/01 22:46:00*/,
////		void (*put)(SAMPLE_INTERFACE** intf, int value);
////		int  (*get)(SAMPLE_INTERFACE** intf);
////	);
////	
////	SAMPLE_INTERFACE** sample_create(int initial_value);
////	
////	/*----- *.cファイルに記述し、非公開の部分 -----*/
////	
////	static void* sample_query_interface(SAMPLE_INTERFACE** intf, int id);
////	static void sample_addref(SAMPLE_INTERFACE** intf);
////	static void sample_release(SAMPLE_INTERFACE** intf);
////	static void sample_put(SAMPLE_INTERFACE** intf, int value);
////	static int sample_get(SAMPLE_INTERFACE** intf);
////	
////	static SAMPLE_INTERFACE sample_interface = {
////		sample_query_interface,
////		sample_addref,
////		sample_release,
////		sample_put,
////		sample_get,
////	};
////	
////	typedef struct _SAMPLE {
////		SAMPLE_INTERFACE* sample_interface;
////		int refcnt;
////		int value;
////	} SAMPLE;
////	
////	SAMPLE_INTERFACE**
////	sample_create(int initial_value)
////	{
////		SAMPLE* this = calloc(1, sizeof(SAMPLE));
////		if(!this) {
////			DIE();
////		}
////		this->sample_interface = &sample_interface;
////		this->refcnt = 1; /* 作成直後の参照カウントは1 */
////		this->value = initial_value;
////		return &this->sample_interface;
////	}
////	
////	static void
////	sample_delete(SAMPLE* this)
////	{
////		free(this);
////		printf("Delete!\n");
////	}
////	
////	static void*
////	sample_query_interface(SAMPLE_INTERFACE** intf, int id)
////	{
////		SAMPLE* this = CONTAINING_RECORD(intf, SAMPLE, sample_interface);
////		UNKNOWN_INTERFACE** unknown;
////		switch(id) {
////		case UNKNOWN_INTERFACE_ID:
////		case SAMPLE_INTERFACE_ID:
////			unknown = (void*)&this->sample_interface;
////			this->refcnt++; /* query_interface()が成功したら参照カウントを+1 */
////			break;
////		default:
////			unknown = NULL;
////			break;
////		}
////		return unknown;
////	}
////	
////	static void
////	sample_addref(SAMPLE_INTERFACE** intf)
////	{
////		SAMPLE* this = CONTAINING_RECORD(intf, SAMPLE, sample_interface);
////		this->refcnt++;
////	}
////	
////	static void
////	sample_release(SAMPLE_INTERFACE** intf)
////	{
////		SAMPLE* this = CONTAINING_RECORD(intf, SAMPLE, sample_interface);
////		if(!--this->refcnt) {
////			sample_delete(this);
////		}
////	}
////	
////	static void
////	sample_put(SAMPLE_INTERFACE** intf, int value)
////	{
////		SAMPLE* this = CONTAINING_RECORD(intf, SAMPLE, sample_interface);
////		this->value = value;
////	}
////	
////	static int
////	sample_get(SAMPLE_INTERFACE** intf)
////	{
////		SAMPLE* this = CONTAINING_RECORD(intf, SAMPLE, sample_interface);
////		return this->value;
////	}
////	
////	/*----- テストプログラム -----*/
////	
////	void
////	test_main()
////	{
////		SAMPLE_INTERFACE** sample = sample_create(123);
////		printf("%d\n", (*sample)->get(sample));	/* "123"と表示されます */
////		(*sample)->put(sample, 456);
////		printf("%d\n", (*sample)->get(sample));	/* "456"と表示されます */
////		(*sample)->release(sample);		/* "Delete!"と表示されます */
////	}
////	
////----------------------------------------------------------------------------
//
///* * オブジェクト初期化と、query_interface()の実装を簡単にする、ヘルパ関数のための構造体です。
// *   インターフェイスを実装するクラス毎に、あらかじめINTERFACE_MAPの配列を定義しておけば、
// *   オブジェクト初期化とquery_interface()の処理の大部分を、ヘルパ関数に任せられます。
// * * インターフェイスマップは、INTERFACE_MAP.id=0の要素で終端します。
// *   インターフェイスID=0は、実際にはUNKNOWN_INTERFACE_IDに相当するのですが、
// *   INTERFACE_MAPの配列においては、UNKNOWN_INTERFACE_IDでなく、単なる終端マークと見なします。
// * * インターフェイスマップには、UNKNOWN_INTERFACEに相当する要素は含めません。
// *   その代りに、先頭のインターフェイスが「暗黙のUNKNOWN_INTERFACE」として扱われます。
// *   UNKNOWN_INTERFACE_IDを指定して、query_interface_map()を呼び出した場合、
// *   query_interface_map()は、インターフェイスマップの先頭の要素のインターフェイスを、
// *   「暗黙のUNKNOWN_INTERFACE」として、呼び出し元に返します。
// * * 上述のように、先頭のインターフェイスを固定的に「暗黙のUNKNOWN_INTERFACE」とするために、
// *   インターフェイスマップには、少なくとも一つ以上の有効な要素が必要です。
// *   すなわち、インターフェイスマップの先頭の要素が、id=0であってはいけません。
// *   言い換えると、INTERFACE_MAPを利用してインターフェイスを管理するオブジェクトは、
// *   UNKNOWN_INTERFACE以外に、一つ以上のインターフェイスを持っている必要があります。
// */
//typedef struct _INTERFACE_MAP {
//	int id;		/* インターフェイスID (id=0にて終端。終端要素のoffset,vtblは無意味) */
//	int offset;	/* オブジェクトの先頭から、インターフェイスまでのオフセットバイト数 */
//	void* vtbl;	/* インターフェイスVTBLのポインタ (apply_interface_map()だけが参照) */
//} INTERFACE_MAP;
//
///* オブジェクト作成時に、インターフェイスを格納する、ヘルパ関数です。
// * [in]
// *	this		オブジェクトの先頭アドレス。
// *	map		インターフェイスマップ。
// *			INTERFACE_MAP.id=0の要素で、明示的に配列を終端してください。
// * [note]
// *	* query_interface_map()のコメントと、後述の利用例を参照してください。
// */
//void apply_interface_map(void* this, const INTERFACE_MAP* map);
//
///* インターフェイスマップを検索する、ヘルパ関数です。
// * [in]
// *	this		オブジェクトの先頭アドレス。
// *	id		検索するインターフェイスID。
// *	map		インターフェイスマップ。
// *			INTERFACE_MAP.id=0の要素で、明示的に配列を終端してください。
// * [out]
// *	戻り値		成功ならば、参照カウントを+1し、インターフェイスを返します。
// *			失敗ならば、参照カウントを変更せず、NULLを返します。
// * [note]
// *	* インターフェイスマップに、UNKNOWN_INTERFACEに対応する要素を含めてはいけません。
// *	  id=UNKNOWN_INTERFACE_IDが指定された場合、最初の要素のインターフェイスを返します。
// *	  すなわち、インターフェイスマップの最初の要素が「代表UNKNOWN_INTERFACE」になります。
// */
//void* query_interface_map(void* this, int id, const INTERFACE_MAP* map);
//
////----------------------------------------------------------------------------
////				利用例
////----------------------------------------------------------------------------
////	
////	typedef struct _SAMPLE {
////		int refcnt;
////		SAMPLE1_INTERFACE* sample1_interface;
////		SAMPLE2_INTERFACE* sample2_interface;
////		SAMPLE3_INTERFACE* sample3_interface;
////		int value;
////	} SAMPLE;
////	
////	SAMPLE1_INTERFACE sample1_interface = { ... };
////	SAMPLE2_INTERFACE sample2_interface = { ... };
////	SAMPLE3_INTERFACE sample3_interface = { ... };
////	
////	static const INTERFACE_MAP sample_interface_map[] = {
////		{ SAMPLE1_INTERFACE_ID, FIELD_OFFSET(SAMPLE, sample1_interface), &sample1_interface },
////		{ SAMPLE2_INTERFACE_ID, FIELD_OFFSET(SAMPLE, sample2_interface), &sample2_interface },
////		{ SAMPLE3_INTERFACE_ID, FIELD_OFFSET(SAMPLE, sample3_interface), &sample3_interface },
////		{ 0 } /* インターフェイスマップの終端。忘れないで!! */
////	};
////	
////	SAMPLE*
////	sample_create()
////	{
////		SAMPLE* this = calloc(1, sizeof(SAMPLE));
////		if(!this) {
////			DIE();
////		}
////		this->refcnt = 1;
////		apply_interface_map(this, sample_interface_map);
////		return this;
////	}
////	
////	static void*
////	sample1_query_interface(SAMPLE1_INTERFACE** intf, int id)
////	{
////		SAMPLE* this = CONTAINING_RECORD(intf, SAMPLE, sample1_interface);
////		return query_interface_map(this, id, sample_interface_map);
////	}
////	
////	static void*
////	sample2_query_interface(SAMPLE2_INTERFACE** intf, int id)
////	{
////		SAMPLE* this = CONTAINING_RECORD(intf, SAMPLE, sample2_interface);
////		return query_interface_map(this, id, sample_interface_map);
////	}
////	
////	static void*
////	sample3_query_interface(SAMPLE3_INTERFACE** intf, int id)
////	{
////		SAMPLE* this = CONTAINING_RECORD(intf, SAMPLE, sample3_interface);
////		return query_interface_map(this, id, sample_interface_map);
////	}
////	
////----------------------------------------------------------------------------
//
///* インターフェイスポインタの参照カウントを、増加します。
// * インターフェイスポインタがNULLだったら、何もしません。
// */
////#define safe_addref(ptr) do {		\
////	if(ptr) {			\
////		(*(ptr))->addref(ptr);	\
////	}				\
////} while(0)
////↓2005/12/10 safe_addref(ptr)が、ptrを返すように変更しました。
////↓このような仕様とした理由は、safe_addref(ptr)の後、直ちにptrを返す関数のためです。
////↓上述の、参照カウントの増減ルール[ルール1-1]を参照してください。
////↓これまでは、
////↓	safe_addref(ptr);
////↓	return ptr;
////↓と記述していた処理を、今後は、
////↓	return safe_addref(ptr);
////↓と記述することができるようになりました。
//#define safe_addref(ptr) ((ptr) ? ((*(ptr))->addref(ptr), (ptr)) : (ptr))
//
///* インターフェイスポインタの参照カウントを減少後、NULLにします。
// * インターフェイスポインタがもともとNULLだったら、何もしません。
// */
//#define safe_release(ptr) do {		\
//	if(ptr) {			\
//		(*(ptr))->release(ptr);	\
//		(ptr) = NULL;		\
//	}				\
//} while(0)
//
///* インターフェイスポインタに、新しいインターフェイスをアサインします。
// * - dstとsrcが、同じオブジェクトを指している可能性があるので、
// *   新しくアサインするインターフェイスの参照カウントを増加した後、
// *   既存インターフェイスの参照カウントを減少することに注意してください。
// *   この手順を逆順にすると、途中でオブジェクトが削除されてしまいます。
// * - <使用例>
// *	SAMPLE_INTERFACE** sample1 = sample_create(123); // sample(123)'s refcnt=1
// *	SAMPLE_INTERFACE** sample2 = sample_create(456); // sample(456)'s refcnt=1
// *	safe_assign(sample1, sample2); // sample(123)'s refcnt=0, sample(456)'s refcnt=2
// */
//#define safe_assign(dst, src) do {			\
//	UNKNOWN_INTERFACE** __tmp__ = (void*)(dst);	\
//	(dst) = (src);					\
//	safe_addref(dst);				\
//	safe_release(__tmp__);				\
//} while(0)
//
///* インターフェイスポインタに、新しいインターフェイスをアタッチします。
// * - 新しくアサインするインターフェイスを得る式(src)の中に、(dst)が含まれている可能性があるので、
// *   式(src)を評価した後に、(dst)の参照カウントを減少することに注意してください。
// *   この手順を逆順にすると、途中でオブジェクトが削除されてしまいます。
// *	<例> safe_attach(sample, (*sample)->clone(sample));
// * - safe_assign()との違いは、新しいインターフェイスの参照カウントを増加しないことです。
// * - <使用例>
// *	SAMPLE_INTERFACE** sample = sample_create(123); // sample(123)'s refcnt=1
// *	safe_attach(sample, sample_create(234)); // sample(123)'s refcnt=0, sample(456)'s refcnt=1
// */
//#define safe_attach(dst, src) do {			\
//	UNKNOWN_INTERFACE** __tmp__ = (void*)(dst);	\
//	(dst) = (src);					\
//	safe_release(__tmp__);				\
//} while(0)
//
///* インターフェイスを取り出し、インターフェイスポインタをクリアします。
// * - 参照カウントの増加、減少は伴いません。
// * - P/ECEでは、GCC拡張機能を利用して、マクロのみで定義しています。
// *   Win32では、GCC拡張機能が利用できないため、マクロとインライン関数で定義しています。
// *   Win32では、やむを得ず(void*)へのキャストを行うため、型チェックが少し甘くなります。
// * - <使用例>
// *	SAMPLE_INTERFACE** sample = sample_create(123); // sample(123)'s refcnt=1
// *	return safe_detach(sample); // sample(123)'s refcnt=1
// *   上述の使用例は、safe_detach()を使わず、単純に、
// *	return sample_create(123);
// *   と変更する方法でも、同じ結果が得られます。
// */
//#ifdef PIECE
//#define safe_detach(ptr) ({			\
//	typeof(ptr) __tmp__ = (ptr);		\
//	(ptr) = NULL;				\
//	__tmp__;				\
//})
//#else /*PIECE*/
//#define safe_detach(ptr) _safe_detach(&(ptr))
//static __inline void* _safe_detach(void* _pptr) {
//	UNKNOWN_INTERFACE*** pptr = _pptr;
//	UNKNOWN_INTERFACE**   ptr = *pptr;
//	*pptr = NULL;
//	return ptr;
//}
//#endif /*PIECE*/
//
///* 安全なquery_interface()呼び出しを行います。
// * - インターフェイスポインタがNULLでなければ、query_interface()を呼び出し、戻り値を適切にキャストします。
// *   インターフェイスポインタがNULLならば、query_interface()を呼び出さずに、NULLを返します。
// * - P/ECE版は、GCC拡張機能を利用し、引数ptrを複数回評価しない、安全な実装となっています。
// *   Win32版は、GCC拡張機能が利用できないため、やむを得ず、引数ptrを複数回評価しています。
// *   引数ptrに、関数呼び出しを含む式や、副作用のある式を指定しないよう、注意してください。
// * - <使用例>
// *	SAMPLE_INTERFACE** sample = safe_query_interface(unknown, SAMPLE_INTERFACE);
// */
//#ifdef PIECE
//#define safe_query_interface(ptr, intfname) ((intfname**)({			\
//	typeof(ptr) __tmp__ = (ptr);						\
//	(__tmp__) ? (*(__tmp__))->query_interface((__tmp__), intfname##_ID)	\
//	      : NULL;								\
//}))
//#else /*PIECE*/
//#define safe_query_interface(ptr, intfname) ((intfname**)(	\
//	(ptr) ? (*(ptr))->query_interface((ptr), intfname##_ID)	\
//	      : NULL						\
//))
//#endif /*PIECE*/
//
///* safe_query_interface()とsafe_attach()は、同時に使うケースが多いので、簡略表記を用意しました。
// * 以下のコード:
// *	SAMPLE1_INTERFACE** sample1 = ...;
// *	SAMPLE2_INTERFACE** sample2 = ...;
// *	safe_attach(sample2, safe_query_interface(sample1, SAMPLE2_INTERFACE));
// * を、次のように記述できます。
// *	SAMPLE1_INTERFACE** sample1 = ...;
// *	SAMPLE2_INTERFACE** sample2 = ...;
// *	safe_assign_interface(sample2, sample1, SAMPLE2);
// * safe_attach_interface()ではなく、safe_assign_interface()というマクロ名にした理由は、
// * オブジェクトの参照カウント数の合計が、新たに1増えることを強調するためです。
// */
//#define safe_assign_interface(dst_ptr, src_ptr, dst_intfname)			\
//	safe_attach((dst_ptr), safe_query_interface((src_ptr), dst_intfname))
//
///* 二つのインターフェイスポインタが、同じオブジェクトに属するものか否か、調べます。
// * 同じオブジェクトに属するものならば1、さもなくば0を返します。
// * - 以下のいずれか条件に一致する場合、同じオブジェクトに属すると判断します。
// *	①intf1とintf2が、いずれもNULLの場合。
// *	②intf1とintf2に対し、明示的にUNKNOWN_INTERFACEを要求し、それらが一致した場合。
// * - P/ECEでは、GCC拡張機能を利用して、マクロのみで定義しています。
// *   Win32では、GCC拡張機能が利用できないため、マクロとインライン関数で定義しています。
// *   Win32では、やむを得ず(void*)へのキャストを行うため、型チェックが少し甘くなります。
// * - .NET Frameworkの、Object.ReferenceEqualsメソッドから、名前を借りました。
// */
//#ifdef PIECE
//#define reference_equals(intf1, intf2) ({						\
//	UNKNOWN_INTERFACE** unk1 = safe_query_interface((intf1), UNKNOWN_INTERFACE);	\
//	UNKNOWN_INTERFACE** unk2 = safe_query_interface((intf2), UNKNOWN_INTERFACE);	\
//	if(unk1) (*unk1)->release(unk1);						\
//	if(unk2) (*unk2)->release(unk2);						\
//	unk1 == unk2;									\
//})
//#else /*PIECE*/
//#define reference_equals(intf1, intf2) _reference_equals((void*)(intf1), (void*)(intf2))
//static __inline int _reference_equals(UNKNOWN_INTERFACE** intf1, UNKNOWN_INTERFACE** intf2) {
//	UNKNOWN_INTERFACE** unk1 = safe_query_interface((intf1), UNKNOWN_INTERFACE);
//	UNKNOWN_INTERFACE** unk2 = safe_query_interface((intf2), UNKNOWN_INTERFACE);
//	if(unk1) (*unk1)->release(unk1);
//	if(unk2) (*unk2)->release(unk2);
//	return unk1 == unk2;
//}
//#endif /*PIECE*/
//}}2015/01/06削除:インターフェイス関連の宣言を、clipmisc.hからclipintf.hへ分離しました。

//{{2015/01/06削除:ファイルパック形式関連の宣言を、clipmisc.hからclipfpk.hへ分離しました。
///*****************************************************************************
// *	ユーティリティ：ファイルパック形式
// *****************************************************************************/
//
///*                           0 +-----------------------------+
// *                             | FILE_PAC_INFO               |
// *                             +-----------------------------+
// *                             | FILE_INFO[0]                |
// *                             +-----------------------------+
// *                             | FILE_INFO[1]                |
// *                             +-----------------------------+
// *                             =                             =
// *                             +-----------------------------+
// *                             | FILE_INFO[famount-1]        |
// *         FILE_INFO[0].offset +-----------------------------+－
// *                             |                             |↑
// *                             | ファイル[0]のデータ         |｜FILE_INFO[0].size + 3 & ~3
// *                             |                             |↓
// *         FILE_INFO[1].offset +-----------------------------+－
// *                             |                             |↑
// *                             | ファイル[1]のデータ         |｜FILE_INFO[1].size + 3 & ~3
// *                             |                             |↓
// *                             +-----------------------------+－
// *                             =                             =
// * FILE_INFO[famount-1].offset +-----------------------------+－
// *                             |                             |↑
// *                             | ファイル[famount-1]のデータ |｜FILE_INFO[famount-1].size
// *                             |                             |↓
// *                             +-----------------------------+－
// */
//#define FILE_PAC_INFO_HEAD	 ('F' << 24 | 'P' << 16 | 'A' << 8 | 'K')
//typedef struct _FILE_PAC_INFO {	/* ファイルパック情報                   */
//	unsigned long head;	/* シグネチャ('FPAK'固定。並びは"KAPF") */
//	long famount;		/* ファイル数                           */
//} FILE_PAC_INFO;
//typedef struct _FILE_INFO {	/* ファイル情報                         */
//	char fname[16];		/* ファイル名                           */
//	unsigned long offset;	/* オフセット(fpkファイル先頭を0とする) */
//	unsigned long size;	/* ファイルサイズ                       */
//} FILE_INFO;
//
///* fpkファイル内のファイルサイズを取得します。
// * [in]
// *	fname		fpkファイル名。
// *	name		ファイルエントリ名。
// * [out]
// *	戻り値		ファイルサイズ[バイト]。
// * [note]
// *	* ファイルエントリ名は、大文字小文字を区別せずに比較します。
// *	* ファイルエントリが見つからなかった場合は、アサートします。
// */
//int fpk_size(const char* fname, const char* name);
//
///* fpkファイル内のファイルを読み込みます。
// * [in]
// *	fname		fpkファイル名。
// *	name		ファイルエントリ名。
// *	buffer		バッファアドレス。
// *	buflen		バッファサイズ。
// * [out]
// *	戻り値		実際に読み込んだファイルサイズ[バイト]。
// * [note]
// *	* ファイルエントリ名は、大文字小文字を区別せずに比較します。
// *	* ファイルエントリが見つからなかった場合は、アサートします。
// *	* バッファサイズがファイルサイズ未満の場合は、アサートします。
// */
//int fpk_load(const char* fname, const char* name, void* buffer, int buflen);
//
///*****************************************************************************
// *	ユーティリティ：オンメモリファイルパック形式
// *****************************************************************************/
//
///* オンメモリfpk内のファイル先頭アドレスを取得します。
// * [in]
// *	fpk		オンメモリfpkの先頭アドレス。
// *	name		ファイルエントリ名。
// *	size		ファイルサイズを格納する変数へのポインタ。
// *			NULLを指定するとファイルサイズは格納されません。
// * [out]
// *	戻り値		実際に読み込んだファイルサイズ[バイト]。
// * [note]
// *	* ファイルエントリ名は、大文字小文字を区別せずに比較します。
// *	* ファイルエントリが見つからなかった場合は、アサートします。
// */
//const void* fpk_address(const void* fpk, const char* name, int* size);
//}}2015/01/06削除:ファイルパック形式関連の宣言を、clipmisc.hからclipfpk.hへ分離しました。

//{{2015/01/06削除:乱数関連の宣言と実装を、clipmisc.*⇒cliprnd.*へ分離しました。
///*****************************************************************************
// *	ユーティリティ：範囲乱数
// *****************************************************************************/
//
///* 0～xの範囲で正確に分布する、乱数値を取得します。
// * [in]
// *	x		乱数値の最大値(xも含みます)
// *	generator	乱数生成関数
// *	param		乱数生成関数への引数
// * [out]
// *	戻り値		乱数値
// * [note]
// *	- 正確な分布で特定の範囲の乱数を取得する方法を定義するために、本関数を作成しました。
// *
// *	- 特定の範囲の乱数を取得する場合、剰余を使用すると、正確な分布が得られません。
// *	  以下、極端な例を挙げて説明します。
// *	  
// *	  0～255の乱数を生成する関数を利用して、0～99の範囲の乱数を取得するケースを考えます:
// *	    //0～255の乱数を生成する関数 (Test1～Test3で共通使用)
// *	    unsigned SimpleRng(unsigned* s) {
// *	      (*s) = (*s) * 5 + 0x3711;
// *	      return (unsigned char)((*s) >> 8);
// *	    }
// *	  
// *	  ■実験① 剰余を用いる方法
// *	    void Test1() {
// *	      unsigned s = 0, i, r, c[100];
// *	      memset(c, 0, sizeof c);
// *	      for(i = 0; i < 10000000; i++) {
// *	        r = SimpleRng(&s) % 100; //←①
// *	        c[r]++;
// *	      }
// *	      die("c[0]=%d,c[99]=%d", c[0], c[99]);
// *	      //⇒結果: c[0]=117179,c[99]=78111
// *	    }
// *	  □考察
// *	    [0]の回数が[99]の回数よりも明らかに多く、一様な乱数が得られていません。
// *	    原因は、0～255を100で剰余すると、200～255の分が、0～55への偏りになるからです。
// *	    解決策は、乱数生成関数から得られた値のうち、範囲外の値を捨てることです。
// *	  
// *	  ■実験② 範囲内の値となるまで繰り返す方法
// *	    void Test2() {
// *	      unsigned s = 0, i, r, c[100];
// *	      memset(c, 0, sizeof c);
// *	      for(i = 0; i < 10000000; i++) {
// *	        do { r = SimpleRng(&s); } while(r > 99); //←②
// *	        c[r]++;
// *	      }
// *	      die("c[0]=%d,c[99]=%d", c[0], c[99]);
// *	      //⇒結果: c[0]= 99993,c[99]=99986
// *	    }
// *	  □考察
// *	    [0]の回数と[99]の回数がほぼ同じとなり、一様な乱数が得られました。
// *	    ただし、②の方法は、実行速度の問題が生じるケースがあります。
// *	    仮に、乱数生成関数が0～65535を返し、得たい範囲が0～9だったとすると、0～9を得るまでに多くの回数繰り返す必要が生じます。
// *	    改善策として、乱数生成関数から返された値の、上位ビット一定範囲を捨てた後、範囲内の値となるまで繰り返す方法を採ります。
// *	    一般的に、乱数生成関数は[0～(2^N-1)]の値を生成するので、上位ビット一定範囲を捨てても、一様な分布に影響は無いはずです。
// *	  
// *	  ■実験③ マスクを取って範囲内の値となるまで繰り返す方法
// *	    void Test3() {
// *	      unsigned s = 0, i, r, c[100];
// *	      memset(c, 0, sizeof c);
// *	      for(i = 0; i < 10000000; i++) {
// *	        do { r = SimpleRng(&s) & 127; } while(r > 99); //←③
// *	        c[r]++;
// *	      }
// *	      die("c[0]=%d,c[99]=%d", c[0], c[99]);
// *	      //⇒結果: c[0]=100007,c[99]=99999
// *	    }
// *	  □考察
// *	    ②と同様に、[0]の回数と[99]の回数がほぼ同じであり、一様な乱数が得られています。
// *	    ③の方法ならば、範囲内の値となるまで繰り返す回数は、平均2回程度となるはずです。
// *	  
// *	  ■結論 "実験③"と同じ方法を、本関数を利用して実行する方法は、以下の通りです:
// *	    void Test4() {
// *	      unsigned s = 0, i, r, c[100];
// *	      memset(c, 0, sizeof c);
// *	      for(i = 0; i < 10000000; i++) {
// *	        r = random_value_less_than_or_equal_to(99, (unsigned(*)(void*))SimpleRng, &s); //←④
// *	        c[r]++;
// *	      }
// *	      die("c[0]=%d,c[99]=%d", c[0], c[99]);
// *	      //⇒結果: c[0]=100007,c[99]=99999
// *	    }
// *
// *	- 既存の乱数生成関数を利用しての、使用例を挙げます:
// *	  ＜例:Xorshift乱数＞
// *	    int s = pceTimerGetCount();
// *	    r = random_value_less_than_or_equal_to(<最大値>, (unsigned(*)(void*))rnd32, &s);
// *	  ＜例:MT乱数＞
// *	    MT mt;
// *	    MT_init(&mt, pceTimerGetCount());
// *	    r = random_value_less_than_or_equal_to(<最大値>, (unsigned(*)(void*))MT_int32, &mt);
// *	  ＜例:WELL乱数＞
// *	    WELL w;
// *	    WELL_init(&w, pceTimerGetCount());
// *	    r = random_value_less_than_or_equal_to(<最大値>, (unsigned(*)(void*))WELL_next, &w);
// *	  ＜例:JKISS32乱数＞
// *	    JKISS32 jk;
// *	    JKISS32_init(&jk, pceTimerGetCount());
// *	    r = random_value_less_than_or_equal_to(<最大値>, (unsigned(*)(void*))JKISS32_next, &jk);
// */
//unsigned random_value_less_than_or_equal_to(unsigned x, unsigned (*generator)(void* param), void* param);
//
///* x以上,かつ,最小の、マスク値を作成します。
// * [in]
// *	x		マスク値を作成する値
// * [out]
// *	戻り値		マスク値
// * [note]
// *	- 主に、random_value_less_than_or_equal_to()から利用するために作成しましたが、
// *	  汎用的なので、アプリケーションからも利用できるよう、宣言することにしました。
// *	- 引数(x)と、戻り値(マスク値)の対応は、以下の通りです:
// *	  ----------------------    ----------
// *	        引数の範囲            戻り値  
// *	  ----------------------    ----------
// *	  0x00000000             ⇒ 0x00000000
// *	  0x00000001             ⇒ 0x00000001
// *	  0x00000002～0x00000003 ⇒ 0x00000003
// *	  0x00000004～0x00000007 ⇒ 0x00000007
// *	  0x00000008～0x0000000F ⇒ 0x0000000F
// *	  0x00000010～0x0000001F ⇒ 0x0000001F
// *	  0x00000020～0x0000003F ⇒ 0x0000003F
// *	  0x00000040～0x0000007F ⇒ 0x0000007F
// *	  0x00000080～0x000000FF ⇒ 0x000000FF
// *	  0x00000100～0x000001FF ⇒ 0x000001FF
// *	  0x00000200～0x000003FF ⇒ 0x000003FF
// *	  0x00000400～0x000007FF ⇒ 0x000007FF
// *	  0x00000800～0x00000FFF ⇒ 0x00000FFF
// *	  0x00001000～0x00001FFF ⇒ 0x00001FFF
// *	  0x00002000～0x00003FFF ⇒ 0x00003FFF
// *	  0x00004000～0x00007FFF ⇒ 0x00007FFF
// *	  0x00008000～0x0000FFFF ⇒ 0x0000FFFF
// *	  0x00010000～0x0001FFFF ⇒ 0x0001FFFF
// *	  0x00020000～0x0003FFFF ⇒ 0x0003FFFF
// *	  0x00040000～0x0007FFFF ⇒ 0x0007FFFF
// *	  0x00080000～0x000FFFFF ⇒ 0x000FFFFF
// *	  0x00100000～0x001FFFFF ⇒ 0x001FFFFF
// *	  0x00200000～0x003FFFFF ⇒ 0x003FFFFF
// *	  0x00400000～0x007FFFFF ⇒ 0x007FFFFF
// *	  0x00800000～0x00FFFFFF ⇒ 0x00FFFFFF
// *	  0x01000000～0x01FFFFFF ⇒ 0x01FFFFFF
// *	  0x02000000～0x03FFFFFF ⇒ 0x03FFFFFF
// *	  0x04000000～0x07FFFFFF ⇒ 0x07FFFFFF
// *	  0x08000000～0x0FFFFFFF ⇒ 0x0FFFFFFF
// *	  0x10000000～0x1FFFFFFF ⇒ 0x1FFFFFFF
// *	  0x20000000～0x3FFFFFFF ⇒ 0x3FFFFFFF
// *	  0x40000000～0x7FFFFFFF ⇒ 0x7FFFFFFF
// *	  0x80000000～0xFFFFFFFF ⇒ 0xFFFFFFFF
// */
//unsigned minimum_mask_greater_than_or_equal_to(unsigned x);
//}}2015/01/06削除:乱数関連の宣言と実装を、clipmisc.*⇒cliprnd.*へ分離しました。

//{{2014/10/11削除:strtrim(),strescape(),strcompress()を、clipmisc.h,cからclipstr.h,cへ移動しました。今後は「ユーティリティ：文字列操作」はclipstr.h,cに追加してください。
///*****************************************************************************
// *	ユーティリティ：文字列操作
// *****************************************************************************/
///* 指定した文字だけを取り除く。
// * [in]
// *	s		元の文字列
// *	mode		除去する位置の指定	0 両端にある指定文字を除去する
// *						1 左端にある指定文字を除去する
// *						2 右端にある指定文字を除去する
// *						3 文字列内にある全ての指定文字を除去する
// *	reject		除去する文字		NULLを指定した場合は、空白文字を除去する
// * [out]
// *	戻り値		結果の文字列		呼び出し側にて、free()で開放してください
// * [note]
// *	- HSPのstrtrim関数の仕様に倣いました。
// * [使用例]
// *	const char src[] = "   - - - Sample  String - - -   ";
// *	char* dst;
// *	dst = strtrim(src, 0, NULL); puts(dst); free(dst); //   "- - - Sample  String - - -"
// *	dst = strtrim(src, 1, NULL); puts(dst); free(dst); //   "- - - Sample  String - - -   "
// *	dst = strtrim(src, 2, NULL); puts(dst); free(dst); //"   - - - Sample  String - - -"
// *	dst = strtrim(src, 3, NULL); puts(dst); free(dst); //       "---SampleString---"
// *	dst = strtrim(src, 0, " -"); puts(dst); free(dst); //         "Sample  String"
// *	dst = strtrim(src, 1, " -"); puts(dst); free(dst); //         "Sample  String - - -   "
// *	dst = strtrim(src, 2, " -"); puts(dst); free(dst); //"   - - - Sample  String"
// *	dst = strtrim(src, 3, " -"); puts(dst); free(dst); //          "SampleString"
// */
//char* strtrim(const char* s, int mode, const char* reject);
///*---------------------------------------------------------------------------*/
///* 文字列のバイナリデータを、印字可能な文字列にエスケープします。
// * [in]
// *	s		文字列のバイナリデータ
// *	need_escape	アプリケーション定義のエスケープが必要な文字	(NULL=無し)
// *			
// * [out]
// *	戻り値		エスケープされた文字列	呼び出し側にて、free()で開放してください。
// * [note]
// *	- 当関数の名前は、GLibのg_strescapeから取りました。
// *	  関数仕様はg_strescapeと完全互換ではありません。(need_escapeが独自拡張です。)
// *	- 当関数は、以下の処理を行います。
// *	  1. C言語のエスケープシーケンスに相当する文字を、エスケープシーケンスに変換する。
// *	  2. アプリケーション定義のエスケープが必要な文字の前に、'\'を追加する。
// *	  3. 印字可能でない文字を、'\'+8進表記3桁に変換する。
// *	  4. それ以外の文字は、そのまま出力する。
// * [使用例]
// *	- C言語の文字列エスケープ処理
// *	  dst=strescape(src,NULL);
// *	- Tcl言語の文字列エスケープ処理(TclのソースのTcl_ConvertElement()に相当)
// *	  dst=strescape(src," $;[]{}");
// *	- Tcl言語のリスト作成処理(TclのソースのTcl_Merge()に相当)
// *	  *dst='\0';
// *	  for(i=0;i<argc;i++){
// *	    char*tmp=strescape(argv[i]," $;[]{}");
// *	    if(i){strcat(dst," ");}
// *	    strcat(dst,(*tmp)?tmp:"{}");//空要素は{}に置き換えて明示的に格納する
// *	    free(tmp);
// *	  }
// */
//char* strescape(const char* s, const char* need_escape);
///* エスケープされた文字列を、文字列のバイナリデータに復元します。
// * [in]
// *	s		エスケープされた文字列
// *	delim		文字列sの処理を終了する文字セットを指定します。	NULLが指定された場合は文字列sの終端まで処理を行います。
// *									endptrと組み合わせて使用することを想定していますが、endptrを指定せずdelim のみ指定することも可能です。
// *	endptr		文字列sの処理を終了した位置を格納します。	NULLが指定された場合は格納しません。
// *									delim と組み合わせて使用することを想定していますが、delim を指定せずendptrのみ指定することも可能です。
// * [out]
// *	戻り値		文字列のバイナリデータ
// * [note]
// *	- 当関数の名前は、GLibのg_strcompressから取りました。
// *	  関数仕様はg_strcompressと完全互換ではありません。(endptr,delimが独自拡張です。)
// *	- 当関数は、以下の処理を行います。
// *	  1. 文字列sから一文字取得し、文字cとする。文字cによって以下2.～4.のいずれかの処理を行う。
// *	  2. 文字cが'\0',又は,delim(指定されていれば)の文字セットに一致した場合:
// *	    2-1. endptr(指定されていれば)に文字cの位置を格納する。
// *	    2-2. 出力文字列を'\0'で終端する。
// *	    2-3. 処理を終了する。
// *	  3. 文字cが'\'である場合、文字cの次の文字を取得し、以下3-1.～3-5.のいずれかの処理を行う。
// *	    3-1. '\'にnulが続く場合、'\'を破棄して処理2.を行い終了する。('\'にnulが続くのは'エスケープされた文字列'として不正だが、文字列の終端を超えないように最低限の対策を行うことにした)
// *	    3-2. '\'に続くC言語のエスケープシーケンス文字を、1文字に変換して出力する。
// *	    3-3. '\'に続く8進表記(1～3桁)を、1文字に変換して出力する。
// *	    3-4. '\'に続く16進表記(1～∞桁)を、1文字に変換して出力する。
// *	    3-5. '\'に続く改行を、'\'ごと削除する。(Cプリプロセッサ,Python,Tcl,sed,awk,bash,…の行の継続に相当)
// *	    3-6. '\'に続くそれ以外の文字を、'\'を削除して文字のみに変換して出力する。('アプリケーション定義のエスケープが必要な文字'も含む)
// *	  4. 文字cが2.～3.以外である場合、以下4-1.の処理を行う。
// *	    4-1. 文字cをそのまま出力する。
// *	- endptr,delimは、「エスケープされていない特定の文字を分割文字と見なすリストから、一要素を復元して取得する」ために使用します。
// *	  たとえば、Tclのリストから一要素を復元して取得する場合に使用します。
// *	  Cソース文字列の単純な復元の場合は考慮する必要はありませんので、endptr,delimにNULLを指定してください。
// * [使用例]
// *	- C言語の文字列エスケープ復元処理
// *	  dst=strcompress(src,NULL,NULL);
// *	- Tcl言語のリスト分割処理。(厳密にはTclでは{}でのエスケープも考慮する必要があるが、説明を簡単にするため以下の例では省略する。)
// *	  for(;;){
// *	    src+=strspn(src,"\t\n\v\f\r ");                  //先行するデリミタを飛ばす。
// *	    if(!*src){break;}                                //リスト終端ならば終了する。
// *	    argv[argc++]=strcompress(src,&src,"\t\n\v\f\r ");//一要素を復元して取得する。
// *	  }
// */
//char* strcompress(const char* s, const char** endptr, const char* delim);
//}}2014/10/11削除:strtrim(),strescape(),strcompress()を、clipmisc.h,cからclipstr.h,cへ移動しました。今後は「ユーティリティ：文字列操作」はclipstr.h,cに追加してください。

/*****************************************************************************
 *	コマンドライン分割
 *****************************************************************************/

#ifdef  _MSC_VER
char** parse_cmdline(const char* str);
//{{2016/08/16追加:merge_env_option()が確実に実行されるように、「#pragma comment(linker, "/INCLUDE:_pmerge_env_option")」を追加しました。
// * Tue Aug 16 22:54:46 JST 2016 Naoyuki Sawa
// - merge_env_option()が確実に実行されるように、「#pragma comment(linker, "/INCLUDE:_pmerge_env_option")」を追加しました。
//   具体的には、clipmisc.c内のpmerge_env_option変数をローカル変数からグローバル変数に変更し、その変数がアプリケーションに常にリンクされるように、clipmisc.h内に上記のプラグマを追加しました。
//   そうした理由は、以下の通りです。
// - 本日、エラー停止処理とトレース出力処理を、clipmisc.h,clipmisc.cから、clipdie.h,clipdie.cへ分離した事に伴い、当モジュールで定義されるグローバルシンボルが大分少なくなりました。
//   これまでは、当モジュールがdie()等の必ず参照されるグローバルシンボルを含んでいたので、当モジュールは必ずリンクされ、merge_env_option()もまず確実に呼び出されていたのですが、
//   本日の変更によって、die()等が別モジュールへ移動し、当モジュールで定義されるグローバルシンボルをアプリケーションが(直接,又は,間接的に)参照するか、やや心配になって来ました。
//   実験したところ、本日時点のモジュール構成で、最小限のアプリケーションでも、当モジュールはリンクされ、merge_env_option()は呼び出されるようです。(EnterCS等が参照されているためかと思います)
//   とは言え、偶然に依存するのも心許無いので、今のうちに、merge_env_option()が確実に実行されるようにしておく事にしました。
//   その方法としては、pmerge_env_optionを明示的に参照する事によって、merge_env_option()が確実に実行されるようにしました。
//   pmerge_env_optionを明示的に参照する方法は、下記のプラグマを利用しました。
//   □「MSDN ライブラリ Microsoft Visual Studio 6.0 - comment」より:
//   │linker
//   │オブジェクトファイルにリンカオプションを記録します。
//   │このコメント型を使うと、[プロジェクト設定]ダイアログボックスの[リンク]タブでオプションを指定する代わりにリンカオプションを指定できます。
//   │たとえば、次のように/includeオプションを指定して、強制的にシンボルを取り込むことができます。
//   │#pragma comment(linker, "/include:__mySymbol")
// - 「#pragma comment(linker, "/INCLUDE:pmerge_env_option")」ではなく、「#pragma comment(linker, "/INCLUDE:_pmerge_env_option")」とする必要が有る事に注意して下さい。
//   変数pmerge3_env_optionはCリンケージなので、リンカのシンボル名としては先頭に「_」が一つ付与されるからです。
//   例えば上のMSDN ライブラリの例の場合、元の変数名は「_mySymbol」で、シンボル名としては「_」を一つ付与して「__mySymbol」になったのだろうと推測されます。
//{{2016/09/07変更:64ビット版では、「#pragma comment(linker, "/INCLUDE:_pmerge_env_option")」を「#pragma comment(linker, "/INCLUDE:pmerge_env_option")」に変更しました。
//#pragma comment(linker, "/INCLUDE:_pmerge_env_option")
//↓2016/09/07変更:64ビット版では、「#pragma comment(linker, "/INCLUDE:_pmerge_env_option")」を「#pragma comment(linker, "/INCLUDE:pmerge_env_option")」に変更しました。
#ifndef _WIN64
#pragma comment(linker, "/INCLUDE:_pmerge_env_option")	//32ビットでは、シンボル名の先頭に'_'が付きます。
#else //_WIN64
#pragma comment(linker, "/INCLUDE:pmerge_env_option")	//64ビットでは、シンボル名の先頭に'_'が付きません。
#endif//_WIN64
//}}2016/09/07変更:64ビット版では、「#pragma comment(linker, "/INCLUDE:_pmerge_env_option")」を「#pragma comment(linker, "/INCLUDE:pmerge_env_option")」に変更しました。
//}}2016/08/16追加:merge_env_option()が確実に実行されるように、「#pragma comment(linker, "/INCLUDE:_pmerge_env_option")」を追加しました。
#endif//_MSC_VER

#ifdef  __cplusplus
}//extern "C"
#endif//__cplusplus

#endif /*__CLIP_MISC_H__*/
