#pragma ident "@(#) wsubformHTML.c 0.0.4 2010.05.24,16:25"
/*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*
  名称
      wsubformHTML.c
      
  概要
  	PostgreSQLデータベースからレコードを検索してHTMLフォームに表示するC言語のコードを生成します。
	INSERT,UPDATE,DELETE用のコードも自動生成します。
	検索結果はFETCHでメモリに確保されるためC言語からの操作がECPGのホスト変数の利用で簡単に出来ます。
	UTF-8に対応しています。
	ウインドウ番号とある箇所はNCURSES版のなごりです。現在別の利用方法を考案中です。


	void sf_tbegin();
	テキスト入力を始める場合必ず必要。テキストのリングポインタの最初の位置に移動する。

	void sf_tprev();
	テキスト入力時現在位置より後ろにポインタを進める。

	void sf_tnext();
	テキスト入力時現在位置より前にポインタを進める。

	この関数はテキストボックスへ文字を書き込みます。
	int sf_tput(int no, int col, char *s);
	int no		ウインドウ番号
	int col		現在のカラム番号
	char *s		テキストボックスセルに書き込む文字列
	返り値：成功は0、失敗は-1

	この関数はグリッドセルへ文字を書き込みます。
	int sf_gput(int no, int col, int line, char *s);
	int no		ウインドウ番号
	int col		カラム番号
	int line		行番号
	char *s		グリッドセルに書き込む文字列
	返り値：成功は0、失敗は-1

	この関数はグリッドセルから文字列を取り出します。
	int sf_gget(int no, int col, int line,char *s);
	int no		ウインドウ番号
	int col		カラム番号
	int line		行番号
	char *s		グリッドセルから読み込んだ文字列
	返り値：成功は0、失敗は-1


	※以下はDBに対応した関数です。col と line の位置が逆になっていることに注意してください。
	※DBに関連した関数は特殊な処理をしています。
	  特にwsubform.h に定義されている splitDBbuff[][] は ase エディタで定義された定義ファイルの情報を利用します。

	void sf_startcell(int no);
	int no		ウインドウ番号
	セルのポジションを０で初期化します。

	void sf_to_text(int in,char *out)
	int in		int の数値
	char *out	数値を文字に変換したバッファ
	DBの各行をsplitDBbuff[][]に格納するために数値を文字列(テキスト)化します。

	long sf_to_numeric(char *in);
	char *in	数値を文字に変換したバッファ
	整数字の文字列を数値にして返す。
	splitDBbuff[][]の各行をDBに格納するために数字の場合は数値(long int)に変換します。

	int sf_to_integer(char *in);
	char *in	数字の文字列
	整数字の文字列を数値にして返す。
	splitDBbuff[][]の各行をDBに格納するために数字の場合は数値(int)に変換します。

	int sf_to_double(char *in);
	小数点数字の文字列を小数点を含む数値にして返します。

	void sf_freeDB(int no, int DBcount, int maxcol);
	int no		ウインドウ番号
	int DBcount	データベーステーブル行の現在の行数
	int maxcol	データベーステーブル行の最大項目数
	テーブルのカラム項目と行が割り当てられたsplitDBbuff[][]をメモリから開放します。

	int sf_textboxfree(int maxtext);
	int maxtext	データベーステーブル列の最大項目数

	int sf_ggetDB(int no, int line, int col, int startline,char *s);
	int no		ウインドウ番号
	int line	DBグリッドの行番号
	int col		DBグリッドのカラム番号
	int startline	グリッドの１行目に読み込むDBの行番号
	char *s		DBから読み込んだ文字列
	返り値：成功は0、失敗は-1
	グリッドセルと同じ位置にあるデータベース行とカラムの情報を読み取ります。

	int sf_gputDBHTML(int no, int line, int col, int startline,char *s);
	int no		ウインドウ番号
	int line	DBグリッドの行番号
	int col		DBグリッドのカラム番号
	int startline	グリッドの１行目に書き込むDBの行番号
	char *s		DBに書き込む文字列
	返り値：成功は0、失敗は-1
	グリッドセルと同じ位置にあるデータベーステーブル行カラムに情報を書き込みます。

	int sf_tputDB(int no, int col, char *s);
	int no		ウインドウ番号
	int col		テキストボックスのカラム番号
	char *s		DBに書き込む文字列
	返り値：成功は0、失敗は-1
	テキストボックスセルと同じ位置にあるデータベーステーブル行カラムに情報を書き込みます。

	int sf_tgetDBallHTML(int no);
	int no		ウインドウ番号
	※テキストボックスをDBテキストボックス化する。

	void sf_assgetDB(int no,int line,int col, char *buff, int size);
	int no		ウインドウ番号
	int line	行番号
	int col		カラム番号
	char *buff	DBから読み込んだ文字列
	int size	ecpg で定義された内部配列のサイズ
	ECPGソースの内部で定義された配列をsf_DBgrid()で扱えるようsplitDBbuff[][]に展開します。
	同時に初期化も行います。
	FETCHされたDB行を扱うための関数です。DBからの読み取り専用の関数です。

	void sf_assputDB(int no,int col, char *buff, int size);
	int no		ウインドウ番号
	int col		カラム番号
	char *buff	DBに書き込む文字列
	int size	ecpg で定義された内部配列のサイズ
	テキストボックス用配列splitDBbuff[]に展開されたデータ(char*)をECPGで扱えるように元に戻すための準備をします。
	同時に初期化も行います。
	特にINSERT,UPDATEでDBへの書き込みを行う場合に使用します。


	以下の2つの関数は定義ファイルを使用しないで直接テキストボックスやグリッドを
	作成する機能を持ちます。

	この関数は定義ファイルを使用しないでテキストボックスを作成します。
	aseのエディター画面から'c'コマンドでＣ言語のソースファイルを生成し、
	その中身部分を定義ファイル呼出部分と置き換えて利用します。
	int MakeTextBoxHTML(int no,int fx,int fy,int xcol,int xrow,int *label_no,char **label_text,int *label_x,int *label_y,int *label_length,int *textbox_no,int *textbox_x,int *textbox_y,int *textbox_length,int *align,int *action,int *field,int *skipstep, int m)

	int no	ウインドウ番号	
	int fx	ウインドウＸ軸開始位置
	int fy	ウインドウＹ軸開始位置
	int xcol	ウインドウ横幅
	int xrow	ウインドウ高さ
	int *label_no	ラベル番号
	char **label_text	ラベル内文字列(ラベルテキストの配列へのポインタ)
	int *label_x	ラベルＸ軸開始位置
	int *label_y	ラベルＹ軸開始位置
	int *label_length	ラベルの長さ
	int *textbox_no		テキストボックス番号
	int *textbox_x	テキストボックスＸ軸開始位置
	int *textbox_y	テキストボックスＹ軸開始位置
	int *textbox_length	テキストボックスの長さ
	int *align	テキストボックス内の文字の位置属性(1.右 2.左 3.センター)
	int *action	テキストボックスの編集属性(0.編集可 1.編集不可)
	int *field	テキストボックスの属性
		TEXT.1 NUMERIC.2 BOOL.3 CURRENCY.4 DATE.5 SINGLE.6 DOUBLE.7 BYTE.8
	int *skipstep 	テキストボックス移動属性(0.SKIP 1.STEP)
	int m	テキストボックスの数

	この関数は定義ファイルを使用しないでグリッドを作成します。
	aseのエディター画面からコマンドでＣ言語のソースファイルを生成し、
	その中身部分を定義ファイル呼出部分と置き換えて利用します。
	int MakeWsubFormHTML(int no, int xcol,int rows,int fx ,int fy,int grid_sx,int grid_sy,int grid_ex,int grid_ey,int *length,int *align,int *action,int *field,int *skipstep,char **grid_titles,int m)

	int no		ウインドウ番号
	int xcol	ウインドウ横幅
	int rows	ウインドウ高さ
	int fx 		ウインドウＸ軸開始位置
	int fy		ウインドウＹ軸開始位置
	int grid_sx		グリッドＸ軸開始位置
	int grid_sy		グリッドＹ軸開始位置
	int grid_ex		グリッドＸ軸終端位置
	int grid_ey		グリッドＹ軸終端位置
	int *length		グリッド各縦列の幅
	int *align		グリッド各縦列の文字の位置属性(1.右 2.左 3.センター)
	int *action		グリッド各縦列の編集属性(0.編集可 1.編集不可)
	int *field		グリッド各縦列の属性
		TEXT.1 NUMERIC.2 BOOL.3 CURRENCY.4 DATE.5 SINGLE.6 DOUBLE.7 BYTE.8
	int *skipstep		グリッド各縦列の移動属性(0.SKIP 1.STEP)
	char **grid_titles		グリッド各縦列内の文字列(テキストの配列へのポインタ)
	int m			グリッドの行数


  説明

      
  多言語化対応
      

  診断
      

  例
      添付の sample.c を参照

  参照
	ncurses
      
  バグ
      
      
  著者
	
	Shigeki Ono. 2001/01/15
      
  標準準拠
      


  作者後書


*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*X*/

