/*	
 *	clipstr.h
 *
 *	ユーティリティ：文字列操作
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2001-2016 Naoyuki Sawa
 *
 *	* Sat Oct 11 12:29:17 JST 2014 Naoyuki Sawa
 *	- 作成開始。
 *	- strtrim(),strescape(),strcompress()を、clipmisc.h,cからclipstr.h,cへ移動しました。
 *	- strfreev(),strv_length(),strdup_printf(),strdup_vprintf(),strjoin(),strjoinv(),strsplit(),strsplit_set()を追加しました。
 *	* Mon Oct 13 02:54:55 JST 2014 Naoyuki Sawa
 *	- str_has_prefix(),str_has_suffix()を追加しました。
 *	* Sat Oct 18 18:55:59 JST 2014 Naoyuki Sawa
 *	- string_match()を追加しました。
 *	* Thu Nov 06 00:58:25 JST 2014 Naoyuki Sawa
 *	- strreverse()を追加しました。
 *	* Sat Nov 08 16:50:24 JST 2014 Naoyuki Sawa
 *	- strdupv()を追加しました。
 *	* Tue Nov 11 23:26:40 JST 2014 Naoyuki Sawa
 *	- strconcat()を追加しました。
 *	* Sat Nov 15 20:39:46 JST 2014 Naoyuki Sawa
 *	- str_has_prefix_suffixのバグを修正しました。
 *	  str_has_prefix_suffixの中で%r3を使用しているのに、%r0〜%r2しか退避していないバグでした。
 *	  そのために、str_has_prefix_suffixを呼び出すモジュールが、不正な動作を起こしていました。
 *	  具体的には、cliptcl.cのTcl_GetIndex()が、アドレスエラーで不正終了してしまっていました。
 *	* Sat Mar 07 16:39:40 JST 2015 Naoyuki Sawa
 *	- strstrip(),strchug(),strchomp()を追加しました。
 *	* Sat Mar 07 23:27:25 JST 2015 Naoyuki Sawa
 *	- textwrap()を追加しました。
 *	* Sun Mar 08 10:55:52 JST 2015 Naoyuki Sawa
 *	- strsplit_set()とビットマップGCを併用し、ある程度大きなファイルを分割しようとすると、ビットマップGCがエラー停止する事が有ります。
 *	  この問題について調査した結果を、clipstr.cのstrsplit_set()関数の上に追記しました。
 *	* Mon Mar 09 23:08:36 JST 2015 Naoyuki Sawa
 *	- textwrap()をアセンブラ化しました。
 *	* Sun Jul 19 12:59:05 JST 2015 Naoyuki Sawa
 *	- quark_from_string(),quark_to_string(),intern_string()を追加しました。
 *	* Thu Jul 23 21:03:39 JST 2015 Naoyuki Sawa
 *	- strreplace()を追加しました。
 *	* Wed Aug 12 21:46:27 JST 2015 Naoyuki Sawa
 *	- memdup()を追加しました。
 *	* Thu Oct 15 00:58:32 JST 2015 Naoyuki Sawa
 *	- strnatcmp(),strnatcasecmp()を追加しました。
 *	* Thu Oct 15 22:15:08 JST 2015 Naoyuki Sawa
 *	- strnatcmp(),strnatcasecmp()をアセンブラ化しました。コードサイズが80バイト減りました。
 *	  とりあえず、C言語版,アセンブラ版の両方で、テストスイートをパスする事は確認したのですが、まだアセンブラ版の動作確認が不十分です。
 *	* Fri Oct 16 21:16:43 JST 2015 Naoyuki Sawa
 *	- strnatcmp(),strnatcasecmp()の動作を変更しました。
 *	  詳細は、clipstr.hのstrnatcmp(),strnatcasecmp()のコメントを参照して下さい。
 *	* Wed Nov 18 21:37:53 JST 2015 Naoyuki Sawa
 *	- 'extern "C" {'〜'}'で囲みました。.cppを含むWin32プロジェクトからもインクルード出来るようにするためです。
 *	* Tue Jan 19 21:44:45 JST 2016 Naoyuki Sawa
 *	- StrConv()を追加しました。
 *	* Sat Apr 09 21:06:53 JST 2016 Naoyuki Sawa
 *	- strdup_splitpath()とstrdup_makepath()を追加しました。
 *	  splitpath()とmakepath()も、strdup_printf()と同様に使えると便利なので、自分の判断で'strdup_*()'バージョンを追加する事にしました。
 *	* Fri May 06 21:58:10 JST 2016 Naoyuki Sawa
 *	- intern_string()が、キーと値が同じメモリを指すようにして、メモリの無駄を低減しました。
 *	* Sat May 21 22:36:02 JST 2016 Naoyuki Sawa
 *	- strsplit()とstrsplit_set()をマルチバイト対応しました。
 *	  古いコードでは配列のメモリ確保を関数内で行っていましたが、新しいコードではstrv.cの機能を使うように変更し、コードが簡潔になりました。
 *	  コードが簡潔になったことによって、マルチバイト対応を追加したにもかかわらず、当モジュールのコードサイズが約24バイト小さくなりました。
 *	  ただし、strv.oもリンクされるようになった分コードサイズが増加するので、全体としてはコードサイズは増加していると思います。
 *	- 新しいコードで実装を大幅に変更しましたが、基本的なアルゴリズムは古いコードと変わっていません。
 *	  新しいコードには詳細なコメントを付けていないので、アルゴリズムについては古いコードのコメントを参照して下さい。
 *	- マルチバイト非対応の古いコードも、これまで長く安定して動作していた実績が有るので、コードを残しておく事にしました。
 *	  USE_STRSPLIT_MBCSシンボルを定義してライブラリをビルドすると、新しいマルチバイト対応版のstrsplit()とstrsplit_set()を使用します。
 *	  USE_STRSPLIT_MBCSシンボルを定義せずにライブラリをビルドすると、古いマルチバイト非対応版のstrsplit()とstrsplit_set()を使用します。
 *	  基本的には、新しいマルチバイト対応版のstrsplit()とstrsplit_set()を使う予定ですが、もし今後マルチバイト対応が不要になった場合は、古いコードに戻して下さい。
 *	- ■検証プログラム
 *	  │void test1() {
 *	  │  char** s = strsplit("表現\\十回\\予備", "\\", 0);
 *	  │  char** t = s;
 *	  │  while(*t) { printf("'%s'\n", *t++); }
 *	  │  strfreev(s);
 *	  │}
 *	  │//□結果(マルチバイト非対応版)…誤り
 *	  │//│'\x95'  「表」の2バイト目に'\'がマッチしてしまっている。
 *	  │//│'現'
 *	  │//│'\x8F'  「十」の2バイト目に'\'がマッチしてしまっている。
 *	  │//│'回'
 *	  │//│'\x97'  「予」の2バイト目に'\'がマッチしてしまっている。
 *	  │//│'備'
 *	  │//□結果(マルチバイト対応版)…正しい
 *	  │//│'表現'
 *	  │//│'十回'
 *	  │//│'予備'
 *	  │void test2() {
 *	  │  char** s = strsplit_set("表現\\十回\\予備", "表十予", 0);
 *	  │  char** t = s;
 *	  │  while(*t) { printf("'%s'\n", *t++); }
 *	  │  strfreev(s);
 *	  │}
 *	  │//□結果(マルチバイト非対応版)…誤り
 *	  │//│''      「表」の1バイト目が個別に「表」の1バイト目にマッチしてしまっている。
 *	  │//│''      「表」の2バイト目が個別に「表」の2バイト目にマッチしてしまっている。
 *	  │//│'現'    「表」又は「十」又は「予」の2バイト目が'\'にマッチしてしまっている。
 *	  │//│''      「十」の1バイト目が個別に「十」の1バイト目にマッチしてしまっている。
 *	  │//│''      「十」の2バイト目が個別に「十」の2バイト目にマッチしてしまっている。
 *	  │//│'回'    「表」又は「十」又は「予」の2バイト目が'\'にマッチしてしまっている。
 *	  │//│''      「予」の1バイト目が個別に「予」の1バイト目にマッチしてしまっている。
 *	  │//│''      「予」の2バイト目が個別に「予」の2バイト目にマッチしてしまっている。
 *	  │//│'備'    「表」又は「十」又は「予」の2バイト目が'\'にマッチしてしまっている。
 *	  │//□結果(マルチバイト対応版)…正しい
 *	  │//│''
 *	  │//│'現\'
 *	  │//│'回\'
 *	  │//│'備'
 *	* Sun May 22 21:58:55 JST 2016 Naoyuki Sawa
 *	- textwrap()の実装を変更しました。結果は変わりません。
 *	  変更点は以下の通りです。
 *	- 変更前は、textwrap()の中で文字列配列のメモリ確保を行っていました。
 *	  変更後は、strv.cモジュールの機能を使って文字列配列のメモリ確保を行うようにしました。
 *	  この変更によって、関数の実装が単純になり、コードサイズが約44バイト小さくなりました。
 *	  strv.oをリンクするためのコードサイズ増加は有りますが、既にstrstrip()がstrv.oを使用しているので、新たな増加は有りません。
 *	- 変更前のコードも、これまで安定して(…という程頻繁には使っていませんでしたが…)動作していたので、#if 0〜で切り分けて残してあります。
 *	  変更後のコードには、変更前のコードほど詳細なコメントは付けていないので、アルゴリズムについては変更前のコードのコメントを参照して下さい。
 *	  変更後のコードも、変更前のコードと同じアルゴリズムで、文字列配列のメモリを確保する方法が変わっただけです。
 *	* Wed May 25 10:22:02 JST 2016 Naoyuki Sawa
 *	- C言語版のstrcompress()をマルチバイト対応しました。
 *	  strcompress()をマルチバイト対応した目的は、clipyaml.cモジュールのyaml_path_get_node(),yaml_path_set_string()で使用するためです。
 *	  詳細は、clipyaml.cモジュールの同日のコメントを参照して下さい。
 *	- アセンブラ版のstrcompress()はまだ、マルチバイト対応していません。
 *	  アセンブラ版のstrcompress()も、マルチバイト対応する必要が有ります。	⇒{{2016/05/26コメント追記:アセンブラ版のstrcompress()もマルチバイト対応しました。}}
 *	- strcompress()はstrescape()と対を成す関数ですが、今回strcompress()だけをマルチバイト対応した事により、strcompress()とstrescape()の非対称性が生じました。
 *	  半角文字だけを使う限りは問題は生じませんが、全角文字を使用すると、strescape()でエスケープした文字列をstrcompress()で復元した時に、元の文字列にならない可能性が有ります。
 *	  対称性を保つために、strescape()もマルチバイト対応する必要が有ります。	⇒{{2016/05/26コメント追記:strescape()をマルチバイト対応しました。}}
 *	* Thu May 26 20:37:02 JST 2016 Naoyuki Sawa
 *	- アセンブラ版のstrcompress()もマルチバイト対応しました。
 *	  以下の動作確認を行いました。
 *	  │//下記のテスト関数から利用するサブルーチン
 *	  │void test_subr(const char* s, const char* delim) {
 *	  │  do {
 *	  │    char* t = strcompress(s, (char**)&s, delim);
 *	  │    printf("'%s'\n", t);
 *	  │    free(t);
 *	  │    s = mbsninc(s, 1);  //sが既に'\0'を指していた場合に進まないようにするためmbsninc()を使う必要が有る事に注意せよ。mbsinc()ではsが既に'\0'を指していても進んでしまう。
 *	  │  } while(*s);
 *	  │}
 *	  │//■マルチバイト対応になった事を確認するテスト
 *	  │void test1() {
 *	  │  test_subr("表現\\十回\\予備", "\\");
 *	  │  //□変更前
 *	  │  //│'\x95'	←変更前は、全角文字の2バイト目の'\'を間違えてエスケープの'\'と見なしてしまっていた。
 *	  │  //│'現'
 *	  │  //│'\x8F'
 *	  │  //│'回'
 *	  │  //│'\x97'
 *	  │  //│'備'
 *	  │  //□変更前
 *	  │  //│'表現'	←変更後は、正しくなった。
 *	  │  //│'十回'
 *	  │  //│'予備'
 *	  │}
 *	  │//■マルチバイト対応版が様々なケースで正しく動作している事を確認するテスト(以下は全て変更後の出力です)
 *	  │void test2() {
 *	  │  test_subr("", NULL);
 *	  │  //│''
 *	  │  test_subr("ﾊﾝｶｸ", NULL);
 *	  │  //│'ﾊﾝｶｸ'
 *	  │  test_subr("全角", NULL);
 *	  │  //│'全角'
 *	  │  test_subr("\\x30\\x31\\x32", NULL);
 *	  │  //│'012'
 *	  │  test_subr("\\x30\\x31\\x32", "\\");
 *	  │  //│''
 *	  │  //│'x30'
 *	  │  //│'x31'
 *	  │  //│'x32'
 *	  │  test_subr("あいう.えお[かき]", ".[]");
 *	  │  //│'あいう'
 *	  │  //│'えお'
 *	  │  //│'かき'
 *	  │  test_subr("あいう．えお［かき］", "．［］");		//全角文字のデリミタも利用出来るようになった。
 *	  │  //│'あいう'
 *	  │  //│'えお'
 *	  │  //│'かき'
 *	  │  test_subr("あいう\\.えお\\[かき\\]", ".[]");
 *	  │  //│'あいう.えお[かき]'
 *	  │  test_subr("あいう\\．えお\\［かき\\］", "．［］");	//全角文字のデリミタも'\'でエスケープ出来ます。
 *	  │  //│'あいう．えお［かき］'
 *	  │}
 *	* Thu May 26 23:31:18 JST 2016 Naoyuki Sawa
 *	- strescape()をマルチバイト対応しました。
 *	  この対応により、strescape()とstrcompress()の対称性が復活しました。
 *	  詳細は、'Wed May 25 10:22:02 JST 2016'のコメントを参照して下さい。
 *	  以下の動作確認を行いました。
 *	  │//下記のテスト関数から利用するサブルーチン
 *	  │void test_subr(const char* s, const char* need_escape) {
 *	  │  char *t, *u;
 *	  │  t = strescape(s, need_escape);	//┬エスケープした結果を表示する。
 *	  │  printf("'%s'\n", t);		//┘
 *	  │  u = strcompress(t, NULL, NULL);	//┬エスケープを解除して元の文字列とバイナリ一致する事を確認する。
 *	  │  if(strcmp(s, u)) { DIE(); }	//┘
 *	  │  free(t);
 *	  │  free(u);
 *	  │}
 *	  │//■マルチバイト対応版が様々なケースで正しく動作している事を確認するテスト
 *	  │void test() {
 *	  │  test_subr("\1\2\3\4\5\6\7\10\11\12\13\14\15\16\17", NULL);
 *	  │  //│'\001\002\003\004\005\006\a\b\t\n\v\f\r\016\017'
 *	  │  test_subr("C:\\usr\\PIECE\\docs\\PIECE ポート解説.htm", NULL);
 *	  │  //│'C:\\usr\\PIECE\\docs\\PIECE ポート解説.htm'
 *	  │  test_subr("ABC.DEF[123]", NULL);
 *	  │  //│'ABC.DEF[123]'
 *	  │  test_subr("ABC.DEF[123]", ".[]");
 *	  │  //│'ABC\.DEF\[123\]'
 *	  │  test_subr("表現.十回[予備]", NULL);
 *	  │  //│'表現.十回[予備]'				//全角文字はエスケープせずにそのまま表示するようになった。
 *	  │  test_subr("表現.十回[予備]", ".[]");
 *	  │  //│'表現\.十回\[予備\]'
 *	  │  test_subr("表現．十回［予備］", "．［］");	//全角文字もエスケープ対象に出来ます。
 *	  │  //│'表現\．十回\［予備\］'
 *	  │}
 *	* Mon May 30 21:45:50 JST 2016 Naoyuki Sawa
 *	- intern_string()自身で排他制御を行うようにしました。
 *	  これまでは、アプリケーションが注意してintern_string()を割り込みルーチンやマルチスレッド環境で使用しないようにしていましたが、
 *	  intern_string()は様々なモジュールからも間接的に利用するので、アプリケーションが意図して割り込みルーチンやマルチスレッド環境で使用しないように注意するのは難しいと思ったからです。
 *	  今後は、quark_from_string()/quark_to_string()/intern_string()や、これらを間接的に呼び出す各モジュールの関数を、割り込みルーチンやマルチスレッド環境で安全に使用出来るようになりました。
 *	* Mon Jun 06 21:45:00 JST 2016 Naoyuki Sawa
 *	- memrotate()を追加しました。
 *	* Tue Jun 07 22:13:11 JST 2016 Naoyuki Sawa
 *	- memrotate()の実装を変更しました。
 *	  詳細は、clipstl.cモジュールの、std_rotate()関数のコメントを参照して下さい。
 *	  memrotate()の関数仕様は変わっていません。
 */
