/* aewm - a minimalist X11 window mananager. vim:sw=4:ts=4:et
 * Copyright 1998-2003 Decklin Foster <decklin@red-bean.com>
 * This program is free software; see LICENSE for details. */

#include "parser.h"
#include <string.h>
#include <ctype.h>

/* Our crappy parser. A token is either a whitespace-delimited word,
 * or a bunch or words in double quotes. Inside "", \" may be used.
 * src points to somewhere in a buffer -- the caller must save the
 * location of this buffer, because we update src to point past all
 * the tokens found so far. If we find a token, we write it into dest
 * (caller is responsible for allocating storage) and return 1.
 * Otherwise return 0. */

int get_token(char **src, char *dest)
{
    char *tok_start, *tok_end, *p;
    int quoted, nchars = 0;

    /* skip initial spaces */
    while (**src && isspace(**src)) (*src)++;

    if (*src[0] == '"') {
        quoted = 1;
        tok_start = *src+1;
        tok_end = strchr(tok_start, '"');
        if (!tok_end) return 0; /* unterminated quote */
        while (*(tok_end-1) == '\\')
            tok_end = strchr(tok_end+1, '"');
    } else {
        quoted = 0;
        tok_start = *src;
        tok_end = strpbrk(*src, " \t\n");
    }

    p = tok_start;
    while (tok_end ? p < tok_end : *p) {
        if (quoted && *p == '\\' && *(p+1) == '"') {
            p++;
        } else {
            nchars++;
            *dest++ = *p++;
        }
    }
    *dest = '\0';

    *src = ++tok_end;
    return nchars || quoted;
}
