Added mappings for a few messages.
[wine] / tools / wmc / wmc.c
1 /*
2  * Wine Message Compiler main program
3  *
4  * Copyright 2000 Bertho A. Stultiens (BS)
5  *
6  */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <signal.h>
11
12 #include "config.h"
13
14 #include "wmc.h"
15 #include "utils.h"
16 #include "lang.h"
17 #include "write.h"
18
19 static char usage[] =
20         "Usage: wmc [options...] [inputfile.mc]\n"
21         "   -B x        Set output byte-order x={n[ative], l[ittle], b[ig]}\n"
22         "               (default is n[ative] which equals "
23 #ifdef WORDS_BIGENDIAN
24         "big"
25 #else
26         "little"
27 #endif
28         "-endian)\n"
29         "   -c          Set 'custom-bit' in values\n"
30         "   -d          Use decimal values in output\n"
31         "   -D          Set debug flag\n"
32         "   -h          This message\n"
33         "   -H file     Write headerfile to file (default is inputfile.h)\n"
34         "   -i          Inline messagetable(s)\n"
35         "   -o file     Output to file (default is inputfile.rc)\n"
36         "   -u          Inputfile is in unicode\n"
37         "   -U          Output unicode messagetable(s)\n"
38         "   -v          Show supported codepages and languages\n"
39         "   -V          Print version end exit\n"
40         "   -W          Enable pedantic warnings\n"
41         "Input is taken from stdin if no inputfile is specified.\n"
42         "Byteorder of unicode input is based upon the first couple of\n"
43         "bytes read, which should be 0x0000..0x00ff.\n"
44         ;
45
46 static char version_string[] =
47         "Wine Message Compiler Version " WMC_FULLVERSION "\n"
48         "Copyright 2000 Bertho A. Stultiens\n"
49         ;
50
51 /*
52  * The output byte-order of resources (set with -B)
53  */
54 int byteorder = WMC_BO_NATIVE;
55
56 /*
57  * Custom bit (bit 29) in output values must be set (-c option)
58  */
59 int custombit = 0;
60
61 /*
62  * Output decimal values (-d option)
63  */
64 int decimal = 0;
65
66 /*
67  * Enable pedantic warnings; check arg references (-W option)
68  */
69 int pedantic = 0;
70
71 /*
72  * Unicode input (-u option)
73  */
74 int unicodein = 0;
75
76 /*
77  * Unicode output (-U option)
78  */
79 int unicodeout = 0;
80
81 /*
82  * Inline the messagetables (don't write *.bin files; -i option)
83  */
84 int rcinline = 0;
85
86 /*
87  * Debugging flag (-D option)
88  */
89 int dodebug = 0;
90
91 char *output_name = NULL;       /* The name given by the -o option */
92 char *input_name = NULL;        /* The name given on the command-line */
93 char *header_name = NULL;       /* The name given by the -H option */
94
95 int line_number = 1;            /* The current line */
96 int char_number = 1;            /* The current char pos within the line */
97
98 char *cmdline;                  /* The entire commandline */
99 time_t now;                     /* The time of start of wmc */
100
101 int getopt (int argc, char *const *argv, const char *optstring);
102 static void segvhandler(int sig);
103
104 int main(int argc,char *argv[])
105 {
106         extern char* optarg;
107         extern int   optind;
108         int optc;
109         int lose = 0;
110         int ret;
111         int i;
112         int cmdlen;
113
114         signal(SIGSEGV, segvhandler);
115
116         now = time(NULL);
117
118         /* First rebuild the commandline to put in destination */
119         /* Could be done through env[], but not all OS-es support it */
120         cmdlen = 4; /* for "wmc " */
121         for(i = 1; i < argc; i++)
122                 cmdlen += strlen(argv[i]) + 1;
123         cmdline = (char *)xmalloc(cmdlen);
124         strcpy(cmdline, "wmc ");
125         for(i = 1; i < argc; i++)
126         {
127                 strcat(cmdline, argv[i]);
128                 if(i < argc-1)
129                         strcat(cmdline, " ");
130         }
131
132         while((optc = getopt(argc, argv, "B:cdDhH:io:p:uUvVW")) != EOF)
133         {
134                 switch(optc)
135                 {
136                 case 'B':
137                         switch(optarg[0])
138                         {
139                         case 'n':
140                         case 'N':
141                                 byteorder = WMC_BO_NATIVE;
142                                 break;
143                         case 'l':
144                         case 'L':
145                                 byteorder = WMC_BO_LITTLE;
146                                 break;
147                         case 'b':
148                         case 'B':
149                                 byteorder = WMC_BO_BIG;
150                                 break;
151                         default:
152                                 fprintf(stderr, "Byteordering must be n[ative], l[ittle] or b[ig]\n");
153                                 lose++;
154                         }
155                         break;
156                 case 'c':
157                         custombit = 1;
158                         break;
159                 case 'd':
160                         decimal = 1;
161                         break;
162                 case 'D':
163                         dodebug = 1;
164                         break;
165                 case 'h':
166                         printf("%s", usage);
167                         exit(0);
168                         /* No return */
169                 case 'H':
170                         header_name = xstrdup(optarg);
171                         break;
172                 case 'i':
173                         rcinline = 1;
174                         break;
175                 case 'o':
176                         output_name = xstrdup(optarg);
177                         break;
178                 case 'u':
179                         unicodein = 1;
180                         break;
181                 case 'U':
182                         unicodeout = 1;
183                         break;
184                 case 'v':
185                         show_languages();
186                         show_codepages();
187                         exit(0);
188                         /* No return */
189                 case 'V':
190                         printf(version_string);
191                         exit(0);
192                         /* No return */
193                 case 'W':
194                         pedantic = 1;
195                         break;
196                 default:
197                         lose++;
198                         break;
199                 }
200         }
201
202         if(lose)
203         {
204                 fprintf(stderr, "%s", usage);
205                 return 1;
206         }
207
208         yydebug = dodebug;
209         if(dodebug)
210         {
211                 setbuf(stdout, 0);
212                 setbuf(stderr, 0);
213         }
214
215         /* Check for input file on command-line */
216         if(optind < argc)
217         {
218                 input_name = argv[optind];
219         }
220
221         /* Generate appropriate outfile names */
222         if(!output_name)
223         {
224                 output_name = dup_basename(input_name, ".mc");
225                 strcat(output_name, ".rc");
226         }
227
228         if(!header_name)
229         {
230                 header_name = dup_basename(input_name, ".mc");
231                 strcat(header_name, ".h");
232         }
233
234         if(input_name)
235         {
236                 if(!(yyin = fopen(input_name, "rb")))
237                         error("Could not open %s for input\n", input_name);
238         }
239         else
240                 yyin = stdin;
241
242         ret = yyparse();
243
244         if(input_name)
245                 fclose(yyin);
246
247         if(ret)
248         {
249                 /* Error during parse */
250                 exit(1);
251         }
252
253         write_h_file(header_name);
254         write_rc_file(output_name);
255         if(!rcinline)
256                 write_bin_files();
257
258         return 0;
259 }
260
261 static void segvhandler(int sig)
262 {
263         fprintf(stderr, "\n%s:%d: Oops, segment violation\n", input_name, line_number);
264         fflush(stdout);
265         fflush(stderr);
266         abort();
267 }
268