Added ctype.h.
[wine.git] / tools / winebuild / main.c
blobfa890ce528d81089719dab7c4cc25846808d68f1
1 /*
2 * Main function
4 * Copyright 1993 Robert J. Amstadt
5 * Copyright 1995 Martin von Loewis
6 * Copyright 1995, 1996, 1997 Alexandre Julliard
7 * Copyright 1997 Eric Youngdale
8 * Copyright 1999 Ulrich Weigand
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 #include "config.h"
26 #include "wine/port.h"
28 #include <assert.h>
29 #include <stdio.h>
30 #include <errno.h>
31 #include <string.h>
32 #include <ctype.h>
34 #include "build.h"
36 ORDDEF *EntryPoints[MAX_ORDINALS];
37 ORDDEF *Ordinals[MAX_ORDINALS];
38 ORDDEF *Names[MAX_ORDINALS];
40 SPEC_MODE SpecMode = SPEC_MODE_DLL;
41 int Base = MAX_ORDINALS;
42 int Limit = 0;
43 int DLLHeapSize = 0;
44 int UsePIC = 0;
45 int stack_size = 0;
46 int nb_entry_points = 0;
47 int nb_names = 0;
48 int nb_debug_channels = 0;
49 int nb_lib_paths = 0;
50 int display_warnings = 0;
52 /* we only support relay debugging on i386 */
53 #if defined(__i386__) && !defined(NO_TRACE_MSGS)
54 int debugging = 1;
55 #else
56 int debugging = 0;
57 #endif
59 char DLLName[80];
60 char DLLFileName[80];
61 char owner_name[80];
62 char *init_func = NULL;
63 char **debug_channels = NULL;
64 char **lib_path = NULL;
66 char *input_file_name = NULL;
67 const char *output_file_name = NULL;
69 static FILE *input_file;
70 static FILE *output_file;
71 static const char *current_src_dir;
73 /* execution mode */
74 static enum
76 MODE_NONE,
77 MODE_SPEC,
78 MODE_EXE,
79 MODE_GLUE,
80 MODE_DEF,
81 MODE_DEBUG,
82 MODE_RELAY16,
83 MODE_RELAY32
84 } exec_mode = MODE_NONE;
86 /* set the dll file name from the input file name */
87 static void set_dll_file_name( const char *name )
89 char *p;
91 if ((p = strrchr( name, '\\' ))) name = p + 1;
92 if ((p = strrchr( name, '/' ))) name = p + 1;
93 strcpy( DLLFileName, name );
94 if ((p = strrchr( DLLFileName, '.' )) && !strcmp( p, ".spec" )) *p = 0;
95 if (!strchr( DLLFileName, '.' )) strcat( DLLFileName, ".dll" );
98 /* cleanup on program exit */
99 static void cleanup(void)
101 if (output_file_name) unlink( output_file_name );
105 /*******************************************************************
106 * command-line option handling
109 struct option_descr
111 const char *name;
112 int has_arg;
113 void (*func)();
114 const char *usage;
117 static void do_output( const char *arg );
118 static void do_usage(void);
119 static void do_warnings(void);
120 static void do_f_flags( const char *arg );
121 static void do_define( const char *arg );
122 static void do_include( const char *arg );
123 static void do_k_flags( const char *arg );
124 static void do_exe_mode( const char *arg );
125 static void do_module( const char *arg );
126 static void do_heap( const char *arg );
127 static void do_name( const char *arg );
128 static void do_spec( const char *arg );
129 static void do_def( const char *arg );
130 static void do_exe( const char *arg );
131 static void do_glue(void);
132 static void do_relay16(void);
133 static void do_relay32(void);
134 static void do_debug(void);
135 static void do_sym(void);
136 static void do_chdir( const char *arg );
137 static void do_lib( const char *arg );
138 static void do_import( const char *arg );
139 static void do_dimport( const char *arg );
140 static void do_rsrc( const char *arg );
142 static const struct option_descr option_table[] =
144 { "-h", 0, do_usage, "-h Display this help message" },
145 { "-w", 0, do_warnings,"-w Turn on warnings" },
146 { "-C", 1, do_chdir, "-C dir Change directory to <dir> before opening source files" },
147 { "-f", 1, do_f_flags, "-f flags Compiler flags (only -fPIC is supported)" },
148 { "-D", 1, do_define, "-D sym Ignored for C flags compatibility" },
149 { "-I", 1, do_include, "-I dir Ignored for C flags compatibility" },
150 { "-K", 1, do_k_flags, "-K flags Compiler flags (only -KPIC is supported)" },
151 { "-m", 1, do_exe_mode,"-m mode Set the executable mode (cui|gui|cuiw|guiw)" },
152 { "-M", 1, do_module, "-M module Set the name of the main (Win32) module for a Win16 dll" },
153 { "-L", 1, do_lib, "-L directory Look for imports libraries in 'directory'" },
154 { "-l", 1, do_import, "-l lib.dll Import the specified library" },
155 { "-dl", 1, do_dimport, "-dl lib.dll Delay-import the specified library" },
156 { "-H", 1, do_heap, "-H size Set the heap size for a Win16 dll" },
157 { "-N", 1, do_name, "-N dllname Set the DLL name (default: set from input file name)" },
158 { "-res", 1, do_rsrc, "-res rsrc.res Load resources from rsrc.res" },
159 { "-o", 1, do_output, "-o name Set the output file name (default: stdout)\n" },
160 { "-sym", 0, do_sym, NULL }, /* ignored for backwards compatibility */
161 { "-spec", 1, do_spec, "-spec file.spec Build a .c file from a spec file" },
162 { "-def", 1, do_def, "-def file.spec Build a .def file from a spec file" },
163 { "-exe", 1, do_exe, "-exe name Build a .c file for the named executable" },
164 { "-debug", 0, do_debug, "-debug [files] Build a .c file containing debug channels declarations" },
165 { "-glue", 0, do_glue, "-glue [files] Build the 16-bit glue for the source files" },
166 { "-relay16", 0, do_relay16, "-relay16 Build the 16-bit relay assembly routines" },
167 { "-relay32", 0, do_relay32, "-relay32 Build the 32-bit relay assembly routines" },
168 { NULL, 0, NULL, NULL }
171 static void do_output( const char *arg )
173 if ( ( unlink ( arg ) ) == -1 && ( errno != ENOENT ) )
175 fprintf ( stderr, "Unable to create output file '%s'\n", arg );
176 exit (1);
178 if (!(output_file = fopen( arg, "w" )))
180 fprintf( stderr, "Unable to create output file '%s'\n", arg );
181 exit(1);
183 output_file_name = arg;
184 atexit( cleanup ); /* make sure we remove the output file on exit */
187 static void do_usage(void)
189 const struct option_descr *opt;
190 fprintf( stderr, "Usage: winebuild [options]\n\n" );
191 fprintf( stderr, "Options:\n" );
192 for (opt = option_table; opt->name; opt++)
193 if (opt->usage) fprintf( stderr, " %s\n", opt->usage );
195 fprintf( stderr, "\nExactly one of -spec, -def, -exe, -debug, -glue, -relay16 or -relay32 must be specified.\n\n" );
196 exit(1);
199 static void do_warnings(void)
201 display_warnings = 1;
204 static void do_f_flags( const char *arg )
206 if (!strcmp( arg, "PIC" )) UsePIC = 1;
207 /* ignore all other flags */
210 static void do_define( const char *arg )
212 /* nothing */
215 static void do_include( const char *arg )
217 /* nothing */
220 static void do_k_flags( const char *arg )
222 /* Ignored, because cc generates correct code. */
223 /* if (!strcmp( arg, "PIC" )) UsePIC = 1; */
224 /* ignore all other flags */
227 static void do_heap( const char *arg )
229 if (!isdigit(arg[0]))
230 fatal_error( "Expected number argument with -H option instead of '%s'\n", arg );
231 DLLHeapSize = atoi(arg);
232 if (DLLHeapSize > 65535) fatal_error( "Invalid heap size %d, maximum is 65535\n", DLLHeapSize );
235 static void do_name( const char *arg )
237 strncpy( DLLName, arg, sizeof(DLLName) );
238 DLLName[sizeof(DLLName) - 1] = 0;
241 static void do_spec( const char *arg )
243 if (exec_mode != MODE_NONE || !arg[0]) do_usage();
244 exec_mode = MODE_SPEC;
245 input_file = open_input_file( NULL, arg );
246 set_dll_file_name( arg );
249 static void do_def( const char *arg )
251 if (exec_mode != MODE_NONE || !arg[0]) do_usage();
252 exec_mode = MODE_DEF;
253 input_file = open_input_file( NULL, arg );
254 set_dll_file_name( arg );
257 static void do_exe( const char *arg )
259 const char *p;
261 if (exec_mode != MODE_NONE || !arg[0]) do_usage();
262 exec_mode = MODE_EXE;
263 if ((p = strrchr( arg, '/' ))) p++;
264 else p = arg;
265 strcpy( DLLFileName, p );
266 if (!strchr( DLLFileName, '.' )) strcat( DLLFileName, ".exe" );
267 if (SpecMode == SPEC_MODE_DLL) SpecMode = SPEC_MODE_GUIEXE;
270 static void do_exe_mode( const char *arg )
272 if (!strcmp( arg, "gui" )) SpecMode = SPEC_MODE_GUIEXE;
273 else if (!strcmp( arg, "cui" )) SpecMode = SPEC_MODE_CUIEXE;
274 else if (!strcmp( arg, "guiw" )) SpecMode = SPEC_MODE_GUIEXE_UNICODE;
275 else if (!strcmp( arg, "cuiw" )) SpecMode = SPEC_MODE_CUIEXE_UNICODE;
276 else do_usage();
279 static void do_module( const char *arg )
281 strcpy( owner_name, arg );
284 static void do_glue(void)
286 if (exec_mode != MODE_NONE) do_usage();
287 exec_mode = MODE_GLUE;
290 static void do_debug(void)
292 if (exec_mode != MODE_NONE) do_usage();
293 exec_mode = MODE_DEBUG;
296 static void do_chdir( const char *arg )
298 current_src_dir = arg;
301 static void do_relay16(void)
303 if (exec_mode != MODE_NONE) do_usage();
304 exec_mode = MODE_RELAY16;
307 static void do_relay32(void)
309 if (exec_mode != MODE_NONE) do_usage();
310 exec_mode = MODE_RELAY32;
313 static void do_sym(void)
315 /* nothing */
318 static void do_lib( const char *arg )
320 lib_path = xrealloc( lib_path, (nb_lib_paths+1) * sizeof(*lib_path) );
321 lib_path[nb_lib_paths++] = xstrdup( arg );
324 static void do_import( const char *arg )
326 add_import_dll( arg, 0 );
329 static void do_dimport( const char *arg )
331 add_import_dll( arg, 1 );
334 static void do_rsrc( const char *arg )
336 load_res32_file( arg );
339 /* parse options from the argv array and remove all the recognized ones */
340 static void parse_options( char *argv[] )
342 const struct option_descr *opt;
343 char **ptr, **last;
344 const char* arg=NULL;
346 for (ptr = last = argv + 1; *ptr; ptr++)
348 for (opt = option_table; opt->name; opt++)
350 if (opt->has_arg && !strncmp( *ptr, opt->name, strlen(opt->name) ))
352 arg=*ptr+strlen(opt->name);
353 if (*arg=='\0')
355 ptr++;
356 arg=*ptr;
358 break;
360 if (!strcmp( *ptr, opt->name ))
362 arg=NULL;
363 break;
367 if (opt->name)
369 if (opt->has_arg && arg != NULL) opt->func( arg );
370 else opt->func( "" );
372 else /* keep this argument */
374 if (last != ptr) *last = *ptr;
375 last++;
378 *last = NULL;
382 /*******************************************************************
383 * main
385 int main(int argc, char **argv)
387 output_file = stdout;
388 parse_options( argv );
390 switch(exec_mode)
392 case MODE_SPEC:
393 switch (ParseTopLevel( input_file, 0 ))
395 case SPEC_WIN16:
396 if (argv[1])
397 fatal_error( "file argument '%s' not allowed in this mode\n", argv[1] );
398 BuildSpec16File( output_file );
399 break;
400 case SPEC_WIN32:
401 read_undef_symbols( argv + 1 );
402 BuildSpec32File( output_file );
403 break;
404 default: assert(0);
406 break;
407 case MODE_EXE:
408 read_undef_symbols( argv + 1 );
409 BuildSpec32File( output_file );
410 break;
411 case MODE_DEF:
412 if (argv[1]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[1] );
413 switch (ParseTopLevel( input_file, 1 ))
415 case SPEC_WIN16:
416 fatal_error( "Cannot yet build .def file for 16-bit dlls\n" );
417 break;
418 case SPEC_WIN32:
419 BuildDef32File( output_file );
420 break;
421 default: assert(0);
423 break;
424 case MODE_DEBUG:
425 BuildDebugFile( output_file, current_src_dir, argv + 1 );
426 break;
427 case MODE_GLUE:
428 BuildGlue( output_file, current_src_dir, argv + 1 );
429 break;
430 case MODE_RELAY16:
431 if (argv[1]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[1] );
432 BuildRelays16( output_file );
433 break;
434 case MODE_RELAY32:
435 if (argv[1]) fatal_error( "file argument '%s' not allowed in this mode\n", argv[1] );
436 BuildRelays32( output_file );
437 break;
438 default:
439 do_usage();
440 break;
442 if (output_file_name)
444 fclose( output_file );
445 output_file_name = NULL;
447 return 0;