/*
 * 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>
#ifdef HAVE_GETOPT_H
# include <getopt.h>
#endif

#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, --help                 Print this message\n"
	"   -H FILE                    Write header file to FILE (default is inputfile.h)\n"
	"   -i                         Inline messagetable(s)\n"
	"   -o, --output=FILE          Output to FILE (default is infile.rc)\n"
	"   -O, --output-format=FORMAT The output format (`rc', `res', or `pot')\n"
	"   -P, --po-dir=DIR           Directory containing po files for translations\n"
	"   -u                         Input file is in unicode\n"
	"   -U                         Output unicode messagetable(s)\n"
	"   -v                         Show supported codepages and languages\n"
	"   -V, --version              Print version end exit\n"
	"   -W, --pedantic             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)
 */
static int dodebug = 0;

static char *po_dir;

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;

FILE *yyin;

static enum
{
    FORMAT_RC,
    FORMAT_RES,
    FORMAT_POT
} output_format;

static const char short_options[] = "B:cdDhH:io:O:P:uUvVW";
static const struct option long_options[] =
{
	{ "help", 0, NULL, 'h' },
	{ "output", 1, NULL, 'o' },
	{ "output-format", 1, NULL, 'O' },
	{ "pedantic", 0, NULL, 'W' },
	{ "po-dir", 1, NULL, 'P' },
	{ "version", 0, NULL, 'v' }
};

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 opti = 0;
	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

	/* First rebuild the commandline to put in destination */
	/* Could be done through env[], but not all OS-es support it */
	cmdlen = 5; /* for "wmc " and \0 */
	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_long(argc, argv, short_options, long_options, &opti)) != 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 'O':
			if (!strcmp( optarg, "rc" )) output_format = FORMAT_RC;
			else if (!strcmp( optarg, "res" )) output_format = FORMAT_RES;
			else if (!strcmp( optarg, "pot" )) output_format = FORMAT_POT;
			else
                        {
                            fprintf(stderr, "Output format must be rc or res\n" );
                            lose++;
                        }
                        break;
		case 'P':
			po_dir = 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, NULL);
		setbuf(stderr, NULL);
	}

	/* 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);
	}

#ifdef WORDS_BIGENDIAN
	byte_swapped = (byteorder == WMC_BO_LITTLE);
#else
	byte_swapped = (byteorder == WMC_BO_BIG);
#endif

        switch (output_format)
        {
        case FORMAT_RC:
            write_h_file(header_name);
            write_rc_file(output_name);
            if(!rcinline)
		write_bin_files();
            break;
        case FORMAT_RES:
            add_translations( po_dir );
            write_res_file( output_name );
            break;
        case FORMAT_POT:
            write_pot_file( output_name );
            break;
        }
	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();
}
