Sweden-Number/tools/wmc/wmc.c

270 lines
5.0 KiB
C

/*
* Wine Message Compiler main program
*
* Copyright 2000 Bertho A. Stultiens (BS)
*
*/
#include "config.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 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 char version_string[] =
"Wine Message Compiler Version " WMC_FULLVERSION "\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 getopt (int argc, char *const *argv, const char *optstring);
static void segvhandler(int sig);
int main(int argc,char *argv[])
{
extern char* optarg;
extern int optind;
int optc;
int lose = 0;
int ret;
int i;
int cmdlen;
signal(SIGSEGV, segvhandler);
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 = (char *)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;
}
yydebug = 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 = yyparse();
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();
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();
}