/*+JMJ
 * template.c - C source template (command line)
 * Copyright 201x David Meyer <papa@sdf.org>
 * template.c is part of template
 *
 */

#include <stdio.h>
#include <string.h>
#include "krcompat.h"

/* IDENTIFICATION: *************************************************/

#define PROGRAM "template"
#define VERSION "0.0"
#define SRCFILE "template.c"
#define COPYRIGHT "Copyright 201x David Meyer"
#define CONTACT "David Meyer <papa@sdf.org>"
#define DESCRIPTION "C source template (command line)"
#define USAGE "Usage: template [<options>] [<arguments> ...]"

/* CONSTANTS: ******************************************************/

/* MACROS: *********************************************************/

/* GLOBALS: ********************************************************/

/* PROTOTYPES: *****************************************************/

void msghelp ();
void msgversion ();
int parseopts PARAMS((int argc, char* argv[], int optstat, char *optarg[]));

/* MAIN: ***********************************************************/

/* main() parses and validates command line arguments, then calls
 * render() if all OK.
 */
int main(argc, argv)
  int argc;
  char *argv[];
{
  int optstat = 0;                /* Specified options:
				   * Bit 0: -d (dataset)
				   *     1: -o (object)
				   *     2: -h (help)
				   *     3: -V (version)
				   */
  char *optarg[2];                /* Option arguments:
				   * [0]: -d (dataset)
				   * [1]: -o (object)
				   */

  optstat = parseopts(argc, argv, optstat, optarg);

  /* arg test:
  if (optstat & 1) printf("-l %s\n", optarg[0]);
  if (optstat & 2) printf("-o %s\n", optarg[1]);
  if (optstat & 4) printf("-h\n");
  if (optstat & 8) printf("-V\n");
  */
  
  if (optstat & 4) {              /* Arg. -h: display help, exit */
    msghelp();
    exit(0);
  }

  if (optstat & 8) {             /* Arg. -V: display version, exit */
    msgversion();
    exit(0);
  }

                                  /* Arg. -d, <dataset> invalid:
                                   * display error, exit
				   */
  if ((optstat & 1) && baddataset(optarg[0])) {
    printf("Error: invalid dataset\n");
    exit(1);
  }

                                  /* Arg. -o, <object> invalid:
                                   * display error, exit
				   */
  /* what about default ds?*/
  if ((optstat & 2) && badobject(optarg[0], optarg[1])) {
    printf("Error: invalid object\n");
    exit(1);
  }

                                  /* Arg's OK: render specified
                                   * object or default
				   */
  return render((optstat & 1) ? optarg[0] : DEFAULT_DATASET,
		(optstat & 2) ? optarg[1] : DEFAULT_OBJECT);

}

/* FUNCTIONS: ******************************************************/

/* msghelp() - display help message
 */
void msghelp ()
{
  printf("%s\n%s
-h                Display this information
-V                Display version
-d <dataset>      Render target dataset
-o <object>       Render target object (path to directory or file)
", DESCRIPTION, USAGE);
}

/* msgversion() - display program version message
 */
void msgversion ()
{
  printf("%s %s\n", PROGRAM, VERSION);
}

/* parseopts() - parse options in commnd line arguments
 */
int parseopts (argc, argv, optstat, optarg)
     int argc;
     char *argv[]; 
     int optstat;
     char *optarg[];
{
  int a, n;

  for (a = 1; a < argc; a++) {    /* for each argument */

                                  /* options d, o take arguments
				   * and must be specified
				   * individually.
				   * opt. arg. value is either
				   * string following opt. char.
				   * or next argument.
				   */
    if (!strcmp(argv[a], "-d")) { /* arg. = -d: */
      if (a == argc - 1) {        /* last arg. on cl.l */
	printf("Option -d requires argument\n");
	exit(1);
      }
      optstat = optstat | 1;      
      optarg[0] = (char *) malloc(strlen(argv[++a])+1);
      strcpy(optarg[0], argv[a]);
    }
                                  /* arg. = -d*: */
    else if (!strncmp(argv[a], "-d", 2)) {
      optstat = optstat | 1;      
      optarg[0] = (char *) malloc(strlen(argv[a])-1);
      strcpy(optarg[0], argv[a]+2);
    }

                                  /* arg. = -o: */
    else if (!strcmp(argv[a], "-o")) {
      if (a == argc - 1) {        /* last arg. on cl.l */
	printf("Option -o requires argument\n");
	exit(1);
      }
      optstat = optstat | 2;      
      optarg[1] = (char *) malloc(strlen(argv[++a])+1);
      strcpy(optarg[1], argv[a]);
    }
                                  /* arg. = -o*: */
    else if (!strncmp(argv[a], "-o", 2)) {
      optstat = optstat | 2;      
      optarg[1] = (char *) malloc(strlen(argv[a])-1);
      strcpy(optarg[1], argv[a]+2);
    }

    else if (argv[a][0] == '-') { /* flag arg. (-*) */
                                  /* for each char. in flag string */
      for (n = 1; n < strlen(argv[a]); n++) {

	if (argv[a][n] == 'h') {  /* flag opt. h */
	  optstat = optstat | 4;
	}

                                  /* flag opt. V */
	else if (argv[a][n] == 'V') {
	  optstat = optstat | 8;
	}

	else {                    /* unrecognized flag. opt. */
	  printf("Invalid option: -%c\n%s\n", argv[a][n], USAGE);
	  exit(1);
	}
      }
    }

    else {                        /* unrecognized arg.
				   * for compatibility with CGI
				   * query string format, c.l.
				   * I/F has no non-option args.
				   */
      printf("Invalid argument: %s\n%s\n", argv[a], USAGE);
      exit(1);
    }
  }
  return optstat;
}