#include "wsubformHTML.h"

static char label[MAX_POS][MAX_LEN];	//For label strings
static int Labelpos[MAX_POS][4];	//For label positionos
static int Textpos[MAX_POS][4];		//For Textbox positionos
static char tmpbuff1[MAX_TMP];		//Tempolary buffer no 1
static char tmpbuff2[MAX_TMP];		//Tempolary buffer no 2

int wmode;				//For input key mode
//WINDOW *emi;				//Emidiate window used (wmode)
char gridtitles[MAX_POS][MAX_LEN];	//For grid title

typedef struct stat Dir;		//for definition of curses display file
Dir dirptr;
Dir  *fileptr = &dirptr;

TextBox	Begin, Ending;			//Dummy hedder for Textbox links
TextBox	 *begin = &Begin;		
TextBox	 *ending = &Ending;
TextBox	 *tp = &Begin;

char tmp[MAX_STR];

/************************************************************************/
/* NAME      :sf_tbegin()*/
/* FUNCTION  :*/ 
/*            */ 
/*            */ 
/*            */ 
/* RETURN    :                        */
/************************************************************************/
void sf_tbegin(void)
{
	if(begin->next != (TextBox *)NULL)
	{
		tp = begin->next;
	}
}

/************************************************************************/
/* NAME      :sf_tprev()*/
/* FUNCTION  :*/ 
/*            */ 
/*            */ 
/*            */ 
/* RETURN    :                        */
/************************************************************************/
int sf_tprev(void)
{
	if(tp->prev != (TextBox *)NULL)
	{
		tp = tp->prev;
		return(0);
	}
	else
	{
		return(-1);
	}
}

/************************************************************************/
/* NAME      :sf_to_integer()*/
/* FUNCTION  :*/ 
/*            */ 
/*            */ 
/*            */ 
/* RETURN    :                        */
/************************************************************************/
int sf_to_integer(char *in)
{
	int out;
	out = atoi(in);
	return(out);
}
/************************************************************************/
/* NAME      :sf_to_double()*/
/* FUNCTION  :*/ 
/*            */ 
/*            */ 
/*            */ 
/* RETURN    :                        */
/************************************************************************/
double sf_to_double(char *in)
{
	double out;
	out = atof(in);
	return(out);
}

/************************************************************************/
/* NAME      :sf_tputDB()*/
/* FUNCTION  :*/ 
/*            */ 
/*            */ 
/*            */ 
/* RETURN    :                        */
/************************************************************************/
int sf_tputDB(int no, int col, char *s)
{
	sprintf(s,"%s",splitDBbuff[col]);
	if(sf_tput(no,col,s) == -1)
		return(-1);
	else
		return(0);
}

/************************************************************************/
/* NAME      :sf_tgetDBallHTML()*/
/* FUNCTION  :*/ 
/*            */ 
/*            */ 
/*            */ 
/* RETURN    :                        */
/************************************************************************/
int sf_tgetDBallHTML(int no)
{
	int t;
	char s[MAX_STR];

	sf_tbegin();
	for(t=0;tp->next != (TextBox *)NULL;t++)
	{
		splitDBbuff[t] = (char *)malloc((tp->len*3)+1);
		sprintf(s,"%s",KEY[t]);
		sprintf(splitDBbuff[t],"%s",s);
		sf_tnext();
	}
	splitDBbuff[t] = (char *)malloc((tp->len*3)+1);
	sprintf(s,"%s",KEY[t]);
	sprintf(splitDBbuff[t],"%s",s);
}

