/*
 *  Option processing and main()
 *
 *  Copyright 2000 Jon Griffiths
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "config.h"
#include "wine/port.h"

#include "winedump.h"

_globals globals; /* All global variables */


static void do_include (const char *arg)
{
  char *newIncludes;

  if (!globals.directory)
    globals.directory = strdup(arg);
  else {
    newIncludes = str_create (3,globals.directory," ",arg);
    free(globals.directory);
    globals.directory = newIncludes;
  }
  globals.do_code = 1;
}


static inline const char* strip_ext (const char *str)
{
  int len = strlen(str);
  if (len>4 && strcmp(str+len-4,".dll") == 0)
    return str_substring (str, str+len-4);
  else
    return strdup (str);
}


static void do_name (const char *arg)
{
  globals.dll_name = strip_ext (arg);
}


static void do_spec (const char *arg)
{
    if (globals.mode != NONE) fatal("Only one mode can be specified\n");
    globals.mode = SPEC;
}


static void do_demangle (const char *arg)
{
    if (globals.mode != NONE) fatal("Only one mode can be specified\n");
    globals.mode = DMGL;
    globals.do_code = 1;
}


static void do_dump (const char *arg)
{
    if (globals.mode != NONE) fatal("Only one mode can be specified\n");
    globals.mode = DUMP;
    globals.do_code = 1;
}


static void do_code (void)
{
  globals.do_code = 1;
}


static void do_trace (void)
{
  globals.do_trace = 1;
  globals.do_code = 1;
}


static void do_forward (const char *arg)
{
  globals.forward_dll = arg;
  globals.do_trace = 1;
  globals.do_code = 1;
}

static void do_document (void)
{
  globals.do_documentation = 1;
}

static void do_cdecl (void)
{
  globals.do_cdecl = 1;
}


static void do_quiet (void)
{
  globals.do_quiet = 1;
}


static void do_start (const char *arg)
{
  globals.start_ordinal = atoi (arg);
  if (!globals.start_ordinal)
    fatal ("Invalid -s option (must be numeric)");
}


static void do_end (const char *arg)
{
  globals.end_ordinal = atoi (arg);
  if (!globals.end_ordinal)
    fatal ("Invalid -e option (must be numeric)");
}


static void do_symfile (const char *arg)
{
  FILE *f;
  char symstring[256];    /* keep count with "%<width>s" below */
  search_symbol *symbolp,**symbolptail = &globals.search_symbol;

  if (!(f = fopen(arg, "rt")))
    fatal ("Cannot open <symfile>");
  while (1 == fscanf(f, "%255s", symstring))    /* keep count with [<width>] above */
  {
    symstring[sizeof(symstring)-1] = '\0';
    if (!(symbolp = malloc(sizeof(*symbolp) + strlen(symstring))))
      fatal ("Out of memory");
    strcpy(symbolp->symbolname, symstring);
    symbolp->found = 0;
    symbolp->next = NULL;
    *symbolptail = symbolp;
    symbolptail = &symbolp->next;
  }
  if (fclose(f))
    fatal ("Cannot close <symfile>");
}


static void do_verbose (void)
{
  globals.do_verbose = 1;
}


static void do_symdmngl (void)
{
    globals.do_demangle = 1;
}

static void do_dumphead (void)
{
    globals.do_dumpheader = 1;
}

static void do_dumpsect (const char* arg)
{
    globals.dumpsect = arg;
}

static void do_rawdebug (void)
{
    globals.do_debug = 1;
}

static void do_dumpall(void)
{
    globals.do_dumpheader = 1;
    globals.do_dump_rawdata = 1;
    globals.dumpsect = "ALL";
}

struct my_option
{
  const char *name;
  Mode mode;
  int   has_arg;
  void  (*func) ();
  const char *usage;
};

