/*
 * Wine Message Compiler main program
 *
 * Copyright 2000 Bertho A. Stultiens (BS)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wine/port.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>

#include "wmc.h"
#include "utils.h"
#include "lang.h"
#include "write.h"

static const char usage[] =
	"Usage: wmc [options...] [inputfile.mc]\n"
	"   -B x        Set output byte-order x={n[ative], l[ittle], b[ig]}\n"
	"               (default is n[ative] which equals "
#ifdef WORDS_BIGENDIAN
	"big"
#else
	"little"
#endif
	"-endian)\n"
	"   -c          Set 'custom-bit' in values\n"
	"   -d          Use decimal values in output\n"
	"   -D		Set debug flag\n"
	"   -h          This message\n"
	"   -H file     Write headerfile to file (default is inputfile.h)\n"
	"   -i          Inline messagetable(s)\n"
	"   -o file     Output to file (default is inputfile.rc)\n"
	"   -u          Inputfile is in unicode\n"
	"   -U          Output unicode messagetable(s)\n"
	"   -v          Show supported codepages and languages\n"
	"   -V          Print version end exit\n"
	"   -W          Enable pedantic warnings\n"
	"Input is taken from stdin if no inputfile is specified.\n"
	"Byteorder of unicode input is based upon the first couple of\n"
	"bytes read, which should be 0x0000..0x00ff.\n"
	;

static const char version_string[] =
	"Wine Message Compiler version " PACKAGE_VERSION "\n"
	"Copyright 2000 Bertho A. Stultiens\n"
	;

/*
 * The output byte-order of resources (set with -B)
 */
int byteorder = WMC_BO_NATIVE;

/*
 * Custom bit (bit 29) in output values must be set (-c option)
 */
int custombit = 0;

/*
 * Output decimal values (-d option)
 */
int decimal = 0;

/*
 * Enable pedantic warnings; check arg references (-W option)
 */
int pedantic = 0;

/*
 * Unicode input (-u option)
 */
int unicodein = 0;

/*
 * Unicode output (-U option)
 */
int unicodeout = 0;

/*
 * Inline the messagetables (don't write *.bin files; -i option)
 */
int rcinline = 0;

/*
 * Debugging flag (-D option)
 */
int dodebug = 0;

char *output_name = NULL;	/* The name given by the -o option */
char *input_name = NULL;	/* The name given on the command-line */
char *header_name = NULL;	/* The name given by the -H option */

int line_number = 1;		/* The current line */
int char_number = 1;		/* The current char pos within the line */

char *cmdline;			/* The entire commandline */
time_t now;			/* The time of start of wmc */

int mcy_debug;

int getopt (int argc, char *const *argv, const char *optstring);
static void segvhandler(int sig);

static void cleanup_files(void)
{
    if (output_name) unlink( output_name );
    if (header_name) unlink( header_name );
}

static void exit_on_signal( int sig )
{
    exit(1);  /* this will call the atexit functions */
}

int main(int argc,char *argv[])
{
	extern char* optarg;
	extern int   optind;
	int optc;
	int lose = 0;
	int ret;
	int i;
	int cmdlen;

	atexit( cleanup_files );
	signal(SIGSEGV, segvhandler);
	signal( SIGTERM, exit_on_signal );
	signal( SIGINT, exit_on_signal );
#ifdef SIGHUP
	signal( SIGHUP, exit_on_signal );
#endif

	now = time(NULL);

	/* First rebuild the commandline to put in destination */
	/* Could be done through env[], but not all OS-es support it */
	cmdlen = 4; /* for "wmc " */
	for(i = 1; i < argc; i++)
		cmdlen += strlen(argv[i]) + 1;
	cmdline = xmalloc(cmdlen);
	strcpy(cmdline, "wmc ");
	for(i = 1; i < argc; i++)
	{
		strcat(cmdline, argv[i]);
		if(i < argc-1)
			strcat(cmdline, " ");
	}

	while((optc = getopt(argc, argv, "B:cdDhH:io:p:uUvVW")) != EOF)
	{
		switch(optc)
		{
		case 'B':
			switch(optarg[0])
			{
			case 'n':
			case 'N':
				byteorder = WMC_BO_NATIVE;
				break;
			case 'l':
			case 'L':
				byteorder = WMC_BO_LITTLE;
				break;
			case 'b':
			case 'B':
				byteorder = WMC_BO_BIG;
				break;
			default:
				fprintf(stderr, "Byteordering must be n[ative], l[ittle] or b[ig]\n");
				lose++;
			}
			break;
		case 'c':
			custombit = 1;
			break;
		case 'd':
			decimal = 1;
			break;
		case 'D':
			dodebug = 1;
			break;
		case 'h':
			printf("%s", usage);
			exit(0);
			/* No return */
		case 'H':
			header_name = xstrdup(optarg);
			break;
		case 'i':
			rcinline = 1;
			break;
		case 'o':
			output_name = xstrdup(optarg);
			break;
		case 'u':
			unicodein = 1;
			break;
		case 'U':
			unicodeout = 1;
			break;
		case 'v':
			show_languages();
			show_codepages();
			exit(0);
			/* No return */
		case 'V':
			printf(version_string);
			exit(0);
			/* No return */
		case 'W':
			pedantic = 1;
			break;
		default:
			lose++;
			break;
		}
	}

	if(lose)
	{
		fprintf(stderr, "%s", usage);
		return 1;
	}

	mcy_debug = dodebug;
	if(dodebug)
	{
		setbuf(stdout, 0);
		setbuf(stderr, 0);
	}

	/* Check for input file on command-line */
	if(optind < argc)
	{
		input_name = argv[optind];
	}

	/* Generate appropriate outfile names */
	if(!output_name)
	{
		output_name = dup_basename(input_name, ".mc");
		strcat(output_name, ".rc");
	}

	if(!header_name)
	{
		header_name = dup_basename(input_name, ".mc");
		strcat(header_name, ".h");
	}

	if(input_name)
	{
		if(!(yyin = fopen(input_name, "rb")))
			error("Could not open %s for input\n", input_name);
	}
	else
		yyin = stdin;

	ret = mcy_parse();

	if(input_name)
		fclose(yyin);

	if(ret)
	{
		/* Error during parse */
		exit(1);
	}

	write_h_file(header_name);
	write_rc_file(output_name);
	if(!rcinline)
		write_bin_files();
	output_name = NULL;
	header_name = NULL;
	return 0;
}

static void segvhandler(int sig)
{
	fprintf(stderr, "\n%s:%d: Oops, segment violation\n", input_name, line_number);
	fflush(stdout);
	fflush(stderr);
	abort();
}