/************************************************************************/
/* NAME      :sf_assputDB()*/
/* FUNCTION  :*/ 
/*            */ 
/*            */ 
/*            */ 
/* RETURN    :                        */
/************************************************************************/
void sf_assputDB(int no,int col, char *buff, int size)
{
	switch(ft[no].cp[col][0].ftype)
	{
	case 1:	//TEXT or char or varchar TYPE
	//	memset(buff,'\0',size);
		memset(buff,'\0',sizeof(buff));
	//	sprintf(buff,"%s",decodeUTF(splitDBbuff[col]));
		sprintf(buff,"%s",splitDBbuff[col]);
		free(splitDBbuff[col]);
		break;
	case 2:	//NUMERIC or integer TYPE
	//	memset(buff,'\0',size);
		memset(buff,'\0',sizeof(buff));
		sprintf(buff,"%s",splitDBbuff[col]);
		free(splitDBbuff[col]);
		break;
	case 3:	//BOOL TYPE
		memset(buff,'\0',sizeof(buff));
		sprintf(buff,"%s",splitDBbuff[col]);
		free(splitDBbuff[col]);
		break;
	case 4:	//CURRENCY AND MOENY TYPE
		memset(buff,'\0',sizeof(buff));
		sprintf(buff,"%s",splitDBbuff[col]);
		free(splitDBbuff[col]);
		break;
	case 5:	//DATE TYPE
		memset(buff,'\0',sizeof(buff));
		sprintf(buff,"%-8s",splitDBbuff[col]);
		free(splitDBbuff[col]);
		break;
	case 6:	//SINGLE TYPE
		memset(buff,'\0',sizeof(buff));
		sprintf(buff,"%.4f",atof(splitDBbuff[col]));
		free(splitDBbuff[col]);
		break;
	case 7:	//DOUBLE TYPE
		memset(buff,'\0',sizeof(buff));
		sprintf(buff,"%.8F",atof(splitDBbuff[col]));
		free(splitDBbuff[col]);
		break;
	case 8:	//BYTE TYPE
		memset(buff,'\0',sizeof(buff));
		sprintf(buff,"%c",splitDBbuff[col][0]);
		free(splitDBbuff[col]);
		break;
	default:
		break;
	}
}
//-----------------------------------------------------------------2006-07-18

/************************************************************************/
/* NAME      :sf_startcell()*/
/* FUNCTION  :*/ 
/*            */ 
/*            */ 
/*            */ 
/* RETURN    :                        */
/************************************************************************/
void sf_startcell(int no)
{
	ft[no].pos[0].col = 0;
	ft[no].pos[0].line = 0;
	ft[no].st[0][0].col = 0;
	ft[no].st[0][0].line = 0;
}

/************************************************************************/
/* NAME      :sf_to_text()*/
/* FUNCTION  :*/ 
/*            */ 
/*            */ 
/*            */ 
/* RETURN    :                        */
/************************************************************************/
void sf_to_text(int in,char *out)
{
	sprintf(out,"%d",in);
}

/************************************************************************/
/* NAME      :sf_to_text4F()*/
/* FUNCTION  :*/ 
/*            */ 
/*            */ 
/*            */ 
/* RETURN    :                        */
/************************************************************************/
void sf_to_text4F(double in,char *out)
{
	sprintf(out,"%.4F",in);
}

/************************************************************************/
/* NAME      :sf_to_text8F()*/
/* FUNCTION  :*/ 
/*            */ 
/*            */ 
/*            */ 
/* RETURN    :                        */
/************************************************************************/
void sf_to_text8F(double in,char *out)
{
	sprintf(out,"%.8F",in);
}
/************************************************************************/
/* NAME      :sf_to_numeric()*/
/* FUNCTION  :*/ 
/*            */ 
/*            */ 
/*            */ 
/* RETURN    :                        */
/************************************************************************/
long sf_to_numeric(char *in)
{
	long out;
	out = atol(in);
	return(out);
}

/************************************************************************/
/* NAME      :sf_freeDB()*/
/* FUNCTION  :*/ 
/*            */ 
/*            */ 
/*            */ 
/* RETURN    :                        */
/************************************************************************/
void sf_freeDB(int no, int DBcount, int maxcol)
{
	int i,j;
	for(i=0;i<DBcount;i++)
	{
		for(j=0;j<maxcol;j++)
		{
			free(ft[no].splitDBbuff[i][j]);
		}
	}
}

/************************************************************************/
/* NAME      :sf_ggetDB()*/
/* FUNCTION  :*/ 
/*            */ 
/*            */ 
/*            */ 
/* RETURN    :                        */
/************************************************************************/
int sf_ggetDB(int no, int line, int col, int startline,char *s)
{
	sf_gget(no,col,line,s);
	sprintf(ft[no].splitDBbuff[line+startline][col],"%s",s);

}

/************************************************************************/
/* NAME      :sf_gputDBHTML()*/
/* FUNCTION  :*/ 
/*            */ 
/*            */ 
/*            */ 
/* RETURN    :                        */
/************************************************************************/
int sf_gputDBHTML(int no, int line, int col, int startline,char *s)
{
	sprintf(s,"%s",ft[no].splitDBbuff[line][col]);
	if(sf_gputHTML(no,col,line-startline,s) == -1)
		return(-1);
	else
		return(0);
}

