/*	
 *	clipmisc.h
 *
 *	エラー処理、その他いろいろです。
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2014 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に追加してください。
 */
#ifndef __CLIP_MISC_H__
#define __CLIP_MISC_H__

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

#ifdef WIN32

#undef HIBYTE
#undef LOBYTE

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

#define _LIST_ENTRY _xLIST_ENTRY
#define  LIST_ENTRY  xLIST_ENTRY

#define strcasecmp  stricmp
#define strncasecmp strnicmp

#endif /*WIN32*/

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

/* * 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.
 */
#define typecheck(type, x) ({			\
	type      __dummy1__;			\
	typeof(x) __dummy2__;			\
	(void)(&__dummy1__ == &__dummy2__);	\
	1; })

//{{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*/

/* ビット操作 */
#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++では使えません。) */
#define XCHG(a, b) do {		\
	typeof(a) __a__ = (a);	\
	typeof(b) __b__ = (b);	\
	(a) = __b__;		\
	(b) = __a__;		\
} while(0)

/* 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))

///* 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)))

/* 配列(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])))

/* 構造体メンバのサイズを返します。(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)))

/* 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)))

/* * 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))

/* 配列要素をシャッフルします。
 * [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);

/* 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で定義されているマクロは、引数を二回評価する副作用が【有る】ことに注意してください。
 */
#ifdef  __GNUC__
#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;})
#endif/*__GNUC__*/

/* * 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() を追加しました。
 */
#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])))
#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の最大値,又は,最小値へ飽和する飽和加減算マクロ 
 * - 変数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__

/*****************************************************************************
 *	エラー処理
 *****************************************************************************/

/* エラーメッセージを表示し、プログラムを強制終了します。
 * [in]
 *	fmt,...		printf()の引数と同様です。
 * [note]
 *	* この関数は処理を返しません。
 */
#ifdef PIECE
void die(const char* fmt, ...) __attribute__((noreturn));
//{{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, ...);
//{{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, ...);

/*****************************************************************************
 *	ユーティリティ：任意長パケットキュー
 *****************************************************************************/

/* * 任意長パケットの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);

/*****************************************************************************
 *	ユーティリティ：リングバッファ
 *****************************************************************************/

/* 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);

/*****************************************************************************
 *	ユーティリティ：ダブルリンクリスト
 *****************************************************************************/

/* 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);

/*****************************************************************************
 *	ユーティリティ：検索
 *****************************************************************************/

/* クイックサーチ法を使って、バイナリパターン検索を行います。
 * [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);

/*****************************************************************************
 *	ユーティリティ：ソート
 *****************************************************************************/

/* マージソートを実行します。
 * [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 */

/*****************************************************************************
 *	ユーティリティ：コレクションのヘルパ関数
 *****************************************************************************/

/* ヘルパ関数の実装例: コレクションがメモリ管理を行わないポインタ、または、数値
 */
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追加: 参照カウント式ガーベージコレクションの機能を内包*/

/*****************************************************************************
 *	ユーティリティ：簡略版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*/

/*****************************************************************************
 *	ユーティリティ：ファイルパック形式
 *****************************************************************************/

/*                           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);

/*****************************************************************************
 *	ユーティリティ：範囲乱数
 *****************************************************************************/

/* 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);

//{{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に追加してください。

#endif /*__CLIP_MISC_H__*/
