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