/************************************************************************/
/* NAME      :sf_assgetDB()*/
/* FUNCTION  :*/ 
/*            */ 
/*            */ 
/*            */ 
/* RETURN    :                        */
/************************************************************************/
void sf_assgetDB(int no,int line,int col, char *buff, int size)
{
	switch(ft[no].cp[col][0].ftype)
	{
	case 1:	//TEXT or char or varchar TYPE
		ft[no].splitDBbuff[line][col] = (char *)malloc(size*3);
	//	ft[no].splitDBbuff[line][col] = (char *)malloc(size);
		memset(ft[no].splitDBbuff[line][col],'\0',size*3);
	//	memset(ft[no].splitDBbuff[line][col],'\0',size);
		sprintf(ft[no].splitDBbuff[line][col],"%s", buff);
		break;
	case 2:	//NUMERIC or integer TYPE
		ft[no].splitDBbuff[line][col] = (char *)malloc(size);
		memset(ft[no].splitDBbuff[line][col],'\0',size);
		sprintf(ft[no].splitDBbuff[line][col],"%d", atol(buff));
		break;
	case 3:	//BOOL TYPE
		ft[no].splitDBbuff[line][col] = (char *)malloc(size);
	//	memset(ft[no].splitDBbuff[line][col],'\0',sizeof(buff));
		memset(ft[no].splitDBbuff[line][col],'\0',size);
	//	sprintf(ft[no].splitDBbuff[line][col],"%d", atoi(buff));
		sprintf(ft[no].splitDBbuff[line][col],"%c", buff[0]);
		break;
	case 4:	//CURRENCY AND MONY TYPE
		ft[no].splitDBbuff[line][col] = (char *)malloc(size);
		memset(ft[no].splitDBbuff[line][col],'\0',sizeof(buff));
	//	sprintf(ft[no].splitDBbuff[line][col],"%15d", atol(buff));
		sprintf(ft[no].splitDBbuff[line][col],"%s", varprint(buff));
		break;
	case 5:	//DATE TYPE
		ft[no].splitDBbuff[line][col] = (char *)malloc(size);
		memset(ft[no].splitDBbuff[line][col],'\0',sizeof(buff));
		sprintf(ft[no].splitDBbuff[line][col],"%-8s", buff);
		break;
	case 6:	//SINGLE TYPE
		ft[no].splitDBbuff[line][col] = (char *)malloc(size);
		memset(ft[no].splitDBbuff[line][col],'\0',sizeof(buff));
		sprintf(ft[no].splitDBbuff[line][col],"%.4f", atof(buff));
		break;
	case 7:	//DOUBLE TYPE
		ft[no].splitDBbuff[line][col] = (char *)malloc(size);
		memset(ft[no].splitDBbuff[line][col],'\0',sizeof(buff));
		sprintf(ft[no].splitDBbuff[line][col],"%.4F", atof(buff));
		break;
	case 8:	//BYTE TYPE
		ft[no].splitDBbuff[line][col] = (char *)malloc(size);
		memset(ft[no].splitDBbuff[line][col],'\0',sizeof(buff));
		sprintf(ft[no].splitDBbuff[line][col],"%c", buff[0]);
		break;
	default:
		break;
	}
}
//-----------------------------------------------------------------2006-07-16
/************************************************************************/
/* NAME      :sf_tnext()*/
/* FUNCTION  :*/ 
/*            */ 
/*            */ 
/*            */ 
/* RETURN    :                        */
/************************************************************************/
int sf_tnext(void)
{
	if(tp->next != (TextBox *)NULL)
	{
		tp = tp->next;
		return(0);
	}
	else
	{
		return(-1);
	}
}

/************************************************************************/
/* NAME      :sf_tput()*/
/* FUNCTION  :*/ 
/*            */ 
/*            */ 
/*            */ 
/* RETURN    :                        */
/************************************************************************/
int sf_tput(int no, int col, char *s)
{
	int ret;
	char spacer[MAX_STR];
	int len;
	ret = 0;

	if(tp->len > strlen(s))
	{
		memset(spacer,'\0',sizeof(spacer));
		memset(spacer,' ',tp->len-strlen(s));
		sprintf(tmpbuff2,"%s%s",s,spacer);
	}
	else
	{
		s[tp->len] = '\0';
		sprintf(tmpbuff2,"%s",s); 
	}
	switch(tp->align)
	{
	case 0:
		sprintf(tp->s,"%s",tmpbuff2);
		break;
	case 1:
		sprintf(tp->s,"%s",srcep(tmpbuff2));
		break;
	case 2:
		sprintf(tp->s,"%s",slcep(tmpbuff2));
		break;
	case 3:
		sprintf(tp->s,"%s",sccep(tmpbuff2));
		break;
	default:
		sprintf(tp->s,"%s",slcep(tmpbuff2));
		break;
	}
	return(ret);
}

/************************************************************************/
/* NAME      :sf_gputHTML()*/
/* FUNCTION  :*/ 
/*            */ 
/*            */ 
/*            */ 
/* RETURN    :                        */
/************************************************************************/
int sf_gputHTML(int no, int col, int line, char *s)
{
	int ret;
	int len;
	char spacer[MAX_STR];
	ret = 0;

	if(col > ft[no].lcol)
		return(-1);
	if(line > (ft[no].ey-ft[no].sy))
		return(-1);
	len = strlen(s);
	if(ft[no].cp[col][line].len > len)
	{
		memset(spacer,'\0',sizeof(spacer));
	//	memset(spacer,' ',ft[no].cp[col][line].len-strlen(s));
		memset(spacer,' ',ft[no].cp[col][line].len-len);
		sprintf(tmpbuff2,"%s%s",s,spacer);
	}
	else
	{
	//2010.04.07
		s[len] = '\0';
		sprintf(tmpbuff2,"%s",s);
	}
	switch(ft[no].cp[col][line].align)
	{
	case 0:
		sprintf(ft[no].cp[col][line].s,"%s",tmpbuff2);
		break;
	case 1:
		sprintf(ft[no].cp[col][line].s,"%s",srcep(tmpbuff2));
		break;
	case 2:
		sprintf(ft[no].cp[col][line].s,"%s",slcep(tmpbuff2));
		break;
	case 3:
		sprintf(ft[no].cp[col][line].s,"%s",sccep(tmpbuff2));
		break;
	default:
		sprintf(ft[no].cp[col][line].s,"%s",slcep(tmpbuff2));
		break;
	}
	return(ret);
}

