/*************************************
 *   Command for MS-DOS : tab_open   *
 *      Program made bu K,Ajima      *
 *   Copyright  ajiyan soft l.t.d.   *
 *************************************/



#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>



#include <err.h>



#include "tab_open.dtv"



char old_name[128];									/* バックアップファイル名 */



#define ERR_NOWRITE		5
#define ERR_NOMAKE_OLD	4
#define ERR_NOOPEN_OUT	3
#define ERR_NOSIZE		1
#define ERR_DISSIZE		1
#define ERR_NONAME		2



/********************************************************************
 *   前振り
 ********************************************************************/
void _fastcall start_up(void)
{
	cputs("Command for MS-DOS : tab_open ver." DTV_ADDVER() );
	cputs("\x0d\x0aProgram made bu K,Ajima\x0d\x0a");
	cputs("Copyright ajiyan soft l.t.d.   " DTV_ADDTS() );
	cputs("\x0d\x0a\x0d\x0a");
}



/********************************************************************
 *   ヘルプ
 ********************************************************************/
void _fastcall help(void)
{
	cputs("Syntax : tab_open [ /b ] < tab_size > < file name >\x0d\x0a");
	cputs("\x0d\x0a");

	exit(0);
}



/********************************************************************
 *   書き込みエラー
 ********************************************************************/
void _fastcall err_write(FILE *in,FILE *out,char *name)
{
	out_err(ERR_NOWRITE,"tab_open error : 書き込みが出来ません",NULL);

	fclose(in); fclose(out);

													/* バックアップファイルより復元 */
	remove(name);
	rename(old_name,name);

	exit(5);
}



/********************************************************************
 *   バックアップファイル名取得
 *     ファイル名
 ********************************************************************/
void _fastcall get_backup_name(char *name)
{
	char *c;

	strcpy(old_name,name);
	c=strrchr(old_name,'.');
	if(c!=NULL && strlen(c)<=4U) {
		*c='\x00';
	}
	strcat(old_name,".bak");
}



/********************************************************************
 *   入力ファイルオープン
 *     ファイル名
 *     ret: ファイルポインタ
 ********************************************************************/
FILE * _fastcall in_open(char *name)
{
	FILE *fp;

													/* バックアップファイル作成 */
	remove(old_name);
	if(rename(name,old_name)) {
		out_err(ERR_NOMAKE_OLD,"tab_open error : バックアップファイル "
				,old_name," が作成できません",NULL);
	}

													/* バックアップファイルオープン */
	if((fp=fopen(old_name,"rb"))==NULL) {
		out_err(ERR_NOMAKE_OLD,"tab_open error : バックアップファイル "
				,old_name," が作成できません",NULL);
	}

	return(fp);
}



/********************************************************************
 *   出力ファイルオープン
 *     ファイル名
 *     ret: ファイルポインタ
 ********************************************************************/
FILE * _fastcall out_open(char *name)
{
	FILE *fp;

	if((fp=fopen(name,"wb"))==NULL) {
		out_err(ERR_NOOPEN_OUT,"tab_open error : 出力ファイル "
				,name," がオープンできません",NULL);
	}

	return(fp);
}



/********************************************************************
 *   タブ展開
 *     1. 名前
 *     2. サイズ
 *     3. 入力ファイルポインタ
 *     4. 出力ファイルポインタ
 ********************************************************************/
void _fastcall tab_open(char *name,int size,FILE *in,FILE *out)
{
	int c;
	int x=0;										/* x 座標 */
	long r_size=0,									/* 読み込みサイズ */
		 w_size=0;									/* 書き込みサイズ */

	cputs("Terget : ");
		cputs(name); cputs("\x0d\x0a");				/* ターゲット */

	for(;;) {
		if(!(r_size & 1023)) {
			printf("Read size : %08ld   /   Write size : %08ld\r",
					r_size,w_size);
		}

		if((c=fgetc(in))==EOF) break;					/* 読み込み */
		r_size++;

		if(c=='\t') {									/* タブ ? */
			if(fwrite("                ",
					size-x%size,1,out)==EOF) {				/* タブを展開し書き込み */
				err_write(in,out,name);							/* 書き込みエラー */
			}
			w_size+=size-x%size;
			x+=size-x%size;
		}
		else {											/* not タブ */
			if(fputc(c,out)==EOF) {							/* 書き込み */
				err_write(in,out,name);							/* 書き込みエラー */
			}

			w_size++;
			x++;
			if(c=='\x0a') {									/* LF ? */
				x=0;											/* 行頭 */
			}
		}
	}

	printf("Read size : %08ld   /   Write size : %08ld\r",
			r_size,w_size);
}



/********************************************************************
 *   バックアップファイル削除
 ********************************************************************/
void _fastcall del_backup(void)
{
	remove(old_name);
}



/********************************************************************
 *   main
 ********************************************************************/
void _cdecl main(int argc,char **argv)
{
	int	i,											/* argv 添字 */
		b=0,										/* /b 有無 */
		size;										/* タブサイズ */

	FILE *in,										/* 入力ファイル */
		 *out;										/* 出力ファイル */

	start_up();										/* 前振り */

	if(argc==2 && !strcmp(argv[1],"/?")) {
		help();											/* ヘルプ */
	}

	if(argc>1 && !stricmp(argv[1],"/b")) {			/* /b 判定 */
		i=2;
		b=1;
	}
	else {
		i=1;
	}

	if(argc<i+1) {									/* サイズ指定無し */
		out_err(ERR_NOSIZE,"tab_open error : タブサイズが指定されていません",NULL);
	}

	size=atoi(argv[i]);								/* サイズ取得 */
	i++;

	if(size<1 || size>16) {							/* サイズ指定エラー */
		out_err(ERR_DISSIZE,"tab_open error : タブサイズの指定がちがいます",NULL);

	}

	if(argc<i+1) {									/* ファイル指定無し */
		out_err(ERR_NONAME,"tab_open error : ファイル名が指定されていません",NULL);

	}

	get_backup_name(argv[i]);						/* バックアップファイル名を取得 */

	in=in_open(argv[i]);							/* 入力ファイルオープン */
	out=out_open(argv[i]);							/* 出力ファイルオープン */

	tab_open(argv[i],size,in,out);					/* タブ展開 */

	if(!b) {
		del_backup();									/* バックアップファイル削除 */
	}

	fclose(in); fclose(out);
}
