/*
 * File helper functions.
 *
 *  Copyright (C) 2001-2007  Peter Johnson
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#include <util.h>
/*@unused@*/ RCSID("$Id: file.c 2116 2008-07-15 05:49:29Z peter $");

/* Need either unistd.h or direct.h (on Windows) to prototype getcwd() */
#if defined(HAVE_UNISTD_H)
#include <unistd.h>
#elif defined(HAVE_DIRECT_H)
#include <direct.h>
#endif

#include <ctype.h>
#include <errno.h>

#include "errwarn.h"
#include "file.h"

#define BSIZE   8192        /* Fill block size */


void
yasm_scanner_initialize(yasm_scanner *s)
{
    s->bot = NULL;
    s->tok = NULL;
    s->ptr = NULL;
    s->cur = NULL;
    s->lim = NULL;
    s->top = NULL;
    s->eof = NULL;
}

void
yasm_scanner_delete(yasm_scanner *s)
{
    if (s->bot) {
        yasm_xfree(s->bot);
        s->bot = NULL;
    }
}

int
yasm_fill_helper(yasm_scanner *s, unsigned char **cursor,
                 size_t (*input_func) (void *d, unsigned char *buf,
                                       size_t max),
                 void *input_func_data)
{
    size_t cnt;
    int first = 0;

    if (s->eof)
        return 0;

    cnt = s->tok - s->bot;
    if (cnt > 0) {
        memmove(s->bot, s->tok, (size_t)(s->lim - s->tok));
        s->tok = s->bot;
        s->ptr -= cnt;
        *cursor -= cnt;
        s->lim -= cnt;
    }
    if (!s->bot)
        first = 1;
    if ((s->top - s->lim) < BSIZE) {
        unsigned char *buf = yasm_xmalloc((size_t)(s->lim - s->bot) + BSIZE);
        memcpy(buf, s->tok, (size_t)(s->lim - s->tok));
        s->tok = buf;
        s->ptr = &buf[s->ptr - s->bot];
        *cursor = &buf[*cursor - s->bot];
        s->lim = &buf[s->lim - s->bot];
        s->top = &s->lim[BSIZE];
        if (s->bot)
            yasm_xfree(s->bot);
        s->bot = buf;
    }
    if ((cnt = input_func(input_func_data, s->lim, BSIZE)) == 0) {
        s->eof = &s->lim[cnt];
        *s->eof++ = '\n';
    }
    s->lim += cnt;
    return first;
}

void
yasm_unescape_cstring(unsigned char *str, size_t *len)
{
    unsigned char *s = str;
    unsigned char *o = str;
    unsigned char t[4];

    while ((size_t)(s-str)<*len) {
        if (*s == '\\' && (size_t)(&s[1]-str)<*len) {
            s++;
            switch (*s) {
                case 'b': *o = '\b'; s++; break;
                case 'f': *o = '\f'; s++; break;
                case 'n': *o = '\n'; s++; break;
                case 'r': *o = '\r'; s++; break;
                case 't': *o = '\t'; s++; break;
                case 'x':
                    /* hex escape; grab last two digits */
                    s++;
                    while ((size_t)(&s[2]-str)<*len && isxdigit(s[0])
                           && isxdigit(s[1]) && isxdigit(s[2]))
                        s++;
                    if ((size_t)(s-str)<*len && isxdigit(*s)) {
                        t[0] = *s++;
                        t[1] = '\0';
                        t[2] = '\0';
                        if ((size_t)(s-str)<*len && isxdigit(*s))
                            t[1] = *s++;
                        *o = (unsigned char)strtoul((char *)t, NULL, 16);
                    } else
                        *o = '\0';
                    break;
                default:
                    if (isdigit(*s)) {
                        int warn = 0;
                        /* octal escape */
                        if (*s > '7')
                            warn = 1;
                        *o = *s++ - '0';
                        if ((size_t)(s-str)<*len && isdigit(*s)) {
                            if (*s > '7')
                                warn = 1;
                            *o <<= 3;
                            *o += *s++ - '0';
                            if ((size_t)(s-str)<*len && isdigit(*s)) {
                                if (*s > '7')
                                    warn = 1;
                                *o <<= 3;
                                *o += *s++ - '0';
                            }
                        }
                        if (warn)
                            yasm_warn_set(YASM_WARN_GENERAL,
                                          N_("octal value out of range"));
                    } else
                        *o = *s++;
                    break;
            }
            o++;
        } else
            *o++ = *s++;
    }
    *len = o-str;
}