#ifndef __CLIP_STR_H__
#define __CLIP_STR_H__

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

/*****************************************************************************
 *	トリム
 *****************************************************************************/

/* 指定した文字だけを取り除く。
 * [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);

/* 両端(目的だけならば),又は,左側(strchug),又は,右側(strchomp)の空白文字を除去する。
 * [in]
 *	s		元の文字列
 * [out]
 *	戻り値		引数sをそのまま返す。
 * [note]
 *	- これらの関数は、新しい文字列を作成せずに、元の文字列を直接変更する。
 *	- GLibのg_strstrip(),g_strchug(),g_strchomp()に互換です。
 *	  これらの関数を追加した理由は、GLib互換の関数を用意しておこうと思ったからだけです。
 *	  'トリム'を行う目的だけならば、上のstrtrim()関数の方が高機能です。
 *	  実際のところこれらの関数は内部で、strtrim()関数を呼び出して実装しました。
 */
char* strstrip(char* s);
char* strchug( char* s);
char* strchomp(char* s);

/*****************************************************************************
 *	エスケープ
 *****************************************************************************/

/* 文字列のバイナリデータを、印字可能な文字列にエスケープします。
 * [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, char** endptr, const char* delim);

/*****************************************************************************
 *	文字列ポインタ配列
 *****************************************************************************/

