Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/tools/wmc/wmc.c
4389 views
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19
*/
20
21
#include "config.h"
22
23
#include <stdio.h>
24
#include <stdlib.h>
25
#include <string.h>
26
#include <limits.h>
27
#include <sys/types.h>
28
29
#include "wmc.h"
30
#include "utils.h"
31
#include "lang.h"
32
#include "write.h"
33
34
static const char usage[] =
35
"Usage: wmc [options...] [inputfile.mc]\n"
36
" -c Set 'custom-bit' in values\n"
37
" -d Use decimal values in output\n"
38
" -D Set debug flag\n"
39
" -h, --help Print this message\n"
40
" -H FILE Write header file to FILE (default is inputfile.h)\n"
41
" -i Inline messagetable(s)\n"
42
" --nls-dir=DIR Directory containing the NLS codepage mappings\n"
43
" -o, --output=FILE Output to FILE (default is infile.rc)\n"
44
" -O, --output-format=FORMAT The output format (`rc', `res', or `pot')\n"
45
" -P, --po-dir=DIR Directory containing po files for translations\n"
46
" -u Input file is in unicode\n"
47
" -U Output unicode messagetable(s)\n"
48
" -v Show supported codepages and languages\n"
49
" -V, --version Print version end exit\n"
50
" -W, --pedantic Enable pedantic warnings\n"
51
"Input is taken from stdin if no inputfile is specified.\n"
52
"Byteorder of unicode input is based upon the first couple of\n"
53
"bytes read, which should be 0x0000..0x00ff.\n"
54
;
55
56
static const char version_string[] =
57
"Wine Message Compiler version " PACKAGE_VERSION "\n"
58
"Copyright 2000 Bertho A. Stultiens\n"
59
;
60
61
/*
62
* Custom bit (bit 29) in output values must be set (-c option)
63
*/
64
int custombit = 0;
65
66
/*
67
* Output decimal values (-d option)
68
*/
69
int decimal = 0;
70
71
/*
72
* Enable pedantic warnings; check arg references (-W option)
73
*/
74
int pedantic = 0;
75
76
/*
77
* Unicode input (-u option)
78
*/
79
int unicodein = 0;
80
81
/*
82
* Inline the messagetables (don't write *.bin files; -i option)
83
*/
84
int rcinline = 0;
85
86
/*
87
* Debugging flag (-D option)
88
*/
89
static int dodebug = 0;
90
91
static char *po_dir;
92
93
char *output_name = NULL; /* The name given by the -o option */
94
const char *input_name = NULL; /* The name given on the command-line */
95
char *header_name = NULL; /* The name given by the -H option */
96
97
static const char *bindir;
98
const char *nlsdirs[3] = { NULL, DATADIR "/wine/nls", NULL };
99
100
int line_number = 1; /* The current line */
101
int char_number = 1; /* The current char pos within the line */
102
103
char *cmdline; /* The entire commandline */
104
time_t now; /* The time of start of wmc */
105
106
int mcy_debug;
107
108
FILE *yyin;
109
110
static enum
111
{
112
FORMAT_UNKNOWN,
113
FORMAT_RC,
114
FORMAT_RES,
115
FORMAT_POT
116
} output_format;
117
118
enum long_options_values
119
{
120
LONG_OPT_NLS_DIR = 1,
121
};
122
123
static const char short_options[] = "cdDhH:io:O:P:uUvVW";
124
static const struct long_option long_options[] =
125
{
126
{ "help", 0, 'h' },
127
{ "nls-dir", 1, LONG_OPT_NLS_DIR },
128
{ "output", 1, 'o' },
129
{ "output-format", 1, 'O' },
130
{ "pedantic", 0, 'W' },
131
{ "po-dir", 1, 'P' },
132
{ "version", 0, 'v' },
133
{ NULL }
134
};
135
136
static void cleanup_files(void)
137
{
138
if (output_name) unlink( output_name );
139
if (header_name) unlink( header_name );
140
}
141
142
static void exit_on_signal( int sig )
143
{
144
exit(1); /* this will call the atexit functions */
145
}
146
147
static void option_callback( int optc, char *optarg )
148
{
149
switch(optc)
150
{
151
case 'c':
152
custombit = 1;
153
break;
154
case 'd':
155
decimal = 1;
156
break;
157
case 'D':
158
dodebug = 1;
159
break;
160
case 'h':
161
printf("%s", usage);
162
exit(0);
163
/* No return */
164
case 'H':
165
header_name = xstrdup(optarg);
166
break;
167
case 'i':
168
rcinline = 1;
169
break;
170
case 'o':
171
output_name = xstrdup(optarg);
172
break;
173
case 'O':
174
if (!strcmp( optarg, "rc" )) output_format = FORMAT_RC;
175
else if (!strcmp( optarg, "res" )) output_format = FORMAT_RES;
176
else if (!strcmp( optarg, "pot" )) output_format = FORMAT_POT;
177
else error("Output format must be rc or res\n" );
178
break;
179
case 'P':
180
po_dir = xstrdup( optarg );
181
break;
182
case 'u':
183
unicodein = 1;
184
break;
185
case 'U': /* ignored for backwards compatibility */
186
break;
187
case 'v':
188
show_languages();
189
exit(0);
190
/* No return */
191
case 'V':
192
printf(version_string);
193
exit(0);
194
/* No return */
195
case 'W':
196
pedantic = 1;
197
break;
198
case LONG_OPT_NLS_DIR:
199
nlsdirs[0] = xstrdup( optarg );
200
break;
201
case '?':
202
fprintf(stderr, "wmc: %s\n\n%s", optarg, usage);
203
exit(1);
204
}
205
}
206
207
int main(int argc,char *argv[])
208
{
209
int ret;
210
int i;
211
int cmdlen;
212
struct strarray files;
213
214
atexit( cleanup_files );
215
init_signals( exit_on_signal );
216
bindir = get_bindir( argv[0] );
217
nlsdirs[0] = get_nlsdir( bindir, "/tools/wmc" );
218
219
/* First rebuild the commandline to put in destination */
220
/* Could be done through env[], but not all OS-es support it */
221
cmdlen = 5; /* for "wmc " and \0 */
222
for(i = 1; i < argc; i++)
223
cmdlen += strlen(argv[i]) + 1;
224
cmdline = xmalloc(cmdlen);
225
strcpy(cmdline, "wmc ");
226
for(i = 1; i < argc; i++)
227
{
228
strcat(cmdline, argv[i]);
229
if(i < argc-1)
230
strcat(cmdline, " ");
231
}
232
233
files = parse_options( argc, argv, short_options, long_options, 0, option_callback );
234
235
mcy_debug = dodebug;
236
if(dodebug)
237
{
238
setbuf(stdout, NULL);
239
setbuf(stderr, NULL);
240
}
241
242
/* Check for input file on command-line */
243
if (files.count) input_name = files.str[0];
244
245
/* Guess output format */
246
if (output_format == FORMAT_UNKNOWN)
247
{
248
if (output_name && strendswith( output_name, ".res" )) output_format = FORMAT_RES;
249
else if (output_name && strendswith( output_name, ".pot" )) output_format = FORMAT_POT;
250
else output_format = FORMAT_RC;
251
}
252
253
/* Generate appropriate outfile names */
254
if(!output_name)
255
{
256
const char *name = input_name ? get_basename(input_name) : "wmc.tab";
257
output_name = replace_extension( name, ".mc", ".rc" );
258
}
259
260
if(!header_name)
261
{
262
const char *name = input_name ? get_basename(input_name) : "wmc.tab";
263
header_name = replace_extension( name, ".mc", ".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 = mcy_parse();
275
276
if(input_name)
277
fclose(yyin);
278
279
if(ret)
280
{
281
/* Error during parse */
282
exit(1);
283
}
284
285
switch (output_format)
286
{
287
case FORMAT_RC:
288
write_h_file(header_name);
289
write_rc_file(output_name);
290
if(!rcinline)
291
write_bin_files();
292
break;
293
case FORMAT_RES:
294
add_translations( po_dir );
295
write_res_file( output_name );
296
break;
297
case FORMAT_POT:
298
write_pot_file( output_name );
299
break;
300
default:
301
break;
302
}
303
output_name = NULL;
304
header_name = NULL;
305
return 0;
306
}
307
308