/*
 * 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>

#ifndef PATH_MAX
#define PATH_MAX MAX_PATH
#endif

#include "debugger.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(winedbg);

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


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

static struct open_file_list*   source_ofiles;

static struct search_list*      source_list_head;
static char source_current_file[PATH_MAX];
static int source_start_line = -1;
static int source_end_line = -1;

void source_show_path(void)
{
    struct search_list* sl;

    dbg_printf("Search list:\n");
    for (sl = source_list_head; sl; sl = sl->next) dbg_printf("\t%s\n", sl->path);
    dbg_printf("\n");
}

void source_add_path(const char* path)
{
    struct search_list* sl;

    if (!(sl = HeapAlloc(GetProcessHeap(), 0, sizeof(struct search_list))))
        return;

    sl->next = source_list_head;
    sl->path = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(path) + 1), path);
    source_list_head = sl;
}

void source_nuke_path(void)
{
    struct search_list* sl;
    struct search_list* nxt;

    for (sl = source_list_head; sl; sl = nxt)
    {
        nxt = sl->next;
        HeapFree(GetProcessHeap(), 0, sl->path);
        HeapFree(GetProcessHeap(), 0, sl);
    }

    source_list_head = NULL;
}

static  void*   source_map_file(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     source_unmap_file(void* addr, HANDLE hMap)
{
    UnmapViewOfFile(addr);
    CloseHandle(hMap);
}

static struct open_file_list* source_search_open_file(const char* name)
{
    struct open_file_list*      ol;

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

static int source_display(const char* sourcefile, int start, int end)
{
    char*                       addr;
    int				i;
    struct open_file_list*      ol;
    int				nlines;
    const char*                 basename = NULL;
    char*                       pnt;
    int				rtn;
    struct search_list*         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 = source_search_open_file(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 = source_search_open_file(basename);
    }

    if (ol == NULL)
    {
        /*
         * Crapola.  We need to try and open the file.
         */
        status = GetFileAttributes(sourcefile);
        if (status != INVALID_FILE_ATTRIBUTES)
        {
            strcpy(tmppath, sourcefile);
        }
        else if ((status = GetFileAttributes(basename)) != INVALID_FILE_ATTRIBUTES)
        {
            strcpy(tmppath, basename);
        }
        else
        {
            for (sl = source_list_head; 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 != INVALID_FILE_ATTRIBUTES) break;
            }

            if (sl == NULL)
            {
                if (dbg_interactiveP)
                {
                    char zbuf[256];
                    /*
                     * Still couldn't find it.  Ask user for path to add.
                     */
                    snprintf(zbuf, sizeof(zbuf), "Enter path to file '%s': ", sourcefile);
                    input_read_line(zbuf, tmppath, sizeof(tmppath));

                    if (tmppath[strlen(tmppath) - 1] != '/')
                    {
                        strcat(tmppath, "/");
                    }
                    /*
                     * Now append the base file name.
                     */
                    strcat(tmppath, basename);

                    status = GetFileAttributes(tmppath);
                }
                else
                {
                    status = INVALID_FILE_ATTRIBUTES;
                    strcpy(tmppath, sourcefile);
                }

                if (status == INVALID_FILE_ATTRIBUTES)
                {
                    /*
                     * OK, I guess the user doesn't really want to see it
                     * after all.
                     */
                    ol = HeapAlloc(GetProcessHeap(), 0, sizeof(*ol));
                    ol->path = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(sourcefile) + 1), sourcefile);
                    ol->real_path = NULL;
                    ol->next = source_ofiles;
                    ol->nlines = 0;
                    ol->linelist = NULL;
                    source_ofiles = ol;
                    dbg_printf("Unable to open file %s\n", tmppath);
                    return FALSE;
                }
            }
        }
        /*
         * Create header for file.
         */
        ol = HeapAlloc(GetProcessHeap(), 0, sizeof(*ol));
        ol->path = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(sourcefile) + 1), sourcefile);
        ol->real_path = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(tmppath) + 1), tmppath);
        ol->next = source_ofiles;
        ol->nlines = 0;
        ol->linelist = NULL;
        ol->size = 0;
        source_ofiles = ol;

        addr = source_map_file(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 = HeapAlloc(GetProcessHeap(), 0, 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 = source_map_file(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);
	}
        dbg_printf("%d\t%s\n", i + 1, buffer);
    }

    source_unmap_file(addr, hMap);
    return rtn;
}

void source_list(IMAGEHLP_LINE* src1, IMAGEHLP_LINE* src2, int delta)
{
    int         end;
    int         start;
    const char* sourcefile;

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

    sourcefile = NULL;
    if (src1 && src1->FileName) sourcefile = src1->FileName;
    if (!sourcefile && src2 && src2->FileName) sourcefile = src2->FileName;
    if (!sourcefile) sourcefile = source_current_file;

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

    if (src1) start = src1->LineNumber;
    if (src2) end   = src2->LineNumber;
    if (start == -1 && end == -1)
    {
        if (delta < 0)
	{
            end = source_start_line;
            start = end + delta;
	}
        else
	{
            start = source_end_line;
            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.
     */
    source_display(sourcefile, start, end);

    if (sourcefile != source_current_file)
        strcpy(source_current_file, sourcefile);
    source_start_line = start;
    source_end_line = end;
}

void source_list_from_addr(const ADDRESS* addr, int nlines)
{
    IMAGEHLP_LINE       il;
    DWORD               lin;

    if (!addr)
    {
        ADDRESS la;
        memory_get_current_pc(&la);
        lin = (unsigned long)memory_to_linear_addr(&la);
    }
    else lin = (unsigned long)memory_to_linear_addr(addr);

    il.SizeOfStruct = sizeof(il);
    if (SymGetLineFromAddr(dbg_curr_process->handle, lin, NULL, &il))
        source_list(&il, NULL, nlines);
}