static const struct my_option option_table[] = {
  {"--help",NONE, 0, do_usage,    "--help       Display this help message"},
  {"-h",    NONE, 0, do_usage,    "-h           Synonym for --help"},
  {"-?",    NONE, 0, do_usage,    "-?           Synonym for --help"},
  {"sym",   DMGL, 0, do_demangle, "sym <sym>    Demangle C++ symbol <sym> and exit"},
  {"spec",  SPEC, 0, do_spec,     "spec <dll>   Use dll for input file and generate implementation code"},
  {"-I",    SPEC, 1, do_include,  "-I dir       Look for prototypes in 'dir' (implies -c)"},
  {"-c",    SPEC, 0, do_code,     "-c           Generate skeleton code (requires -I)"},
  {"-t",    SPEC, 0, do_trace,    "-t           TRACE arguments (implies -c)"},
  {"-f",    SPEC, 1, do_forward,  "-f dll       Forward calls to 'dll' (implies -t)"},
  {"-D",    SPEC, 0, do_document, "-D           Generate documentation"},
  {"-o",    SPEC, 1, do_name,     "-o name      Set the output dll name (default: dll). note: strips .dll extensions"},
  {"-C",    SPEC, 0, do_cdecl,    "-C           Assume __cdecl calls (default: __stdcall)"},
  {"-s",    SPEC, 1, do_start,    "-s num       Start prototype search after symbol 'num'"},
  {"-e",    SPEC, 1, do_end,      "-e num       End prototype search after symbol 'num'"},
  {"-S",    SPEC, 1, do_symfile,  "-S symfile   Search only prototype names found in 'symfile'"},
  {"-q",    SPEC, 0, do_quiet,    "-q           Don't show progress (quiet)."},
  {"-v",    SPEC, 0, do_verbose,  "-v           Show lots of detail while working (verbose)."},
  {"dump",  DUMP, 0, do_dump,     "dump <file>  Dumps the contents of a file (dll, exe, lib...)"},
  {"-C",    DUMP, 0, do_symdmngl, "-C           Turns on symbol demangling"},
  {"-f",    DUMP, 0, do_dumphead, "-f           Dumps file header information"},
  {"-G",    DUMP, 0, do_rawdebug, "-G           Dumps raw debug information"},
  {"-j",    DUMP, 1, do_dumpsect, "-j sect_name Dumps only the content of section sect_name (import, export, debug, resource, tls, clr)"},
  {"-x",    DUMP, 0, do_dumpall,  "-x           Dumps everything"},
  {NULL,    NONE, 0, NULL,        NULL}
};

void do_usage (void)
{
    const struct my_option *opt;
    printf ("Usage: winedump [-h | sym <sym> | spec <dll> | dump <file>]\n");
    printf ("Mode options (can be put as the mode (sym/spec/dump...) is declared):\n");
    printf ("\tWhen used in --help mode\n");
    for (opt = option_table; opt->name; opt++)
	if (opt->mode == NONE)
	    printf ("\t   %s\n", opt->usage);
    printf ("\tWhen used in sym mode\n");
    for (opt = option_table; opt->name; opt++)
	if (opt->mode == DMGL)
	    printf ("\t   %s\n", opt->usage);
    printf ("\tWhen used in spec mode\n");
    for (opt = option_table; opt->name; opt++)
	if (opt->mode == SPEC)
	    printf ("\t   %s\n", opt->usage);
    printf ("\tWhen used in dump mode\n");
    for (opt = option_table; opt->name; opt++)
	if (opt->mode == DUMP)
	    printf ("\t   %s\n", opt->usage);

    puts ("");
    exit (1);
}


/*******************************************************************
 *          parse_options
 *
 * Parse options from the argv array
 */
static void parse_options (char *argv[])
{
  const struct my_option *opt;
  char *const *ptr;
  const char *arg = NULL;

  ptr = argv + 1;

  while (*ptr != NULL)
  {
    for (opt = option_table; opt->name; opt++)
    {
     if (globals.mode != NONE && opt->mode != NONE && globals.mode != opt->mode)
       continue;
     if (((opt->has_arg == 1) && !strncmp (*ptr, opt->name, strlen (opt->name))) ||
	 ((opt->has_arg == 2) && !strcmp (*ptr, opt->name)))
      {
        arg = *ptr + strlen (opt->name);
        if (*arg == '\0') arg = *++ptr;
        break;
      }
      if (!strcmp (*ptr, opt->name))
      {
        arg = NULL;
        break;
      }
    }

    if (!opt->name)
    {
        if ((*ptr)[0] == '-')
            fatal ("Unrecognized option");
        if (globals.input_name != NULL)
            fatal ("Only one file can be treated at once");
        globals.input_name = *ptr;
    }
    else if (opt->has_arg && arg != NULL)
	opt->func (arg);
    else
	opt->func ("");

    ptr++;
  }

  if (globals.mode == SPEC && globals.do_code && !globals.directory)
    fatal ("-I must be used if generating code");

  if (VERBOSE && QUIET)
    fatal ("Options -v and -q are mutually exclusive");

  if (globals.mode == NONE)
      do_dump("");
}

