/*	
 *	clipxls.h
 *
 *	ユーティリティ：エクセル
 *
 *	CLiP - Common Library for P/ECE
 *	Copyright (C) 2016 Naoyuki Sawa
 *
 *	* Tue Jun 28 21:02:01 JST 2016 Naoyuki Sawa
 *	- 1st リリース。
 *	  エクセルデータを直接操作する時に利用する関数を、当モジュールに実装する事にしました。
 *	  2016/06/28現在の所、strtoref()のみです。
 *	  実際にこれを使用するツールやアプリケーションは、まだ作成していません。
 *	  これからツールやアプリケーションを作成しながら、動作検証する予定です。
 *	* Wed Jun 29 21:00:15 JST 2016 Naoyuki Sawa
 *	- strtoref()の、パス名,ブック名,シート名のパース処理を、シフトJIS対応にしました。
 *	  そのために、strtoref_parse1()内で文字を取得する処理を、mbsnextc(),mbsinc()を使うように変更しました。
 *	- strtoref()が判定ている特殊文字は、「'」「!」「[」「]」が有りますが、シフトJISの2バイト目に一致するのは「[」「]」だけなので、「'」「!」は考慮不要です。
 *	  「[」「]」は、パス名,ブック名,シート名のパース(strtoref_parse1())と、R1C1形式のパース(strtoref_parse2())で判定していますが、
 *	  シフトJIS文字が現れる可能性が有るのは前者(strtoref_parse1())だけなので、後者(strtoref_parse2())ではシフトJIS対応は不要です。
 *	  従って、今回変更した部分は、strtoref_parse1()だけです。
 *	- これまでは、パス名,ブック名,シート名にシフトJIS文字が含まれていると、間違った結果になる事が有りましたが、今回の変更によって、正しい結果になりました。
 *	  動作確認結果は、以下の通りです。
 *	  □テストプログラム
 *	  │void test() {
 *	  │  const char ref[]="格納回転イロハ!A1";	//="\x8A\x69\x94\x5B\x89\xF1\x93\x5D\x83\x43\x83\x8D\x83\x6E\x21\x41\x31"
 *	  │  char *book, *sheet;
 *	  │  int flag, col, row;
 *	  │  flag = strtoref(ref, NULL, &book, &sheet, &row, &col);
 *	  │  printf("%-40s %06b %'8d %'8d %-24s %-24s\n", ref, flag, row, col, book ? book : "(NULL)", sheet ? sheet : "(NULL)");
 *	  │  free(book);
 *	  │  free(sheet);
 *	  │}
 *	  ×結果(修正前)
 *	  │格納回転イロハ!A1  101001  1  1  格\x94回\x93  イロハ	「納」の2バイト目が「[」，「転」の2バイト目が「]」に偶然一致して、"格\x94[回\x93]イロハ!A1"と見なされてしまっている。
 *	  ○結果(修正後)
 *	  │格納回転イロハ!A1  101001  1  1  (NULL)        格納回転イロハ
 *	* Sat Jul 02 21:34:21 JST 2016 Naoyuki Sawa
 *	- reftostr()を追加しました。
 */
