#include <STDIO.H>
#include <STDLIB.H>
#include <STRING.H>
#include <DOS.H>
#include <CTYPE.H>

#ifdef LSI_C
#include <PATH.H>
#endif

#include "SYMBOL.H"

static int wordcmp(char *, char *);

void main(int argc, char *argv[])
{
int arg, text, guideptr, i;
unsigned int length;
char *idx_ptr, *headptr;
FILE *file;
static char guide[GUIDSIZE];
static char drive[_MAX_DRIVE],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
static char idxname[_MAX_PATH], manname[_MAX_PATH], index[32768];

/********************************* 著作権表示 ********************************/
	fputs("\n<TINYHELP> Ver 1.04  Copyright (c) RYO 1993.\n\n", stderr);

/********* ｺﾏﾝﾄﾞﾗｲﾝ引数無し､またはﾍﾙﾌﾟ指定で起動したときはヘルプ表示 *********/
	if ((argc==1) || ((argc>=2)&&(*argv[1]=='?'))) {
	   fputs("書式 --- TINYHELP [-Gｶﾞｲﾄﾞ文字列] [-Fｲﾝﾃﾞｯｸｽ･ﾌｧｲﾙ] ﾄﾋﾟｯｸ [ﾄﾋﾟｯｸ･･･]", stderr);
	   exit(1);
	}
/****************************** 準備,初期設定 ********************************/
	strncpy(guide, GUIDE, sizeof(guide)-1);
	guide[sizeof(guide)-1]='\0';
	_splitpath(argv[0], drive, dir, fname, ext);  /* 起動ﾌｧｲﾙのﾊﾟｽを分解 */
	_makepath(idxname,  drive, dir, FILENAME, HLPEXT);     /* ﾍﾙﾌﾟﾌｧｲﾙ名 */

/********************** コマンドライン・パラメータの処理 *********************/
	for (arg=1; (arg<argc)&&(*argv[arg]=='-'); arg++) {
	   switch (toupper(*(argv[arg]+1))) {
	      case'G':strncpy(guide, argv[arg]+2, sizeof(guide)-1);
		      guide[sizeof(guide)-1]='\0';
		      break;
	      case'F':_splitpath(argv[arg]+2, drive, dir, fname, ext);
		      if (ext[0]=='\0') strcpy(ext, HLPEXT);
		      _makepath(idxname, drive, dir, fname, ext);
		      break;
	      default:fputs("ｺﾏﾝﾄﾞﾗｲﾝ･ﾊﾟﾗﾒｰﾀ <", stderr);
		      fputs(argv[arg], stderr);
		      fputs(">ｵﾌﾟｼｮﾝは未定義です.", stderr);
		      exit(2);
	      }
	}

/********************** インデックスファイルの読み込み ***********************/
	file=fopen(idxname, "r");                 /* ｲﾝﾃﾞｯｸｽ･ﾌｧｲﾙをｵｰﾌﾟﾝする */
	if (file==NULL) {
	   fputs("ｲﾝﾃﾞｯｸｽ･ﾌｧｲﾙ <", stderr);
	   fputs(idxname, stderr);
	   fputs("> が見つかりません.", stderr);
	   exit(3);
	}
/******************* インデックスファイルのヘッダチェック ********************/
	for (headptr=HELPHEAD; *headptr; headptr++) {
	   text=getc(file);
	   if (text != *headptr) {
HEADERR:      fputs("ｲﾝﾃﾞｯｸｽ･ﾌｧｲﾙ <", stderr);
	      fputs(idxname, stderr);
	      fputs("> の形式が違っています.", stderr);
	      fclose(file);
	      exit(3);
	   }
	}

/********************* マニュアルファイル名の読み込み,作成 *******************/
	for (i=0; (text=getc(file))!='.'; i++) {   /* ﾏﾆｭｱﾙ･ﾌｧｲﾙ名の名前部分 */
	   if (i>=8 || text==EOF || text==' ' || iscntrl(text)) goto HEADERR;
	   fname[i]=text;
	}
	fname[i]='\0';
	for (i=0; (text=getc(file))!='\f'; i++) {/* ﾏﾆｭｱﾙ･ﾌｧｲﾙ名の拡張子部分 */
	   if (i>=3 || text==EOF || text==' ' || iscntrl(text)) goto HEADERR;
	   ext[i]=text;
	}
	ext[i]='\0';
	_makepath(manname, drive, dir, fname, ext);

/************************ インデックスファイルの読み込み *********************/
	for (length=0; length<sizeof(index); length++) {
	   if ((index[length]=getc(file)) == EOF) break;
	}
	index[length-1]='\0';
	fclose(file);

/*************************** マニュアルファイルのオープン ********************/
	file=fopen(manname, "r");
	if (file==NULL) {
	   fputs("ﾏﾆｭｱﾙ･ﾌｧｲﾙ <", stderr);
	   fputs(manname, stderr);
	   fputs("> が見つかりません.", stderr);
	   fcloseall();
	   exit(3);
	}

/****************************** 各トピックの検索,表示 ************************/
	for ( ; arg<argc; arg++) {
	   idx_ptr=&index[0];                   /* ｲﾝﾃﾞｯｸｽ･ﾎﾟｲﾝﾀを先頭に戻す */
	   while(wordcmp(idx_ptr, argv[arg])) {             /* ｲﾝﾃﾞｯｸｽを捜す */
	      while(iscsym(*idx_ptr)) {    /* 次のﾄﾋﾟｯｸまで文字ﾎﾟｲﾝﾀを進める */
		 idx_ptr++;
	      }
	      if (*idx_ptr=='\t') {            /* ﾀﾌﾞｺｰﾄﾞなら､その行には無い */
		 while(*idx_ptr != '\n') {                 /* 行末まで進める */
		    idx_ptr++;
		 }
	      }
	      if (*(++idx_ptr)=='\0')       /* ｲﾝﾃﾞｯｸｽ内には見つからなかった */
		 break;
	   }
	   if (*idx_ptr=='\0') {            /* ｲﾝﾃﾞｯｸｽ内には見つからなかった */
	      fputs("\nﾄﾋﾟｯｸ <", stdout);
	      fputs(argv[arg], stdout);
	      fputs("> は見つかりません.\n\n", stdout);
	      continue;                               /* 次のﾄﾋﾟｯｸを処理する */
	   }

/****************************** ﾄﾋﾟｯｸ発見 ************************************/
	   while(*idx_ptr != '\t')         /* 位置情報記述部分まで読み飛ばす */
	      idx_ptr++;
	   fseek(file, atol(idx_ptr), SEEK_SET);   /* 位置情報を取り込み､ｼｰｸ */

/***************************** ﾄﾋﾟｯｸ内容の表示 *******************************/
	   while((text=getc(file))!=EOF) {
CHECK:	      if (text=='\f') break;                     /* ﾄﾋﾟｯｸ終了ﾏｰｸか？ */
	      if (text=='\n') {                                  /* 行末か？ */
		 putc(text, stdout);
                                                /* ｶﾞｲﾄﾞ文字列と一致するか？ */
		 for (guideptr=0; guide[guideptr] != '\0'; guideptr++) {
		    if ((text=getc(file))!=guide[guideptr])    /* 不一致なら */
		       break;                                    /* 比較終了 */
		 }
		 if (guide[guideptr]=='\0')   /* ｶﾞｲﾄﾞ文字列と一致していたら */
		    break;                                  /* ﾄﾋﾟｯｸ表示終了 */
		 else {
/* ｶﾞｲﾄﾞ文字列と一致している部分は､表示してこなかったので､改めて表示し直す */
		    for (i=0; i<guideptr; i++)
		       putc(guide[i], stdout);
		    goto CHECK;            /* 今の文字はﾁｪｯｸし直しから始める */
		 }
	      }
	      putc(text, stdout);                    /* マニュアル内容の表示 */
	   }
	}
	exit(0);
}

static int wordcmp(char *word1, char *word2)
{
/* 2つの指定文字列を､C言語のｼﾝﾎﾞﾙ文字(英数字および'_')で構成された単語として比較する｡ ｼﾝﾎﾞﾙ文字以外はｾﾊﾟﾚｰﾀ文字とみなす */

	while(iscsym(*word1))
	   {
	   if (iscsym(*word2)==0)    return -1;
	   if (tolower(*word1++) != tolower(*word2++)) return -2;
	   }
	if (iscsym(*word2)) return -3;
	else                return 0;
}
