/*+JMJ * cmd.c - tir HTML renderer command line interface * Copyright 2011 David Meyer * cmd.c is part of tirrender * * 2011-07-28 * cmd.c implements a command line interface for the tirrender * HTML rendering engine (implemented in common.c). The command * line interface is intended for testing rendering functionality * and for static rendering (rendered output saved to .html file * for later and repeated access). cgi.c will implement CGI * interface for dynamic rendering (rendered output generated for * each HTTP request and returned to browser). */ #include #include #include "krcompat.h" #include "tirrender.h" /* IDENTIFICATION: *************************************************/ #define PROGRAM "tirrender" #define VERSION "0.0" #define COPYRIGHT "Copyright 2011 David Meyer" #define CONTACT "David Meyer " #define DESCRIPTION "tir HTML renderer for files and directories" #define USAGE "Usage: tirrender [-hV] [-d ] [-l ] [-f ]" /* 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: -l (location) * 2: -f (file) * 3: -h (help) * 4: -V (version) */ char *optarg[3]; /* Option arguments: * [0]: -d (dataset) * [1]: -l (location) * [2]: -f (file) */ optstat = parseopts(argc, argv, optstat, optarg); if (optstat & 8) { /* Arg. -h: display help, exit */ msghelp(); exit(0); } if (optstat & 16) { /* Arg. -V: display version, exit */ msgversion(); exit(0); } /* Arg. -d, invalid: * display error, exit */ if ((optstat & 1) && baddataset(optarg[0])) { printf("Error: invalid dataset\n"); exit(1); } /* Arg. -l, invalid: * display error, exit */ if ((optstat & 2) && badlocation(optarg[1])) { printf("Error: invalid location\n"); exit(1); } /* Arg. -f, invalid: * display error, exit */ if ((optstat & 4) && badfile(optarg[2])) { printf("Error: invalid file\n"); exit(1); } /* Arg's OK: render specified * object or default */ /* 2011-07-28 * "specified object": instead of separate location and file * options, I could have single "object" option specified * with the file/directory path relative to the dataset root. * Use file status to determine file or directory rendering. */ return render((optstat & 1) ? optarg[0] : DEFAULT_DATASET, (optstat & 2) ? optarg[1] : DEFAULT_LOCATION, (optstat & 4) ? optarg[2] : DEFAULT_FILE); } /* FUNCTIONS: ******************************************************/ /* msghelp() - display help message */ void msghelp () { printf("%s\n%s -h Display this information -V Display version -d Render target dataset -l Render target location (directory) -f Render target file\n", 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, l, f 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: */ 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. = -l: */ else if (!strcmp(argv[a], "-l")) { optstat = optstat | 2; optarg[1] = (char *) malloc(strlen(argv[++a])+1); strcpy(optarg[1], argv[a]); } /* arg. = -l*: */ else if (!strncmp(argv[a], "-l", 2)) { optstat = optstat | 2; optarg[1] = (char *) malloc(strlen(argv[a])-1); strcpy(optarg[1], argv[a]+2); } /* arg. = -f: */ else if (!strcmp(argv[a], "-f")) { optstat = optstat | 4; optarg[2] = (char *) malloc(strlen(argv[++a])+1); strcpy(optarg[2], argv[a]); } /* arg. = -f*: */ else if (!strncmp(argv[a], "-f", 2)) { optstat = optstat | 4; optarg[2] = (char *) malloc(strlen(argv[a])-1); strcpy(optarg[2], 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 | 8; } /* flag opt. V */ else if (argv[a][n] == 'V') { optstat = optstat | 16; } else { /* unrecognized flag. opt. */ printf("Invalid option: -%c\n%s\n", argv[a][n], USAGE); exit(0); } } } 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(0); } } return optstat; }