Added mappings for a few messages.
[wine] / tools / winebuild / main.c
1 /*
2  * Main function
3  *
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  */
10
11 #include <assert.h>
12 #include <stdio.h>
13 #include <unistd.h>
14 #include <errno.h>
15 #include <string.h>
16
17 #include "config.h"
18 #include "winnt.h"
19 #include "build.h"
20
21 ORDDEF *EntryPoints[MAX_ORDINALS];
22 ORDDEF *Ordinals[MAX_ORDINALS];
23 ORDDEF *Names[MAX_ORDINALS];
24
25 SPEC_MODE SpecMode = SPEC_MODE_DLL;
26 int Base = MAX_ORDINALS;
27 int Limit = 0;
28 int DLLHeapSize = 0;
29 int UsePIC = 0;
30 int stack_size = 0;
31 int nb_entry_points = 0;
32 int nb_names = 0;
33 int nb_debug_channels = 0;
34 int nb_lib_paths = 0;
35
36 /* we only support relay debugging on i386 */
37 #if defined(__i386__) && !defined(NO_TRACE_MSGS)
38 int debugging = 1;
39 #else
40 int debugging = 0;
41 #endif
42
43 char DLLName[80];
44 char DLLFileName[80];
45 char owner_name[80];
46 char *init_func = NULL;
47 char **debug_channels = NULL;
48 char **lib_path = NULL;
49
50 const char *input_file_name;
51 const char *output_file_name;
52
53 static FILE *input_file;
54 static FILE *output_file;
55
56 /* execution mode */
57 static enum { MODE_NONE, MODE_SPEC, MODE_GLUE, MODE_RELAY } exec_mode = MODE_NONE;
58
59 /* open the input file */
60 static void open_input( const char *name )
61 {
62     input_file_name = name;
63     if (!(input_file = fopen( name, "r" )))
64     {
65         fprintf( stderr, "Cannot open input file '%s'\n", name );
66         exit(1);
67     }
68 }
69
70 /* cleanup on program exit */
71 static void cleanup(void)
72 {
73     if (output_file_name) unlink( output_file_name );
74 }
75
76
77 /*******************************************************************
78  *         command-line option handling
79  */
80
81 struct option_descr
82 {
83     const char *name;
84     int         has_arg;
85     void      (*func)();
86     const char *usage;
87 };
88
89 static void do_pic(void);
90 static void do_output( const char *arg );
91 static void do_usage(void);
92 static void do_spec( const char *arg );
93 static void do_glue( const char *arg );
94 static void do_relay(void);
95 static void do_sym( const char *arg );
96 static void do_lib( const char *arg );
97
98 static const struct option_descr option_table[] =
99 {
100     { "-fPIC",  0, do_pic,    "-fPIC            Generate PIC code" },
101     { "-h",     0, do_usage,  "-h               Display this help message" },
102     { "-L",     1, do_lib,    "-L directory     Look for imports libraries in 'directory'" },
103     { "-o",     1, do_output, "-o name          Set the output file name (default: stdout)" },
104     { "-sym",   1, do_sym,    "-sym file.o      Read the list of undefined symbols from 'file.o'" },
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,     0, NULL,      NULL }
109 };
110
111 static void do_pic(void)
112 {
113     UsePIC = 1;
114 }
115
116 static void do_output( const char *arg )
117 {
118     if ( ( unlink ( arg ) ) == -1 && ( errno != ENOENT ) ) 
119     {
120         fprintf ( stderr, "Unable to create output file '%s'\n", arg );
121         exit (1);
122     }
123     if (!(output_file = fopen( arg, "w" )))
124     {
125         fprintf( stderr, "Unable to create output file '%s'\n", arg );
126         exit(1);
127     }
128     output_file_name = arg;
129     atexit( cleanup );  /* make sure we remove the output file on exit */
130 }
131
132 static void do_usage(void)
133 {
134     const struct option_descr *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);
140 }
141
142 static void do_spec( const char *arg )
143 {
144     if (exec_mode != MODE_NONE || !arg[0]) do_usage();
145     exec_mode = MODE_SPEC;
146     open_input( arg );
147 }
148
149 static void do_glue( const char *arg )
150 {
151     if (exec_mode != MODE_NONE || !arg[0]) do_usage();
152     exec_mode = MODE_GLUE;
153     open_input( arg );
154 }
155
156 static void do_relay(void)
157 {
158     if (exec_mode != MODE_NONE) do_usage();
159     exec_mode = MODE_RELAY;
160 }
161
162 static void do_sym( const char *arg )
163 {
164     extern void read_undef_symbols( const char *name );
165     read_undef_symbols( arg );
166 }
167
168 static void do_lib( const char *arg )
169 {
170     lib_path = xrealloc( lib_path, (nb_lib_paths+1) * sizeof(*lib_path) );
171     lib_path[nb_lib_paths++] = xstrdup( arg );
172 }
173
174 /* parse options from the argv array and remove all the recognized ones */
175 static void parse_options( char *argv[] )
176 {
177     const struct option_descr *opt;
178     char * const * ptr;
179     const char* arg=NULL;
180
181     ptr=argv+1;
182     while (*ptr != NULL)
183     {
184         for (opt = option_table; opt->name; opt++)
185         {
186             if (opt->has_arg && !strncmp( *ptr, opt->name, strlen(opt->name) ))
187             {
188                 arg=*ptr+strlen(opt->name);
189                 if (*arg=='\0')
190                 {
191                     ptr++;
192                     arg=*ptr;
193                 }
194                 break;
195             }
196             if (!strcmp( *ptr, opt->name ))
197             {
198                 arg=NULL;
199                 break;
200             }
201         }
202
203         if (!opt->name)
204         {
205             fprintf( stderr, "Unrecognized option '%s'\n", *ptr );
206             do_usage();
207         }
208
209         if (opt->has_arg && arg!=NULL) opt->func( arg );
210         else opt->func( "" );
211         ptr++;
212     }
213 }
214
215
216 /*******************************************************************
217  *         main
218  */
219 int main(int argc, char **argv)
220 {
221     output_file = stdout;
222     parse_options( argv );
223
224     switch(exec_mode)
225     {
226     case MODE_SPEC:
227         switch (ParseTopLevel( input_file ))
228         {
229             case SPEC_WIN16:
230                 BuildSpec16File( output_file );
231                 break;
232             case SPEC_WIN32:
233                 BuildSpec32File( output_file );
234                 break;
235             default: assert(0);
236         }
237         break;
238     case MODE_GLUE:
239         BuildGlue( output_file, input_file );
240         break;
241     case MODE_RELAY:
242         BuildRelays( output_file );
243         break;
244     default:
245         do_usage();
246         break;
247     }
248     if (output_file_name)
249     {
250         fclose( output_file );
251         output_file_name = NULL;
252     }
253     return 0;
254 }