/************************************************************************/
/* NAME      :sf_gget()*/
/* FUNCTION  :*/ 
/*            */ 
/*            */ 
/*            */ 
/* RETURN    :                        */
/************************************************************************/
int sf_gget(int no, int col, int line,char *s)
{
	int ret;
	char *p;

	ret = 0;
	if(col > ft[no].lcol)
		return(-1);
	if(line > (ft[no].ey-ft[no].sy))
		return(-1);

//2001.02.01
	sprintf(s,"%s",ft[no].cp[col][line].s);
	cutspace_right(s);
	return(0);
}

/*
TEXT			1
NUMERIC			2
BOOL			3
CURRENCY		4
DATE			5
SINGLE			6
DOUBLE			7
BYTE			8
*/

/************************************************************************/
/* NAME      :textboxfree()*/
/* FUNCTION  :*/ 
/*            */ 
/*            */ 
/*            */ 
/* RETURN    :                        */
/************************************************************************/
int sf_textboxfree(int maxtext)
{
	int i;
	tp = begin->next;
	free(tp->s);
	free(tp);
	for(i=0;i<maxtext;i++)
	{
		if(tp->next != (TextBox *)NULL)
		{
			tp = tp->next;
			free(tp->s);
			free(tp);
		}
	}
}

/*
TEXT			1
NUMERIC			2
BOOL			3
CURRENCY		4
DATE			5
SINGLE			6
DOUBLE			7
BYTE			8
VARIANT			9
*/

int MakeTextBoxHTML(int no,int fx,int fy,int xcol,int xrow,int *label_no,char **label_text,int *label_x,int *label_y,int *label_length,int *textbox_no,int *textbox_x,int *textbox_y,int *textbox_length,int *align,int *action,int *field,int *skipstep, int m)
{
	static TextBox *gp;
	static int i,j,k;
	static char p[MAX_STR];
	static int maxtext;
	static int a;

	maxtext = m;

	if(maxtext == 0)
		return(0);

	for(i=0;i<maxtext;i++)
	{
		Labelpos[i][0] = 0;
		Labelpos[i][1] = 0;
		Labelpos[i][2] = 0;
		Labelpos[i][3] = 0;
		Textpos[i][0] = 0;
		Textpos[i][1] = 0;
		Textpos[i][2] = 0;
		Textpos[i][3] = 0;
	}
	for(i=0;i<maxtext;i++)
	{
		Labelpos[i][0] = label_no[i];
		Labelpos[i][1] = label_x[i];
		Labelpos[i][2] = label_y[i];
		Labelpos[i][3] = label_length[i];
	}
	for(i=0;i<maxtext;i++)
	{
		Textpos[i][0] = textbox_no[i];
		Textpos[i][1] = textbox_x[i];
		Textpos[i][2] = textbox_y[i];
		Textpos[i][3] = textbox_length[i];
	}

	i = 0;
	k = 0;

	memset(tmpbuff1,'\0',sizeof(tmpbuff1));

	for(j=0;j<maxtext;j++)
	{
		if((gp = (TextBox *)calloc(1,sizeof(TextBox))) == (TextBox  *)NULL)
		{
			return -1;
		}
		if((gp->s = (char *)calloc(2,sizeof(tmpbuff1) + 1)) == (char  *)NULL)
		{
			return -1;
		}

		memset(tmpbuff1,'\0',sizeof(tmpbuff1));
		memset(tmpbuff1,' ',Textpos[j][3]);
		sprintf(gp->s,"%s",tmpbuff1);

		gp->no = i;
		gp->n = i;
		gp->col = i;
		gp->no = Textpos[j][0];
		gp->x = Textpos[j][1];
		gp->y = Textpos[j][2];
		gp->c = i+1;
		gp->len = Textpos[j][3];
		gp->align = align[j];
		gp->action = action[j];
		gp->ftype = field[j];
		gp->stype = skipstep[j];

		ft[no].pos[i].col = i;
		ft[no].pos[i].n = i;
		ft[no].pos[i].c = i+1;
		ft[no].pos[i].len = Textpos[j][3];
		ft[no].pos[i].x = Textpos[j][1];
		ft[no].pos[i].y = Textpos[j][2];
		ft[no].pos[i].align = align[j];
		ft[no].pos[i].action = action[j];
		ft[no].pos[i].ftype = field[j];
		ft[no].pos[i].stype = skipstep[j];

		gp->prev = ending->prev;
		ending->prev = gp;

		gp->next = tp->next;
		tp->next = gp;

		tp = gp;
		i++;
	}

	maxtext = i;

	tp = begin->next;
	for(i=0;i<maxtext+1;i++)
	{
		if(tp->next != (TextBox *)NULL)
		{
			tp = tp->next;
		}
	}
	return(maxtext);
}

int MakeWsubFormHTML(int no, int xcol,int rows,int fx ,int fy,int grid_sx,int grid_sy,int grid_ex,int grid_ey,int *length,int *align,int *action,int *field,int *skipstep,char **grid_titles,int m)
{
	static char p[MAX_TMP];
	static int ch;
	static int i,j,k,l;
	static int c;
	static int maxcell;
	static int ncol,lcol;
	static int ret;

	for(i=0;i<MAX_TMP;i++)
	{
		memset(tmpbuff1,'\0',sizeof(tmpbuff1)) ;
		memset(tmpbuff2,'\0',sizeof(tmpbuff2)) ;
	}

	wmode = 1;

	lcol = m;

	ft[no].sx = grid_sx;
	ft[no].ex = grid_ex;
	ft[no].sy = grid_sy;
	ft[no].ey = grid_ey;
	ft[no].lcol = lcol;
	ft[no].width = xcol;
	ft[no].height = rows;

	if(lcol == 0)
		return(0);

	ncol = 0;
	for(i=0;i < lcol;i++)
		ncol = ncol + length[i];

	i = 0;
	l = 0;

	ncol = 0;
	for(i=0;i < lcol;i++)
		ncol = ncol + length[i];

	for(k=0,c=0;k<(ncol+(m-1));k=(k+length[l-1]+1),c++)
	{
		for(j=0;j<(grid_ey-grid_sy)+1;j++)
		{
			ft[no].st[c][j].x = (k+1);
			ft[no].st[c][j].y = j+1;
			ft[no].cp[c][j].no = i;
			ft[no].cp[c][j].x = (k+1);
			ft[no].cp[c][j].len = length[l];
			ft[no].cp[c][j].y = j;
			ft[no].cp[c][j].c = l;

			ft[no].cp[c][j].align = align[c];
			ft[no].cp[c][j].action = action[c];
			ft[no].cp[c][j].ftype = field[c];
			ft[no].cp[c][j].stype = skipstep[c];

			memset(ft[no].cp[c][j].s,' ',length[l]);
			i++;
		}
		l++;
	}

	i--;

	maxcell = i;

 	l = 0;

	for(i=0,j=0;i < m;i++,j++)
	{
		sprintf(ft[no].LabelName[i],"%s",*(grid_titles+i));
		j = j + length[i];
	}
	return(xcol);
}


