blob: 858606f01032654958d1f609fc654c15a639c924 [file] [log] [blame]
Bertho Stultiens30855912000-06-13 04:34:41 +00001/*
2 * Wine Message Compiler main program
3 *
4 * Copyright 2000 Bertho A. Stultiens (BS)
5 *
Alexandre Julliard0799c1a2002-03-09 23:29:33 +00006 * 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.
10 *
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.
15 *
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
Jonathan Ernst360a3f92006-05-18 14:49:52 +020018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
Bertho Stultiens30855912000-06-13 04:34:41 +000019 */
Francois Gougete5ddd262001-10-14 16:18:52 +000020
21#include "config.h"
Alexandre Julliard49b7fdc2005-08-03 21:25:10 +000022#include "wine/port.h"
Francois Gougete5ddd262001-10-14 16:18:52 +000023
Bertho Stultiens30855912000-06-13 04:34:41 +000024#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <signal.h>
28
Bertho Stultiens30855912000-06-13 04:34:41 +000029#include "wmc.h"
30#include "utils.h"
31#include "lang.h"
32#include "write.h"
33
34static 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 " -u Inputfile is in unicode\n"
52 " -U Output unicode messagetable(s)\n"
53 " -v Show supported codepages and languages\n"
54 " -V Print version end exit\n"
55 " -W Enable pedantic warnings\n"
56 "Input is taken from stdin if no inputfile is specified.\n"
57 "Byteorder of unicode input is based upon the first couple of\n"
58 "bytes read, which should be 0x0000..0x00ff.\n"
59 ;
60
61static char version_string[] =
Alexandre Julliardac21d342005-10-10 10:43:41 +000062 "Wine Message Compiler version " PACKAGE_VERSION "\n"
Bertho Stultiens30855912000-06-13 04:34:41 +000063 "Copyright 2000 Bertho A. Stultiens\n"
64 ;
65
66/*
67 * The output byte-order of resources (set with -B)
68 */
69int byteorder = WMC_BO_NATIVE;
70
71/*
72 * Custom bit (bit 29) in output values must be set (-c option)
73 */
74int custombit = 0;
75
76/*
77 * Output decimal values (-d option)
78 */
79int decimal = 0;
80
81/*
82 * Enable pedantic warnings; check arg references (-W option)
83 */
84int pedantic = 0;
85
86/*
87 * Unicode input (-u option)
88 */
89int unicodein = 0;
90
91/*
92 * Unicode output (-U option)
93 */
94int unicodeout = 0;
95
96/*
97 * Inline the messagetables (don't write *.bin files; -i option)
98 */
99int rcinline = 0;
100
101/*
102 * Debugging flag (-D option)
103 */
104int dodebug = 0;
105
106char *output_name = NULL; /* The name given by the -o option */
107char *input_name = NULL; /* The name given on the command-line */
108char *header_name = NULL; /* The name given by the -H option */
109
110int line_number = 1; /* The current line */
111int char_number = 1; /* The current char pos within the line */
112
113char *cmdline; /* The entire commandline */
114time_t now; /* The time of start of wmc */
115
116int getopt (int argc, char *const *argv, const char *optstring);
117static void segvhandler(int sig);
118
Alexandre Julliard22aad632006-05-27 13:23:24 +0200119static void cleanup_files(void)
120{
121 if (output_name) unlink( output_name );
122 if (header_name) unlink( header_name );
123}
124
125static void exit_on_signal( int sig )
126{
127 exit(1); /* this will call the atexit functions */
128}
129
Bertho Stultiens30855912000-06-13 04:34:41 +0000130int main(int argc,char *argv[])
131{
132 extern char* optarg;
133 extern int optind;
134 int optc;
135 int lose = 0;
136 int ret;
137 int i;
138 int cmdlen;
139
Alexandre Julliard22aad632006-05-27 13:23:24 +0200140 atexit( cleanup_files );
Bertho Stultiens30855912000-06-13 04:34:41 +0000141 signal(SIGSEGV, segvhandler);
Alexandre Julliard22aad632006-05-27 13:23:24 +0200142 signal( SIGTERM, exit_on_signal );
143 signal( SIGINT, exit_on_signal );
144#ifdef SIGHUP
145 signal( SIGHUP, exit_on_signal );
146#endif
Bertho Stultiens30855912000-06-13 04:34:41 +0000147
148 now = time(NULL);
149
150 /* First rebuild the commandline to put in destination */
151 /* Could be done through env[], but not all OS-es support it */
152 cmdlen = 4; /* for "wmc " */
153 for(i = 1; i < argc; i++)
154 cmdlen += strlen(argv[i]) + 1;
Alexandre Julliard1916cb12006-08-26 21:35:32 +0200155 cmdline = xmalloc(cmdlen);
Bertho Stultiens30855912000-06-13 04:34:41 +0000156 strcpy(cmdline, "wmc ");
157 for(i = 1; i < argc; i++)
158 {
159 strcat(cmdline, argv[i]);
160 if(i < argc-1)
161 strcat(cmdline, " ");
162 }
163
164 while((optc = getopt(argc, argv, "B:cdDhH:io:p:uUvVW")) != EOF)
165 {
166 switch(optc)
167 {
168 case 'B':
169 switch(optarg[0])
170 {
171 case 'n':
172 case 'N':
173 byteorder = WMC_BO_NATIVE;
174 break;
175 case 'l':
176 case 'L':
177 byteorder = WMC_BO_LITTLE;
178 break;
179 case 'b':
180 case 'B':
181 byteorder = WMC_BO_BIG;
182 break;
183 default:
184 fprintf(stderr, "Byteordering must be n[ative], l[ittle] or b[ig]\n");
185 lose++;
186 }
187 break;
188 case 'c':
189 custombit = 1;
190 break;
191 case 'd':
192 decimal = 1;
193 break;
194 case 'D':
195 dodebug = 1;
196 break;
197 case 'h':
198 printf("%s", usage);
199 exit(0);
200 /* No return */
201 case 'H':
202 header_name = xstrdup(optarg);
203 break;
204 case 'i':
205 rcinline = 1;
206 break;
207 case 'o':
208 output_name = xstrdup(optarg);
209 break;
210 case 'u':
211 unicodein = 1;
212 break;
213 case 'U':
214 unicodeout = 1;
215 break;
216 case 'v':
217 show_languages();
218 show_codepages();
219 exit(0);
220 /* No return */
221 case 'V':
222 printf(version_string);
223 exit(0);
224 /* No return */
225 case 'W':
226 pedantic = 1;
227 break;
228 default:
229 lose++;
230 break;
231 }
232 }
233
234 if(lose)
235 {
236 fprintf(stderr, "%s", usage);
237 return 1;
238 }
239
240 yydebug = dodebug;
241 if(dodebug)
242 {
243 setbuf(stdout, 0);
244 setbuf(stderr, 0);
245 }
246
247 /* Check for input file on command-line */
248 if(optind < argc)
249 {
250 input_name = argv[optind];
251 }
252
253 /* Generate appropriate outfile names */
254 if(!output_name)
255 {
256 output_name = dup_basename(input_name, ".mc");
257 strcat(output_name, ".rc");
258 }
259
260 if(!header_name)
261 {
262 header_name = dup_basename(input_name, ".mc");
263 strcat(header_name, ".h");
264 }
265
266 if(input_name)
267 {
268 if(!(yyin = fopen(input_name, "rb")))
269 error("Could not open %s for input\n", input_name);
270 }
271 else
272 yyin = stdin;
273
274 ret = yyparse();
275
276 if(input_name)
277 fclose(yyin);
278
279 if(ret)
280 {
281 /* Error during parse */
282 exit(1);
283 }
284
285 write_h_file(header_name);
286 write_rc_file(output_name);
287 if(!rcinline)
288 write_bin_files();
Alexandre Julliard22aad632006-05-27 13:23:24 +0200289 output_name = NULL;
290 header_name = NULL;
Bertho Stultiens30855912000-06-13 04:34:41 +0000291 return 0;
292}
293
294static void segvhandler(int sig)
295{
296 fprintf(stderr, "\n%s:%d: Oops, segment violation\n", input_name, line_number);
297 fflush(stdout);
298 fflush(stderr);
299 abort();
300}