/*
    Copyright (C) 1995-1997
        Rainer Schnitker, Heeper Str. 283, 33607 Bielefeld
        email: rainer@mathematik.uni-bielefeld.de

    All rights reserved
*/

#include <rsxnt.h>
#include <string.h>
#include <ctype.h>

static void parse_arg(char *, char **, const char *, int *, int *);

struct argenv {
    char *esp;
    char *ArgPtr;
    char *EnvPtr;
    int argc;
    int envc;
    int space;
};

void __cdecl get_argv_env(struct argenv * ae)
{
    char *mem;
    int len, size;

    ae->ArgPtr = (char *) GetCommandLineA();

    parse_arg(ae->ArgPtr, NULL, ae->ArgPtr, &ae->argc, &len);
    
    ae->EnvPtr = mem = (char *) GetEnvironmentStrings();
    ae->envc = 0;

    /* count env string */
    while (*mem) {
        ae->envc++;
        size = lstrlen(mem) + 1;
        mem += size;
        len += size;
    }

    /* space needed on stack */
    ae->space = (ae->argc + ae->envc + 2) * sizeof(char *) + len;
    ae->space = (ae->space + 3) & ~3;
}

void __cdecl cpy_argv_env(struct argenv * ae)
{
    char **argv, **env;
    char *str, *mem;
    int i, len;

    env = (char **) ae->esp;
    argv = env + ae->envc + 1;
    str = ae->esp + (ae->argc + ae->envc + 2) * sizeof(char *);

    parse_arg(str, argv, ae->ArgPtr, &ae->argc, &len);

    /* fill environment */
    str += len + 1;
    i = 0;
    mem = ae->EnvPtr;
    while (*mem) {
        char *upr;
        len = lstrlen(mem) + 1;
        memcpy (str, mem, len);
        upr = str;
        while (*upr && *upr != '=')
            *upr++ = (char) CharUpper((LPTSTR) *upr);
        env[i++] = str;
        mem += len;
        str += len;
    }
    env[i] = NULL;
}

void parse_arg (char *dstbuf, char **argvec, const char *cline, int *arg_count, int * arg_size)
{
    int argc, src, dst, bs, quote;
    char *q;

    argc = 0;
    dst = src = 0;

    while (cline[src] == ' ' || cline[src] == '\t' || cline[src] == '\n')
        ++src;
    do {
        if (cline[src] == 0)
            q = NULL;
        else {
            q = dstbuf + dst;
            bs = 0;
            quote = 0;
            for (;;) {
                if (cline[src] == '"') {
                    while (bs >= 2) {
                        if (argvec)
                            dstbuf[dst] = '\\';
                        ++dst;
                        bs -= 2;
                    }
                    if (bs & 1) {
                        if (argvec)
                            dstbuf[dst] = '"';
                        ++dst;
                    }
                    else
                        quote = !quote;
                    bs = 0;
                } else if (cline[src] == '\\')
                    ++bs;
                else {
                    while (bs != 0) {
                        if (argvec)
                            dstbuf[dst] = '\\';
                        ++dst;
                        --bs;
                    }
                    if ((cline[src] == ' ' || cline[src] == '\t') && !quote)
                        break;
                    if (argvec)
                        dstbuf[dst] = cline[src];
                    ++dst;
                    if (cline[src] == 0)
                        break;
                }
                ++src;
            }
            while (cline[src] == ' ' || cline[src] == '\t'
                || cline[src] == '\n')
                ++src;
            if (argvec)
                dstbuf[dst] = 0;
            dst++;
        }
        if (argvec)
            argvec[argc] = q;
        argc++;
    } while (q != NULL);

    *arg_count = argc - 1;
    *arg_size = dst;
}
