# DIVIDE_START=update.doc
 -------------------------- rcd 0.01b --------------------------
 1994.2.12
 ・フリコレ８応募版。
 
 -------------------------- rcd 0.01a --------------------------
 1994.1.9
 ・作成開始。元のソースは rtd 0.01e である。
 ・仕様
 　ＣＴＤに準じる。
# DIVIDE_END

/* DIVIDE_START=main.c */
/*
	コメントツリー作成プログラム								main.c

			作 : 飛雪（NIFTY-ID:GHH01217）
*/
#define		MAIN	1
#include	"rct.h"

#include	<process.h>
#include	<errno.h>

char	*touppers( char *str );
void	append_yen( char *str );
char	*last_comma( char *str );
char	*last_yen( char *str );
void	ExecError( );

	char	*Version = VERSION;
	char	TmpDir[ 128 ];
	char	OutDir[ 128 ];
	char	*Argv[ 32 ];
	int		Argc = 0;
	int		FirstLZHFile = FALSE;

	char	FileName[ 64 ];

	extern	unsigned	_heaplen = 2048;
	extern	unsigned	_stklen  = 2048;

static	void	copy( char *str )
{
	char	*p;
	int		len;

	len = strlen( str ) + 2 ;	p = malloc( len );
	if ( p == NULL ) {	puts( "メモリー不足です" );	exit( 1 );	};
	strcpy( p, str );		Argv[Argc++] = p;
	Argv[ Argc ] = NULL;
}

static	void
deleteTmpFile( char *path, char *attr, int sw, int Lha_E_Sw );

static	void	LhaE( char *file )
{
	char	*p;
	char	str[ MAX_FILENAME_LEN ];

	if ( strcmp( last_comma( file ), ".LZH" ) != 0 )		return;

	strcpy( str, TmpDir );
	p = file;
	/* ドライブ名を読み飛ばす */
	if ( p[1] == ':' )		p += 2;
	/* 先頭の \ を読み飛ばす */
	if ( *p == '\\' )		p++;

	/* ファイル名の長さをチェックしておく */
	if ( strlen( str ) + strlen( p ) >= MAX_FILENAME_LEN ) {
		/* 長すぎるので処理を続行できない */
		printf( "解凍後のファイル名の長さが長すぎるので処理を続行できません\n"
				"<%s%s>\n",str, p
		);
		exit( 1 );
	};

	/* TmpDir に追加する */
	strcat( str, p );
	/* 拡張子の .LZH を削除しておく */
	p = last_comma( str );
	*p++ = '\\';	*p = '\0';
	/* 先に解凍するディレクトリの下のファイルを削除しておく */
	if ( FirstLZHFile == FALSE ) {	deleteTmpFile( TmpDir,   "*.*",YES,FALSE);
									FirstLZHFile = TRUE;
	} else {						deleteTmpFile( str, "*.*",YES,FALSE);
	};
#ifdef	VERIFY
	printf( "lha x %s %s\n", file, str );
#endif
	if ( spawnlp( P_WAIT, "lha", "lha", "x", file, str, NULL) == -1 ) {
#ifdef	VERIFY
		ExecError( );
#endif
	};
}

static	void
deleteTmpFile( char *path, char *attr, int R_sw, int Lha_E_Sw )
{
			int		done ;
	struct	ffblk	ffblk;
			char	f_name[ 64 ];

	strcpy( f_name, path );
	append_yen( f_name );
	strcat( f_name, attr );

	done = findfirst( f_name , &ffblk , FA_DIREC );
	while ( ! done ) {
		strcpy( f_name, path );	append_yen( f_name );
		strcat( f_name, ffblk.ff_name );
		if ( ffblk.ff_attrib == FA_DIREC ) {
			if (	strcmp( ffblk.ff_name , "." ) != 0
			&&		strcmp( ffblk.ff_name , ".." ) != 0
			&&		R_sw == YES
			) {	/* Sub dir 再帰呼出し */
				deleteTmpFile( f_name, attr, R_sw, Lha_E_Sw );
				if ( Lha_E_Sw == TRUE ) {
#ifdef	VERIFY
					printf( "<%s>(dir)を検索します\n", f_name );
#endif
				} else {
#ifdef	VERIFY
					printf( "<%s>(dir)を削除します\n", f_name );
#endif
					rmdir( f_name );
				};
			};
		} else {
			if ( Lha_E_Sw == TRUE ) {
#ifdef	VERIFY
				printf( "<%s>を解凍します\n", f_name );
#endif
				LhaE( f_name );
			} else {
#ifdef	VERIFY
				printf( "<%s>を削除します\n", f_name );
#endif
				remove( f_name );
			};
		};
		done = findnext( &ffblk );
	};
}