#ifndef __CLIP_XLS_H__
#define __CLIP_XLS_H__
#ifdef  __cplusplus
extern "C" {
#endif//__cplusplus
/****************************************************************************
 *	定数
 ****************************************************************************/
//strtoref()の戻り値
#define XlsRef_Style_A1		(1<<0)		//A1形式	┬どちらか一方がセットされる。
#define XlsRef_Style_R1C1	(1<<1)		//R1C1形式	┘
#define XlsRef_Style_Mask	(XlsRef_Style_A1|XlsRef_Style_R1C1)
#define XlsRef_RowType_Abs	(1<<2)		//行絶対	┬どちらか一方がセットされる。
#define XlsRef_RowType_Rel	(1<<3)		//行相対	┘
#define XlsRef_RowType_Mask	(XlsRef_RowType_Abs|XlsRef_RowType_Rel)
#define XlsRef_ColType_Abs	(1<<4)		//列絶対	┬どちらか一方がセットされる。
#define XlsRef_ColType_Rel	(1<<5)		//列相対	┘
#define XlsRef_ColType_Mask	(XlsRef_ColType_Abs|XlsRef_ColType_Rel)
/****************************************************************************
 *	グローバル関数
 ****************************************************************************/
//エクセルの参照表現をパースして、各要素を取得します。
//[in]
//	_ptr		エクセルの参照表現の文字列
//	_endptr		変換に使われた最終文字の次の文字へのポインタを格納する変数へのポインタ		NULL可
//			失敗ならば、引数_ptrの元の値をそのまま格納します。
//	_book		パス名とブック名を連結した文字列を格納する変数へのポインタ			NULL可
//			失敗ならば、NULLを格納します。
//			成功しても、参照表現の中にパス名もブック名も無ければ、NULLを格納します。
//			文字列が格納された場合、呼び出し側にてfree(_book)で解放して下さい。
//	_sheet		シート名の文字列を格納する変数へのポインタ					NULL可
//			失敗ならば、NULLを格納します。
//			成功しても、参照表現の中にシート名が無ければ、NULLを格納します。
//			文字列が格納された場合、呼び出し側にてfree(_sheet)で解放して下さい。
//	_row		行を格納する変数へのポインタ							NULL可
//			失敗ならば、0を格納します。
//	_col		列を格納する変数へのポインタ							NULL可
//			失敗ならば、0を格納します。
//[out]
//	戻り値		成功ならば、XlsRef_Style_*,XlsRef_RowType_*,XlsRef_ColType_*を組み合わせた値を返します。
//			失敗ならば、0を返します。
//[note]
//	- 当関数が受け付ける、エクセルの参照表現は、以下の通りです。	--- 例 ---				--- 備考 ---
//	  │セル参照	─	セル名					A1
//	  │シート参照	┬	シート名!セル名				Sheet1!A1
//	  │		└	'シート名'!セル名			'Sheet 1'!A1				シート名に空白や記号が含まれる場合は、この形式になるようです。
//	  │ブック参照	┬	[ブック名]シート名!セル名		[Book1.xlsx]Sheet1!A1
//	  │		│	'[ブック名]シート名'!セル名		'[Book 1.xlsx]Sheet 1'!A1		ブック名,又は,シート名に空白や記号が含まれる場合は、この形式になるようです。
//	  │		└	'パス名[ブック名]シート名'!セル名	'C:\Home\[Book1.xlsx]Sheet1'!A1		パス名が含まれる場合は、空白や記号の有無に関係無く、この形式になるようです。
//	- 「'」〜「'」の中にある「''」は、単一の「'」と見なします。	'C:\H''o''me\[Book1.xlsx]Sheet1'!A1
//	-  パス名やブック名に「[」や「]」が含まれているケースは、考慮していません。
//	   本物のExcelでも、ブック参照のパス名やブック名に「[」や「]」が含まれていると、リンク貼り付け時に「(」や「)」に化けて、正しく動作しないようです。(Excel 2013にて確認)
//	   尚、シート名には(Excelの制約で)「[」や「]」は使えないので、シート名に「[」や「]」が含まれているケースは、考慮する必要は有りません。
//	- 当関数が受け付ける、セル名の文字列は、以下の通りです。
//	  │ABC数値		行相対		列相対
//	  │$ABC数値		行相対		列絶対
//	  │ABC$数値		行絶対		列相対
//	  │$ABC$数値		行絶対		列絶対
//	  │RC			行相対		列相対
//	  │R数値C		行絶対		列相対
//	  │RC数値		行相対		列絶対
//	  │R数値C数値		行絶対		列絶対
//	  │R[数値]C		行相対		列相対		[〜]の中の数値はマイナス可
//	  │RC[数値]		行相対		列相対		[〜]の中の数値はマイナス可
//	  │R[数値]C[数値]	行相対		列相対		[〜]の中の数値はマイナス可
//	- A1形式の列を示すアルファベット,及び,R1C1形式のRとCは、小文字でも構いません。
int strtoref(const char* _ptr, char** _endptr/*NULL可*/, char** _book/*NULL可*/, char** _sheet/*NULL可*/, int* _row/*NULL可*/, int* _col/*NULL可*/);
/*--------------------------------------------------------------------------*/
//ブック名(省略可),シート名(省略可),行,列を、エクセルの参照表現の文字列に組み立てます。
//[in]
//	book		ブック名の文字列
//			パスを含んでいても、ファイル名だけでも構いません。				NULL可
//	sheet		シート名の文字列								NULL可
//	row		行
//			R1C1形式の行相対の場合のみ、1未満でも構いません。それ以外は、1以上必須です。
//	row		列
//			R1C1形式の列相対の場合のみ、1未満でも構いません。それ以外は、1以上必須です。
//	flag		XlsRef_Style_*,XlsRef_RowType_*,XlsRef_ColType_*を組み合わせた値を指定して下さい。
//[out]
//	戻り値		組み立てた文字列を返します。
//			呼び出し側にてfree()で解放して下さい。
char* reftostr(const char* book/*NULL可*/, const char* sheet/*NULL可*/, int row, int col, int flag);
#ifdef  __cplusplus
}//extern "C"
#endif//__cplusplus
#endif//__CLIP_XLS_H__
