(Merged by Marcus Meissner <marcus@jet.franken.de>)
[wine/testsucceed.git] / tools / winebuild / main.c
blob1cb5776287f53ca73e7b3e36c6fc6d9ec5e465c0
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
9 */
11 #include <assert.h>
12 #include <stdio.h>
13 #include <unistd.h>
14 #include <errno.h>
16 #include "winnt.h"
17 #include "build.h"
19 #ifdef __i386__
20 extern WORD __get_cs(void);
21 extern WORD __get_ds(void);
22 __ASM_GLOBAL_FUNC( __get_cs, "movw %cs,%ax\n\tret" );
23 __ASM_GLOBAL_FUNC( __get_ds, "movw %ds,%ax\n\tret" );
24 #else
25 static inline WORD __get_cs(void) { return 0; }
26 static inline WORD __get_ds(void) { return 0; }
27 #endif
30 ORDDEF EntryPoints[MAX_ORDINALS];
31 ORDDEF *Ordinals[MAX_ORDINALS];
32 ORDDEF *Names[MAX_ORDINALS];
34 SPEC_MODE SpecMode = SPEC_MODE_DLL;
35 int Base = MAX_ORDINALS;
36 int Limit = 0;
37 int DLLHeapSize = 0;
38 int UsePIC = 0;
39 int nb_entry_points = 0;
40 int nb_names = 0;
41 int nb_imports = 0;
42 int debugging = 1;
44 char DLLName[80];
45 char DLLFileName[80];
46 char DLLInitFunc[80];
47 char *DLLImports[MAX_IMPORTS];
48 char rsrc_name[80];
49 char owner_name[80];
51 const char *input_file_name;
52 const char *output_file_name;
54 unsigned short code_selector;
55 unsigned short data_selector;
57 static FILE *input_file;
58 static FILE *output_file;
60 /* execution mode */
61 static enum { MODE_NONE, MODE_SPEC, MODE_GLUE, MODE_RELAY } exec_mode = MODE_NONE;
63 /* open the input file */
64 static void open_input( const char *name )
66 input_file_name = name;
67 if (!(input_file = fopen( name, "r" )))
69 fprintf( stderr, "Cannot open input file '%s'\n", name );
70 exit(1);
74 /* cleanup on program exit */
75 static void cleanup(void)
77 if (output_file_name) unlink( output_file_name );
81 /*******************************************************************
82 * command-line option handling
85 struct option
87 const char *name;
88 int has_arg;
89 void (*func)();
90 const char *usage;
93 static void do_pic(void);
94 static void do_output( const char *arg );
95 static void do_usage(void);
96 static void do_spec( const char *arg );
97 static void do_glue( const char *arg );
98 static void do_relay(void);
100 static const struct option option_table[] =
102 { "-fPIC", 0, do_pic, "-fPIC Generate PIC code" },
103 { "-h", 0, do_usage, "-h Display this help message" },
104 { "-o", 1, do_output, "-o name Set the output file name (default: stdout)" },
105 { "-spec", 1, do_spec, "-spec file.spec Build a .c file from a spec file" },
106 { "-glue", 1, do_glue, "-glue file.c Build the 16-bit glue for a .c file" },
107 { "-relay", 0, do_relay, "-relay Build the relay assembly routines" },
108 { NULL }
111 static void do_pic(void)
113 UsePIC = 1;
116 static void do_output( const char *arg )
118 if ( ( unlink ( arg ) ) == -1 && ( errno != ENOENT ) )
120 fprintf ( stderr, "Unable to create output file '%s'\n", arg );
121 exit (1);
123 if (!(output_file = fopen( arg, "w" )))
125 fprintf( stderr, "Unable to create output file '%s'\n", arg );
126 exit(1);
128 output_file_name = arg;
129 atexit( cleanup ); /* make sure we remove the output file on exit */
132 static void do_usage(void)
134 const struct option *opt;
135 fprintf( stderr, "Usage: winebuild [options]\n\n" );
136 fprintf( stderr, "Options:\n" );
137 for (opt = option_table; opt->name; opt++) fprintf( stderr, " %s\n", opt->usage );
138 fprintf( stderr, "\nExactly one of -spec, -glue or -relay must be specified.\n\n" );
139 exit(1);
142 static void do_spec( const char *arg )
144 if (exec_mode != MODE_NONE || !arg[0]) do_usage();
145 exec_mode = MODE_SPEC;
146 open_input( arg );
149 static void do_glue( const char *arg )
151 if (exec_mode != MODE_NONE || !arg[0]) do_usage();
152 exec_mode = MODE_GLUE;
153 open_input( arg );
156 static void do_relay(void)
158 if (exec_mode != MODE_NONE) do_usage();
159 exec_mode = MODE_RELAY;
163 /* parse options from the argv array and remove all the recognized ones */
164 static void parse_options( char *argv[] )
166 const struct option *opt;
167 int i;
169 for (i = 1; argv[i]; i++)
171 for (opt = option_table; opt->name; opt++)
172 if (!strcmp( argv[i], opt->name )) break;
174 if (!opt->name)
176 fprintf( stderr, "Unrecognized option '%s'\n", argv[i] );
177 do_usage();
180 if (opt->has_arg && argv[i+1]) opt->func( argv[++i] );
181 else opt->func( "" );
186 /*******************************************************************
187 * main
189 int main(int argc, char **argv)
191 output_file = stdout;
192 parse_options( argv );
194 /* Retrieve the selector values; this assumes that we are building
195 * the asm files on the platform that will also run them. Probably
196 * a safe assumption to make.
198 code_selector = __get_cs();
199 data_selector = __get_ds();
201 switch(exec_mode)
203 case MODE_SPEC:
204 switch (ParseTopLevel( input_file ))
206 case SPEC_WIN16:
207 BuildSpec16File( output_file );
208 break;
209 case SPEC_WIN32:
210 BuildSpec32File( output_file );
211 break;
212 default: assert(0);
214 break;
215 case MODE_GLUE:
216 BuildGlue( output_file, input_file );
217 break;
218 case MODE_RELAY:
219 BuildRelays( output_file );
220 break;
221 default:
222 do_usage();
223 break;
225 fclose( output_file );
226 output_file_name = NULL;
227 return 0;