size_t
yasm__splitpath_unix(const char *path, /*@out@*/ const char **tail)
{
    const char *s;
    s = strrchr(path, '/');
    if (!s) {
        /* No head */
        *tail = path;
        return 0;
    }
    *tail = s+1;
    /* Strip trailing ./ on path */
    while ((s-1)>=path && *(s-1) == '.' && *s == '/'
           && !((s-2)>=path && *(s-2) == '.'))
        s -= 2;
    /* Strip trailing slashes on path (except leading) */
    while (s>path && *s == '/')
        s--;
    /* Return length of head */
    return s-path+1;
}

size_t
yasm__splitpath_win(const char *path, /*@out@*/ const char **tail)
{
    const char *basepath = path;
    const char *s;

    /* split off drive letter first, if any */
    if (isalpha(path[0]) && path[1] == ':')
        basepath += 2;

    s = basepath;
    while (*s != '\0')
        s++;
    while (s >= basepath && *s != '\\' && *s != '/')
        s--;
    if (s < basepath) {
        *tail = basepath;
        if (path == basepath)
            return 0;   /* No head */
        else
            return 2;   /* Drive letter is head */
    }
    *tail = s+1;
    /* Strip trailing .\ or ./ on path */
    while ((s-1)>=basepath && *(s-1) == '.' && (*s == '/' || *s == '\\')
           && !((s-2)>=basepath && *(s-2) == '.'))
        s -= 2;
    /* Strip trailing slashes on path (except leading) */
    while (s>basepath && (*s == '/' || *s == '\\'))
        s--;
    /* Return length of head */
    return s-path+1;
}

char *
yasm__getcwd(void)
{
    char *buf;
    size_t size;

    size = 1024;
    buf = yasm_xmalloc(size);
    while (getcwd(buf, size) == NULL) {
        if (errno != ERANGE) {
            yasm__fatal(N_("could not determine current working directory"));
            yasm_xfree(buf);
            return NULL;
        }
        size *= 2;
        buf = yasm_xrealloc(buf, size);
    }
    return buf;
}

char *
yasm__abspath(const char *path)
{
    char *curdir, *abspath;

    curdir = yasm__getcwd();
    abspath = yasm__combpath(curdir, path);
    yasm_xfree(curdir);

    return abspath;
}

char *
yasm__combpath_unix(const char *from, const char *to)
{
    const char *tail;
    size_t pathlen, i, j;
    char *out;

    if (to[0] == '/') {
        /* absolute "to" */
        out = yasm_xmalloc(strlen(to)+1);
        /* Combine any double slashes when copying */
        for (j=0; *to; to++) {
            if (*to == '/' && *(to+1) == '/')
                continue;
            out[j++] = *to;
        }
        out[j++] = '\0';
        return out;
    }

    /* Get path component; note this strips trailing slash */
    pathlen = yasm__splitpath_unix(from, &tail);

    out = yasm_xmalloc(pathlen+strlen(to)+2);   /* worst case maximum len */

    /* Combine any double slashes when copying */
    for (i=0, j=0; i<pathlen; i++) {
        if (i<pathlen-1 && from[i] == '/' && from[i+1] == '/')
            continue;
        out[j++] = from[i];
    }
    pathlen = j;

    /* Add trailing slash back in */
    if (pathlen > 0 && out[pathlen-1] != '/')
        out[pathlen++] = '/';

    /* Now scan from left to right through "to", stripping off "." and "..";
     * if we see "..", back up one directory in out unless last directory in
     * out is also "..".
     *
     * Note this does NOT back through ..'s in the "from" path; this is just
     * as well as that could skip symlinks (e.g. "foo/bar/.." might not be
     * the same as "foo").
     */
    for (;;) {
        if (to[0] == '.' && to[1] == '/') {
            to += 2;        /* current directory */
            while (*to == '/')
                to++;           /* strip off any additional slashes */
        } else if (pathlen == 0)
            break;          /* no more "from" path left, we're done */
        else if (to[0] == '.' && to[1] == '.' && to[2] == '/') {
            if (pathlen >= 3 && out[pathlen-1] == '/' && out[pathlen-2] == '.'
                && out[pathlen-3] == '.') {
                /* can't ".." against a "..", so we're done. */
                break;
            }

            to += 3;    /* throw away "../" */
            while (*to == '/')
                to++;           /* strip off any additional slashes */

            /* and back out last directory in "out" if not already at root */
            if (pathlen > 1) {
                pathlen--;      /* strip off trailing '/' */
                while (pathlen > 0 && out[pathlen-1] != '/')
                    pathlen--;
            }
        } else
            break;
    }

    /* Copy "to" to tail of output, and we're done */
    /* Combine any double slashes when copying */
    for (j=pathlen; *to; to++) {
        if (*to == '/' && *(to+1) == '/')
            continue;
        out[j++] = *to;
    }
    out[j++] = '\0';

    return out;
}