/* 文字列ポインタ配列の、メモリを開放する。
 * [in]
 *	str_array		文字列ポインタ配列。	配列はNULLポインタ要素で終端されていること。(main()関数のargv[]と同様です。)
 *							str_array自体にNULLポインタを指定した場合は、当関数は何もせずに処理を返す。
 * [note]
 *	- GLibのg_strfreev()に互換です。
 */
void strfreev(char** str_array);

/* 文字列ポインタ配列の、要素数を取得する。
 * [in]
 *	str_array		文字列ポインタ配列。	配列はNULLポインタ要素で終端されていること。(main()関数のargv[]と同様です。)
 * [out]
 *	戻り値			要素数。		終端のNULLポインタ要素は、要素数に含めない。
 * [note]
 *	- GLibのg_strv_length()に互換です。
 */
size_t strv_length(char** str_array);

/* 文字列ポインタ配列の、'深い'複製を作成する。
 * [in]
 *	str_array		複製する、文字列ポインタ配列。	配列はNULLポインタ要素で終端されていること。(main()関数のargv[]と同様です。)
 * [out]
 *	戻り値			複製した、文字列ポインタ配列。	呼び出し側にて、strfreev()を使って開放せよ。
 * [note]
 *	- GLibのg_strdupv()に互換です。ただし、以下の一点において、非互換です。
 *	- GLibのg_strdupv()は、引数str_arrayにNULLポインタを指定することができ、g_strdupv()は何もせずにNULLポインタを返します。
 *	  それに対し当実装は、引数str_arrayにNULLポインタを指定することができません。もし指定した場合は、不正な動作となります。
 *	  GLibのg_strdupv()は、独自のg_strdup()が引数にNULLポインタ指定可であることに倣って、g_strdupv()も引数にNULLポインタ指定可としているのだと思いますが、
 *	  g_strdup()やg_strdupv()の引数にNULLポインタ指定可であることは、かえってバグを見つけ辛くなる問題があるように思います。
 *	  従って当実装では、標準的なstrdup()と同様に、引数にNULLポインタ指定不可とすることにしました。
 */