static void set_module_name(unsigned setUC)
{
    const char*	ptr;
    char*	buf;
    int		len;

    /* FIXME: we shouldn't assume all module extensions are .dll in winedump
     * in some cases, we could have some .drv for example
     */
    /* get module name from name */
    if ((ptr = strrchr (globals.input_name, '/')))
	ptr++;
    else
	ptr = globals.input_name;
    len = strlen(ptr);
    if (len > 4 && strcmp(ptr + len - 4, ".dll") == 0)
	len -= 4;
    buf = malloc(len + 1);
    memcpy(buf, (const void*)ptr, len);
    buf[len] = 0;
    globals.input_module = buf;
    OUTPUT_UC_DLL_NAME = (setUC) ? str_toupper( strdup (OUTPUT_DLL_NAME)) : "";
}

/* Marks the symbol as 'found'! */
/* return: perform-search */
static int symbol_searched(int count, const char *symbolname)
{
    search_symbol *search_symbol;

    if (!(count >= globals.start_ordinal
          && (!globals.end_ordinal || count <= globals.end_ordinal)))
        return 0;
    if (!globals.search_symbol)
        return 1;
    for (search_symbol = globals.search_symbol;
         search_symbol;
         search_symbol = search_symbol->next)
    {
        if (!strcmp(symbolname, search_symbol->symbolname))
        {
            search_symbol->found = 1;
            return 1;
        }
    }
    return 0;
}

/* return: some symbols weren't found */
static int symbol_finish(void)
{
    const search_symbol *search_symbol;
    int started = 0;

    for (search_symbol = globals.search_symbol;
         search_symbol;
         search_symbol = search_symbol->next)
    {
        if (search_symbol->found)
            continue;
        if (!started)
        {
            /* stderr? not a practice here */
            puts("These requested <symfile> symbols weren't found:");
            started = 1;
        }
        printf("\t%s\n",search_symbol->symbolname);
    }
    return started;
}

/*******************************************************************
 *         main
 */
#ifdef __GNUC__
int   main (int argc __attribute__((unused)), char *argv[])
#else
int   main (int argc, char *argv[])
#endif
{
    parsed_symbol symbol;
    int count = 0;

    globals.mode = NONE;
    globals.forward_dll = NULL;
    globals.input_name = NULL;
    globals.dumpsect = NULL;

    parse_options (argv);

    memset (&symbol, 0, sizeof (parsed_symbol));

    switch (globals.mode)
    {
    case DMGL:
	VERBOSE = 1;

        if (globals.input_name == NULL)
            fatal("No symbol name has been given\n");
        printf("%s\n", get_symbol_str(globals.input_name));
	break;

    case SPEC:
        if (globals.input_name == NULL)
            fatal("No file name has been given\n");
	set_module_name(1);
	if (!dll_open (globals.input_name))
            break;

	output_spec_preamble ();
	output_header_preamble ();
	output_c_preamble ();

	while (!dll_next_symbol (&symbol))
	{
	    count++;

	    if (NORMAL)
		printf ("Export %3d - '%s' ...%c", count, symbol.symbol,
			VERBOSE ? '\n' : ' ');

	    if (globals.do_code && symbol_searched(count, symbol.symbol))
	    {
		/* Attempt to get information about the symbol */
		int result = symbol_demangle (&symbol);

		if (result)
		    result = symbol_search (&symbol);

		if (!result && symbol.function_name)
		    /* Clean up the prototype */
		    symbol_clean_string (symbol.function_name);

		if (NORMAL)
		    puts (result ? "[Not Found]" : "[OK]");
	    }
	    else if (NORMAL)
		puts ("[Ignoring]");

	    output_spec_symbol (&symbol);
	    output_header_symbol (&symbol);
	    output_c_symbol (&symbol);

	    symbol_clear (&symbol);
	}

	output_makefile ();

	if (VERBOSE)
	    puts ("Finished, Cleaning up...");
        if (symbol_finish())
            return 1;
	break;
    case NONE:
	do_usage();
	break;
    case DUMP:
        if (globals.input_name == NULL)
            fatal("No file name has been given\n");
	set_module_name(0);
	dump_file(globals.input_name);
	break;
    }

    return 0;
}