char *
yasm__combpath_win(const char *from, const char *to)
{
    const char *tail;
    size_t pathlen, i, j;
    char *out;

    if ((isalpha(to[0]) && to[1] == ':') || (to[0] == '/' || to[0] == '\\')) {
        /* absolute or drive letter "to" */
        out = yasm_xmalloc(strlen(to)+1);
        /* Combine any double slashes when copying */
        for (j=0; *to; to++) {
            if ((*to == '/' || *to == '\\')
                && (*(to+1) == '/' || *(to+1) == '\\'))
                continue;
            if (*to == '/')
                out[j++] = '\\';
            else
                out[j++] = *to;
        }
        out[j++] = '\0';
        return out;
    }

    /* Get path component; note this strips trailing slash */
    pathlen = yasm__splitpath_win(from, &tail);

    out = yasm_xmalloc(pathlen+strlen(to)+2);   /* worst case maximum len */

    /* Combine any double slashes when copying */
    for (i=0, j=0; i<pathlen; i++) {
        if (i<pathlen-1 && (from[i] == '/' || from[i] == '\\')
            && (from[i+1] == '/' || from[i+1] == '\\'))
            continue;
        if (from[i] == '/')
            out[j++] = '\\';
        else
            out[j++] = from[i];
    }
    pathlen = j;

    /* Add trailing slash back in, unless it's only a raw drive letter */
    if (pathlen > 0 && out[pathlen-1] != '\\'
        && !(pathlen == 2 && isalpha(out[0]) && out[1] == ':'))
        out[pathlen++] = '\\';

    /* Now scan from left to right through "to", stripping off "." and "..";
     * if we see "..", back up one directory in out unless last directory in
     * out is also "..".
     *
     * Note this does NOT back through ..'s in the "from" path; this is just
     * as well as that could skip symlinks (e.g. "foo/bar/.." might not be
     * the same as "foo").
     */
    for (;;) {
        if (to[0] == '.' && (to[1] == '/' || to[1] == '\\')) {
            to += 2;        /* current directory */
            while (*to == '/' || *to == '\\')
                to++;           /* strip off any additional slashes */
        } else if (pathlen == 0
                 || (pathlen == 2 && isalpha(out[0]) && out[1] == ':'))
            break;          /* no more "from" path left, we're done */
        else if (to[0] == '.' && to[1] == '.'
                 && (to[2] == '/' || to[2] == '\\')) {
            if (pathlen >= 3 && out[pathlen-1] == '\\'
                && out[pathlen-2] == '.' && out[pathlen-3] == '.') {
                /* can't ".." against a "..", so we're done. */
                break;
            }

            to += 3;    /* throw away "../" (or "..\") */
            while (*to == '/' || *to == '\\')
                to++;           /* strip off any additional slashes */

            /* and back out last directory in "out" if not already at root */
            if (pathlen > 1) {
                pathlen--;      /* strip off trailing '/' */
                while (pathlen > 0 && out[pathlen-1] != '\\')
                    pathlen--;
            }
        } else
            break;
    }

    /* Copy "to" to tail of output, and we're done */
    /* Combine any double slashes when copying */
    for (j=pathlen; *to; to++) {
        if ((*to == '/' || *to == '\\') && (*(to+1) == '/' || *(to+1) == '\\'))
            continue;
        if (*to == '/')
            out[j++] = '\\';
        else
            out[j++] = *to;
    }
    out[j++] = '\0';

    return out;
}

