msvcrt: Add a new file for the x86_64 exception handling.
[wine/multimedia.git] / tools / wmc / wmc.c
blobc9ad9c4aa3e65690c3e6e9823e983b48b004ecf3
1 /*
2 * Wine Message Compiler main program
4 * Copyright 2000 Bertho A. Stultiens (BS)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
22 #include "wine/port.h"
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <signal.h>
29 #include "wmc.h"
30 #include "utils.h"
31 #include "lang.h"
32 #include "write.h"
34 static const char usage[] =
35 "Usage: wmc [options...] [inputfile.mc]\n"
36 " -B x Set output byte-order x={n[ative], l[ittle], b[ig]}\n"
37 " (default is n[ative] which equals "
38 #ifdef WORDS_BIGENDIAN
39 "big"
40 #else
41 "little"
42 #endif
43 "-endian)\n"
44 " -c Set 'custom-bit' in values\n"
45 " -d Use decimal values in output\n"
46 " -D Set debug flag\n"
47 " -h This message\n"
48 " -H file Write headerfile to file (default is inputfile.h)\n"
49 " -i Inline messagetable(s)\n"
50 " -o file Output to file (default is inputfile.rc)\n"
51 " -O fmt Set output format (rc, res, pot)\n"
52 " -P dir Directory where to find po files\n"
53 " -u Inputfile is in unicode\n"
54 " -U Output unicode messagetable(s)\n"
55 " -v Show supported codepages and languages\n"
56 " -V Print version end exit\n"
57 " -W Enable pedantic warnings\n"
58 "Input is taken from stdin if no inputfile is specified.\n"
59 "Byteorder of unicode input is based upon the first couple of\n"
60 "bytes read, which should be 0x0000..0x00ff.\n"
63 static const char version_string[] =
64 "Wine Message Compiler version " PACKAGE_VERSION "\n"
65 "Copyright 2000 Bertho A. Stultiens\n"
69 * The output byte-order of resources (set with -B)
71 int byteorder = WMC_BO_NATIVE;
74 * Custom bit (bit 29) in output values must be set (-c option)
76 int custombit = 0;
79 * Output decimal values (-d option)
81 int decimal = 0;
84 * Enable pedantic warnings; check arg references (-W option)
86 int pedantic = 0;
89 * Unicode input (-u option)
91 int unicodein = 0;
94 * Unicode output (-U option)
96 int unicodeout = 0;
99 * Inline the messagetables (don't write *.bin files; -i option)
101 int rcinline = 0;
104 * Debugging flag (-D option)
106 static int dodebug = 0;
108 static char *po_dir;
110 char *output_name = NULL; /* The name given by the -o option */
111 char *input_name = NULL; /* The name given on the command-line */
112 char *header_name = NULL; /* The name given by the -H option */
114 int line_number = 1; /* The current line */
115 int char_number = 1; /* The current char pos within the line */
117 char *cmdline; /* The entire commandline */
118 time_t now; /* The time of start of wmc */
120 int mcy_debug;
122 FILE *yyin;
124 static enum
126 FORMAT_RC,
127 FORMAT_RES,
128 FORMAT_POT
129 } output_format;
131 int getopt (int argc, char *const *argv, const char *optstring);
132 static void segvhandler(int sig);
134 static void cleanup_files(void)
136 if (output_name) unlink( output_name );
137 if (header_name) unlink( header_name );
140 static void exit_on_signal( int sig )
142 exit(1); /* this will call the atexit functions */
145 int main(int argc,char *argv[])
147 extern char* optarg;
148 extern int optind;
149 int optc;
150 int lose = 0;
151 int ret;
152 int i;
153 int cmdlen;
155 atexit( cleanup_files );
156 signal(SIGSEGV, segvhandler);
157 signal( SIGTERM, exit_on_signal );
158 signal( SIGINT, exit_on_signal );
159 #ifdef SIGHUP
160 signal( SIGHUP, exit_on_signal );
161 #endif
163 now = time(NULL);
165 /* First rebuild the commandline to put in destination */
166 /* Could be done through env[], but not all OS-es support it */
167 cmdlen = 5; /* for "wmc " and \0 */
168 for(i = 1; i < argc; i++)
169 cmdlen += strlen(argv[i]) + 1;
170 cmdline = xmalloc(cmdlen);
171 strcpy(cmdline, "wmc ");
172 for(i = 1; i < argc; i++)
174 strcat(cmdline, argv[i]);
175 if(i < argc-1)
176 strcat(cmdline, " ");
179 while((optc = getopt(argc, argv, "B:cdDhH:io:O:P:uUvVW")) != EOF)
181 switch(optc)
183 case 'B':
184 switch(optarg[0])
186 case 'n':
187 case 'N':
188 byteorder = WMC_BO_NATIVE;
189 break;
190 case 'l':
191 case 'L':
192 byteorder = WMC_BO_LITTLE;
193 break;
194 case 'b':
195 case 'B':
196 byteorder = WMC_BO_BIG;
197 break;
198 default:
199 fprintf(stderr, "Byteordering must be n[ative], l[ittle] or b[ig]\n");
200 lose++;
202 break;
203 case 'c':
204 custombit = 1;
205 break;
206 case 'd':
207 decimal = 1;
208 break;
209 case 'D':
210 dodebug = 1;
211 break;
212 case 'h':
213 printf("%s", usage);
214 exit(0);
215 /* No return */
216 case 'H':
217 header_name = xstrdup(optarg);
218 break;
219 case 'i':
220 rcinline = 1;
221 break;
222 case 'o':
223 output_name = xstrdup(optarg);
224 break;
225 case 'O':
226 if (!strcmp( optarg, "rc" )) output_format = FORMAT_RC;
227 else if (!strcmp( optarg, "res" )) output_format = FORMAT_RES;
228 else if (!strcmp( optarg, "pot" )) output_format = FORMAT_POT;
229 else
231 fprintf(stderr, "Output format must be rc or res\n" );
232 lose++;
234 break;
235 case 'P':
236 po_dir = xstrdup( optarg );
237 break;
238 case 'u':
239 unicodein = 1;
240 break;
241 case 'U':
242 unicodeout = 1;
243 break;
244 case 'v':
245 show_languages();
246 show_codepages();
247 exit(0);
248 /* No return */
249 case 'V':
250 printf(version_string);
251 exit(0);
252 /* No return */
253 case 'W':
254 pedantic = 1;
255 break;
256 default:
257 lose++;
258 break;
262 if(lose)
264 fprintf(stderr, "%s", usage);
265 return 1;
268 mcy_debug = dodebug;
269 if(dodebug)
271 setbuf(stdout, NULL);
272 setbuf(stderr, NULL);
275 /* Check for input file on command-line */
276 if(optind < argc)
278 input_name = argv[optind];
281 /* Generate appropriate outfile names */
282 if(!output_name)
284 output_name = dup_basename(input_name, ".mc");
285 strcat(output_name, ".rc");
288 if(!header_name)
290 header_name = dup_basename(input_name, ".mc");
291 strcat(header_name, ".h");
294 if(input_name)
296 if(!(yyin = fopen(input_name, "rb")))
297 error("Could not open %s for input\n", input_name);
299 else
300 yyin = stdin;
302 ret = mcy_parse();
304 if(input_name)
305 fclose(yyin);
307 if(ret)
309 /* Error during parse */
310 exit(1);
313 #ifdef WORDS_BIGENDIAN
314 byte_swapped = (byteorder == WMC_BO_LITTLE);
315 #else
316 byte_swapped = (byteorder == WMC_BO_BIG);
317 #endif
319 switch (output_format)
321 case FORMAT_RC:
322 write_h_file(header_name);
323 write_rc_file(output_name);
324 if(!rcinline)
325 write_bin_files();
326 break;
327 case FORMAT_RES:
328 if (po_dir) add_translations( po_dir );
329 write_res_file( output_name );
330 break;
331 case FORMAT_POT:
332 write_pot_file( output_name );
333 break;
335 output_name = NULL;
336 header_name = NULL;
337 return 0;
340 static void segvhandler(int sig)
342 fprintf(stderr, "\n%s:%d: Oops, segment violation\n", input_name, line_number);
343 fflush(stdout);
344 fflush(stderr);
345 abort();