/*
以下の２つの関数は文字としての16進コードを実際の16進コードに変換する機能を持ちます。
この機能はGET及びPOSTメソッドでエンコードされたマルチバイトコードを元に戻す場合使用します。
UTF-8コードのデコードに利用してください。
*/
/************************************************************************/
/* NAME      :decodeUTF()*/
/* FUNCTION  :*/ 
/*            */ 
/*            */ 
/*            */ 
/* RETURN    : デコードされた文字列*/
/************************************************************************/
static int cnv(int a)
{
	static char c;

	switch(a)
	{
	case 'A':
		c = 0x0a;
		break;
	case 'B':
		c = 0x0b;
		break;
	case 'C':
		c = 0x0c;
		break;
	case 'D':
		c = 0x0d;
		break;
	case 'E':
		c = 0x0e;
		break;
	case 'F':
		c = 0x0f;
		break;
	case '0':
		c = 0x00;
		break;
	case '1':
		c = 0x01;
		break;
	case '2':
		c = 0x02;
		break;
	case '3':
		c = 0x03;
		break;
	case '4':
		c = 0x04;
		break;
	case '5':
		c = 0x05;
		break;
	case '6':
		c = 0x06;
		break;
	case '7':
		c = 0x07;
		break;
	case '8':
		c = 0x08;
		break;
	case '9':
		c = 0x09;
		break;
	}
	return(c);
}

char *decodeUTF(char *query)
{
	int i,j;
	int len;
	int cnt;
	char buff[1024];
	char allstr[8192];
	char utf[4096];
	char ascii[4096];
	char c1,c2,c3,c4,c5,c6;
	char x1,x2,x3;
	char *qt;
	char meta[2];

	c1 = c2 = c3 = c4 = c5 = c6 = 0x00;
	memset(allstr,'\0',sizeof(allstr));
	memset(utf,'\0',sizeof(utf));
	memset(ascii,'\0',sizeof(ascii));
	cnt = 0;
	len = strlen(query);
	for(i=0,j=0;i<len;i++)
	{
		switch(query[i])
		{
		case '%':
			cnt++;
			j = 0;
			break;
		default:
			if(cnt == 0)
			{
				sprintf(ascii,"%c",query[i]);
				strcat(allstr,ascii);
			}
			buff[j] = query[i];
			j++;
			if(j == 2)
			{
				switch(cnt)
				{
				case 0:
					break;
				case 1:
					c1 = cnv(buff[0]);
					c2 = cnv(buff[1]);
					x1 = c1 << 4 & 0xff; 
					x1 = x1 | c2;
					switch(x1)
					{
					case 0x0a: case 0x0d:
					case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: case 0x28: case 0x29:
					case 0x2a: case 0x2b: case 0x2c: case 0x2d: case 0x2e: case 0x2f:
					case 0x3a: case 0x3b: case 0x3c: case 0x3d: case 0x3e: case 0x3f:
					case 0x40:
					case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
					case 0x60:
					case 0x7b: case 0x7c: case 0x7d: case 0x7e:
					//	printf("%c",x1);
						sprintf(meta,"%c",x1);
						strcat(allstr,meta);
						cnt = 0;
						continue;
					default:
						break;
					}
					break;
				case 2:
					c3 = cnv(buff[0]);
					c4 = cnv(buff[1]);
					x2 = c3 << 4 & 0xff; 
					x2 = x2 | c4;
					break;
				case 3:
					c5 = cnv(buff[0]);
					c6 = cnv(buff[1]);
					x3 = c5 << 4 & 0xff; 
					x3 = x3 | c6;
					sprintf(utf,"%c%c%c",x1,x2,x3);
					strcat(allstr,utf);
					cnt = 0;
					break;
				case 4:
					cnt = 0;
					break;
				}
			}
		}
	}
	qt = malloc(sizeof(allstr));
	sprintf(qt,"%s",allstr);
	return((char *)qt);
//	sprintf(query,"%s",allstr);
//	return((char *)query);
}

/************************************************************************/
/* NAME      :varprint()*/
/* FUNCTION  :*/ 
/*            数値に３桁毎にカンマを付ける。１５桁までの数値に対応*/ 
/*            */ 
/*            */ 
/* RETURN    : カンマを付けた文字列へのポインタ。*/
/************************************************************************/
char *varprint(char *buff)
{
	static int k,l,m,len;
	static char buff2[MAX_STR];

	len = strlen(buff);
	if(len > 17)
	{
		sprintf(buff,"%s","-1");
		return(buff);
	}
	for(k=0;k<len;k++)
		if(buff[k] == '.')
			return(buff);
	for(k=0,l=0,m=len;k<len;k++,m--)
	{
		switch(buff[k])
		{
		case '*':
		case '\\':
		case '$':
		case '%':
		case ' ':
		case ',':
			break;
		default:
			if(buff[k-1] != '-')
			if(buff[k-1] != '+')
			if(buff[k-1] != '*')
			if(buff[k-1] != '\\')
			if(buff[k-1] != '$')
			if(buff[k-1] != '%')
			if(buff[k-1] != ' ')
			if (((k==(len-3)||k==(len-6)||k==(len-9)||k==(len-12)||k==(len-15)) && k >= 4) && k != 0)
			{
				buff2[l] = ',';
				l++;
			}

			buff2[l] = buff[k];
			l++;
			break;
		}
	}
	if(l > 19)
		return(buff);
	buff2[l] = '\0';
	sprintf(buff,"%s",buff2);
	return((char *)buff);
}

