Release 1.1.14.
[wine/gsoc-2012-control.git] / tools / wmc / wmc.c
blob910a654b3c8666a1f790adccfaac6b91164bc4b4
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 " -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"
61 static const char version_string[] =
62 "Wine Message Compiler version " PACKAGE_VERSION "\n"
63 "Copyright 2000 Bertho A. Stultiens\n"
67 * The output byte-order of resources (set with -B)
69 int byteorder = WMC_BO_NATIVE;
72 * Custom bit (bit 29) in output values must be set (-c option)
74 int custombit = 0;
77 * Output decimal values (-d option)
79 int decimal = 0;
82 * Enable pedantic warnings; check arg references (-W option)
84 int pedantic = 0;
87 * Unicode input (-u option)
89 int unicodein = 0;
92 * Unicode output (-U option)
94 int unicodeout = 0;
97 * Inline the messagetables (don't write *.bin files; -i option)
99 int rcinline = 0;
102 * Debugging flag (-D option)
104 int dodebug = 0;
106 char *output_name = NULL; /* The name given by the -o option */
107 char *input_name = NULL; /* The name given on the command-line */
108 char *header_name = NULL; /* The name given by the -H option */
110 int line_number = 1; /* The current line */
111 int char_number = 1; /* The current char pos within the line */
113 char *cmdline; /* The entire commandline */
114 time_t now; /* The time of start of wmc */
116 int mcy_debug;
118 int getopt (int argc, char *const *argv, const char *optstring);
119 static void segvhandler(int sig);
121 static void cleanup_files(void)
123 if (output_name) unlink( output_name );
124 if (header_name) unlink( header_name );
127 static void exit_on_signal( int sig )
129 exit(1); /* this will call the atexit functions */
132 int main(int argc,char *argv[])
134 extern char* optarg;
135 extern int optind;
136 int optc;
137 int lose = 0;
138 int ret;
139 int i;
140 int cmdlen;
142 atexit( cleanup_files );
143 signal(SIGSEGV, segvhandler);
144 signal( SIGTERM, exit_on_signal );
145 signal( SIGINT, exit_on_signal );
146 #ifdef SIGHUP
147 signal( SIGHUP, exit_on_signal );
148 #endif
150 now = time(NULL);
152 /* First rebuild the commandline to put in destination */
153 /* Could be done through env[], but not all OS-es support it */
154 cmdlen = 4; /* for "wmc " */
155 for(i = 1; i < argc; i++)
156 cmdlen += strlen(argv[i]) + 1;
157 cmdline = xmalloc(cmdlen);
158 strcpy(cmdline, "wmc ");
159 for(i = 1; i < argc; i++)
161 strcat(cmdline, argv[i]);
162 if(i < argc-1)
163 strcat(cmdline, " ");
166 while((optc = getopt(argc, argv, "B:cdDhH:io:p:uUvVW")) != EOF)
168 switch(optc)
170 case 'B':
171 switch(optarg[0])
173 case 'n':
174 case 'N':
175 byteorder = WMC_BO_NATIVE;
176 break;
177 case 'l':
178 case 'L':
179 byteorder = WMC_BO_LITTLE;
180 break;
181 case 'b':
182 case 'B':
183 byteorder = WMC_BO_BIG;
184 break;
185 default:
186 fprintf(stderr, "Byteordering must be n[ative], l[ittle] or b[ig]\n");
187 lose++;
189 break;
190 case 'c':
191 custombit = 1;
192 break;
193 case 'd':
194 decimal = 1;
195 break;
196 case 'D':
197 dodebug = 1;
198 break;
199 case 'h':
200 printf("%s", usage);
201 exit(0);
202 /* No return */
203 case 'H':
204 header_name = xstrdup(optarg);
205 break;
206 case 'i':
207 rcinline = 1;
208 break;
209 case 'o':
210 output_name = xstrdup(optarg);
211 break;
212 case 'u':
213 unicodein = 1;
214 break;
215 case 'U':
216 unicodeout = 1;
217 break;
218 case 'v':
219 show_languages();
220 show_codepages();
221 exit(0);
222 /* No return */
223 case 'V':
224 printf(version_string);
225 exit(0);
226 /* No return */
227 case 'W':
228 pedantic = 1;
229 break;
230 default:
231 lose++;
232 break;
236 if(lose)
238 fprintf(stderr, "%s", usage);
239 return 1;
242 mcy_debug = dodebug;
243 if(dodebug)
245 setbuf(stdout, 0);
246 setbuf(stderr, 0);
249 /* Check for input file on command-line */
250 if(optind < argc)
252 input_name = argv[optind];
255 /* Generate appropriate outfile names */
256 if(!output_name)
258 output_name = dup_basename(input_name, ".mc");
259 strcat(output_name, ".rc");
262 if(!header_name)
264 header_name = dup_basename(input_name, ".mc");
265 strcat(header_name, ".h");
268 if(input_name)
270 if(!(yyin = fopen(input_name, "rb")))
271 error("Could not open %s for input\n", input_name);
273 else
274 yyin = stdin;
276 ret = mcy_parse();
278 if(input_name)
279 fclose(yyin);
281 if(ret)
283 /* Error during parse */
284 exit(1);
287 write_h_file(header_name);
288 write_rc_file(output_name);
289 if(!rcinline)
290 write_bin_files();
291 output_name = NULL;
292 header_name = NULL;
293 return 0;
296 static void segvhandler(int sig)
298 fprintf(stderr, "\n%s:%d: Oops, segment violation\n", input_name, line_number);
299 fflush(stdout);
300 fflush(stderr);
301 abort();