/*
 *  getopt.c - Enhanced implementation of BSD getopt(1)
 *  Copyright (c) 1997-2014 Frodo Looijaard <frodo@frodo.looijaard.name>
 *
 *  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
 *  (at your option) 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.
 */

/*
 * Version 1.0-b4: Tue Sep 23 1997. First public release.
 * Version 1.0: Wed Nov 19 1997.
 *   Bumped up the version number to 1.0
 *   Fixed minor typo (CSH instead of TCSH)
 * Version 1.0.1: Tue Jun 3 1998
 *   Fixed sizeof instead of strlen bug
 *   Bumped up the version number to 1.0.1
 * Version 1.0.2: Thu Jun 11 1998 (not present)
 *   Fixed gcc-2.8.1 warnings
 *   Fixed --version/-V option (not present)
 * Version 1.0.5: Tue Jun 22 1999
 *   Make -u option work (not present)
 * Version 1.0.6: Tue Jun 27 2000
 *   No important changes
 * Version 1.1.0: Tue Jun 30 2000
 *   Added NLS support (partly written by Arkadiusz Miśkiewicz
 *     <misiek@pld.org.pl>)
 * Version 1.1.4: Mon Nov 7 2005
 *   Fixed a few type's in the manpage
 * Version 1.1.5: Sun Aug 12 2012
 *  Sync with util-linux-2.21, fixed build problems, many new translations
 * Version 1.1.6: Mon Nov 24 2014
 *  Sync with util-linux git 20141120, detect ambiguous long options, fix
 *  backslash problem in tcsh
 */

/* Exit codes:
 *   0) No errors, successful operation.
 *   1) getopt(3) returned an error.
 *   2) A problem with parameter parsing for getopt(1).
 *   3) Internal error, out of memory
 *   4) Returned for -T
 */
#define GETOPT_EXIT_CODE	1
#define PARAMETER_EXIT_CODE	2
#define XALLOC_EXIT_CODE	3
#define CLOSE_EXIT_CODE		XALLOC_EXIT_CODE
#define TEST_EXIT_CODE		4

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <getopt.h>
#ifdef HAVE_SYS_PARAM_H
# include <sys/param.h> /* BSD */
#endif

#include "closestream.h"
#include "nls.h"
#include "xalloc.h"

/* NON_OPT is the code that is returned getopt(3) when a non-option is
 * found in 'char optstring[]="-abc...";', e.g., it begins by '-' */
#define NON_OPT 1
/* LONG_OPT is the code that is returned when a long option is found. */
#define LONG_OPT 0

/* The shells recognized. */
typedef enum { BASH, TCSH } shell_t;

struct getopt_control {
	shell_t shell;			/* the shell we generate output for */
	char *optstr;			/* getopt(3) optstring */
	char *name;
	struct option *long_options;	/* long options */
	int long_options_length;	/* length of options array */
	int long_options_nr;		/* number of used elements in array */
	unsigned int
		compatible:1,		/* compatibility mode for 'difficult' programs */
		quiet_errors:1,		/* print errors */
		quiet_output:1,		/* print output */
		quote:1;		/* quote output */
};

enum { REALLOC_INCREMENT = 8 };

/* Allow changing which getopt is in use with function pointer. */
int (*getopt_long_fp) (int argc, char *const *argv, const char *optstr,
		       const struct option * longopts, int *longindex);

/*
 * This function 'normalizes' a single argument: it puts single quotes
 * around it and escapes other special characters. If quote is false, it
 * just returns its argument.
 *
 * Bash only needs special treatment for single quotes; tcsh also recognizes
 * exclamation marks within single quotes, and nukes whitespace. This
 * function returns a pointer to a buffer that is overwritten by each call.
 */