typedef struct incpath {
    STAILQ_ENTRY(incpath) link;
    /*@owned@*/ char *path;
} incpath;

STAILQ_HEAD(, incpath) incpaths = STAILQ_HEAD_INITIALIZER(incpaths);

FILE *
yasm_fopen_include(const char *iname, const char *from, const char *mode,
                   char **oname)
{
    FILE *f;
    char *combine;
    incpath *np;

    /* Try directly relative to from first, then each of the include paths */
    if (from) {
        combine = yasm__combpath(from, iname);
        f = fopen(combine, mode);
        if (f) {
            if (oname)
                *oname = combine;
            else
                yasm_xfree(combine);
            return f;
        }
        yasm_xfree(combine);
    }

    STAILQ_FOREACH(np, &incpaths, link) {
        combine = yasm__combpath(np->path, iname);
        f = fopen(combine, mode);
        if (f) {
            if (oname)
                *oname = combine;
            else
                yasm_xfree(combine);
            return f;
        }
        yasm_xfree(combine);
    }

    if (oname)
        *oname = NULL;
    return NULL;
}

void
yasm_delete_include_paths(void)
{
    incpath *n1, *n2;

    n1 = STAILQ_FIRST(&incpaths);
    while (n1) {
        n2 = STAILQ_NEXT(n1, link);
        yasm_xfree(n1->path);
        yasm_xfree(n1);
        n1 = n2;
    }
    STAILQ_INIT(&incpaths);
}

const char *
yasm_get_include_dir(void **iter)
{
    incpath *p = (incpath *)*iter;

    if (!p)
        p = STAILQ_FIRST(&incpaths);
    else
        p = STAILQ_NEXT(p, link);

    *iter = p;
    if (p)
        return p->path;
    else
        return NULL;
}

void
yasm_add_include_path(const char *path)
{
    incpath *np = yasm_xmalloc(sizeof(incpath));
    size_t len = strlen(path);

    np->path = yasm_xmalloc(len+2);
    memcpy(np->path, path, len+1);
    /* Add trailing slash if it is missing */
    if (path[len-1] != '\\' && path[len-1] != '/') {
        np->path[len] = '/';
        np->path[len+1] = '\0';
    }

    STAILQ_INSERT_TAIL(&incpaths, np, link);
}

size_t
yasm_fwrite_16_l(unsigned short val, FILE *f)
{
    if (fputc(val & 0xFF, f) == EOF)
        return 0;
    if (fputc((val >> 8) & 0xFF, f) == EOF)
        return 0;
    return 1;
}

size_t
yasm_fwrite_32_l(unsigned long val, FILE *f)
{
    if (fputc((int)(val & 0xFF), f) == EOF)
        return 0;
    if (fputc((int)((val >> 8) & 0xFF), f) == EOF)
        return 0;
    if (fputc((int)((val >> 16) & 0xFF), f) == EOF)
        return 0;
    if (fputc((int)((val >> 24) & 0xFF), f) == EOF)
        return 0;
    return 1;
}

size_t
yasm_fwrite_16_b(unsigned short val, FILE *f)
{
    if (fputc((val >> 8) & 0xFF, f) == EOF)
        return 0;
    if (fputc(val & 0xFF, f) == EOF)
        return 0;
    return 1;
}

size_t
yasm_fwrite_32_b(unsigned long val, FILE *f)
{
    if (fputc((int)((val >> 24) & 0xFF), f) == EOF)
        return 0;
    if (fputc((int)((val >> 16) & 0xFF), f) == EOF)
        return 0;
    if (fputc((int)((val >> 8) & 0xFF), f) == EOF)
        return 0;
    if (fputc((int)(val & 0xFF), f) == EOF)
        return 0;
    return 1;
}
