/*
 * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

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

#include "debugger.h"

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

void source_show_path(void)
{
    const char* ptr;
    const char* next;

    dbg_printf("Search list:\n");
    for (ptr = dbg_curr_process->search_path; ptr; ptr = next)
    {
        next = strchr(ptr, ';');
        if (next)
            dbg_printf("\t%.*s\n", (int)(next++ - ptr), ptr);
        else
            dbg_printf("\t%s\n", ptr);
    }
    dbg_printf("\n");
}

void source_add_path(const char* path)
{
    char*       new;
    unsigned    size;

    size = strlen(path) + 1;
    if (dbg_curr_process->search_path)
    {
        unsigned pos = strlen(dbg_curr_process->search_path) + 1;
        new = HeapReAlloc(GetProcessHeap(), 0, dbg_curr_process->search_path, pos + size);
        if (!new) return;
        new[pos - 1] = ';';
        strcpy(&new[pos], path);
    }
    else
    {
        new = HeapAlloc(GetProcessHeap(), 0, size);
        if (!new) return;
        strcpy(new, path);
    }
    dbg_curr_process->search_path = new;
}

void source_nuke_path(struct dbg_process* p)
{
    HeapFree(GetProcessHeap(), 0, p->search_path);
    p->search_path = NULL;
}

static  void*   source_map_file(const char* name, HANDLE* hMap, unsigned* size)
{
    HANDLE              hFile;

    hFile = CreateFileA(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)) == INVALID_FILE_SIZE) {
        CloseHandle(hFile);
        return (void*)-1;
    }
    *hMap = CreateFileMappingW(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 = dbg_curr_process->source_ofiles; ol; ol = ol->next)
    {
        if (strcmp(ol->path, name) == 0) break;
    }
    return ol;
}

static BOOL     source_locate_file(const char* srcfile, char* path)
{
    BOOL        found = FALSE;

    if (GetFileAttributesA(srcfile) != INVALID_FILE_ATTRIBUTES)
    {
        strcpy(path, srcfile);
        found = TRUE;
    }
    else if (dbg_curr_process->search_path)
    {
        const char* spath;

        spath = srcfile;
        while (!found)
        {
            while (*spath && *spath != '/' && *spath != '\\') spath++;
            if (!*spath) break;
            spath++;
            found = SearchPathA(dbg_curr_process->search_path, spath, NULL, MAX_PATH, path, NULL);
        }
    }
    return found;
}

static struct open_file_list* source_add_file(const char* name, const char* realpath)
{
    struct open_file_list*      ol;
    size_t                      sz, nlen;

    sz = sizeof(*ol);
    nlen = strlen(name) + 1;
    if (realpath) sz += strlen(realpath) + 1;
    ol = HeapAlloc(GetProcessHeap(), 0, sz + nlen);
    if (!ol) return NULL;
    strcpy(ol->path = (char*)(ol + 1), name);
    if (realpath)
        strcpy(ol->real_path = ol->path + nlen, realpath);
    else
        ol->real_path = NULL;
    ol->next = dbg_curr_process->source_ofiles;
    ol->nlines = 0;
    ol->linelist = NULL;
    ol->size = 0;
    return dbg_curr_process->source_ofiles = 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;
    HANDLE                      hMap;
    char			tmppath[MAX_PATH];

    /*
     * 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.
         */
        if (!source_locate_file(sourcefile, tmppath))
        {
            if (dbg_interactiveP)
            {
                char zbuf[256];

                for (;;)
                {
                    size_t      len;
                    /*
                     * Still couldn't find it.  Ask user for path to add.
                     */
                    snprintf(zbuf, sizeof(zbuf), "Enter path to file '%s' (<cr> to end search): ", sourcefile);
                    input_read_line(zbuf, tmppath, sizeof(tmppath));
                    if (!(len = strlen(tmppath))) break;

                    /* append '/' if missing at the end */
                    if (tmppath[len - 1] != '/' && tmppath[len - 1] != '\\')
                        tmppath[len++] = '/';
                    strcpy(&tmppath[len], basename);
                    if (GetFileAttributesA(tmppath) != INVALID_FILE_ATTRIBUTES)
                        break;
                    dbg_printf("Unable to access file '%s'\n", tmppath);
                }
            }
            else
            {
                dbg_printf("Unable to access file '%s'\n", sourcefile);
                tmppath[0] = '\0';
            }

            if (!tmppath[0])
            {
                /*
                 * OK, I guess the user doesn't really want to see it
                 * after all.
                 */
                source_add_file(sourcefile, NULL);
                return FALSE;
            }
        }
        /*
         * Create header for file.
         */
        ol = source_add_file(sourcefile, tmppath);

        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_LINE64* src1, IMAGEHLP_LINE64* 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 = dbg_curr_process->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 = dbg_curr_process->source_start_line;
            start = end + delta;
	}
        else
	{
            start = dbg_curr_process->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 != dbg_curr_process->source_current_file)
        strcpy(dbg_curr_process->source_current_file, sourcefile);
    dbg_curr_process->source_start_line = start;
    dbg_curr_process->source_end_line = end;
}

void source_list_from_addr(const ADDRESS64* addr, int nlines)
{
    IMAGEHLP_LINE64     il;
    ADDRESS64           la;
    DWORD               disp;

    if (!addr)
    {
        memory_get_current_pc(&la);
        addr = &la;
    }

    il.SizeOfStruct = sizeof(il);
    if (SymGetLineFromAddr64(dbg_curr_process->handle,
                             (DWORD_PTR)memory_to_linear_addr(addr),
			     &disp, &il))
        source_list(&il, NULL, nlines);
}

void source_free_files(struct dbg_process* p)
{
    struct open_file_list*      ofile;
    struct open_file_list*      ofile_next;

    for (ofile = p->source_ofiles; ofile; ofile = ofile_next)
    {
        ofile_next = ofile->next;
        HeapFree(GetProcessHeap(), 0, ofile->linelist);
        HeapFree(GetProcessHeap(), 0, ofile);
    }
}