static void print_normalized(const struct getopt_control *ctl, const char *arg)
{
	char *buf;
	const char *argptr = arg;
	char *bufptr;

	if (!ctl->quote) {
		printf(" %s", arg);
		return;
	}

	/*
	 * Each character in arg may take up to four characters in the
	 * result: For a quote we need a closing quote, a backslash, a quote
	 * and an opening quote! We need also the global opening and closing
	 * quote, and one extra character for '\0'.
	 */
	buf = xmalloc(strlen(arg) * 4 + 3);
	bufptr = buf;

	for (*bufptr++ = '\''; *argptr; argptr++) {
		if (ctl->shell == TCSH) {
			switch (*argptr) {
			case '\\':
				/* Backslash: replace it with: '\\' */
				*bufptr++ = '\\';
				*bufptr++ = '\\';
				continue;
			case '!':
				/* Exclamation mark: replace it with: \! */
				*bufptr++ = '\'';
				*bufptr++ = '\\';
				*bufptr++ = '!';
				*bufptr++ = '\'';
				continue;
			case '\n':
				/* Newline: replace it with: \n */
				*bufptr++ = '\\';
				*bufptr++ = 'n';
				continue;
			}
			if (isspace(*argptr)) {
				/* Non-newline whitespace: replace it with \<ws> */
				*bufptr++ = '\'';
				*bufptr++ = '\\';
				*bufptr++ = *argptr;
				*bufptr++ = '\'';
				continue;
			}
		}
		if (*argptr == '\'') {
			/* Quote: replace it with: '\'' */
			*bufptr++ = '\'';
			*bufptr++ = '\\';
			*bufptr++ = '\'';
			*bufptr++ = '\'';
		} else
			/* Just copy */
			*bufptr++ = *argptr;
	}

	*bufptr++ = '\'';
	*bufptr++ = '\0';
	printf(" %s", buf);
	free(buf);
}

/*
 * Generate the output. argv[0] is the program name (used for reporting errors).
 * argv[1..] contains the options to be parsed. argc must be the number of
 * elements in argv (ie. 1 if there are no options, only the program name),
 * optstr must contain the short options, and longopts the long options.
 * Other settings are found in global variables.
 */
static int generate_output(struct getopt_control *ctl, char *argv[], int argc)
{
	int exit_code = EXIT_SUCCESS;	/* Assume everything will be OK */
	int opt;
	int longindex;
	const char *charptr;

	if (ctl->quiet_errors)
		/* No error reporting from getopt(3) */
		opterr = 0;
	/* Reset getopt(3) */
	optind = 0;

	while ((opt =
		(getopt_long_fp
		 (argc, argv, ctl->optstr,
		  (const struct option *)ctl->long_options, &longindex)))
	       != EOF) {
		if (opt == '?' || opt == ':')
			exit_code = GETOPT_EXIT_CODE;
		else if (!ctl->quiet_output) {
			switch (opt) {
			case LONG_OPT:
				printf(" --%s", ctl->long_options[longindex].name);
				if (ctl->long_options[longindex].has_arg)
					print_normalized(ctl, optarg ? optarg : "");
				break;
			case NON_OPT:
				print_normalized(ctl, optarg ? optarg : "");
				break;
			default:
				printf(" -%c", opt);
				charptr = strchr(ctl->optstr, opt);
				if (charptr != NULL && *++charptr == ':')
					print_normalized(ctl, optarg ? optarg : "");
			}
		}
	}
	if (!ctl->quiet_output) {
		printf(" --");
		while (optind < argc)
			print_normalized(ctl, argv[optind++]);
		printf("\n");
	}
	for (longindex = 0; longindex < ctl->long_options_nr; longindex++)
		free((char *)ctl->long_options[longindex].name);
	free(ctl->long_options);
	free(ctl->optstr);
	free(ctl->name);
	return exit_code;
}

/*
 * Report an error when parsing getopt's own arguments. If message is NULL,
 * we already sent a message, we just exit with a helpful hint.
 */