char** strdupv(char** str_array);

/****************************************************************************
 *	書式化文字列
 ****************************************************************************/

/* asprintf()と同様だが、文字列を戻り値とする点が異なる。
 * [in]
 *	fmt			書式文字列。
 *	...			可変引数。
 * [out]
 *	戻り値			文字列。		呼び出し側にて、使用終了後に、free()で開放すること。
 * [note]
 *	- GLibのg_strdup_printf()に互換です。
 */
char* strdup_printf(const char* fmt, ...);

/* vasprintf()と同様だが、文字列を戻り値とする点が異なる。
 * [in]
 *	fmt			書式文字列。
 *	ap			可変引数。
 * [out]
 *	戻り値			文字列。		呼び出し側にて、使用終了後に、free()で開放すること。
 * [note]
 *	- GLibのg_strdup_vprintf() に互換です。
 */
char* strdup_vprintf(const char* fmt, va_list ap);

/*****************************************************************************
 *	連結
 *****************************************************************************/

/* 複数の文字列を、一つの文字列に連結する。
 * [in]
 *	s, ...			複数の文字列。		NULLポインタで終端すること。
 * [out]
 *	戻り値			文字列。		呼び出し側にて、使用終了後に、free()で開放すること。
 * [note]
 *	- GLibのg_strconcat()に互換です。
 *	- g_strconcat()の仕様では、最初の文字列sは「the first string to add, which must not be NULL」となっているが、
 *	  当関数は、最初の文字列sがNULLも可とし、その場合、当関数は空文字列("")を返すようにした。
 *	  その方が、strjoin()やstrjoinv()と対象性が有り、便利であるし、判り易いと思ったからです。
 */
