/*--- EDIT # 0042	15 Apr 1982   13:36:34	DB1:[21,14]FLAG.C;70  */
/*--- PREVIOUS EDIT	13 Apr 1982   14:40:56	DB1:[21,14]FLAG.C;66  */
/************* flag.c *****************
 * This is an example program to process & handle command-line flags.
 * Including boolean flags (specified or not), numeric value flags,
 * ascii string value flags.
 * Note that flags may always be in any order, and that arguments
 * and flags may be freely intermixed.
 * Also note that
 * redirection of stdin and/or stdout is transparent and the program
 * does not even know when it happens.
 *
 * The command-line options can be any of the following forms:
 *     where:
 *	a, b, c are individual flags
 *	n	is a numeric value flag
 *	NN	is the actual number
 *	f	is a file-spec flag (other than stdin, stdout,
 *		infile) (for example, a wierd output file, work
 *		file, auxiliary input file, etc)
 *	FF	is the actual file-spec
 *	-?	always gives long usage info
 *	argn	is a parameter/argument
 *
 *	-a -b -c -d
 *	-ab -cd
 *	-abcd
 *	-anNN -cd
 *	-anNNcd
 *	-aoFF
 *	-bo FF -d
 *	-a arg1 arg2 -bc
 *	-abc arg1 arg2
 */
#include <stdio.h>

int cntflag = 0;	/* numeric value flag		*/
int dflag = 0;		/* debug flag			*/
int nflag = 0;		/* negate flag			*/
char *ofn = NULL;	/* "-o" flag output-file flag	*/

main(argc, argv)
int argc;
char *argv[];
{
   int i;
   char c;	/* 1st char of current command-line argument */
   char *cp;	/* current argument pointer */
   FILE *ifp;	/* currently opened input file */

   printf("Command line: '");
   for (i=1; i<argc; ++i)
      printf("%s ", argv[i]);
   printf("'\n\n");

/* Get all the flag arguments. After processing each one, set it
 * to NULL, so we know it isn't a file-spec.
*/
   for (i=1; i<argc; ++i) {
      cp = argv[i];
      if (*cp == '-') {
	 argv[i] = NULL;
	 ++cp;
	 while (c = *cp++) {
	    switch (tolower(c)) {
	    case 'c':	/* numeric value flag */
	       /* convert to int & skip over it */
	       cntflag = atoi(cp);
	       while (isdigit(c = *cp) || (c == '-') ||
		    (c == '+')) cp++;
	       break;

	    case 'd':
	       ++dflag;
	       break;

	    case 'n':
	       ++nflag;
	       break;

	    case 'o':
	       if (*cp == NULL) { 	/* value is next arg */
		  if (++i >= argc)
		     usage(c);		/* no next arg, error! */
		  if (*(ofn = argv[i]) == '-')
		     usage(c);		/* next arg is itself an arg!! */
		  argv[i] = NULL;	/* eliminate the arg	*/
	       }
	       else {		/* value is in this arg */
		  ofn = cp;
	       }
	       cp = argv[i];/* re-examine current arg (to skip it) */
	       break;

	    default:
	       usage(c);
	    }
	 }
      }
   }
   printf("cnt flag value = %d\n", cntflag);
   printf("dflag value = %d\n", dflag);
   printf("nflag = %s\n", nflag? "TRUE" : "FALSE");

   if (ofn != NULL) {	/* open the output file */
      printf("outfile string: '%s'\n\n", ofn);
      /*ofp = fopen(ofn, "w");*/
   }

/********** get the file-name arguments and process each file. ****/
   for (i = 1; i < argc; argv[i++] = NULL) {/* find 1st non-flag arg */
      if ((cp = argv[i]) != NULL) {
	 if ((ifp = fopen(cp, "r")) == NULL) {
	    fprintf(stderr, "%s: cannot open.\n", cp);
	 }
	 process_file(ifp);
      }
   }
}
/******************************************/
process_file(fp)
FILE *fp;
{
   if (dflag > 1) ;	/* do debug for type 1 */
   if (dflag > 2) ;	/* do debug for type 2 */
   if (dflag != 0) ;	/* do debug */
   fclose(fp);
}

/******************************************/
usage(c)
char c;		/* The char of the option */
{
   printf("Usage: flag [-dn] [-cnnn] [-oOUTFILE] arg1 [argn...]\n");
   if (c == '?') {
      printf("  -cn = count value ('n' is a signed int)\n");
      printf("  -d  = debug (type depends on # of occurences)\n");
      printf("  -n  = negate flag\n");
      printf("  -ox = 'x' is the output filespec, ");
      printf("rather than stdout\n");
   }
   exit();
}
