#include <stdio.h>     /* for printf */
#include <stdlib.h>    /* for exit */
#include <getopt.h>

int
main (int argc, char **argv) {
    int c;

    while (1) {
	int option_index = 0;
	/* The following struct specifies the long options. E.g. --add 
	 * The second field indicates whether the option takes an arugment
	 * The thrird field can be a pointer to a variable that will be set to
	 * the value of the 4th field.
	 * The fourth field i the value that getopt_long will return or load into 
	 * the variable referred to by the 3rd field.
	 */

	/* Example: If the program is run with --create, getopt_long will 
	 * return 'c' which will then be caught in the switch statement
	 * "try_getopt --create foo" prints "option c with value `foo'"
	 */
	static struct option long_options[] = {
	    {"add", 1, 0, 0},
	    {"append", 0, 0, 0},
	    {"create", 1, 0, 'c'},
	    {0, 0, 0, 0}
	};
	
	/* "ac:" is the list of possible single letter options.
	 * The colon indicates that the preceding letter takes an argument
	 * In this example the option -a does not take an argument, but -c does
	 *
	 * long_options is the array of long_options to pass in.
	 * Passing in the address of option_index allows geopt_long to fill in the
	 * index of the option that it sees.
	 * Example: try_getopt --append will result in the value 1 being placed in
	 * option_index.
	 */
	c = getopt_long (argc, argv, "ac:",
			 long_options, &option_index);
	if (c == -1)
	    break;
	
	switch (c) {
	    /* getopt_long returned 0, which means we got a long option
	     * The value of option_index tells us which of the long options we got
	     */
	case 0:
	    printf ("option %s", long_options[option_index].name);
	    if (optarg)
		printf (" with arg %s", optarg);
	    printf ("\n");
	    break;

	    /*getopt_long returned 'a' which means we found the option -a */
	case 'a':
	    printf ("option a\n");
	    break;
	    
	    /*getopt_long returned 'c' which means we found the option -c 
	     * The variable optarg holds the vaule of the argument associated 
	     * with it.
	     */
	case 'c':
	    printf ("option c with value `%s'\n", optarg);
	    break;
	    
	    /* getopt_long did not recognize the option */
	case '?':
	    break;
	    
	default:
	    printf ("?? getopt returned character code 0%o ??\n", c);
	}
    }
    
    /* Any other arguments that follow the list of options can be retrieved by 
     * using optind as a starting point to iterate over the remaining elements of
     * argv
     */
    if (optind < argc) {
	printf ("non-option ARGV-elements: ");
	while (optind < argc)
	    printf ("%s ", argv[optind++]);
	printf ("\n");
    }
    
    exit (0);
}
