/*
 * File source.c - source file handling for internal debugger.
 *
 * Copyright (C) 1997, Eric Youngdale.
 *
 */

#include "config.h"
#include <stdio.h>
#include <stdlib.h>

#include <sys/types.h>
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif
#include <fcntl.h>
#include <sys/stat.h>
#include <limits.h>
#include <string.h>
#include <unistd.h>
#ifndef PATH_MAX
#define PATH_MAX _MAX_PATH
#endif

#include "wine/winbase16.h"
#include "pe_image.h"
#include "peexe.h"
#include "debugger.h"
#include "peexe.h"
#include "task.h"

struct searchlist
{
  char * path;
  struct searchlist * next;
};


struct open_filelist
{
  char			* path;
  char			* real_path;
  struct open_filelist  * next;
  unsigned int		  size;
  signed int		  nlines;
  unsigned int		* linelist;
};

static struct open_filelist * ofiles;

static struct searchlist * listhead;
static char DEBUG_current_sourcefile[PATH_MAX];
static int DEBUG_start_sourceline = -1;
static int DEBUG_end_sourceline = -1;

void
DEBUG_ShowDir()
{
  struct searchlist * sl;

  fprintf(stderr,"Search list :\n");
  for(sl = listhead; sl; sl = sl->next)
    {
      fprintf(stderr, "\t%s\n", sl->path);
    }
  fprintf(stderr, "\n");
}

void
DEBUG_AddPath(const char * path)
{
  struct searchlist * sl;

  sl = (struct searchlist *) DBG_alloc(sizeof(struct searchlist));
  if( sl == NULL )
    {
      return;
    }

  sl->next = listhead;
  sl->path = DBG_strdup(path);
  listhead = sl;
}

void
DEBUG_NukePath()
{
  struct searchlist * sl;
  struct searchlist * nxt;

  for(sl = listhead; sl; sl = nxt)
    {
      nxt = sl->next;
      DBG_free(sl->path);
      DBG_free(sl);
    }

  listhead = NULL;
}