/************************************************************************/
/* NAME      :compare()*/
/* FUNCTION  :*/ 
/*            文字列の比較*/ 
/*            */ 
/*            */ 
/* RETURN    : ０：処理成功、-1：処理失敗                           */
/************************************************************************/
int compare(int c, char *p,char *s)
{
	
	if((strcmp(p,s)) == 0)
		return(c);
	else
		return(-1);
}

/************************************************************************/
/* NAME      :char *cutspace()*/
/* FUNCTION  :スペースを削除*/
/*            文字列の中の全てのスペースを削除する。*/ 
/*            */ 
/*            */ 
/* RETURN    :スペースを削除された文字列へのポインタ*/
/************************************************************************/
char *cutspace(char *s)
{
	static int i,j;
	static int len;
	static char p[MAX_STR];

	len = strlen(s);
	for(i=0,j=0;i<len;i++)
	{
		if(s[i] == ' ')
		;
		else
		{
			p[j] = s[i];
			j++;
		}
	}
	if(j == 0)
	{
		memset(p,'\0',len);
		sprintf(s,"%s",p);
		return(s);
	}
	p[j] = '\0';
	sprintf(s,"%s",p);
	return(s);
}

/************************************************************************/
/* NAME      :char *cutspace_right()*/
/* FUNCTION  :*/
/*            文字列最後の右側のスペースを削除*/ 
/*            */ 
/*            */ 
/* RETURN    :スペースを削除された文字列へのポインタ*/
/************************************************************************/
char * cutspace_right(char *s)
{
	static int i,j;
	static int len;
	static char p[MAX_STR];

	len = strlen(s);
	j=0;
	for(i=len;i >= 0;i--)
	{
		if(s[i] != ' ' && s[i] != '\0')
		{
			break;
		}
		j++;
	}
	for(i=0;i<len-(j-1);i++)
	{
		p[i] = s[i];
	}
	s[i] = '\0';
	return(s);
}

/************************************************************************/
/* NAME      :char *addspace()*/
/* FUNCTION  :*/
/*            文字列にスペースを追加*/ 
/*            */ 
/*            */ 
/* RETURN    :スペースを追加された文字列へのポインタ*/
/************************************************************************/
char *addspace(int len, char *s)
{
	static char spacer[1024];
	static char tmp[1024];

	sprintf(spacer,"%s",(char *)cutspace(s));
	sprintf(tmp,"%s",spacer);
	memset(spacer,'\0',sizeof(spacer));
	memset(spacer,' ',(len-(strlen(tmp))));
	sprintf(s,"%s%s",tmp,spacer);
	return((char *)s);
}

/************************************************************************/
/* NAME      :int *ifspace()*/
/* FUNCTION  :*/
/*            スペースを数える*/ 
/*            */ 
/*            */ 
/* RETURN    :スペースが無い場合は０：あった場合は０以上
/************************************************************************/
int ifspace(int len,char *s)
{
	static int i,j;
	for(i=0,j=0;i<len;i++)
	{
		if(s[i] == ' ')
		{
			j++;
		}
	}
	if(j < 1)
		return 0;
	else
		return (j);
}

/************************************************************************/
/* NAME      :char *srcep()*/
/* FUNCTION  :*/ 
/*            スペースを左に寄せ、文字列を右に寄せる*/ 
/*            */ 
/*            */ 
/* RETURN    :スペースを含んだ文字列へのポインタ*/
/************************************************************************/
char *srcep(char *buff)
{
	static int i,j,k;
	static int len;
	static char p[MAX_STR];

//	if(buff[strlen(buff) - 1] != 0x20)
//		return((char  *)buff);


	for(len=0;buff[len] != 0 ||buff[len] != '\0';len++);

	for(i=len-1,k=0;i>0;i--)
	{
		if(buff[i] != 0x20)
			break;
		k++;
	}
	for(i=0;i<k;i++)
		p[i] = 0x20;
	for(j=0;j<(len-k);i++,j++)
	{
		p[i] = buff[j];
	}
	p[i] = '\0';
	sprintf(buff,p);
	return((char  *)buff);
}

/************************************************************************/
/* NAME      :char *slcep()*/
/* FUNCTION  :*/ 
/*            スペースの右に寄せ、文字列を左に寄せる*/ 
/*            */ 
/*            */ 
/* RETURN    :スペースを含んだ文字列へのポインタ*/
/************************************************************************/
char *slcep(char *buff)
{
	static int i,j,k,l;
	static int len;
	static char p[MAX_STR];


	for(len=0;buff[len] != 0 ||buff[len] != '\0';len++);

	for(i=0;i<len;i++)
	{
		if(buff[i] != 0x20)
			break;
	}
	for(j=0,k=i,l=i;j<(len-l);j++,k++)
		p[j] = buff[k];
	for(i=j;i<len;i++)
		p[i] = 0x20;
	p[i] = '\0';
	sprintf(buff,p);
	return((char  *)buff);
}


/************************************************************************/
/* NAME      :char * sccep()*/
/* FUNCTION  :*/ 
/*            スペースを左右に寄せ、文字列を中央にする*/ 
/*            */ 
/*            */ 
/* RETURN    :スペースを含んだ文字列へのポインタ*/
/************************************************************************/
char *sccep(char *buff)
{
	static int i,j,k;
	static int len,dif;
	static int c,a;
	static char p[MAX_STR];

	for(len=0;buff[len] != 0 ||buff[len] != '\0';len++);

	dif = 0;

	for(i=len-1,k=0;i>0;i--)
	{
		if(buff[i] != 0x20)
			break;
		k++;
	}
	for(c=0;c<len;c++)
	{
		if(buff[c] != 0x20)
			break;
	}
	a = c;
	dif=k+c;
	for(i=0;i<(k+c)/2;i++)
		p[i] = 0x20;
	for(;c<(len-k)+1;i++,c++)
		p[i] = buff[c];
	for(j=0;j<(k+a)/2;i++,j++)
		p[i] = 0x20;
	if(i == len)
	{
		p[i] = '\0';
	}
	else
	{
		p[i-1] = '\0';
		if(strlen(p) > len)
			p[len] = '\0';
	}
	sprintf(buff,"%s",p);
	return((char  *)buff);
}

