- Create entries for ordinal only exports, use ordinals if non-standard.
[wine/hacks.git] / tools / specmaker / main.c
blob2f9edd2d6d086e29413ba88c08eaaed0935ead84
1 /*
2 * Option processing and main()
4 * Copyright 2000 Jon Griffiths
5 */
6 #include "specmaker.h"
9 _globals globals; /* All global variables */
12 static void do_include (const char *arg)
14 globals.directory = arg;
15 globals.do_code = 1;
19 static inline const char* strip_ext (const char *str)
21 char *ext = strstr(str, ".dll");
22 if (ext)
23 return str_substring (str, ext);
24 else
25 return strdup (str);
29 static void do_name (const char *arg)
31 globals.dll_name = strip_ext (arg);
35 static void do_input (const char *arg)
37 globals.input_name = strip_ext (arg);
41 static void do_demangle (const char *arg)
43 globals.do_demangle = 1;
44 globals.do_code = 1;
45 globals.input_name = arg;
49 static void do_code (void)
51 globals.do_code = 1;
55 static void do_trace (void)
57 globals.do_trace = 1;
58 globals.do_code = 1;
62 static void do_forward (const char *arg)
64 globals.forward_dll = arg;
65 globals.do_trace = 1;
66 globals.do_code = 1;
69 static void do_document (void)
71 globals.do_documentation = 1;
74 static void do_cdecl (void)
76 globals.do_cdecl = 1;
80 static void do_quiet (void)
82 globals.do_quiet = 1;
86 static void do_start (const char *arg)
88 globals.start_ordinal = atoi (arg);
89 if (!globals.start_ordinal)
90 fatal ("Invalid -s option (must be numeric)");
94 static void do_end (const char *arg)
96 globals.end_ordinal = atoi (arg);
97 if (!globals.end_ordinal)
98 fatal ("Invalid -e option (must be numeric)");
102 static void do_verbose (void)
104 globals.do_verbose = 1;
108 struct option
110 const char *name;
111 int has_arg;
112 void (*func) ();
113 const char *usage;
117 static const struct option option_table[] = {
118 {"-d", 1, do_input, "-d dll Use dll for input file (mandatory)"},
119 {"-S", 1, do_demangle, "-S sym Demangle C++ symbol 'sym' and exit"},
120 {"-h", 0, do_usage, "-h Display this help message"},
121 {"-I", 1, do_include, "-I dir Look for prototypes in 'dir' (implies -c)"},
122 {"-o", 1, do_name, "-o name Set the output dll name (default: dll)"},
123 {"-c", 0, do_code, "-c Generate skeleton code (requires -I)"},
124 {"-t", 0, do_trace, "-t TRACE arguments (implies -c)"},
125 {"-f", 1, do_forward, "-f dll Forward calls to 'dll' (implies -t)"},
126 {"-D", 0, do_document, "-D Generate documentation"},
127 {"-C", 0, do_cdecl, "-C Assume __cdecl calls (default: __stdcall)"},
128 {"-s", 1, do_start, "-s num Start prototype search after symbol 'num'"},
129 {"-e", 1, do_end, "-e num End prototype search after symbol 'num'"},
130 {"-q", 0, do_quiet, "-q Don't show progress (quiet)."},
131 {"-v", 0, do_verbose, "-v Show lots of detail while working (verbose)."},
132 {NULL, 0, NULL, NULL}
136 void do_usage (void)
138 const struct option *opt;
139 printf ("Usage: specmaker [options] [-d dll | -S sym]\n\nOptions:\n");
140 for (opt = option_table; opt->name; opt++)
141 printf (" %s\n", opt->usage);
142 puts ("\n");
143 exit (1);
147 /*******************************************************************
148 * parse_options
150 * Parse options from the argv array
152 static void parse_options (char *argv[])
154 const struct option *opt;
155 char *const *ptr;
156 const char *arg = NULL;
158 ptr = argv + 1;
160 while (*ptr != NULL)
162 for (opt = option_table; opt->name; opt++)
164 if (opt->has_arg && !strncmp (*ptr, opt->name, strlen (opt->name)))
166 arg = *ptr + strlen (opt->name);
167 if (*arg == '\0')
169 ptr++;
170 arg = *ptr;
172 break;
174 if (!strcmp (*ptr, opt->name))
176 arg = NULL;
177 break;
181 if (!opt->name)
182 fatal ("Unrecognized option");
184 if (opt->has_arg && arg != NULL)
185 opt->func (arg);
186 else
187 opt->func ("");
189 ptr++;
192 if (!globals.do_demangle && globals.do_code && !globals.directory)
193 fatal ("-I must be used if generating code");
195 if (!globals.input_name)
196 fatal ("Option -d is mandatory");
198 if (VERBOSE && QUIET)
199 fatal ("Options -v and -q are mutually exclusive");
203 /*******************************************************************
204 * main
206 #ifdef __GNUC__
207 int main (int argc __attribute__((unused)), char *argv[])
208 #else
209 int main (int argc, char *argv[])
210 #endif
212 parsed_symbol symbol;
213 int count = 0;
215 parse_options (argv);
217 memset (&symbol, 0, sizeof (parsed_symbol));
219 if (globals.do_demangle)
221 int result;
222 globals.uc_dll_name = "";
223 VERBOSE = 1;
224 symbol.symbol = strdup(globals.input_name);
225 result = symbol_demangle (&symbol);
226 if (symbol.flags & SYM_DATA)
227 printf (symbol.arg_text[0]);
228 else
229 output_prototype (stdout, &symbol);
230 fputc ('\n', stdout);
231 return result ? 1 : 0;
234 dll_open (globals.input_name);
236 output_spec_preamble ();
237 output_header_preamble ();
238 output_c_preamble ();
240 while (!dll_next_symbol (&symbol))
242 count++;
244 if (NORMAL)
245 printf ("Export %3d - '%s' ...%c", count, symbol.symbol,
246 VERBOSE ? '\n' : ' ');
248 if (globals.do_code && count >= globals.start_ordinal
249 && (!globals.end_ordinal || count <= globals.end_ordinal))
251 /* Attempt to get information about the symbol */
252 int result = symbol_demangle (&symbol);
254 if (result)
255 result = symbol_search (&symbol);
257 if (!result && symbol.function_name)
258 /* Clean up the prototype */
259 symbol_clean_string (symbol.function_name);
261 if (NORMAL)
262 puts (result ? "[Not Found]" : "[OK]");
264 else if (NORMAL)
265 puts ("[Ignoring]");
267 output_spec_symbol (&symbol);
268 output_header_symbol (&symbol);
269 output_c_symbol (&symbol);
271 symbol_clear (&symbol);
274 output_makefile ();
275 output_install_script ();
277 if (VERBOSE)
278 puts ("Finished, Cleaning up...");
280 return 0;