static void __attribute__ ((__noreturn__)) parse_error(const char *message)
{
	if (message)
		warnx("%s", message);
	fprintf(stderr, _("Try `%s --help' for more information.\n"),
		program_invocation_short_name);
	exit(PARAMETER_EXIT_CODE);
}


/* Register a long option. The contents of name is copied. */
static void add_longopt(struct getopt_control *ctl, const char *name, int has_arg)
{
	static int flag;
	int nr = ctl->long_options_nr;

	if (ctl->long_options_nr == ctl->long_options_length) {
		ctl->long_options_length += REALLOC_INCREMENT;
		ctl->long_options = xrealloc(ctl->long_options,
					     sizeof(struct option) *
					     ctl->long_options_length);
	}
	if (name) {
		/* Not for init! */
		ctl->long_options[nr].has_arg = has_arg;
		ctl->long_options[nr].flag = &flag;
		ctl->long_options[nr].val = ctl->long_options_nr;
		ctl->long_options[nr].name = xstrdup(name);
	} else {
		/* lets use add_longopt(ct, NULL, 0) to terminate the array */
		ctl->long_options[nr].name = NULL;
		ctl->long_options[nr].has_arg = 0;
		ctl->long_options[nr].flag = NULL;
		ctl->long_options[nr].val = 0;
	}
}


/*
 * Register several long options. options is a string of long options,
 * separated by commas or whitespace. This nukes options!
 */
static void add_long_options(struct getopt_control *ctl, char *options)
{
	int arg_opt;
	char *tokptr = strtok(options, ", \t\n");

	while (tokptr) {
		size_t len = strlen(tokptr);

		arg_opt = no_argument;
		if (len > 0) {
			if (tokptr[len - 1] == ':') {
				if (tokptr[len - 2] == ':') {
					tokptr[len - 2] = '\0';
					arg_opt = optional_argument;
				} else {
					tokptr[len - 1] = '\0';
					arg_opt = required_argument;
				}
				if (!*tokptr)
					parse_error(_
						    ("empty long option after "
						     "-l or --long argument"));
			}
			add_longopt(ctl, tokptr, arg_opt);
			ctl->long_options_nr++;
		}
		tokptr = strtok(NULL, ", \t\n");
	}
	add_longopt(ctl, NULL, 0);	/* ensure long_options[] is not full */
}

static shell_t shell_type(const char *new_shell)
{
	if (!strcmp(new_shell, "bash"))
		return BASH;
	if (!strcmp(new_shell, "sh"))
		return BASH;
	if (!strcmp(new_shell, "tcsh"))
		return TCSH;
	if (!strcmp(new_shell, "csh"))
		return TCSH;
	parse_error(_("unknown shell after -s or --shell argument"));
}

static void __attribute__ ((__noreturn__)) print_help(void)
{
	fputs(USAGE_HEADER, stderr);
	fprintf(stderr, _(
		" %1$s <optstring> <parameters>\n"
		" %1$s [options] [--] <optstring> <parameters>\n"
		" %1$s [options] -o|--options <optstring> [options] [--] <parameters>\n"),
		program_invocation_short_name);

	fputs(USAGE_SEPARATOR, stderr);
	fputs(_("Parse command options.\n"), stderr);

	fputs(USAGE_OPTIONS, stderr);
	fputs(_(" -a, --alternative             allow long options starting with single -\n"), stderr);
	fputs(_(" -l, --longoptions <longopts>  the long options to be recognized\n"), stderr);
	fputs(_(" -n, --name <progname>         the name under which errors are reported\n"), stderr);
	fputs(_(" -o, --options <optstring>     the short options to be recognized\n"), stderr);
	fputs(_(" -q, --quiet                   disable error reporting by getopt(3)\n"), stderr);
	fputs(_(" -Q, --quiet-output            no normal output\n"), stderr);
	fputs(_(" -s, --shell <shell>           set quoting conventions to those of <shell>\n"), stderr);
	fputs(_(" -T, --test                    test for getopt(1) version\n"), stderr);
	fputs(_(" -u, --unquoted                do not quote the output\n"), stderr);
	fputs(USAGE_SEPARATOR, stderr);
	fputs(USAGE_HELP, stderr);
	fputs(USAGE_VERSION, stderr);
	fprintf(stderr, USAGE_MAN_TAIL("getopt(1)"));
	exit(PARAMETER_EXIT_CODE);
}