/****************************************************************************
任意位置からの文字の取り出し
*
*   NAME    :   void Mid1(char *ds,char *ss,int a, int b);
*   ARG     :
*               char *ss;   取り出す文字列のポインタ
*               int    a;   取り出す文字の位置
*               int    b;   取り出す文字数
*   ETURN   :   char   *;   取り出された文字列のポインタ
****************************************************************************/
static char *Mid1(char *ss, int a, int b)
{
	int k,n;
//	char *ds;
	static char retds[8192];
	static char ds[8192];

	n=strlen(ss);
//	ds = (char *)malloc(n+1);
	if((0<a && a<=n) && (0<b && b<=n) && (a+b-1<=n)){
		for(k=a; k<a+b; k++)
		ds[k-a]=ss[k-1];
		ds[b]='\0';
	}
	else
		ds[0]='\0';
	sprintf(retds,"%s",ds);
	free(ds);
	return((char *)retds);
}

/************************************************************************/
/* NAME      :char * Right()*/
/* FUNCTION  :*/ 
/*            右側の文字を n 文字返す*/
/*            */ 
/*            */ 
/* RETURN    :nより右側の文字列*/
/************************************************************************/
static char *Right(char *s, int n)
{
    int i;
    int n2;
	char s1[8192];
	char s2[8192];
    static char *sr;

//	s1 = calloc(1,sizeof(s));
//	s2 = calloc(1,sizeof(s));
    n2 = strlen(s) - n;
    for(i=n2; s[i] != '\0';i++)
    {
        s1[i-n2] = s[i];
    }
    s1[i-n2] = '\0';
    strcpy(s2,s1);
    sr = s2;
    return(sr);
}

/************************************************************************/
/* NAME      :int query_postHTML()*/
/* FUNCTION  :*/ 
/*            GETまたはPOSTで送信された文字列を分解する*/
/*            この時checkboxがfalse時に送信文字列から外されたフィールドに
/*            BOOL値の'f'で更新を行う。GET/POST共に利用可能*/
/*            */ 
/*            */ 
/* RETURN    :クエリーの項目数*/
/************************************************************************/
int query_postHTML(char *query, char c, int len)
{
	int i,j,k,l;
	int div;
	char fnum[256][4];
	char af[12];
	char cquery[8192];
	char mquery[8192];
	char tquery[8192];

	strncpy(cquery,query,len);
	cquery[len] = '\0';
	for(i=0,j=0;i<len;i++)
	{
		switch(cquery[i])
		{
		case '=':
			sprintf(fnum[j],"%c%c",cquery[i-2],cquery[i-1]);
			div = atoi(fnum[j]) - j;
			if(div > 0)
			{
				strncpy(mquery,cquery,(i-7));
				sprintf(af,"field%02d=f&",j);
				sprintf(tquery,"%s",Right(cquery,len - (i-7)));
				sprintf(cquery,"%s%s%s",mquery,af,tquery);
				len = strlen(cquery);
			}
			i++;
			for(k=i,l=0;cquery[k] != c && cquery[k] != 0;k++,l++)
			{
				if(cquery[k] == '+')
					cquery[k] = ' ';
				qt.get[j][l] = cquery[k];
			}
			qt.get[j][l] = '\0';
			j++;
			break;
		default:
			break;
		}
	}
	return(j);
}

/************************************************************************/
/* NAME      :int query_getHTML()*/
/* FUNCTION  :*/ 
/*            GETまたはPOSTで送信された文字列を分解する*/
/*            */ 
/*            */ 
/* RETURN    :クエリーの項目数*/
/************************************************************************/
int query_getHTML(char *query, char c)
{
	int i,j,k,l;
	int len;
	
	len = strlen(query);
	for(i=0,j=0;i<len;i++)
	{
		switch(query[i])
		{
		case '=':
			i++;
			for(k=i,l=0;query[k] != c && query[k] != 0;k++,l++)
			{
				qt.get[j][l] = query[k];
			}
			qt.get[j][l] = '\0';
			j++;
			break;
		default:
			break;
		}
	}
	return(j);
}

/************************************************************************/
/* NAME      :int logmsg()*/ 
/* FUNCTION  :*/ 
/*            ログメッセージを記録する*/ 
/*            */ 
/*            */ 
/* RETURN    :１　Ｙｅｓ　０　Ｎｏ*/
/************************************************************************/
/*
	本関数は簡易的に作成されています。
	必要なプログラムは以下になります。
	/home/cms/bin/logctl.sh
	上のプログラムを以下のスタイルで起動してください。
	/home/cms/bin/logctl.sh &
	このプログラムは/home/cms/logs/cgi_log　にログを記録します。
	ログはキューに整列されるためログが混乱することはありません。
*/
int logmsg(char *logmsg)
{
	char *env;
	int qid,pid;
	char buff[MAX_STR];
	int ret;

	if((env = getenv("LOG_QUEID")) == (char *)NULL)
		qid = 20001;
	else
		qid = atoi(env);
	sprintf(buff,"/home/cms/bin/cmsctl -s 20001 \"%s\" %s",logmsg,"end");
	system(buff);
}

/************************************************************************/
/* NAME      :char *create_session_id()*/ 
/* FUNCTION  :*/ 
/*            セッションIDを作成する*/ 
/*            */ 
/*            */ 
/* RETURN    :１　Ｙｅｓ　０　Ｎｏ*/
/************************************************************************/
char *create_session_id(void)
{
	long i,j,k,l;
	time_t t;
	char *session;

	t=time(NULL);
	i = rand();
	i=i*t;
	j = rand();
	j=j*t;
	k = rand();
	k=k*t;
	l = rand();
	l=l*t;

	session = malloc(33);
	sprintf(session,"%8lX%8lX%8lX%8lX",i,j,k,l);
	return((char *)session);
}