char* strconcat(const char* s, ...);

/* 複数の文字列を、一つの文字列に連結する。
 * [in]
 *	separator		セパレータ。		NULLポインタを指定すると、""を指定したのと同じと見なす。
 *	...			複数の文字列。		NULLポインタで終端すること。
 * [out]
 *	戻り値			文字列。		呼び出し側にて、使用終了後に、free()で開放すること。
 * [note]
 *	- GLibのg_strjoin()に互換です。
 */
char* strjoin(const char* separator, ...);

/* 文字列ポインタ配列を、一つの文字列に連結する。
 * [in]
 *	separator		セパレータ。		NULLポインタを指定すると、""を指定したのと同じと見なす。
 *	str_array		文字列ポインタ配列	配列はNULLポインタ要素で終端されていること。(main()関数のargv[]と同様です。)
 * [out]
 *	戻り値			文字列。		呼び出し側にて、使用終了後に、free()で開放すること。
 * [note]
 *	- GLibのg_strjoinv()に互換です。
 */
char* strjoinv(const char* separator, char** str_array);

/****************************************************************************
 *	分割
 ****************************************************************************/

/* 文字列を、デリミタ文字列を用いて分割する。
 * [in]
 *	s			分割する文字列。
 *	delimiter		デリミタ文字列。	""は指定不可。
 *	max_tokens		最大分割数。		1未満の値を指定すると、無限と見なす。
 * [out]
 *	戻り値			文字列ポインタ配列。	呼び出し側にて、使用終了後に、strfreev()で開放すること。
 * [note]
 *	- GLibのg_strsplit()に互換です。
 */
char** strsplit(const char* s, const char* delimiter, int max_tokens);

/* 文字列を、デリミタ文字セットを用いて分割する。
 * [in]
 *	s			分割する文字列。
 *	delimiters		デリミタ文字セット。	""も指定可能。
 *	max_tokens		最大分割数。		1未満の値を指定すると、無限と見なす。
 * [out]
 *	戻り値			文字列ポインタ配列。	呼び出し側にて、使用終了後に、strfreev()で開放すること。
 * [note]
 *	- GLibのg_strsplit_set()に互換です。
 */
char** strsplit_set(const char* s, const char* delimiters, int max_tokens);

/* 文字列を一行の長さに折り返して分割します。
 * [in]
 *	s			折り返す文字列。
 *	w			一行の幅。半角文字は1,全角文字は2と数えます。
 * [out]
 *	戻り値			文字列ポインタ配列。	呼び出し側にて、使用終了後に、strfreev()で開放すること。
 * [note]
 *	- Pythonのtextwrap.wrap()の関数仕様を参考にしました。
 *	- 原則的には、分割された個々の文字列の幅はw以下となります。
 *	  ただし、1文字がw以上の文字が存在した場合、w以上の長さとなる場合も有ります。具体的には、
 *	  wに1未満を指定しても、分割された個々の文字列は幅1以上(半角1文字,又は,全角1文字)に成り得ます。
 *	  wに2未満を指定しても、分割された個々の文字列は幅2以上(全角1文字)に成り得ます。
 *	  この仕様は、Pythonのtextwrap.wrap()と同じです。
 *	- 上記の挙動を応用して、wに1以下を指定すれば、文字列を1文字単位に分割する用途にも利用できます。
 *	- 当関数は、禁則処理は行いません。
 *	- □使用例:
 *	  │char** argv=textwrap("12345六78",3);
 *	  │⇒argv[0]="123",argv[1]="45",argv[2]="六7",argv[3]="8"
 *	  │char** argv=textwrap("1二3",0);
 *	  │⇒argv[0]="1",argv[1]="二",argv[2]="3"
 */