static	void	er_option( char *mes )
{
	puts( mes );	exit(1);
}

#define		NONE_OPTION			0x00
#define		INPUT_OPTION		0x01
#define		OUTPUT_OPTION		0x02
#define		LOAD_OPTION			0x04
#define		TMP_OPTION			0x20
#define		LZH_OPTION			0x40

static	void	useage()
{
	printf(
		"　ＲＣＴドライバー\t\t%s\n"
		"\t\t\tVersion=%s　by .. NIFTY-ID:NAA02244 飛雪\n\n"
		, FileName		/* 起動ドライブが入っている */
		, Version
	);
	puts(
		"\t使い方：rctd  [-options]  [OutDir名]\n"
	);
	puts(
#if	VERIFY == YES
"   ↓: option            ↓: デフォルト\n"
" ★★ 下の２つのオプションは非公開のオプションです ★★\n"
" 動作状態を表示       → v : しない            V   : する\n"
"\n"
" ★★ ここから下が公開オプションです               ★★\n"
#endif
"                         ↓: option\n"
" ＴＭＰﾃﾞｨﾚｸﾄﾘの指定  → -w （次の引数は ＴＭＰﾃﾞｨﾚｸﾄﾘ）\n"
" 出力ﾃﾞｨﾚｸﾄﾘの指定    → -o （次の引数は rct の出力ﾃﾞｨﾚｸﾄﾘ）\n"
" *.LZH ﾌｧｲﾙを解凍     → -Z \n"
"\n"
" -wo オプションを複数指定する場合は次の順序で指定して下さい\n"
"\t１．ＴＭＰディレクトリの指定\n"
"\t２．出力ディレクトリの指定\n"
	);
}

static	int		setOptions( char *p )
{
	int		i, result;
	char	*p2;
	char	str[ 128 ];

	if ( *p == '-' || *p == '/' )	p++;
	result = NONE_OPTION;
	while ( *p ) {
		switch( *p ) {
			case 'F':	/* MaxFileSizeSw = TRUE; */
				/* 数字を読み飛ばす */
				p++;	while ( isdigit( *p ) ) {	p++;	};
				p--;
				break;
			case 'f':	/* MaxFileSizeSw = FALSE; */
				/* 数字を読み飛ばす */
				p++;	while ( isdigit( *p ) ) {	p++;	};
				p--;
				break;
			case 'o':	result |= OUTPUT_OPTION;					break;
			case 'w':	result |= TMP_OPTION;						break;
			/* 下は rctd だけのオプション */
			case 'Z':	result |= LZH_OPTION;
				/* 'Z' を削除する */
				p2 = p + 1 ;
				while ( *p2 ) {		*(p2-1) = *p2;	p2++;	};
				*(p2-1) = '\0';
				break;
			default:
				break;
		};
		p++;
	};
	return( result );
}

static	void	deleteArgv( int num )
{
	int		i;

	/* 引数の書庫名を削除する */
	free( Argv[num] );
	for ( i=num; i <Argc-1; i++ )	Argv[i]= Argv[i+1] ;
	if ( Argc > 0 )		Argv[ --Argc ] = NULL;
}

#ifdef	VERIFY
void	ExecError( )
{
	switch(errno) {
		case E2BIG:		puts( "引数リストが長すぎる" );		break;
		case EINVAL:	puts( "引数が正しくない" );			break;
		case ENOENT:	puts( "パス名またはファイルが見つからない" );
															break;
		case ENOEXEC:	puts( "execフォーマットエラー" );	break;
		case ENOMEM:	puts( "メモリーが不足した" );		break;
		default:		puts( "エラーです" );				break;
	};
	exit( 1 );
}
#endif