int main(int argc, char *argv[])
{
	struct getopt_control ctl = {
		.shell = BASH,
		.quote = 1
	};
	int opt;

	/* Stop scanning as soon as a non-option argument is found! */
	static const char *shortopts = "+ao:l:n:qQs:TuhV";
	static const struct option longopts[] = {
		{"options", required_argument, NULL, 'o'},
		{"longoptions", required_argument, NULL, 'l'},
		{"quiet", no_argument, NULL, 'q'},
		{"quiet-output", no_argument, NULL, 'Q'},
		{"shell", required_argument, NULL, 's'},
		{"test", no_argument, NULL, 'T'},
		{"unquoted", no_argument, NULL, 'u'},
		{"help", no_argument, NULL, 'h'},
		{"alternative", no_argument, NULL, 'a'},
		{"name", required_argument, NULL, 'n'},
		{"version", no_argument, NULL, 'V'},
		{NULL, 0, NULL, 0}
	};

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);
	atexit(close_stdout);

	if (getenv("GETOPT_COMPATIBLE"))
		ctl.compatible = 1;

	if (argc == 1) {
		if (ctl.compatible) {
			/*
			 * For some reason, the original getopt gave no
			 * error when there were no arguments.
			 */
			printf(" --\n");
			return EXIT_SUCCESS;
		} else
			parse_error(_("missing optstring argument"));
	}

	add_longopt(&ctl, NULL, 0);	/* init */
	getopt_long_fp = getopt_long;

	if (argv[1][0] != '-' || ctl.compatible) {
		ctl.quote = 0;
		ctl.optstr = xmalloc(strlen(argv[1]) + 1);
		strcpy(ctl.optstr, argv[1] + strspn(argv[1], "-+"));
		argv[1] = argv[0];
		return generate_output(&ctl, argv + 1, argc - 1);
	}

	while ((opt =
		getopt_long(argc, argv, shortopts, longopts, NULL)) != EOF)
		switch (opt) {
		case 'a':
			getopt_long_fp = getopt_long_only;
			break;
		case 'h':
			print_help();
		case 'o':
			free(ctl.optstr);
			ctl.optstr = xstrdup(optarg);
			break;
		case 'l':
			add_long_options(&ctl, optarg);
			break;
		case 'n':
			free(ctl.name);
			ctl.name = xstrdup(optarg);
			break;
		case 'q':
			ctl.quiet_errors = 1;
			break;
		case 'Q':
			ctl.quiet_output = 1;
			break;
		case 's':
			ctl.shell = shell_type(optarg);
			break;
		case 'T':
			free(ctl.long_options);
			return TEST_EXIT_CODE;
		case 'u':
			ctl.quote = 0;
			break;
		case 'V':
			printf(UTIL_LINUX_VERSION);
			return EXIT_SUCCESS;
		case '?':
		case ':':
			parse_error(NULL);
		default:
			parse_error(_("internal error, contact the author."));
		}

	if (!ctl.optstr) {
		if (optind >= argc)
			parse_error(_("missing optstring argument"));
		else {
			ctl.optstr = xstrdup(argv[optind]);
			optind++;
		}
	}

	if (ctl.name) {
		argv[optind - 1] = ctl.name;
#if defined (HAVE_SETPROGNAME) && !defined (__linux__)
		setprogname(ctl.name);
#endif
	} else
		argv[optind - 1] = argv[0];

	return generate_output(&ctl, argv + optind - 1, argc - optind + 1);
}
