Added pow() forward.
[wine.git] / tools / wmc / wmc.c
blob2750209d47e5ab36e23e537d812c3bbfe16c182f
1 /*
2 * Wine Message Compiler main program
4 * Copyright 2000 Bertho A. Stultiens (BS)
6 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <signal.h>
12 #include "config.h"
14 #include "wmc.h"
15 #include "utils.h"
16 #include "lang.h"
17 #include "write.h"
19 static char usage[] =
20 "Usage: wmc [options...] [inputfile.mc]\n"
21 " -B x Set output byte-order x={n[ative], l[ittle], b[ig]}\n"
22 " (default is n[ative] which equals "
23 #ifdef WORDS_BIGENDIAN
24 "big"
25 #else
26 "little"
27 #endif
28 "-endian)\n"
29 " -c Set 'custom-bit' in values\n"
30 " -d Use decimal values in output\n"
31 " -D Set debug flag\n"
32 " -h This message\n"
33 " -H file Write headerfile to file (default is inputfile.h)\n"
34 " -i Inline messagetable(s)\n"
35 " -o file Output to file (default is inputfile.rc)\n"
36 " -u Inputfile is in unicode\n"
37 " -U Output unicode messagetable(s)\n"
38 " -v Show supported codepages and languages\n"
39 " -V Print version end exit\n"
40 " -W Enable pedantic warnings\n"
41 "Input is taken from stdin if no inputfile is specified.\n"
42 "Byteorder of unicode input is based upon the first couple of\n"
43 "bytes read, which should be 0x0000..0x00ff.\n"
46 static char version_string[] =
47 "Wine Message Compiler Version " WMC_FULLVERSION "\n"
48 "Copyright 2000 Bertho A. Stultiens\n"
52 * The output byte-order of resources (set with -B)
54 int byteorder = WMC_BO_NATIVE;
57 * Custom bit (bit 29) in output values must be set (-c option)
59 int custombit = 0;
62 * Output decimal values (-d option)
64 int decimal = 0;
67 * Enable pedantic warnings; check arg references (-W option)
69 int pedantic = 0;
72 * Unicode input (-u option)
74 int unicodein = 0;
77 * Unicode output (-U option)
79 int unicodeout = 0;
82 * Inline the messagetables (don't write *.bin files; -i option)
84 int rcinline = 0;
87 * Debugging flag (-D option)
89 int dodebug = 0;
91 char *output_name = NULL; /* The name given by the -o option */
92 char *input_name = NULL; /* The name given on the command-line */
93 char *header_name = NULL; /* The name given by the -H option */
95 int line_number = 1; /* The current line */
96 int char_number = 1; /* The current char pos within the line */
98 char *cmdline; /* The entire commandline */
99 time_t now; /* The time of start of wmc */
101 int getopt (int argc, char *const *argv, const char *optstring);
102 static void segvhandler(int sig);
104 int main(int argc,char *argv[])
106 extern char* optarg;
107 extern int optind;
108 int optc;
109 int lose = 0;
110 int ret;
111 int i;
112 int cmdlen;
114 signal(SIGSEGV, segvhandler);
116 now = time(NULL);
118 /* First rebuild the commandline to put in destination */
119 /* Could be done through env[], but not all OS-es support it */
120 cmdlen = 4; /* for "wmc " */
121 for(i = 1; i < argc; i++)
122 cmdlen += strlen(argv[i]) + 1;
123 cmdline = (char *)xmalloc(cmdlen);
124 strcpy(cmdline, "wmc ");
125 for(i = 1; i < argc; i++)
127 strcat(cmdline, argv[i]);
128 if(i < argc-1)
129 strcat(cmdline, " ");
132 while((optc = getopt(argc, argv, "B:cdDhH:io:p:uUvVW")) != EOF)
134 switch(optc)
136 case 'B':
137 switch(optarg[0])
139 case 'n':
140 case 'N':
141 byteorder = WMC_BO_NATIVE;
142 break;
143 case 'l':
144 case 'L':
145 byteorder = WMC_BO_LITTLE;
146 break;
147 case 'b':
148 case 'B':
149 byteorder = WMC_BO_BIG;
150 break;
151 default:
152 fprintf(stderr, "Byteordering must be n[ative], l[ittle] or b[ig]\n");
153 lose++;
155 break;
156 case 'c':
157 custombit = 1;
158 break;
159 case 'd':
160 decimal = 1;
161 break;
162 case 'D':
163 dodebug = 1;
164 break;
165 case 'h':
166 printf("%s", usage);
167 exit(0);
168 /* No return */
169 case 'H':
170 header_name = xstrdup(optarg);
171 break;
172 case 'i':
173 rcinline = 1;
174 break;
175 case 'o':
176 output_name = xstrdup(optarg);
177 break;
178 case 'u':
179 unicodein = 1;
180 break;
181 case 'U':
182 unicodeout = 1;
183 break;
184 case 'v':
185 show_languages();
186 show_codepages();
187 exit(0);
188 /* No return */
189 case 'V':
190 printf(version_string);
191 exit(0);
192 /* No return */
193 case 'W':
194 pedantic = 1;
195 break;
196 default:
197 lose++;
198 break;
202 if(lose)
204 fprintf(stderr, "%s", usage);
205 return 1;
208 yydebug = dodebug;
209 if(dodebug)
211 setbuf(stdout, 0);
212 setbuf(stderr, 0);
215 /* Check for input file on command-line */
216 if(optind < argc)
218 input_name = argv[optind];
221 /* Generate appropriate outfile names */
222 if(!output_name)
224 output_name = dup_basename(input_name, ".mc");
225 strcat(output_name, ".rc");
228 if(!header_name)
230 header_name = dup_basename(input_name, ".mc");
231 strcat(header_name, ".h");
234 if(input_name)
236 if(!(yyin = fopen(input_name, "rb")))
237 error("Could not open %s for input\n", input_name);
239 else
240 yyin = stdin;
242 ret = yyparse();
244 if(input_name)
245 fclose(yyin);
247 if(ret)
249 /* Error during parse */
250 exit(1);
253 write_h_file(header_name);
254 write_rc_file(output_name);
255 if(!rcinline)
256 write_bin_files();
258 return 0;
261 static void segvhandler(int sig)
263 fprintf(stderr, "\n%s:%d: Oops, segment violation\n", input_name, line_number);
264 fflush(stdout);
265 fflush(stderr);
266 abort();