char** textwrap(const char* s, int w);

// * Sat Apr 09 21:06:53 JST 2016 Naoyuki Sawa
// - strdup_splitpath()とstrdup_makepath()を追加しました。
//   splitpath()とmakepath()も、strdup_printf()と同様に使えると便利なので、自分の判断で'strdup_*()'バージョンを追加する事にしました。
// - □使用例
//   │void test(const char* path) {
//   │  char *fname, *ext, *fullpath;
//   │  strdup_splitpath(path, NULL, NULL, &fname, &ext);
//   │  fullpath = strdup_makepath("C:", "\\Home", fname, ext);
//   │  printf("%s\n", fullpath);
//   │  free(fname);    //┐
//   │  free(ext);      //├ガーベージコレクターを使用している場合は解放しなくても構いません。
//   │  free(fullpath); //┘
//   │}
void strdup_splitpath(const char* path, char** drive/*NULL可*/, char** dir/*NULL可*/, char** fname/*NULL可*/, char** ext/*NULL可*/);
char* strdup_makepath(const char* drive/*NULL可*/, const char* dir/*NULL可*/, const char* fname/*NULL可*/, const char* ext/*NULL可*/);

/*****************************************************************************
 *	比較
 *****************************************************************************/

/* 文字列s1のプレフィクス部分が、s2に一致するか調べる。
 * [in]
 *	s1			文字列。
 *	s2			プレフィクス。		""も指定可能。
 * [out]
 *	戻り値			一致しなければ0を返す。
 *				一致したら0以外を返す。
 * [note]
 *	- GLibのg_str_has_prefix()に互換です。
 */
int str_has_prefix(const char* s1, const char* s2);

/* 文字列s1のサフィックス部分が、s2に一致するか調べる。
 * [in]
 *	s1			文字列。
 *	s2			サフィックス。		""も指定可能。
 * [out]
 *	戻り値			一致しなければ0を返す。
 *				一致したら0以外を返す。
 * [note]
 *	- GLibのg_str_has_suffix()に互換です。
 */
int str_has_suffix(const char* s1, const char* s2);

/* Tcl6.7の「string match」に準拠した、文字列パターン比較を行います。
 * [in,out]
 *	│patがstrにマッチするかどうかを確かめます。マッチするならば1を、しないならば0を返します。
 *	│2つの文字列の照合では、patに次の使える特別なシーケンスを除いて、マッチ内容は同一でなければなりません。
 *	│*       空文字列を含むstr内のあらゆる文字シーケンスにマッチします。
 *	│?       str内のあらゆる単独の文字にマッチします。
 *	│[chars] charに与えられたセット内のどれかの文字にマッチします。
 *	│        x-y形式のシーケンスがchars内に現れると、xとyも含まれるxとyの間のいずれかの文字にマッチします。
 *	│        [A-z]は'_'にマッチします。('_'は'Z'と'a'の間にあるので)
 *	│\x      単一の文字xにマッチします。これはpat内の文字*?[]\の特別な解釈を防止する方法を提供します。
 * [note]
 *	- Tcl6.7の「string match」と、一般的な正規表現の相違点として、以下に注意してください:
 *	  一般的な正規表現では、'['の直後の']'は文字クラスを閉じず、文字クラスの一文字と見なされるが、Tcl6.7のstring matchにはこの特例処理が無い。
 *	  一般的な正規表現では、文字クラスの中でも'\'による特殊文字のエスケープやエスケープシーケンスが使えるが、Tcl6.7のstring matchでは使えない。
 *	  行頭を示す'^',行末を示す'$',文字クラス中の'^',グループ化する'(',')',選択する'|'などは有りません。正規表現というよりもVBAのLikeに近いです。
 */
int string_match(const char* pat, const char* str);