void	main( int argc , char *argv[] )
{
	int		sw, i ;
	int		sw2;
	char	*p;

	if ( argc < 2 )	{	useage();	exit( 0 );		};

	/* MS-DOS の環境変数を読み込む */
	*TmpDir= *OutDir= '\0';			p = getenv( "TMP" );
	if ( p != NULL ) {		strcpy( TmpDir, p );	append_yen( TmpDir );	};

	/* RCT の TMP ファイルを削除する */
	deleteTmpFile( TmpDir, "*.$*", NO, FALSE );
	strcat( TmpDir, ")LZH(\\" );

	/* コマンドラインの引数をメモリー上に読み込む */
	copy( "rct.exe" );								/* 第１引数 */
	for ( i=1; i<argc; i++ )	copy( argv[i] );

	sw = FALSE;
	for ( i=1 ; i<Argc ; i++ ) {
		if ( *Argv[i] == '-' ) {
			/* TMP ファイルの削除オプション */
			if ( strcmp( Argv[i], "-DelLzhFile" ) == 0 ) {
				/* TmpDir の下の全ファイルを削除 */
				deleteTmpFile( TmpDir, "*.*", YES, FALSE );
				exit( 0 );
			};
			sw2 = setOptions( Argv[i] );
			if ( (sw2 & TMP_OPTION) != 0 ) {	/* ＴＭＰディレクトリの指定 */
				i++;
				if ( i < Argc ) {
					strcpy( TmpDir, Argv[i] );		append_yen( TmpDir );
					strcat( TmpDir, ")LZH(\\" );
				} else {
					er_option("ＴＭＰディレクトリを指定して下さい");
				};
			};
			if ( (sw2 & OUTPUT_OPTION) != 0 ) {	/* 出力ディレクトリの指定 */
				i++;
				if ( i < Argc ) {
					strcpy( OutDir, Argv[i] );		append_yen( OutDir );
				} else {
					er_option("出力するディレクトリを指定して下さい");
				};
			};
			if ( ( sw2 & LZH_OPTION ) != 0 ) {	/* 複数のLZHファイルを解凍 */
				if ( strcmp( Argv[i], "-" ) == 0 ) {
					/* 引数の書庫名を削除する */
					deleteArgv( i );
				} else {
					i++;
				};
				if ( i < Argc ) {
					while ( i < Argc ) {
						if ( *Argv[i] == '-' )	break;
						/* *.LZH を解凍 */
						deleteTmpFile( Argv[i], "*.*", YES, TRUE );
						/* 引数の書庫名を削除する */
						deleteArgv( i++ );
					};
				} else {
						/* *.LZH を解凍 */
						deleteTmpFile( "", "*.*", YES, TRUE );
				};
				sw = TRUE;
			};
			continue;
		};
		touppers( Argv[i] );
		p = last_yen( Argv[i] );	p = last_comma( p );
		if ( strcmp( p, ".LZH" ) == 0 ) {
			/* LHA を起動してツリーを作る */
			LhaE( Argv[i] );
			/* 引数の書庫名を削除する */
			deleteArgv( i );
			sw = TRUE;
		};
	};

	if ( sw == TRUE )		copy( TmpDir );

	/* 普通に rct.exe を起動する */
#ifdef	VERIFY
	for ( sw =0; sw<Argc; sw++ )	printf( "<%s> ", Argv[sw] );
	puts( "で rct.exe を起動します(通常)" );
#endif

	if ( spawnvp( P_WAIT, "rct.exe", Argv ) == -1 ) {
#ifdef	VERIFY
		ExecError( );
#endif
	};

	/********/
	/* 終了 */
	/********/
	exit( 0 );
}

char	*touppers( char *str0 )		/* 文字列を大文字に変換する */
{
	char	c , *str1 ;

	str1 = str0;
	while( ( c = *str1 ) != '\0' ) {
		if ( iskanji( c ) ) {	str1 += 2;				/* 漢字コード */
		} else {				*str1 = toupper( c );
								str1++;
		};
	};
	return( str0 );
}

void	append_yen( char *str )
{
	char	c;

	if ( *str == '\0' )					return;

	while ( *str )	str++;
	c = *( str -1 );
	if ( c != '\\' && c != ':' ) {	*str++ = '\\';	*str = '\0';	};
}

char	*last_yen( char *str )
{
	char	*result;

	result = str;
	while ( *str ) {	if ( *str == '\\' ) result = str;
						str++;
	};	return( result );
}

