/*
 * File source.c - source file handling for internal debugger.
 *
 * Copyright (C) 1997, Eric Youngdale.
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#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 "debugger.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(void)
{
  struct searchlist * sl;

  DEBUG_Printf(DBG_CHN_MESG,"Search list :\n");
  for(sl = listhead; sl; sl = sl->next)
    {
      DEBUG_Printf(DBG_CHN_MESG, "\t%s\n", sl->path);
    }
  DEBUG_Printf(DBG_CHN_MESG, "\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(void)
{
  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  void*   DEBUG_MapFile(const char* name, HANDLE* hMap, unsigned* size)
{
    HANDLE              hFile;

    hFile = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL, 
                       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile == INVALID_HANDLE_VALUE) return (void*)-1;
    if (size != NULL && (*size = GetFileSize(hFile, NULL)) == -1) return (void*)-1;
    *hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
    CloseHandle(hFile);
    if (!*hMap) return (void*)-1;
    return MapViewOfFile(*hMap, FILE_MAP_READ, 0, 0, 0);
}

static void     DEBUG_UnmapFile(void* addr, HANDLE hMap)
{
    UnmapViewOfFile(addr);
    CloseHandle(hMap);
}

static struct open_filelist*    DEBUG_SearchOpenFile(const char* name)
{
    struct open_filelist*       ol;

    for (ol = ofiles; ol; ol = ol->next)
    {
        if (strcmp(ol->path, name) == 0) break;
    }
    return ol;
}

static
int
DEBUG_DisplaySource(char * sourcefile, int start, int end)
{
    char*                       addr;
    int				i;
    struct open_filelist*       ol;
    int				nlines;
    char*                       basename = NULL;
    char*                       pnt;
    int				rtn;
    struct searchlist*          sl;
    HANDLE                      hMap;
    DWORD			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.
     */
    ol = DEBUG_SearchOpenFile(sourcefile);
    
    if ( ol == NULL )
    {
        /*
         * Try again, stripping the path from the opened file.
         */
        basename = strrchr(sourcefile, '\\' );
        if ( !basename )
            basename = strrchr(sourcefile, '/' );
        if ( !basename )
            basename = sourcefile;
        else
            basename++;
        
        ol = DEBUG_SearchOpenFile(basename);
    }
    
    if ( ol == NULL )
    {
        /*
         * Crapola.  We need to try and open the file.
         */
        status = GetFileAttributes(sourcefile);
        if ( status != -1 )
        {
            strcpy(tmppath, sourcefile);
        }
        else if ( (status = GetFileAttributes(basename)) != -1 )
        {
            strcpy(tmppath, basename);
        }
        else
        {
            for (sl = listhead; sl; sl = sl->next)
            {
                strcpy(tmppath, sl->path);
                if ( tmppath[strlen(tmppath)-1] != '/' && tmppath[strlen(tmppath)-1] != '\\' )
                {
                    strcat(tmppath, "/");
                }
                /*
                 * Now append the base file name.
                 */
                strcat(tmppath, basename);
                
                status = GetFileAttributes(tmppath);
                if ( status != -1 ) break;
            }
            
            if ( sl == NULL )
            {
                if (DEBUG_InteractiveP)
                {
                    char zbuf[256];
                    /*
                     * Still couldn't find it.  Ask user for path to add.
                     */
                    sprintf(zbuf, "Enter path to file '%s': ", sourcefile);
                    DEBUG_ReadLine(zbuf, tmppath, sizeof(tmppath));
                    
                    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, basename);
                    
                    status = GetFileAttributes(tmppath);
                }
                else
                {
                    status = -1;
                    strcpy(tmppath, sourcefile);
                }
                
                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;
                    DEBUG_Printf(DBG_CHN_MESG,"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 = 0;
        ofiles = ol;
        
        addr = DEBUG_MapFile(tmppath, &hMap, &ol->size);
        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
    {
        addr = DEBUG_MapFile(ol->real_path, &hMap, NULL);
        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++)
    {
        char    buffer[1024];

        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);
	}
        DEBUG_Printf(DBG_CHN_MESG,"%d\t%s\n", i + 1,  buffer);
    }
    
    DEBUG_UnmapFile(addr, hMap);
    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 )
    {
      DEBUG_Printf(DBG_CHN_MESG, "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 )
    {
      DEBUG_Printf(DBG_CHN_MESG, "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={0,0};

BOOL DEBUG_DisassembleInstruction(DBG_ADDR *addr)
{
   char		ch;
   BOOL		ret = TRUE;

   DEBUG_PrintAddress(addr, DEBUG_CurrThread->dbg_mode, TRUE);
   DEBUG_Printf(DBG_CHN_MESG, ": ");
   if (!DEBUG_READ_MEM_VERBOSE((void*)DEBUG_ToLinear(addr), &ch, sizeof(ch))) {
      DEBUG_Printf(DBG_CHN_MESG, "-- no code --");
      ret = FALSE;
   } else {
      DEBUG_Disasm(addr, TRUE);
   }
   DEBUG_Printf(DBG_CHN_MESG,"\n");
   return ret;
}

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

  if (xstart) {
    start = *xstart;
    DEBUG_GrabAddress(&start, TRUE);
  }
  if (xend) {
    end = *xend;
    DEBUG_GrabAddress(&end, TRUE);
  }
  if (!xstart && !xend) {
    last = DEBUG_LastDisassemble;
    if (!last.seg && !last.off)
      DEBUG_GetCurrentAddress( &last );

    for (i=0;i<offset;i++)
      if (!DEBUG_DisassembleInstruction(&last)) break;
    DEBUG_LastDisassemble = last;
    return;
  }
  last = start.addr;
  if (!xend) {
    for (i=0;i<offset;i++)
      if (!DEBUG_DisassembleInstruction(&last)) break;
    DEBUG_LastDisassemble = last;
    return;
  }
  while (last.off <= end.addr.off)
    if (!DEBUG_DisassembleInstruction(&last)) break;
  DEBUG_LastDisassemble = last;
  return;
}
