/*
 * argv_parse.c --- utility function for parsing a string into a
 * 	argc, argv array.
 *
 * This file defines a function argv_parse() which parsing a
 * passed-in string, handling double quotes and backslashes, and
 * creates an allocated argv vector which can be freed using the
 * argv_free() function.
 *
 * See argv_parse.h for the formal definition of the functions.
 *
 * Copyright 1999 by Theodore Ts'o.
 *
 * Permission to use, copy, modify, and distribute this software for
 * any purpose with or without fee is hereby granted, provided that
 * the above copyright notice and this permission notice appear in all
 * copies.  THE SOFTWARE IS PROVIDED "AS IS" AND THEODORE TS'O (THE
 * AUTHOR) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  (Isn't
 * it sick that the U.S. culture of lawsuit-happy lawyers requires
 * this kind of disclaimer?)
 *
 * Version 1.1, modified 2/27/1999
 */

#include "config.h"
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include <ctype.h>
#include <string.h>
#include "argv_parse.h"

#define STATE_WHITESPACE	1
#define STATE_TOKEN		2
#define STATE_QUOTED		3

/*
 * Returns 0 on success, -1 on failure.
 */
int argv_parse(char *in_buf, int *ret_argc, char ***ret_argv)
{
	int	argc = 0, max_argc = 0;
	char 	**argv, **new_argv, *buf, ch;
	char	*cp = 0, *outcp = 0;
	int	state = STATE_WHITESPACE;

	buf = malloc(strlen(in_buf)+1);
	if (!buf)
		return -1;

	max_argc = 0; argc = 0; argv = 0;
	outcp = buf;
	for (cp = in_buf; (ch = *cp); cp++) {
		if (state == STATE_WHITESPACE) {
			if (isspace((int) ch))
				continue;
			/* Not whitespace, so start a new token */
			state = STATE_TOKEN;
			if (argc >= max_argc) {
				max_argc += 3;
				new_argv = realloc(argv,
						  (max_argc+1)*sizeof(char *));
				if (!new_argv) {
					free(argv);
					free(buf);
					return -1;
				}
				argv = new_argv;
			}
			argv[argc++] = outcp;
		}
		if (state == STATE_QUOTED) {
			if (ch == '"')
				state = STATE_TOKEN;
			else
				*outcp++ = ch;
			continue;
		}
		/* Must be processing characters in a word */
		if (isspace((int) ch)) {
			/*
			 * Terminate the current word and start
			 * looking for the beginning of the next word.
			 */
			*outcp++ = 0;
			state = STATE_WHITESPACE;
			continue;
		}
		if (ch == '"') {
			state = STATE_QUOTED;
			continue;
		}
		if (ch == '\\') {
			ch = *++cp;
			switch (ch) {
			case '\0':
				ch = '\\'; cp--; break;
			case 'n':
				ch = '\n'; break;
			case 't':
				ch = '\t'; break;
			case 'b':
				ch = '\b'; break;
			}
		}
		*outcp++ = ch;
	}
	if (state != STATE_WHITESPACE)
		*outcp++ = '\0';
	if (argv == 0) {
		argv = malloc(sizeof(char *));
		free(buf);
	}
	argv[argc] = 0;
	if (ret_argc)
		*ret_argc = argc;
	if (ret_argv)
		*ret_argv = argv;
	return 0;
}

void argv_free(char **argv)
{
	free(*argv);
	free(argv);
}

#ifdef DEBUG
/*
 * For debugging
 */

#include <stdio.h>

int main(int argc, char **argv)
{
	int	ac, ret;
	char	**av, **cpp;
	char	buf[256];

	while (!feof(stdin)) {
		if (fgets(buf, sizeof(buf), stdin) == NULL)
			break;
		ret = argv_parse(buf, &ac, &av);
		if (ret != 0) {
			printf("Argv_parse returned %d!\n", ret);
			continue;
		}
		printf("Argv_parse returned %d arguments...\n", ac);
		for (cpp = av; *cpp; cpp++) {
			if (cpp != av)
				printf(", ");
			printf("'%s'", *cpp);
		}
		printf("\n");
		argv_free(av);
	}
	exit(0);
}
#endif /* DEBUG */