/* "自然順"アルゴリズムにより、文字列比較を行います。
 * [in]
 *	s1,s2			文字列。
 * [out]
 *	戻り値			strcmp()と同様です。
 * [note]
 *	- 関数仕様は、PHPのstrnatcmp(),strnatcasecmp()に互換です。
 *	  「PHP マニュアル - strnatcmp」(http://php.net/manual/ja/function.strnatcmp.php)
 *	- 下記のソースを参考にさせて頂きました。
 *	  「Natural Order String Comparison」(http://sourcefrog.net/projects/natsort/)
 *	  オリジナル版の実装は、数字列の比較が一致して外側のループへ抜けた時、比較位置が一文字しか進まない無駄が有るようです。
 *	  最終的な比較結果には違いは有りませんが、速度上の無駄が生じます。
 *	  当実装ではその点を改善し、次の比較位置が数字列の次の位置まで進むようにしました。
 *	- strnatcmp()と、既存のstrverscmp()は、アルゴリズムは異なるのですが、両者による比較結果はほとんど同じなります。
 *	  主な違いは、strnatcmp()は空白を除いて比較する事と、小数部(と見なされる)数字列内の先行する'0'の数による判断基準です。
 *	  後者の違いについては、strverscmp()よりも、strnatcmp()の方が、直観に近い結果だと思います。
 *	  詳細は、実装部の下の「□テストスイート」を参照して下さい。
 *	- strnatcmp()は空白を除いて比較しますが、空白が全く無意味ではない事に注意して下さい。
 *	  数値列の後の空白は、数値列を終端させるアンカーとなります。
 *	* Fri Oct 16 21:16:43 JST 2015 Naoyuki Sawa
 *	- 昨日までの実装は、オリジナル版のstrnatcmp()の動作に準拠していたのですが、明らかに不自然な動作が有って使い辛いので、少し動作を変更することにしました。
 *	  オリジナル版のstrnatcmp()は、POSIX標準というわけではなく、あくまで"自然順"アルゴリズムの実装の一つですから、厳密に準拠しなくても良いと思ったからです。
 *	- オリジナル版のstrnatcmp()は、下記のソート順になるという不自然さがあります。
 *	  │AB C
 *	  │A  C
 *	  なぜこうなるかと言うと、オリジナル版のstrnatcmp()は空白文字を削除して比較するからです。
 *	  この例の場合、内部処理では「ABC」と「AC」の比較になり、前者が小さいと見なされるのです。
 *	- 理由はわかったのですが、明らかに直感に反していて不自然だと思います。
 *	  そこで、当実装では、「空白文字を削除する」のではなく、「連続した空白文字を一つのスペース(' ')に置き換える」事にしました。
 *	  そうすれば、先ほどの例は、内部処理では「AB C」と「A C」の比較になり、前者が大きいと見なせます。
 *	  │A  C
 *	  │AB C
 *	- なお、「連続した空白文字を一つのスペース(' ')に置き換える」事にしたのは、空白文字の種類によって大小を判断するのは不自然だと思ったからです。
 *	  例えば、「\nA\nB\n」「\tA\tB\t」「\r\nA\r\nB\r\n」等は全て、「 A B 」と見なして比較します。
 *	- 単語間の空白については上記の通りなのですが、行頭と行末の空白は、これまでどおり削除して比較します。	←←←■重要■
 *	  そうするのが自然だと思ったからです。
 *	- 以上をまとめますと、判り易い例としては、「A  B C」と「  A B  C  」は、「A B C」と「A B C」の比較となり、一致します。
 */
int strnatcmp(    const char* s1, const char* s2);
int strnatcasecmp(const char* s1, const char* s2);

/*****************************************************************************
 *	反転
 *****************************************************************************/

/* 文字列を反転する。
 * [in]
 *	s		反転する文字列。
 * [out]
 *	戻り値		引数sをそのまま返す。
 * [note]
 *	- GLibのg_strreverse()に互換です。
 */
char* strreverse(char* s);

/*****************************************************************************
 *	単一化
 *****************************************************************************/

/* 文字列の単一化表現の数値を返す。
 * [in]
 *	s		文字列,又は,NULLポンイタ。
 * [out]
 *	戻り値		単一化表現の数値。
 *			文字列にNULLポインタを指定した場合は、0を返す。
 * [note]
 *	- GLibのg_quark_from_string()に互換です。
 *	- GLibのg_quark_from_static_string()に互換な機能は不要だと思うので、追加しませんでした。
 */
int quark_from_string(const char* s);

/* 単一化表現の数値に対応する、文字列を返す。
 * [in]
 *	q		単一化表現の数値,又は,0。
 * [out]
 *	戻り値		文字列。
 *			単一化表現の数値に0を指定した場合は、NULLポインタを返す。
 * [note]
 *	- 引数qに指定出来るのは、'quark_from_string()が返した単一化表現の数値',又は,'0'のみです。
 *	  それ以外の値を指定した場合は、不正な動作となります。
 * [note]
 *	- GLibのg_quark_to_string()に互換です。
 *	- GLibのg_quark_try_string()に互換な機能は不要だと思うので、追加しませんでした。
 */
const char* quark_to_string(int q);

/* 文字列の単一化表現の文字列を返す。
 * [in]
 *	s		文字列,又は,NULLポンイタ。
 * [out]
 *	戻り値		単一化表現の文字列。
 *			文字列にNULLポインタを指定した場合は、NULLポインタを返す。
 * [note]
 *	- GLibのg_intern_string()に互換です。
 *	- GLibのg_intern_static_string()に互換な機能は不要だと思うので、追加しませんでした。
 */
const char* intern_string(const char* s);

/*****************************************************************************
 *	置換
 *****************************************************************************/

/* 文字列sの中の、oldstrを全て、newstrに置換した文字列を作成して返す。
 * [in]
 *	s		元の文字列		""も指定可能。
 *	oldstr		検索する文字列		""は指定不可。
 *	newstr		置換する文字列		""も指定可能。
 * [out]
 *	戻り値		文字列。		呼び出し側にて、使用終了後に、free()で開放すること。
 * [note]
 *	- この関数は、GLib互換ではありません。
 *	  GLibには、文字列置換関数が無いようです。
 */
char* strreplace(const char* s, const char* oldstr, const char* newstr);

/*****************************************************************************
 *	メモリ複製
 *****************************************************************************/