static
int
DEBUG_DisplaySource(char * sourcefile, int start, int end)
{
  char			      * addr;
  char			        buffer[1024];
  int				fd;
  int				i;
  struct open_filelist	      * ol;
  int				nlines;
  char			      * pnt;
  int				rtn;
  struct searchlist	      * sl;
  struct stat			statbuf;
  int				status;
  char				tmppath[PATH_MAX];

  /*
   * First see whether we have the file open already.  If so, then
   * use that, otherwise we have to try and open it.
   */
  for(ol = ofiles; ol; ol = ol->next)
    {
      if( strcmp(ol->path, sourcefile) == 0 )
	{
	  break;
	}
    }

  if( ol == NULL )
    {
      /*
       * Try again, stripping the path from the opened file.
       */
      for(ol = ofiles; ol; ol = ol->next)
	{
	  pnt = strrchr(ol->path, '/');
	  if( pnt != NULL && strcmp(pnt + 1, sourcefile) == 0 )
	    {
	      break;
	    }
	}
      
    }

  if( ol == NULL )
    {
      /*
       * See if this is a DOS style name or not.
       */
      pnt = strchr(sourcefile, '\\' );
      if( pnt == NULL )
	{
	  pnt = strchr(sourcefile, '/' );
	  if( pnt == NULL )
	    {
	      pnt = sourcefile;
	    }
	}

      /*
       * Crapola.  We need to try and open the file.
       */
      status = stat(sourcefile, &statbuf);
      if( status != -1 )
	{
	  strcpy(tmppath, sourcefile);
	}
      else
	{
	  for(sl = listhead; sl; sl = sl->next)
	    {
	      strcpy(tmppath, sl->path);
	      if( tmppath[strlen(tmppath)-1] != '/' )
		{
		  strcat(tmppath, "/");
		}
	      /*
	       * Now append the base file name.
	       */
	      strcat(tmppath, pnt);
	      
	      status = stat(tmppath, &statbuf);
	      if( status != -1 )
		{
		  break;
		}
	    }
	  
	  if( sl == NULL )
	    {
	      /*
	       * Still couldn't find it.  Ask user for path to add.
	       */
	      fprintf(stderr,"Enter path to file %s: ", sourcefile);
	      fgets(tmppath, sizeof(tmppath), stdin);
	      
	      if( tmppath[strlen(tmppath)-1] == '\n' )
		{
		  tmppath[strlen(tmppath)-1] = '\0';
		}
	      
	      if( tmppath[strlen(tmppath)-1] != '/' )
		{
		  strcat(tmppath, "/");
		}
	      /*
	       * Now append the base file name.
	       */
	      strcat(tmppath, pnt);
	      
	      status = stat(tmppath, &statbuf);
	      if( status == -1 )
		{
		  /*
		   * OK, I guess the user doesn't really want to see it
		   * after all.
		   */
		  ol = (struct open_filelist *) DBG_alloc(sizeof(*ol));
		  ol->path = DBG_strdup(sourcefile);
		  ol->real_path = NULL;
		  ol->next = ofiles;
		  ol->nlines = 0;
		  ol->linelist = NULL;
		  ofiles = ol;
		  fprintf(stderr,"Unable to open file %s\n", tmppath);
		  return FALSE;
		}
	    }
	}
      /*
       * Create header for file.
       */
      ol = (struct open_filelist *) DBG_alloc(sizeof(*ol));
      ol->path = DBG_strdup(sourcefile);
      ol->real_path = DBG_strdup(tmppath);
      ol->next = ofiles;
      ol->nlines = 0;
      ol->linelist = NULL;
      ol->size = statbuf.st_size;
      ofiles = ol;

      /*
       * Now open and map the file.
       */
      fd = open(tmppath, O_RDONLY);
      if( fd == -1 )
	{
	  return FALSE;
	}

      addr = mmap(0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
      if( addr == (char *) -1 )
	{
	  return FALSE;
	}

      /*
       * Now build up the line number mapping table.
       */
      ol->nlines = 1;
      pnt = addr;
      while(pnt < addr + ol->size )
	{
	  if( *pnt++ == '\n' )
	    {
	      ol->nlines++;
	    }
	}

      ol->nlines++;
      ol->linelist = (unsigned int*) DBG_alloc( ol->nlines * sizeof(unsigned int) );

      nlines = 0;
      pnt = addr;
      ol->linelist[nlines++] = 0;
      while(pnt < addr + ol->size )
	{
	  if( *pnt++ == '\n' )
	    {
	      ol->linelist[nlines++] = pnt - addr;
	    }
	}
      ol->linelist[nlines++] = pnt - addr;

    }
  else
    {
      /*
       * We know what the file is, we just need to reopen it and remap it.
       */
      fd = open(ol->real_path, O_RDONLY);
      if( fd == -1 )
	{
	  return FALSE;
	}
      
      addr = mmap(0, ol->size, PROT_READ, MAP_PRIVATE, fd, 0);
      if( addr == (char *) -1 )
	{
	  return FALSE;
	}
    }
  
  /*
   * All we need to do is to display the source lines here.
   */
  rtn = FALSE;
  for(i=start - 1; i <= end - 1; i++)
    {
      if( i < 0 || i >= ol->nlines - 1)
	{
	  continue;
	}

      rtn = TRUE;
      memset(&buffer, 0, sizeof(buffer));
      if( ol->linelist[i+1] != ol->linelist[i] )
	{
	  memcpy(&buffer, addr + ol->linelist[i], 
		 (ol->linelist[i+1] - ol->linelist[i]) - 1);
	}
      fprintf(stderr,"%d\t%s\n", i + 1,  buffer);
    }

  munmap(addr, ol->size);
  close(fd);

  return rtn;

}

void
DEBUG_List(struct list_id * source1, struct list_id * source2,
			 int delta)
{
  int    end;
  int    rtn;
  int    start;
  char * sourcefile;

  /*
   * We need to see what source file we need.  Hopefully we only have
   * one specified, otherwise we might as well punt.
   */
  if( source1 != NULL 
      && source2 != NULL 
      && source1->sourcefile != NULL
      && source2->sourcefile != NULL 
      && strcmp(source1->sourcefile, source2->sourcefile) != 0 )
    {
      fprintf(stderr, "Ambiguous source file specification.\n");
      return;
    }

  sourcefile = NULL;
  if( source1 != NULL && source1->sourcefile != NULL )
    {
      sourcefile = source1->sourcefile;
    }

  if( sourcefile == NULL 
      && source2 != NULL 
      && source2->sourcefile != NULL )
    {
      sourcefile = source2->sourcefile;
    }

  if( sourcefile == NULL )
    {
      sourcefile = (char *) &DEBUG_current_sourcefile;
    }

  if( sourcefile == NULL )
    {
      fprintf(stderr, "No source file specified.\n");
      return;
    }

  /*
   * Now figure out the line number range to be listed.
   */
  start = -1;
  end = -1;

  if( source1 != NULL )
    {
      start = source1->line;
    }

  if( source2 != NULL )
    {
      end = source2->line;
    }

  if( start == -1 && end == -1 )
    {
      if( delta < 0 )
	{
	  end = DEBUG_start_sourceline;
	  start = end + delta;
	}
      else
	{
	  start = DEBUG_end_sourceline;
	  end = start + delta;
	}
    }
  else if( start == -1 )
    {
      start = end + delta;
    }
  else if (end == -1)
    {
      end = start + delta;
    }

  /*
   * Now call this function to do the dirty work.
   */
  rtn = DEBUG_DisplaySource(sourcefile, start, end);

  if( sourcefile != (char *) &DEBUG_current_sourcefile )
    {
      strcpy(DEBUG_current_sourcefile, sourcefile);
    }
  DEBUG_start_sourceline = start;
  DEBUG_end_sourceline = end;
}

DBG_ADDR DEBUG_LastDisassemble={NULL,0,0};

static int
_disassemble(DBG_ADDR *addr)
{
	DEBUG_PrintAddress( addr, dbg_mode, TRUE );
	fprintf(stderr,": ");
	if (!DBG_CHECK_READ_PTR( addr, 1 )) return 0;
	DEBUG_Disasm( addr, TRUE );
	fprintf(stderr,"\n");
	return 1;
}

void
_disassemble_fixaddr(DBG_ADDR *addr) {
    DWORD seg2;
    struct datatype *testtype;

    DBG_FIX_ADDR_SEG(addr,CS_reg(&DEBUG_context));
    if( addr->type != NULL )
      {
        if( addr->type == DEBUG_TypeIntConst )
          {
            /*
             * We know that we have the actual offset stored somewhere
             * else in 32-bit space.  Grab it, and we
             * should be all set.
             */
            seg2 = addr->seg;
            addr->seg = 0;
            addr->off = DEBUG_GetExprValue(addr, NULL);
            addr->seg = seg2;
          }
        else
          {
            if (!DBG_CHECK_READ_PTR( addr, 1 )) return;
            DEBUG_TypeDerefPointer(addr, &testtype);
            if( testtype != NULL || addr->type == DEBUG_TypeIntConst )
                addr->off = DEBUG_GetExprValue(addr, NULL);
          }
      }
    else if (!addr->seg && !addr->off)
    {
        fprintf(stderr,"Invalid expression\n");
        return;
    }
}

void
DEBUG_Disassemble(const DBG_ADDR *xstart,const DBG_ADDR *xend,int offset)
{
  int i;
  DBG_ADDR	last;
  DBG_ADDR	end,start;

  if (xstart) {
    start=*xstart;
    _disassemble_fixaddr(&start);
  }
  if (xend) {
    end=*xend;
    _disassemble_fixaddr(&end);
  }
  if (!xstart && !xend) {
    last = DEBUG_LastDisassemble;
    if (!last.seg && !last.off)
    {
        TDB *pTask = (TDB*)GlobalLock16( GetCurrentTask() );
        last.seg = CS_reg(&DEBUG_context);
        last.off = EIP_reg(&DEBUG_context);
        if (ISV86(&DEBUG_context)) last.seg |= (DWORD)(pTask?(pTask->hModule):0)<<16; else
        if (IS_SELECTOR_SYSTEM(last.seg)) last.seg = 0;
        GlobalUnlock16( GetCurrentTask() );
    }
    for (i=0;i<offset;i++)
      if (!_disassemble(&last)) break;
    memcpy(&DEBUG_LastDisassemble,&last,sizeof(last));
    return;
  }
  last = start;
  if (!xend) {
    for (i=0;i<offset;i++)
      if (!_disassemble(&last)) break;
    memcpy(&DEBUG_LastDisassemble,&last,sizeof(last));
    return;
  }
  while (last.off <= end.off)
    if (!_disassemble(&last)) break;
  memcpy(&DEBUG_LastDisassemble,&last,sizeof(last));
  return;
}



#if 0
main()
{
  int i, j;
  DEBUG_AddPath("../../de");
  while(1==1)
    {
      fscanf(stdin,"%d %d", &i, &j);
      DEBUG_DisplaySource("dumpexe.c", i, j);
    }
  return 0;
}
#endif
