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