char	*last_comma( char *str )
{
	char	*result;

	result = str;
	while ( *str ) {	if ( *str == '.' ) result = str;
						str++;
	};	return( result );
}


/* DIVIDE_END */

/* DIVIDE_START=rct.h */
/*
	コメントツリー作成プログラム								rct.h

			作 : 飛雪（NIFTY-ID:NAA02244）
*/

#include	<mylib.h>
#include	<stdlib.h>
#include	<ctype.h>
#include	<jctype.h>
#include	<string.h>
#include	<dos.h>
#include	<conio.h>
#include	<dir.h>

#define		LINE				(1024*2)
#define		MAX_FILENAME_LEN	64
#define		MAX_BUFSIZE			(1024L*20L)

#ifdef	MAIN
#ifdef	VERIFY
			int		verify = FALSE;
#endif
#else
#ifdef	VERIFY
	extern	int		verify ;
#endif
	extern	char	*Version;		/* 本体は main.c にある */
#endif
/* DIVIDE_END */

# DIVIDE_START=makefile
VER1		=	0
VER2		=	01
VER3		=	a			# 元のバージョン
VER4		=	0
VER5		=	01
VER6		=	b			# 現在のバージョン
VER7		=	"$(VER4).$(VER5)$(VER6)"
LZH0		=	rcd$(VER1)$(VER2)
LZH1		=	rcd$(VER4)$(VER5)
MemoryModel	=	t
tc			=	tcc
lib			=	tlib
link		=	tlink
cflags		=	-m$(MemoryModel) -A -d -N -O -DVERSION=$(VER7) #-DVERIFY=YES

.c.obj	:
	$(tc)	-c $(cflags) -Ie:\tc\include $*

com_prg		=	rctd.com

hdr1		=	rct.h
objV		=	main.obj

$(com_prg)	:	$(objV) makefile $(hdr1) all listobj$(MemoryModel)
		tlink	@listobj$(MemoryModel)
		copy	$(com_prg) d:\exe
	#	makebdf		$*.com	$(LZH0) $(VER3) $(LZH1) $(VER6)
		makebdf	-BI	$*.com	$(LZH0) $(VER3) $(LZH1) $(VER6)
	#	makebdf	-I	$*.com	$(LZH0) $(VER3) $(LZH1) $(VER6)

$(objV)		: $(hdr1) makefile		# Version 管理
# DIVIDE_END

# -DIVIDE_START=listobjt
/t e:\tc\lib\c0t.obj main.obj , rctd , nul , e:\tc\lib\emu e:\tc\lib\maths e:\tc\lib\cs
# DIVIDE_END

# -DIVIDE_START=listobjs
e:\tc\lib\c0s.obj main.obj , rctd , nul , e:\tc\lib\emu e:\tc\lib\maths e:\tc\lib\cs
# DIVIDE_END

# -DIVIDE_START=listobjc
e:\tc\lib\c0c.obj main.obj , rctd , nul , e:\tc\lib\emu e:\tc\lib\mathc e:\tc\lib\cc
# DIVIDE_END

REM DIVIDE_START=m.bat
echo off
:loop
	if		"%1"==""	goto	main
	vz		%1
:loop2
	make
	if		errorlevel	1		goto	error
	goto	end
:main
	vz		all
	div		all
	goto	loop2
:error
	pause
	goto loop
:end
REM DIVIDE_END

REM DIVIDE_START=u.bat
	div -u:update.doc all
	if errorlevel 1 goto end
	div -a:*.c all
	div -a:*.h all
	div -a:makefile all
	div -a:listobj all
	div -a:*.bat all
	div -a:readme.doc all
	div -a:*.ggg all
:end
REM DIVIDE_END

/* -DIVIDE_START=rctd.doc */
　　　　　　　　　　　　−−−−−−−−−−−−−
　　　　　　　　　　　　　　　ＲＣＴＤの使い方
　　　　　　　　　　　　−−−−−−−−−−−−−

１．ＲＣＴＤがすること。
  　本プログラムは、ＲＴＢＢＳのログを参照して、そのコメントツリーを表
  示するプログラム（rct.exe）専用のドライバです。
  　普通は、コマンドライン上のオプションをそのまま rct.exe に渡しますが、
  次のオプションは本プログラムの内部で処理され rct.exe には渡されません。
            -DelLzhFile
  　また、拡張子がＬＺＨのファイルを入力として与えられた場合は、ＬＨＡ
  を起動してそのファイルを解凍し rct.exe にはＬＨＡの解凍先ディレクトリ
  を渡してコメントツリーを作るように指示します。


