2 * Option processing and main()
4 * Copyright 2000 Jon Griffiths
9 _globals globals
; /* All global variables */
12 static void do_include (const char *arg
)
14 globals
.directory
= arg
;
19 static inline const char* strip_ext (const char *str
)
21 char *ext
= strstr(str
, ".dll");
23 return str_substring (str
, ext
);
29 static void do_name (const char *arg
)
31 globals
.dll_name
= strip_ext (arg
);
35 static void do_spec (const char *arg
)
37 if (globals
.mode
!= NONE
) fatal("Only one mode can be specified\n");
39 globals
.input_name
= arg
;
43 static void do_demangle (const char *arg
)
45 if (globals
.mode
!= NONE
) fatal("Only one mode can be specified\n");
48 globals
.input_name
= arg
;
52 static void do_dump (const char *arg
)
54 if (globals
.mode
!= NONE
) fatal("Only one mode can be specified\n");
57 globals
.input_name
= arg
;
61 static void do_code (void)
67 static void do_trace (void)
74 static void do_forward (const char *arg
)
76 globals
.forward_dll
= arg
;
81 static void do_document (void)
83 globals
.do_documentation
= 1;
86 static void do_cdecl (void)
92 static void do_quiet (void)
98 static void do_start (const char *arg
)
100 globals
.start_ordinal
= atoi (arg
);
101 if (!globals
.start_ordinal
)
102 fatal ("Invalid -s option (must be numeric)");
106 static void do_end (const char *arg
)
108 globals
.end_ordinal
= atoi (arg
);
109 if (!globals
.end_ordinal
)
110 fatal ("Invalid -e option (must be numeric)");
114 static void do_verbose (void)
116 globals
.do_verbose
= 1;
120 static void do_symdmngl (void)
122 globals
.do_demangle
= 1;
125 static void do_dumphead (void)
127 globals
.do_dumpheader
= 1;
130 static void do_dumpsect (const char* arg
)
132 globals
.dumpsect
= arg
;
135 static void do_dumpall(void)
137 globals
.do_dumpheader
= 1;
138 globals
.dumpsect
= "ALL";
150 static const struct option option_table
[] = {
151 {"-h", NONE
, 0, do_usage
, "-h Display this help message"},
152 {"sym", DMGL
, 2, do_demangle
, "sym <sym> Demangle C++ symbol <sym> and exit"},
153 {"spec", SPEC
, 2, do_spec
, "spec <dll> Use dll for input file and generate implementation code"},
154 {"-I", SPEC
, 1, do_include
, "-I dir Look for prototypes in 'dir' (implies -c)"},
155 {"-c", SPEC
, 0, do_code
, "-c Generate skeleton code (requires -I)"},
156 {"-t", SPEC
, 0, do_trace
, "-t TRACE arguments (implies -c)"},
157 {"-f", SPEC
, 1, do_forward
, "-f dll Forward calls to 'dll' (implies -t)"},
158 {"-D", SPEC
, 0, do_document
, "-D Generate documentation"},
159 {"-o", SPEC
, 1, do_name
, "-o name Set the output dll name (default: dll)"},
160 {"-C", SPEC
, 0, do_cdecl
, "-C Assume __cdecl calls (default: __stdcall)"},
161 {"-s", SPEC
, 1, do_start
, "-s num Start prototype search after symbol 'num'"},
162 {"-e", SPEC
, 1, do_end
, "-e num End prototype search after symbol 'num'"},
163 {"-q", SPEC
, 0, do_quiet
, "-q Don't show progress (quiet)."},
164 {"-v", SPEC
, 0, do_verbose
, "-v Show lots of detail while working (verbose)."},
165 {"dump", DUMP
, 2, do_dump
, "dump <mod> Dumps the content of the module (dll, exe...) named <mod>"},
166 {"-C", DUMP
, 0, do_symdmngl
, "-C Turns on symbol demangling"},
167 {"-f", DUMP
, 0, do_dumphead
, "-f Dumps file header information"},
168 {"-j", DUMP
, 1, do_dumpsect
, "-j sect_name Dumps only the content of section sect_name (import, export, debug)"},
169 {"-x", DUMP
, 0, do_dumpall
, "-x Dumps everything"},
170 {NULL
, NONE
, 0, NULL
, NULL
}
175 const struct option
*opt
;
176 printf ("Usage: winedump [-h sym <sym> spec <dll> dump <dll>] [mode options]\n");
177 printf ("When used in -h mode\n");
178 for (opt
= option_table
; opt
->name
; opt
++)
179 if (opt
->mode
== NONE
)
180 printf (" %s\n", opt
->usage
);
181 printf ("When used in sym mode\n");
182 for (opt
= option_table
; opt
->name
; opt
++)
183 if (opt
->mode
== DMGL
)
184 printf (" %s\n", opt
->usage
);
185 printf ("When used in spec mode\n");
186 for (opt
= option_table
; opt
->name
; opt
++)
187 if (opt
->mode
== SPEC
)
188 printf (" %s\n", opt
->usage
);
189 printf ("When used in dump mode\n");
190 for (opt
= option_table
; opt
->name
; opt
++)
191 if (opt
->mode
== DUMP
)
192 printf (" %s\n", opt
->usage
);
199 /*******************************************************************
202 * Parse options from the argv array
204 static void parse_options (char *argv
[])
206 const struct option
*opt
;
208 const char *arg
= NULL
;
214 for (opt
= option_table
; opt
->name
; opt
++)
216 if (globals
.mode
!= NONE
&& opt
->mode
!= NONE
&& globals
.mode
!= opt
->mode
)
218 if (((opt
->has_arg
== 1) && !strncmp (*ptr
, opt
->name
, strlen (opt
->name
))) ||
219 ((opt
->has_arg
== 2) && !strcmp (*ptr
, opt
->name
)))
221 arg
= *ptr
+ strlen (opt
->name
);
222 if (*arg
== '\0') arg
= *++ptr
;
225 if (!strcmp (*ptr
, opt
->name
))
233 fatal ("Unrecognized option");
235 if (opt
->has_arg
&& arg
!= NULL
)
243 if (globals
.mode
== SPEC
&& globals
.do_code
&& !globals
.directory
)
244 fatal ("-I must be used if generating code");
246 if (VERBOSE
&& QUIET
)
247 fatal ("Options -v and -q are mutually exclusive");
250 static void set_module_name(unsigned setUC
)
256 /* FIXME: we shouldn't assume all module extensions are .dll in winedump
257 * in some cases, we could have some .drv for example
259 /* get module name from name */
260 if ((ptr
= strrchr (globals
.input_name
, '/')))
263 ptr
= globals
.input_name
;
265 if (len
> 4 && strcmp(ptr
+ len
- 4, ".dll") == 0)
267 buf
= malloc(len
+ 1);
268 memcpy(buf
, (void*)ptr
, len
);
270 globals
.input_module
= buf
;
271 OUTPUT_UC_DLL_NAME
= (setUC
) ? str_toupper( strdup (OUTPUT_DLL_NAME
)) : "";
274 /*******************************************************************
278 int main (int argc
__attribute__((unused
)), char *argv
[])
280 int main (int argc
, char *argv
[])
283 parsed_symbol symbol
;
287 globals
.forward_dll
= NULL
;
289 parse_options (argv
);
291 memset (&symbol
, 0, sizeof (parsed_symbol
));
293 switch (globals
.mode
)
296 globals
.uc_dll_name
= "";
299 symbol_init (&symbol
, globals
.input_name
);
300 globals
.input_module
= "";
301 if (symbol_demangle (&symbol
) == -1)
302 fatal( "Symbol hasn't got a mangled name\n");
303 if (symbol
.flags
& SYM_DATA
)
304 printf (symbol
.arg_text
[0]);
306 output_prototype (stdout
, &symbol
);
307 fputc ('\n', stdout
);
308 symbol_clear(&symbol
);
313 dll_open (globals
.input_name
);
315 output_spec_preamble ();
316 output_header_preamble ();
317 output_c_preamble ();
319 while (!dll_next_symbol (&symbol
))
324 printf ("Export %3d - '%s' ...%c", count
, symbol
.symbol
,
325 VERBOSE
? '\n' : ' ');
327 if (globals
.do_code
&& count
>= globals
.start_ordinal
328 && (!globals
.end_ordinal
|| count
<= globals
.end_ordinal
))
330 /* Attempt to get information about the symbol */
331 int result
= symbol_demangle (&symbol
);
334 result
= symbol_search (&symbol
);
336 if (!result
&& symbol
.function_name
)
337 /* Clean up the prototype */
338 symbol_clean_string (symbol
.function_name
);
341 puts (result
? "[Not Found]" : "[OK]");
346 output_spec_symbol (&symbol
);
347 output_header_symbol (&symbol
);
348 output_c_symbol (&symbol
);
350 symbol_clear (&symbol
);
354 output_install_script ();
357 puts ("Finished, Cleaning up...");
364 dump_file(globals
.input_name
);