/*	
 *	dbin2c - バイナリ⇒Ｃ言語配列変換ユーティリティ
 *
 *	Copyright (C) 2004 Naoyuki Sawa
 *
 *	* Wed Mar 27 19:00:00 JST 2004 Naoyuki Sawa
 *	- 作成開始。
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

/* [NOTE]
 * * コマンドライン引数のワイルドカードを展開するために、
 *   [プロジェクトの設定]->[リンク]->[オブジェクト/ライブラリモジュール]に
 *   「setargv.obj」を追加しています。
 *   ただし、本プログラムは複数の入力ファイルを受け付けないので、
 *   ワイルドカード展開はコマンド入力の手間を省く程度の目的に過ぎません。
 */

#define VERSION		"20040527"

/* エラーメッセージを表示して終了します。
 * [in]
 *	fmt		書式文字列。
 *	...		パラメータ。
 */
void
err(const char* fmt, ...)
{
	va_list ap;
	va_start(ap, fmt);
	 fprintf(stderr, "### ");
	vfprintf(stderr, fmt, ap);
	 fprintf(stderr, "\n");
	va_end(ap);
	exit(-1);
}

/* 使い方を表示して終了します。
 */
void
usage()
{
	//		01234567890123456789012345678901234567890123456789012345678901234567890123456789
	fprintf(stderr,"dbin2c - バイナリ⇒Ｃ言語配列変換ユーティリティ (%s)\n", VERSION);
	fprintf(stderr,"Copyright (C) 2004 Naoyuki Sawa\n");
	fprintf(stderr,"\n");
	fprintf(stderr,"使い方: dbin2c <filename> [<labelname>]\n");
	fprintf(stderr,"\n");
	fprintf(stderr,"  filename   入力元バイナリファイル名を指定します。(必須)\n");
	fprintf(stderr,"  labelname  配列名を指定します。(省略可)\n");
	fprintf(stderr,"             配列名省略時は、入力ファイル名を大文字にした名前を配列名とします。\n");
	fprintf(stderr,"\n");
	fprintf(stderr,"出力先は常に標準出力です。必要に応じてファイルへリダイレクトしてください。\n");
	exit(-1);
}

char filename[_MAX_PATH];	/* 入力ファイル名 */
char fullpath[_MAX_PATH];	/* 入力ファイルフルパス名 */
char labelname[_MAX_FNAME];	/* 配列名 */

int
main(int argc, char* argv[])
{
	FILE* fp;
	int i;
	int ch;

	/* コマンドライン解析。 */
	switch(argc - 1/*コマンド名を除いた引数の数*/) {
	case 1:
		/*** ファイル名のみ指定 ***/
		/* ファイル名を格納します。 */
		strncpy(filename, argv[1], sizeof filename - 1);
		/* 配列名を作成します。 */
		_splitpath(filename, NULL, NULL, labelname, NULL);
		_strupr(labelname);
		break;
	case 2:
		/*** ファイル名と配列名を指定 ***/
		/* ファイル名を格納します。 */
		strncpy(filename, argv[1], sizeof filename - 1);
		/* 配列名を格納します。 */
		strncpy(labelname, argv[2], sizeof labelname - 1);
		break;
	default:
		usage();
	}

	/* 相対パスをフルパスに変換します。(メッセージ表示をわかりやすくするため) */
	if(!_fullpath(fullpath, filename, sizeof fullpath)) {
		err("ファイル名またはパス指定が不正です。");
	}

	/* 入力ファイルを開きます。 */
	fp = fopen(fullpath, "rb"); /* バイナリモード必須!! */
	if(!fp) {
		err("%s が開けません。", fullpath);
	}

	/* 配列宣言を出力します。 */
	i = 0;
	printf("/* ");
	for(;;) {
		ch = fullpath[i];
		if(!ch) break;
		if(ch == '\\') { /* C言語ソース中で￥の使用は危険なので、／に置き換えます */
			ch = '/';
		}
		printf("%c", ch);
		i++;
	}
	printf(" */\n");
	printf("const unsigned char %s[] = {\n", labelname);

	/* データを出力します。 */
	i = 0;
	for(;;) {
		ch = fgetc(fp);
		if(ch == EOF) break;
		printf("0x%02x,", ch);
		i++;
		if(i == 16) { /* 16バイト毎に改行します */
			printf("\n");
			i =0;
		}
	}

	/* 配列を閉じます。 */
	if(i) { /* 最後が改行でなければ、改行を追加します */
		printf("\n");
	}
	printf("};\n");

	/* 入力ファイルを閉じます。 */
	fclose(fp);

	return 0;
}
