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
28 #include <sys/types.h>
29 #ifdef HAVE_SYS_SYSCTL_H
30 # include <sys/sysctl.h>
38 static const char usage
[] =
39 "Usage: wmc [options...] [inputfile.mc]\n"
40 " -c Set 'custom-bit' in values\n"
41 " -d Use decimal values in output\n"
42 " -D Set debug flag\n"
43 " -h, --help Print this message\n"
44 " -H FILE Write header file to FILE (default is inputfile.h)\n"
45 " -i Inline messagetable(s)\n"
46 " --nls-dir=DIR Directory containing the NLS codepage mappings\n"
47 " -o, --output=FILE Output to FILE (default is infile.rc)\n"
48 " -O, --output-format=FORMAT The output format (`rc', `res', or `pot')\n"
49 " -P, --po-dir=DIR Directory containing po files for translations\n"
50 " -u Input file is in unicode\n"
51 " -U Output unicode messagetable(s)\n"
52 " -v Show supported codepages and languages\n"
53 " -V, --version Print version end exit\n"
54 " -W, --pedantic 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"
60 static const char version_string
[] =
61 "Wine Message Compiler version " PACKAGE_VERSION
"\n"
62 "Copyright 2000 Bertho A. Stultiens\n"
66 * Custom bit (bit 29) in output values must be set (-c option)
71 * Output decimal values (-d option)
76 * Enable pedantic warnings; check arg references (-W option)
81 * Unicode input (-u option)
86 * Inline the messagetables (don't write *.bin files; -i option)
91 * Debugging flag (-D option)
93 static int dodebug
= 0;
97 char *output_name
= NULL
; /* The name given by the -o option */
98 const char *input_name
= NULL
; /* The name given on the command-line */
99 char *header_name
= NULL
; /* The name given by the -H option */
101 const char *nlsdirs
[3] = { NULL
, NLSDIR
, NULL
};
103 int line_number
= 1; /* The current line */
104 int char_number
= 1; /* The current char pos within the line */
106 char *cmdline
; /* The entire commandline */
107 time_t now
; /* The time of start of wmc */
121 enum long_options_values
123 LONG_OPT_NLS_DIR
= 1,
126 static const char short_options
[] = "cdDhH:io:O:P:uUvVW";
127 static const struct long_option long_options
[] =
130 { "nls-dir", 1, LONG_OPT_NLS_DIR
},
131 { "output", 1, 'o' },
132 { "output-format", 1, 'O' },
133 { "pedantic", 0, 'W' },
134 { "po-dir", 1, 'P' },
135 { "version", 0, 'v' },
139 static void cleanup_files(void)
141 if (output_name
) unlink( output_name
);
142 if (header_name
) unlink( header_name
);
145 static void exit_on_signal( int sig
)
147 exit(1); /* this will call the atexit functions */
150 static void init_argv0_dir( const char *argv0
)
155 #if defined(__linux__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)
156 dir
= realpath( "/proc/self/exe", NULL
);
157 #elif defined (__FreeBSD__) || defined(__DragonFly__)
158 static int pathname
[] = { CTL_KERN
, KERN_PROC
, KERN_PROC_PATHNAME
, -1 };
159 size_t path_size
= PATH_MAX
;
160 char *path
= malloc( path_size
);
161 if (path
&& !sysctl( pathname
, sizeof(pathname
)/sizeof(pathname
[0]), path
, &path_size
, NULL
, 0 ))
162 dir
= realpath( path
, NULL
);
165 dir
= realpath( argv0
, NULL
);
168 dir
= get_dirname( dir
);
169 if (strendswith( dir
, "/tools/wmc" )) nlsdirs
[0] = strmake( "%s/../../nls", dir
);
170 else nlsdirs
[0] = strmake( "%s/%s", dir
, BIN_TO_NLSDIR
);
174 static void option_callback( int optc
, char *optarg
)
192 header_name
= xstrdup(optarg
);
198 output_name
= xstrdup(optarg
);
201 if (!strcmp( optarg
, "rc" )) output_format
= FORMAT_RC
;
202 else if (!strcmp( optarg
, "res" )) output_format
= FORMAT_RES
;
203 else if (!strcmp( optarg
, "pot" )) output_format
= FORMAT_POT
;
204 else error("Output format must be rc or res\n" );
207 po_dir
= xstrdup( optarg
);
212 case 'U': /* ignored for backwards compatibility */
219 printf(version_string
);
225 case LONG_OPT_NLS_DIR
:
226 nlsdirs
[0] = xstrdup( optarg
);
229 fprintf(stderr
, "wmc: %s\n\n%s", optarg
, usage
);
234 int main(int argc
,char *argv
[])
239 struct strarray files
;
241 atexit( cleanup_files
);
242 signal( SIGTERM
, exit_on_signal
);
243 signal( SIGINT
, exit_on_signal
);
245 signal( SIGHUP
, exit_on_signal
);
247 init_argv0_dir( argv
[0] );
249 /* First rebuild the commandline to put in destination */
250 /* Could be done through env[], but not all OS-es support it */
251 cmdlen
= 5; /* for "wmc " and \0 */
252 for(i
= 1; i
< argc
; i
++)
253 cmdlen
+= strlen(argv
[i
]) + 1;
254 cmdline
= xmalloc(cmdlen
);
255 strcpy(cmdline
, "wmc ");
256 for(i
= 1; i
< argc
; i
++)
258 strcat(cmdline
, argv
[i
]);
260 strcat(cmdline
, " ");
263 files
= parse_options( argc
, argv
, short_options
, long_options
, 0, option_callback
);
268 setbuf(stdout
, NULL
);
269 setbuf(stderr
, NULL
);
272 /* Check for input file on command-line */
273 if (files
.count
) input_name
= files
.str
[0];
275 /* Guess output format */
276 if (output_format
== FORMAT_UNKNOWN
)
278 if (output_name
&& strendswith( output_name
, ".res" )) output_format
= FORMAT_RES
;
279 else if (output_name
&& strendswith( output_name
, ".pot" )) output_format
= FORMAT_POT
;
280 else output_format
= FORMAT_RC
;
283 /* Generate appropriate outfile names */
286 const char *name
= input_name
? get_basename(input_name
) : "wmc.tab";
287 output_name
= replace_extension( name
, ".mc", ".rc" );
292 const char *name
= input_name
? get_basename(input_name
) : "wmc.tab";
293 header_name
= replace_extension( name
, ".mc", ".h" );
298 if(!(yyin
= fopen(input_name
, "rb")))
299 error("Could not open %s for input\n", input_name
);
311 /* Error during parse */
315 switch (output_format
)
318 write_h_file(header_name
);
319 write_rc_file(output_name
);
324 add_translations( po_dir
);
325 write_res_file( output_name
);
328 write_pot_file( output_name
);