/*****************************************************************************
 * Bison/Flexプログラム部分をテストするための、Windowsアプリケーションの雛型 *
 * □ビルド・実行方法:                                                       *
 * ┃"C:\Program Files (x86)\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT"  *
 * ┃make -f winapp.mk run                                                   *
 *****************************************************************************/
#include "winapp.h"

/*{{定型コード:main.c========================================================*/
void die(const char* fmt, ...) {
  va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap);
  putc('\n', stderr); exit(EXIT_FAILURE); }
/*}}定型コード:main.c========================================================*/

#define __CLIP_H__
/* getopt */
#include "../../include/getopt.h"
#include "../../getopt.c"
#undef  __CLIP_H__

int opt_FS; /* 'c'=カンマ区切り,'t'=タブ区切り */

/* 使い方を表示して終了する。 */
__declspec(noreturn) void usage() {
	fprintf(stderr, "dpcsvcc - CSV⇒ASCII制御文字分割 変換ユーティリティ (%s)\n", VERSION);
	fprintf(stderr, "Copyright (C) 2013-2014 Naoyuki Sawa\n");
	fprintf(stderr, "\n");
	fprintf(stderr, "USAGE:\n");
	fprintf(stderr, "  dpcsvcc [filename ...] \n");
	fprintf(stderr, "  ・filenameを指定しなければ、標準入力から読み込みます。\n");
	fprintf(stderr, "  ・filenameは、ワイルドカードによる複数指定も可能です。\n");
	fprintf(stderr, "\n");
	fprintf(stderr, "OPTIONS:\n");
	fprintf(stderr, "  -c 入力書式をカンマ区切りとします。(*初期値)\n");
	fprintf(stderr, "  -t 入力書式をタブ区切りとします。\n");
	fprintf(stderr, "     -cと-tを同時に指定してはいけません。\n");
	fprintf(stderr, "  -h 使い方を表示します。\n");
	fprintf(stderr, "\n");
	fprintf(stderr, "DESCRIPTION:\n");
	fprintf(stderr, "  CSVの区切り文字を、ASCII制御文字に変換します。\n");
	fprintf(stderr, "  ・カンマ⇒US(1F)に変換します。\n");
	fprintf(stderr, "  ・改行  ⇒RS(1E)に変換します。ただし、最後のRSは出力しません。\n");
	fprintf(stderr, "  ・filenameを複数指定した場合、ファイル間をGS(1D)で区切ります。\n");
	fprintf(stderr, "  ・空ユニット、及び、空レコードも有効です。\n");
	fprintf(stderr, "  ・ユニット文字列を「\"」で囲むと、「,」及び改行を含められます。\n");
	fprintf(stderr, "  ・「\"」で囲んだユニット文字列の中で、「\"\"」は「\"」を表します。\n");
	exit(EXIT_FAILURE);
}

int main(int argc, char* argv[]) {
	int opt;
#if     (YYDEBUG!=0)
//	yydebug = 1; /* nonzero means print parse trace */
#endif/*(YYDEBUG!=0)*/
	/* コマンドラインオプションを処理する。 */
	opterr = 0; /* オプションエラーは当プログラム内で処理するので、getopt()内でのエラー表示は不要。 */
	while((opt = getopt(argc, argv, "hct")) != -1) {
		switch(opt) {
		default:
		case 'h':
			usage();
		case 'c':
		case 't':
			if(opt_FS) { usage(); }
			opt_FS = opt;
			break;
		}
	}
	/* セパレータが指定されていなければ、カンマ区切りとする。 */
	if(!opt_FS) { opt_FS = 'c'; }
	/* ファイルが指定されていなければ、標準入力から読み込む。 */
	if(optind == argc) {
		yylex_init(stdin);
		if((yyparse() != 0) || (yynerrs != 0)) { die("文法エラーが発生しました。\n"); }
	/* ファイルが指定されていたら、各ファイルを読み込む。 */
	} else {
		int i;
		for(i = optind; i < argc; i++) {
			FILE* fp = fopen(argv[i], "r");
			if(!fp) { die("%s が開けません。\n", argv[i]); }
			if(i != optind) { printf("\x1D"); } /* 1D = ASCII制御文字 GS (Group Separator) */
			yylex_init(fp);
			if((yyparse() != 0) || (yynerrs != 0)) { die("%s: 文法エラーが発生しました。\n", argv[i]); }
			fclose(fp);
		}
	}
	return EXIT_SUCCESS;
}

