/*
    gendef - Generate list of exported symbols from a Portable Executable.
    Copyright (C) 2009-2016  mingw-w64 project

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
#include "compat_string.h"
#include "gendef.h"

typedef struct sImpDef {
  struct sImpDef *next;
  char *name;
  char *data;
  size_t length;
} sImpDef;

static sImpDef *theImpDef = NULL;

typedef struct sDefPaths {
  struct sDefPaths *next;
  char path[1];
} sDefPaths;

static sDefPaths *thePathDefs;
static int theIncludeCurrentDir = 1;

static int find_path_def (const char *path);
static int add_path_def (const char *path);

static sImpDef *is_def_loaded (const char *);
static sImpDef *gendef_loaddef (const char *);
static FILE *fopen_def (const char *name);
static uint32_t get_uint32_by_str (const char **txt_ptr);

int
gendef_getsymbol_info (const char *dllname, const char *symbolname, int *isData, uint32_t *at)
{
  char *r1 = NULL, *r2 = NULL, *def;
  sImpDef *id;
  size_t symlen;
  int ret = 0;

  if (!dllname)
    return 0;
  if (!symbolname || *symbolname == 0)
    {
      char *h = strchr (dllname, '.');
      if (!h)
	return 0;
      r1 = strdup (h + 1);
      if (*r1 == '#')
	{
	  r2 = (char *) malloc (strlen (r1) + 5);
	  sprintf (r2, "ord_%s", r1 + 1);
	  free (r1);
	  r1 = r2;
	}
      symbolname = r1;
      r2 = (char *) malloc (strlen (dllname) + 5);
      strcpy (r2, dllname);
      strcpy (strchr (r2, '.'), ".dll");
      dllname = r2;
    }
  def = (char *) malloc (strlen (dllname) + 5);
  strcpy (def, dllname);
  strlwr (def);
  if (strchr (def, '.') == NULL)
    strcat (def, ".def");
  else
    strcpy (strchr (def, '.'), ".def");
  symlen = strlen (symbolname);
  id = gendef_loaddef (def);
  if (id)
    {
      const char *t = id->data;
      while (t != NULL && *t != 0)
	{
	  t = strchr (t, '\n');
	  if (t)
	    t++;
	  if (t && strncmp (t, symbolname, symlen) == 0)
	    {
	      if ((t[symlen] >= 0 && t[symlen] <= 0x20) || t[symlen] == '@')
		{
		  *at = -1;
		  t += symlen;
		  if (*t == '@')
		    {
		      t++;
		      const char *old_t = t;
		      int num = get_uint32_by_str (&t);
		      if (old_t != t)
			*at = num;
		    }
		  while (*t != 0 && *t != '\n')
		    {
		      if (!strncmp (t, "DATA", 4))
			{
			  *isData = 1;
			  break;
			}
		      t++;
		    }
		  ret = 1;
		  break;
		}

	    }
	}
    }
  if (def)
    free (def);
  if (r2 != NULL && r1 != r2)
    free (r2);
  if (r1 != NULL)
    free (r1);
  return ret;
}

static FILE *
fopen_def (const char *name)
{
  sDefPaths *l = thePathDefs;
  FILE *fp;
  if (theIncludeCurrentDir && (fp = fopen (name, "rb")) != NULL)
    return fp;
  while (l != NULL)
    {
      char *h = (char *) malloc (strlen (name) + strlen (l->path) + 1);
      if (h)
	{
	  strcpy (h, l->path);
	  strcat (h, name);
	  fp = fopen (h, "rb");
	  free (h);
	  if (fp)
	    return fp;
	}
      l = l->next;
    }
  return NULL;
}

static sImpDef *
gendef_loaddef (const char *name)
{
  sImpDef *n;
  FILE *fp;
  char *lname;
  size_t len;
  char *txt;
  if (!name || *name == 0)
    return NULL;
  lname = strdup (name);
  if (!lname)
    return NULL;
  strlwr (lname);
  n = is_def_loaded (lname);
  if (n)
    {
      free (lname);
      return n;
    }
  fp = fopen_def (name);
  if (!fp)
    {
      free (lname);
      return NULL;
    }
  fseek (fp, 0, SEEK_END);
  len = (size_t) ftell (fp);
  fseek (fp, 0, SEEK_SET);
  txt = (char *) malloc (len + 1);
  if (!txt)
    {
      fclose (fp);
      free (lname);
      return NULL;
    }
  if ((size_t) fread (txt, 1, len, fp) != len)
    {
      fclose (fp);
      free (lname);
      free (txt);
      return NULL;
    }
  fclose (fp);
  txt[len] = 0;

  n = (sImpDef *) malloc (sizeof (sImpDef));
  if (!n)
    {
      free (lname);
      free (txt);
      return NULL;
    }
  memset (n, 0, sizeof (sImpDef));
  n->name = lname;
  n->data = txt;
  n->length = len;
  n->next = theImpDef;
  theImpDef = n;
  return n;
}

static sImpDef *
is_def_loaded (const char *dname)
{
  sImpDef *h = theImpDef;
  while (h != NULL)
    {
      if (!strcasecmp (h->name, dname))
	break;
      h = h->next;
    }
  return h;
}

static uint32_t
get_uint32_by_str (const char **txt_ptr)
{
  const char *txt = *txt_ptr;
  uint32_t ret = 0;
  while (*txt != 0 && *txt >= '0' && *txt <= '9')
    {
      ret *= 10;
      ret += (uint32_t) (txt[0] - '0');
      ++txt;
    }
  *txt_ptr = txt;
  return ret;
}

int
gendef_addpath_def (const char *path)
{
  if (find_path_def (path))
    return 1;
  return add_path_def (path);
}

static int
find_path_def (const char *path)
{
  char *h, *p;
  sDefPaths *l = thePathDefs;
  if (!l)
    return 0;
  h = (char *) malloc (strlen (path) + 2);
  if (!h)
    return 0;
  strcpy (h, path);
  for (p = h; *p != 0; p++)
    if (p[0] == '\\')
      p[0] = '/';
  if (p != h && p[-1] != '/')
    strcat (p, "/");
  while (l != NULL)
    {
      if (!strcmp (l->path, h))
        {
	  free (h);
	  return 1;
        }
      l = l->next;
    }
  free (h);
  return 0;
}

static int
add_path_def (const char *path)
{
  char *h, *p;
  sDefPaths *l;
  h = (char *) malloc (strlen (path) + 2);
  if (!h)
    return 0;
  strcpy (h, path);
  for (p = h; *p != 0; p++)
    if (p[0] == '\\')
      p[0] = '/';
  if (p != h && p[-1] != '/')
    strcat (p, "/");
  l = (sDefPaths *) malloc (sizeof (sDefPaths) + strlen (h) + 1);
  if (!l)
    {
      free (h);
      return 0;
    }
  memset (l, 0, sizeof (sDefPaths));
  strcpy (l->path, h);
  free (h);
  l->next = thePathDefs;
  thePathDefs = l;
  return 1;
}

void gendef_no_include_current_dir (void)
{
  theIncludeCurrentDir = 0;
}
