Added spec generation tool specmaker.
[wine/hacks.git] / tools / specmaker / main.c
blob2b99e5d25f5c15bf914388d835449f05f13f73d2
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_code (void)
43 globals.do_code = 1;
47 static void do_trace (void)
49 globals.do_trace = 1;
50 globals.do_code = 1;
54 static void do_forward (const char *arg)
56 globals.forward_dll = arg;
57 globals.do_trace = 1;
58 globals.do_code = 1;
61 static void do_document (void)
63 globals.do_documentation = 1;
66 static void do_cdecl (void)
68 globals.do_cdecl = 1;
72 static void do_quiet (void)
74 globals.do_quiet = 1;
78 static void do_start (const char *arg)
80 globals.start_ordinal = atoi (arg);
81 if (!globals.start_ordinal)
82 fatal ("Invalid -s option (must be numeric)");
86 static void do_end (const char *arg)
88 globals.end_ordinal = atoi (arg);
89 if (!globals.end_ordinal)
90 fatal ("Invalid -e option (must be numeric)");
94 static void do_verbose (void)
96 globals.do_verbose = 1;
100 struct option
102 const char *name;
103 int has_arg;
104 void (*func) ();
105 const char *usage;
109 static const struct option option_table[] = {
110 {"-d", 1, do_input, "-d dll Use dll for input file (mandatory)"},
111 {"-h", 0, do_usage, "-h Display this help message"},
112 {"-I", 1, do_include, "-I dir Look for prototypes in 'dir' (implies -c)"},
113 {"-o", 1, do_name, "-o name Set the output dll name (default: dll)"},
114 {"-c", 0, do_code, "-c Generate skeleton code (requires -I)"},
115 {"-t", 0, do_trace, "-t TRACE arguments (implies -c)"},
116 {"-f", 1, do_forward, "-f dll Forward calls to 'dll' (implies -t)"},
117 {"-D", 0, do_document, "-D Generate documentation"},
118 {"-C", 0, do_cdecl, "-C Assume __cdecl calls (default: __stdcall)"},
119 {"-s", 1, do_start, "-s num Start prototype search after symbol 'num'"},
120 {"-e", 1, do_end, "-e num End prototype search after symbol 'num'"},
121 {"-q", 0, do_quiet, "-q Don't show progress (quiet)."},
122 {"-v", 0, do_verbose, "-v Show lots of detail while working (verbose)."},
123 {NULL, 0, NULL, NULL}
127 void do_usage (void)
129 const struct option *opt;
130 printf ("Usage: specmaker [options] -d dll\n\nOptions:\n");
131 for (opt = option_table; opt->name; opt++)
132 printf (" %s\n", opt->usage);
133 puts ("\n");
134 exit (1);
138 /*******************************************************************
139 * parse_options
141 * Parse options from the argv array
143 static void parse_options (char *argv[])
145 const struct option *opt;
146 char *const *ptr;
147 const char *arg = NULL;
149 ptr = argv + 1;
151 while (*ptr != NULL)
153 for (opt = option_table; opt->name; opt++)
155 if (opt->has_arg && !strncmp (*ptr, opt->name, strlen (opt->name)))
157 arg = *ptr + strlen (opt->name);
158 if (*arg == '\0')
160 ptr++;
161 arg = *ptr;
163 break;
165 if (!strcmp (*ptr, opt->name))
167 arg = NULL;
168 break;
172 if (!opt->name)
173 fatal ("Unrecognized option");
175 if (opt->has_arg && arg != NULL)
176 opt->func (arg);
177 else
178 opt->func ("");
180 ptr++;
183 if (globals.do_code && !globals.directory)
184 fatal ("-I must be used if generating code");
186 if (!globals.input_name)
187 fatal ("Option -d is mandatory");
189 if (VERBOSE && QUIET)
190 fatal ("Options -v and -q are mutually exclusive");
194 /*******************************************************************
195 * main
197 #ifdef __GNUC__
198 int main (int argc __attribute__((unused)), char *argv[])
199 #else
200 int main (int argc, char *argv[])
201 #endif
203 parsed_symbol symbol;
204 int count = 0;
206 parse_options (argv);
208 dll_open (globals.input_name);
210 output_spec_preamble ();
211 output_header_preamble ();
212 output_c_preamble ();
214 memset (&symbol, 0, sizeof (parsed_symbol));
216 while ((symbol.symbol = dll_next_symbol ()))
218 count++;
220 if (NORMAL)
221 printf ("Export %3d - '%s' ...%c", count, symbol.symbol,
222 VERBOSE ? '\n' : ' ');
224 if (globals.do_code && count >= globals.start_ordinal
225 && (!globals.end_ordinal || count <= globals.end_ordinal))
227 /* Attempt to get information about the symbol */
228 int result = symbol_demangle (&symbol);
230 if (result)
231 result = symbol_search (&symbol);
233 if (!result)
234 /* Clean up the prototype */
235 symbol_clean_string (symbol.function_name);
237 if (NORMAL)
238 puts (result ? "[Not Found]" : "[OK]");
240 else if (NORMAL)
241 puts ("[Ignoring]");
243 output_spec_symbol (&symbol);
244 output_header_symbol (&symbol);
245 output_c_symbol (&symbol);
247 symbol_clear (&symbol);
250 output_makefile ();
251 output_install_script ();
253 if (VERBOSE)
254 puts ("Finished, Cleaning up...");
256 return 0;