/*
 * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or any later version.
 *
 * This program 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
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 * You can also choose to distribute this program under the terms of
 * the Unmodified Binary Distribution Licence (as given in the file
 * COPYING.UBDL), provided that you have satisfied its requirements.
 */

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
FILE_SECBOOT ( PERMITTED );

#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <getopt.h>

/** @file
 *
 * Parse command-line options
 *
 */

/**
 * Option argument
 *
 * This will point to the argument for the most recently returned
 * option, if applicable.
 */
char *optarg;

/**
 * Current option index
 *
 * This is an index into the argv[] array.  When getopt() returns -1,
 * @c optind is the index to the first element that is not an option.
 */
int optind;

/**
 * Current option character index
 *
 * This is an index into the current element of argv[].
 */
int nextchar;

/**
 * Unrecognised option
 *
 * When an unrecognised option is encountered, the actual option
 * character is stored in @c optopt.
 */
int optopt;

/**
 * Get option argument from argv[] array
 *
 * @v argc		Argument count
 * @v argv		Argument list
 * @ret argument	Option argument, or NULL
 *
 * Grab the next element of argv[], if it exists and is not an option.
 */
static const char * get_argv_argument ( int argc, char * const argv[] ) {
	char *arg;

	/* Don't overrun argv[] */
	if ( optind >= argc )
		return NULL;
	arg = argv[optind];

	/* If next argv element is an option, then it's not usable as
	 * an argument.
	 */
	if ( *arg == '-' )
		return NULL;

	/** Consume this argv element, and return it */
	optind++;
	return arg;
}

/**
 * Match long option
 *
 * @v argc		Argument count
 * @v argv		Argument list
 * @v opttext		Option text within current argv[] element
 * @v longopt		Long option specification
 * @ret option		Option to return from getopt()
 * @ret matched		Found a match for this long option
 */
static int match_long_option ( int argc, char * const argv[],
			       const char *opttext,
			       const struct option *longopt, int *option ) {
	size_t optlen;
	const char *argument = NULL;

	/* Compare option name */
	optlen = strlen ( longopt->name );
	if ( strncmp ( opttext, longopt->name, optlen ) != 0 )
		return 0;

	/* Check for inline argument */
	if ( opttext[optlen] == '=' ) {
		argument = &opttext[ optlen + 1 ];
	} else if ( opttext[optlen] ) {
		/* Long option with trailing garbage - no match */
		return 0;
	}

	/* Consume this argv element */
	optind++;

	/* If we want an argument but don't have one yet, try to grab
	 * the next argv element
	 */
	if ( ( longopt->has_arg != no_argument ) && ( ! argument ) )
		argument = get_argv_argument ( argc, argv );

	/* If we need an argument but don't have one, sulk */
	if ( ( longopt->has_arg == required_argument ) && ( ! argument ) ) {
		printf ( "Option \"%s\" requires an argument\n",
			 longopt->name );
		*option = ':';
		return 1;
	}

	/* If we have an argument where we shouldn't have one, sulk */
	if ( ( longopt->has_arg == no_argument ) && argument ) {
		printf ( "Option \"%s\" takes no argument\n", longopt->name );
		*option = ':';
		return 1;
	}

	/* Store values and return success */
	optarg = ( char * ) argument;
	if ( longopt->flag ) {
		*(longopt->flag) = longopt->val;
		*option = 0;
	} else {
		*option = longopt->val;
	}
	return 1;
}

/**
 * Match short option
 *
 * @v argc		Argument count
 * @v argv		Argument list
 * @v opttext		Option text within current argv[] element
 * @v shortopt		Option character from option specification
 * @ret option		Option to return from getopt()
 * @ret matched		Found a match for this short option
 */
static int match_short_option ( int argc, char * const argv[],
				const char *opttext, int shortopt,
				enum getopt_argument_requirement has_arg,
				int *option ) {
	const char *argument = NULL;

	/* Compare option character */
	if ( *opttext != shortopt )
		return 0;

	/* Consume option character */
	opttext++;
	nextchar++;
	if ( *opttext ) {
		if ( has_arg != no_argument ) {
			/* Consume remainder of element as inline argument */
			argument = opttext;
			optind++;
			nextchar = 0;
		}
	} else {
		/* Reached end of argv element */
		optind++;
		nextchar = 0;
	}

	/* If we want an argument but don't have one yet, try to grab
	 * the next argv element
	 */
	if ( ( has_arg != no_argument ) && ( ! argument ) )
		argument = get_argv_argument ( argc, argv );

	/* If we need an argument but don't have one, sulk */
	if ( ( has_arg == required_argument ) && ( ! argument ) ) {
		printf ( "Option \"%c\" requires an argument\n", shortopt );
		*option = ':';
		return 1;
	}

	/* Store values and return success */
	optarg = ( char * ) argument;
	*option = shortopt;
	return 1;
}

/**
 * Parse command-line options
 *
 * @v argc		Argument count
 * @v argv		Argument list
 * @v optstring		Option specification string
 * @v longopts		Long option specification table
 * @ret longindex	Index of long option (or NULL)
 * @ret option		Option found, or -1 for no more options
 *
 * Note that the caller must arrange for reset_getopt() to be called
 * before each set of calls to getopt_long().  In Etherboot, this is
 * done automatically by execv().
 */
int getopt_long ( int argc, char * const argv[], const char *optstring,
		  const struct option *longopts, int *longindex ) {
	const char *opttext = argv[optind];
	const struct option *longopt;
	int shortopt;
	enum getopt_argument_requirement has_arg;
	int option;

	/* Check for end of argv array */
	if ( optind >= argc )
		return -1;

	/* Check for end of options */
	if ( *(opttext++) != '-' )
		return -1;

	/* Check for long options */
	if ( *(opttext++) == '-' ) {
		/* "--" indicates end of options */
		if ( *opttext == '\0' ) {
			optind++;
			return -1;
		}
		for ( longopt = longopts ; longopt->name ; longopt++ ) {
			if ( ! match_long_option ( argc, argv, opttext,
						   longopt, &option ) )
				continue;
			if ( longindex )
				*longindex = ( longopt - longopts );
			return option;
		}
		optopt = '?';
		printf ( "Unrecognised option \"--%s\"\n", opttext );
		return '?';
	}

	/* Check for short options */
	if ( nextchar < 1 )
		nextchar = 1;
	opttext = ( argv[optind] + nextchar );
	while ( ( shortopt = *(optstring++) ) ) {
		has_arg = no_argument;
		while ( *optstring == ':' ) {
			has_arg++;
			optstring++;
		}
		if ( match_short_option ( argc, argv, opttext, shortopt,
					  has_arg, &option ) ) {
			return option;
		}
	}
	optopt = *opttext;
	printf ( "Unrecognised option \"-%c\"\n", optopt );
	return '?';
}