/* メモリ領域を複製する。
 * [in]
 *	src		複製元のアドレス。	n=0の場合のみNULL可
 *	n		複製元のバイト数。	0可
 * [out]
 *	戻り値		複製したメモリのアドレス。
 *			失敗した場合はNULLを返す。
 * [note]
 *	- memdup()はC標準ではありません。
 *	  いくつかのUnixやオープンソースのライブラリに含まれているようです。
 *	  │http://www2.research.att.com/sw/download/man/man3/mem.html
 *	  │http://antti-juhani.kaijanaho.fi/darcs/publib/alloc/memdup.c
 *	  │http://opensource.apple.com/source/ksh/ksh-13/ksh/src/lib/libast/string/memdup.c
 *	- memdup()はC標準ではありませんが、便利なので、当ライブラリにも実装する事にしました。
 *	  関数仕様は自明であり、既存のどの実装を参考にしても、同じ関数仕様になります。
 */
void* memdup(const void* src, size_t n);

/*****************************************************************************
 *	メモリローテート
 *****************************************************************************/

//メモリブロックをローテートする。
//[in]
//	base		メモリブロックの先頭アドレス
//	n		ローテート数
//				{base[0]〜base[size-1]}の範囲を、nバイト分ローテートしてずらす。
//				(n>0)ならば、後方へローテートする。([0]→[1]→〜→[size-1]→[0])	┐・結果は左記の通りですが、内部処理としては、当関数内で後方ローテートと前方ローテートどちらで処理する方が早いかを判断し、早い方で処理します。
//				(n<0)ならば、前方へローテートする。([0]←[1]←〜←[size-1]←[0])	┘・ローテート数(の絶対値)に、メモリブロックのサイズ以上の値を指定しても構いません。当関数内で剰余を求めて、最小限のローテート数で処理します。
//				(n=0)ならば、何もしない。
//	size		メモリブロックのバイト数
//				(size=0)ならば、何もしない。
//[out]
//	戻り値		引数baseをそのまま返す。
//[note]
//	- 当関数の仕様は独自です。
//	  参考にした既存のライブラリは有りません。
//	- 当関数を追加した理由は、今後、clipmemc.cにメモリブロックのリサイズ機能を追加する時に、使う予定だからです。
//	  具体的には、リサイズするメモリブロックを、一連の割り当て済み領域の末尾へローテートして移動してから、リサイズすれば簡単に実装出来ると思うからです。
//	  2016/06/06AM現在、clipmemc.cにはまだ上記の機能を追加していませんが、近々追加する予定です。	⇒{{2016/06/06PMコメント追記:clipmemc.cにMemCpt_Resize()を追加しました。memrotate()の応用例としてMemCpt_Resize()を参照して下さい。}}
void* memrotate(void* _base, int n, size_t size);

/*****************************************************************************
 *	変換
 *****************************************************************************/

#ifdef  WIN32
/* VBAのStrConv()に互換な関数です。
 * [in]
 *	str		変換する文字列
 *	conv		実行する変換の種類の値の合計
 * [out]
 *	戻り値		文字列。		呼び出し側にて、使用終了後に、free()で開放すること。
 * [note]
 *	- Win32 APIを使って文字の種類を変換するには、LCMapString()を二回呼び出す必要が有ります。
 *	  アプリケーションが毎回LCMapString()を二回呼び出す手間を省くために、当関数を作成しました。
 *	- LCMapString()よりも、VBAのStrConv()の方が慣れているので、StrConv()互換とする事にしました。
 *	  尚、以下のvb〜定数は直接LCMAP_〜定数の値に定義しても良かったのですが、
 *	  本当のvb〜定数と同じ値にしておく方が後々混乱しないと思うので、本当のvb〜定数と同じ値で定義しました。
 *	  vb〜定数からLCMAP_〜定数への変換は、当関数の処理の中で行っています。
 *	- 当関数の処理内容は、既存の/clip/tool/dpstrcnv/ツールで行っていた処理を、ほぼそのまま持ってきました。
 *	  詳細は、/clip/tool/dpstrcnv/app.cを参照して下さい。
 */
char* StrConv(const char* str, int conv);
//引数convには以下の定数の0個以上の組み合わせを指定して下さい。
#define vbUpperCase	  1	//文字列を大文字に変換します。						┐
#define vbLowerCase	  2	//文字列を小文字に変換します。						│
//#define vbProperCase	  3	//文字列の各単語の先頭の文字を大文字に変換します。			│
#define vbWide		  4	//文字列内の半角文字(1バイト)を全角文字(2バイト)に変換します。		│
#define vbNarrow	  8	//文字列内の全角文字(2バイト)を半角文字(1バイト)に変換します。		├「MSDN ライブラリ Microsoft Visual Studio 6.0 リリース - StrConv 関数」より
#define vbKatakana	 16	//文字列内のひらがなをカタカナに変換します。				│
#define vbHiragana	 32	//文字列内のカタカナをひらがなに変換します。				│
//#define vbUnicode	 64	//システムの既定のコードページを使って文字列をUnicodeに変換します。	│
//#define vbFromUnicode	128	//文字列をUnicodeからシステムの既定のコードページに変換します。		┘
#endif//WIN32

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

#endif/*__CLIP_STR_H__*/