２．ＬＺＨファイルの解凍先ディレクトリについて。
  　ＲＣＴＤでは、ＬＨＡを起動してＬＺＨファイルを解凍します。その解凍先
  はＭＳ−ＤＯＳの環境変数 tmp で設定されたドライブ:ディレクトリの下に
   )LZH( というサブ・ディレクトリを作り、更にその下に解凍するファイル名
  のサブ・ディレクトリを作り、その下に解凍するようにしています。つまり、
  下のようになります。
  　環境変数 tmp が g:\tmp と設定されている場合
        rctd 9310.LZH
  　と、実行すると
        g:\tmp ---- )LZH( ---- 9310 ---- 93100100.LOG
                                         93100200.LOG
  　というように解凍されます。そして、rct.exe を次のようなオプションで
  起動します。
        rct.exe g:\tmp\)LZH(\9310
  　この例ではオプションを無視して示しましたが、rct.exe のオプションは
  そのまま渡されます。


３．ＲＣＴＤ専用のオプションの説明。
　(1) -DelLzhFile
　これは、ＭＳ−ＤＯＳの環境変数 tmp を参照してその下のディレクトリ
		)LZH(
　以下のサブ・ディレクトリ、ファイルを全て削除する物です。
　ただし、読出専用のファイル属性を持つ物は削除しません。


４．作成協力者
　以下の方々にご協力いただいて、本プログラムは作られました。
　ここに紹介して感謝の念を表したいと思います。

　　　NIFTY-ID　　ハンドル
　　　GBH00541　　DORAGON　　 さん
　　　GFH00524　　ロイ　　　　さん
　　　GFH02651　　Ｔ．Ｐ．Ｆ．さん
　　　HGG03505　　ＬＲＡ．　　さん
　　　GHA00253　　Take　　　　さん
　　　HHG03411　　きゃとる　　さん
　　　GEC01471　　けんた　　　さん


５．著作権
　　本プログラムはＮＩＦＴＹ−ＩＤ：ＮＡＡ０２２４４　飛雪（ひせつ）に
　著作権があるものとします。しかし、その使用、配付は自由に行っていただい
　てかまいません。（ＦＡＰＸには、同梱してもらうことにしました）


６．何かありましたら。
  　ＮＩＦＴＹのフォーラムＦＲＡＶの「おきらく・もっぷた〜む」の会議室
  に発言されるか、私あてメールを下さい。

　　　　　　　　　　　　　　　　　　　　　　　ＮＡＡ０２２４４　飛雪
/* DIVIDE_END */

/* -DIVIDE_START=rctd.ggg */
======================================================================
【ソフト  名】  rctd.com　RCTドライバ                    Version 0.01b
【登  録  名】  rcd001b.lzh (LHAで解凍して下さい)
【検索  キー】  1:RCT 2:MOPTERM 3:FAPX 4:RCTD
【著作権  者】  飛雪  NAA02244
【開発  環境】  Turbo-C Ver2.0 + Vz →  rctd.com
【対応  機種】  MS-DOS 汎用
　　　　　　　　運用推奨：ＨＤＤ上
【動作  確認】  FM-TOWNS20F + 8M-RAM  コンソール上
【公  開  日】  94/02/12
【ｿﾌﾄｳｪｱ種別】　通信関連。フリー・ソフトウェア。
======================================================================
【ソフト紹介】
  　本プログラムは、ＲＴＢＢＳのログを参照して、そのコメントツリーを表
  示するＲＣＴというプログラムを起動する物です。

　以下のファイルが含まれます。
　　rctd.com ……………… プログラム本体
　　rctd.doc ……………… rctd の説明
　　rctd.ggg ……………… このファイル（概要）
　　all      ……………… ソースファイル一式（拙作の div で切り分けて下さい）

  　詳しくは rctd.doc をお読み下さい。

  　ダウンロードファイル名を  rcd001b.lzh   として下さい。
                                              ＮＡＡ０２２４４  飛雪
/* DIVIDE_END */

