/*+JMJ
* template.c - C source template (command line)
* Copyright 201x David Meyer <[email protected]>
* 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 <[email protected]>"
#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;
}