usp10: Simplify GPOS_expand_script_cache().
[wine.git] / tools / wmc / wmc.c
bloba7fbd6ab4f65dbdfd700e5754ca2af0ef9749dac
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>
28 #ifdef HAVE_GETOPT_H
29 # include <getopt.h>
30 #endif
32 #include "wmc.h"
33 #include "utils.h"
34 #include "lang.h"
35 #include "write.h"
37 static const char usage[] =
38 "Usage: wmc [options...] [inputfile.mc]\n"
39 " -B x Set output byte-order x={n[ative], l[ittle], b[ig]}\n"
40 " (default is n[ative] which equals "
41 #ifdef WORDS_BIGENDIAN
42 "big"
43 #else
44 "little"
45 #endif
46 "-endian)\n"
47 " -c Set 'custom-bit' in values\n"
48 " -d Use decimal values in output\n"
49 " -D Set debug flag\n"
50 " -h, --help Print this message\n"
51 " -H FILE Write header file to FILE (default is inputfile.h)\n"
52 " -i Inline messagetable(s)\n"
53 " -o, --output=FILE Output to FILE (default is infile.rc)\n"
54 " -O, --output-format=FORMAT The output format (`rc', `res', or `pot')\n"
55 " -P, --po-dir=DIR Directory containing po files for translations\n"
56 " -u Input file is in unicode\n"
57 " -U Output unicode messagetable(s)\n"
58 " -v Show supported codepages and languages\n"
59 " -V, --version Print version end exit\n"
60 " -W, --pedantic Enable pedantic warnings\n"
61 "Input is taken from stdin if no inputfile is specified.\n"
62 "Byteorder of unicode input is based upon the first couple of\n"
63 "bytes read, which should be 0x0000..0x00ff.\n"
66 static const char version_string[] =
67 "Wine Message Compiler version " PACKAGE_VERSION "\n"
68 "Copyright 2000 Bertho A. Stultiens\n"
72 * The output byte-order of resources (set with -B)
74 int byteorder = WMC_BO_NATIVE;
77 * Custom bit (bit 29) in output values must be set (-c option)
79 int custombit = 0;
82 * Output decimal values (-d option)
84 int decimal = 0;
87 * Enable pedantic warnings; check arg references (-W option)
89 int pedantic = 0;
92 * Unicode input (-u option)
94 int unicodein = 0;
97 * Unicode output (-U option)
99 int unicodeout = 0;
102 * Inline the messagetables (don't write *.bin files; -i option)
104 int rcinline = 0;
107 * Debugging flag (-D option)
109 static int dodebug = 0;
111 static char *po_dir;
113 char *output_name = NULL; /* The name given by the -o option */
114 char *input_name = NULL; /* The name given on the command-line */
115 char *header_name = NULL; /* The name given by the -H option */
117 int line_number = 1; /* The current line */
118 int char_number = 1; /* The current char pos within the line */
120 char *cmdline; /* The entire commandline */
121 time_t now; /* The time of start of wmc */
123 int mcy_debug;
125 FILE *yyin;
127 static enum
129 FORMAT_RC,
130 FORMAT_RES,
131 FORMAT_POT
132 } output_format;
134 static const char short_options[] = "B:cdDhH:io:O:P:uUvVW";
135 static const struct option long_options[] =
137 { "help", 0, NULL, 'h' },
138 { "output", 1, NULL, 'o' },
139 { "output-format", 1, NULL, 'O' },
140 { "pedantic", 0, NULL, 'W' },
141 { "po-dir", 1, NULL, 'P' },
142 { "version", 0, NULL, 'v' }
145 static void segvhandler(int sig);
147 static void cleanup_files(void)
149 if (output_name) unlink( output_name );
150 if (header_name) unlink( header_name );
153 static void exit_on_signal( int sig )
155 exit(1); /* this will call the atexit functions */
158 int main(int argc,char *argv[])
160 int optc;
161 int opti = 0;
162 int lose = 0;
163 int ret;
164 int i;
165 int cmdlen;
167 atexit( cleanup_files );
168 signal(SIGSEGV, segvhandler);
169 signal( SIGTERM, exit_on_signal );
170 signal( SIGINT, exit_on_signal );
171 #ifdef SIGHUP
172 signal( SIGHUP, exit_on_signal );
173 #endif
175 /* First rebuild the commandline to put in destination */
176 /* Could be done through env[], but not all OS-es support it */
177 cmdlen = 5; /* for "wmc " and \0 */
178 for(i = 1; i < argc; i++)
179 cmdlen += strlen(argv[i]) + 1;
180 cmdline = xmalloc(cmdlen);
181 strcpy(cmdline, "wmc ");
182 for(i = 1; i < argc; i++)
184 strcat(cmdline, argv[i]);
185 if(i < argc-1)
186 strcat(cmdline, " ");
189 while((optc = getopt_long(argc, argv, short_options, long_options, &opti)) != EOF)
191 switch(optc)
193 case 'B':
194 switch(optarg[0])
196 case 'n':
197 case 'N':
198 byteorder = WMC_BO_NATIVE;
199 break;
200 case 'l':
201 case 'L':
202 byteorder = WMC_BO_LITTLE;
203 break;
204 case 'b':
205 case 'B':
206 byteorder = WMC_BO_BIG;
207 break;
208 default:
209 fprintf(stderr, "Byteordering must be n[ative], l[ittle] or b[ig]\n");
210 lose++;
212 break;
213 case 'c':
214 custombit = 1;
215 break;
216 case 'd':
217 decimal = 1;
218 break;
219 case 'D':
220 dodebug = 1;
221 break;
222 case 'h':
223 printf("%s", usage);
224 exit(0);
225 /* No return */
226 case 'H':
227 header_name = xstrdup(optarg);
228 break;
229 case 'i':
230 rcinline = 1;
231 break;
232 case 'o':
233 output_name = xstrdup(optarg);
234 break;
235 case 'O':
236 if (!strcmp( optarg, "rc" )) output_format = FORMAT_RC;
237 else if (!strcmp( optarg, "res" )) output_format = FORMAT_RES;
238 else if (!strcmp( optarg, "pot" )) output_format = FORMAT_POT;
239 else
241 fprintf(stderr, "Output format must be rc or res\n" );
242 lose++;
244 break;
245 case 'P':
246 po_dir = xstrdup( optarg );
247 break;
248 case 'u':
249 unicodein = 1;
250 break;
251 case 'U':
252 unicodeout = 1;
253 break;
254 case 'v':
255 show_languages();
256 show_codepages();
257 exit(0);
258 /* No return */
259 case 'V':
260 printf(version_string);
261 exit(0);
262 /* No return */
263 case 'W':
264 pedantic = 1;
265 break;
266 default:
267 lose++;
268 break;
272 if(lose)
274 fprintf(stderr, "%s", usage);
275 return 1;
278 mcy_debug = dodebug;
279 if(dodebug)
281 setbuf(stdout, NULL);
282 setbuf(stderr, NULL);
285 /* Check for input file on command-line */
286 if(optind < argc)
288 input_name = argv[optind];
291 /* Generate appropriate outfile names */
292 if(!output_name)
294 output_name = dup_basename(input_name, ".mc");
295 strcat(output_name, ".rc");
298 if(!header_name)
300 header_name = dup_basename(input_name, ".mc");
301 strcat(header_name, ".h");
304 if(input_name)
306 if(!(yyin = fopen(input_name, "rb")))
307 error("Could not open %s for input\n", input_name);
309 else
310 yyin = stdin;
312 ret = mcy_parse();
314 if(input_name)
315 fclose(yyin);
317 if(ret)
319 /* Error during parse */
320 exit(1);
323 #ifdef WORDS_BIGENDIAN
324 byte_swapped = (byteorder == WMC_BO_LITTLE);
325 #else
326 byte_swapped = (byteorder == WMC_BO_BIG);
327 #endif
329 switch (output_format)
331 case FORMAT_RC:
332 write_h_file(header_name);
333 write_rc_file(output_name);
334 if(!rcinline)
335 write_bin_files();
336 break;
337 case FORMAT_RES:
338 add_translations( po_dir );
339 write_res_file( output_name );
340 break;
341 case FORMAT_POT:
342 write_pot_file( output_name );
343 break;
345 output_name = NULL;
346 header_name = NULL;
347 return 0;
350 static void segvhandler(int sig)
352 fprintf(stderr, "\n%s:%d: Oops, segment violation\n", input_name, line_number);
353 fflush(stdout);
354 fflush(stderr);
355 abort();