/*
 *					x r f
 *
 * Cross reference
 */

/*)BUILD	$(PROGRAM)	= xrf
		$(INCLUDE)	= xrf.h
		$(FILES)	= { xrf0 xrf1 xrf2 xrf3 xrfi xrfd }
		$(TKBOPTIONS)	= {
			TASK = ...XRF
			STACK = 1500
		}
		$(ODL)		= {
		;
		; OVERLAY DESCRIPTION FOR XRF
		; BOB DENNY	29-MAY-81
		;
			.ROOT	XRF0-XRF2-XRFD-$(RXLIB)-*(X1,X2,X3)
		;
		X1:	.FCTR	XRFI-X1L1-X1L2-X1L3
		X1L1:	.FCTR	$(RXLIB):CONCAT:FWILD
		; Note: CTIME requires several other library modules:
		X1L2:	.FCTR	$(RXLIB):TIME:CTIME:LOCALT:$$$$RTIME:$$$$UTIME
		X1L3:	.FCTR	$(RXLIB):CALLOC:MUL$$L:$$$$DIV2:EIS$$I
		;
		X2:	.FCTR	XRF1-X2L
		X2L:	.FCTR	$(RXLIB):EIS$$I
		;
		X3:	.FCTR	XRF3-X3L
		X3L:	.FCTR	$(RXLIB):SPRINT
			.END
		}
		$(OVR)		= {
			XRF0,XRF2,XRFD,$(SUPORT),$(RTLIB)
			XRFI,$(RTLIB)/O:1
			XRF1,$(RTLIB)/O:1
			XRF3,$(RTLIB)/O:1
		}
*/

/*
 *              ***************
 *              * X R F 0 . C *
 *              ***************
 *
 * This is the mainline program for the C cross referencer and lister.
 * It handles the following tasks:
 *
 *      - Scans the command line
 *      - Opens the appropriate files
 *      - Calls some initialization functions
 *      - Invokes line by line processing
 *      - Prints the cross-reference index
 *      - Finishes up processing as appropriate
 *
 *
 * Usage:
 *
 *	xrf [-s] [-n] [-o out_file] in_files
 *
 *	Flags:
 *		-s	Spool out_file to printer (RSX11M only (??))
 *
 *		-n	Narrow (80 column) output, normal is 132 column.
 *
 *		-o file	Write output to the indicated file.  If -o is not
 *			specified, output will be to the first in_file
 *			with the filetype set to ".x"
 *
 * Written By:
 *              Bob Denny
 *              Creative System Design Co.
 *              3452 E. Foothill Blvd. << Suite 601 >>
 *              Pasadena, Ca.  91107
 *              (213) 355-6836
 *
 * Experimental Version         X1.0             5-May-80
 * Split off initialization     X1.1             7-May-80
 * Prototype.                   Y1.2             9-May-80
 * Release.                     V1.3             9-May-80
 * Chg. for DECUS OTS. & Cmplr. V1.4             1-Jul-80
 * Add support for RT-11        V1.5             3-Jul-80
 * Conditionalized spool call	V1.6 MM		 9-Jul-80
 * Added narrow, outfile, etc.	V1.7 MM		10-Jul-80
 * Added multiple infiles	V1.8 MM		22-Jul-80
 * Fspool now in the library	V1.9 MM		 2-Aug-80
 * Add VMS I/O redirection	V2.0 JSL	29-May-85
 *  (useless but consistent)
 *
 *****************************************************************************
 */

#ifdef	DOCUMENTATION

title	xrf	Cross-Reference Lister for C Programs
index		Cross-Reference Lister for C Programs

synopsis

	xrf [-options] [-o outfile] [file ...]

description

	xrf prepares a cross-reference listing for C source programs.  The
	following options are defined:
	.lm +8
	.s.i -8;-n	Narrow output (80 columns).  The default is 132
	columns.
	.s.i -8;-s	Spool output to the default line printer.
	.s.i -8;-o file	Write output to the named file.  The default is the
	first input file encountered with a filetype (extension) of ".x".
	.s.lm -8
	xrf accepts wild-card file input.

diagnostics

	.lm +8
	.s.i -8;Trying to get too much.
	.s
	Internal error, get help.
	.s.i -8;Not enough memory space.
	.s
	xrf ran out of main memory space.
	.s.i -8;Cannot open "file"
	.s.i -8;Cannot open listing file "file"
	.s.i -8;Usage ...
	.lm -8

author

	Robert B. Denny

bugs

#endif

#include <stdio.h>                              /* RSX-11M Std. I/O Def's */
#include "xrf.h"                                /* Global definitions */

int pageno;                                     /* Current listing page no. */


main ( argc, argv )
char *argv[];
   {                                            /* Start the main prog. */
   register int i;                              /* Arg count */
   register int c;                              /* Switch character code */
   register char *p;                            /* Fast arg pointer */
   char *in_file;                               /* Source file name string */
   char *out_file;				/* Cref file name string */
   int splflg;                                  /* Spool file flag */
   int nofiles;					/* Flag "got a file" */

#ifdef vms
   argc = getredirection(argc,argv);
#endif

   out_file = NULL;				/* No output file yet */
   splflg = 0;                                  /* Default no spool */
   for( i=1; i<argc; ++i )                      /* For each token */
      {
      p = argv[i];                              /* p --> i'th arg token */
      if( *p++ == '-' )                         /* if it's a switch token */
         {
         while( c = *p++ )                      /* Each char is a switch */
            switch(tolower(c))                  /* Process 'em */
               {
	       case 'o':			/* Output file */
		  argv[i] = 0;
		  if (++i >= argc)
			useage();
		  out_file = argv[i];
		  argv[i] = 0;
		  goto nextarg;

	       case 'n':			/* Narrow output */
		  rperline = (80 - 16)/RSIZE;	/* Set references */
		  break;

               case 's':                        /* Spool listing */
                  splflg++;
                  break;

               default :                        /* Bad switch, give help */
                  useage();
               }
	 argv[i] = 0;				/* Drop this one */
         }
nextarg:;
      }                                         /* Done with cmd string */

   nofiles = 1;
   for( i = 1; i < argc; i++)
      {
      if ((in_file = argv[i]) == 0)
	 continue;
      initinfile(in_file);
      while (nextinfile())
	 {
         if (nofiles)
	   {
 	   initoutfile(out_file);
           nofiles = 0;
	   }
         pageno = 0;                            /* Init. page number */
	 lineno = 0;				/* Init. line number */
	 myfree();				/* Clear out storage */
         root = NULL;                           /* No tree yet */
         newpage();                             /* Start first page */
         while(fgets(scanbf, LWIDTH, src) != NULL) /* Get a line of source */
            {
            ++lineno;                           /* Increment line number */
            scanp = scanbf;                     /* Reset scan pointer */
            while(getid())                      /* scanp --> id or NULL */
               root = search(idbuf, root);      /* Process identifier */
                                                /* Till done with this line */
            lstline();                          /* List this line */
            }                                   /* Till end of source file */
         newpage();                             /* Start index on new page */
         prtree(root);                          /* Print the index */
         }
      }
   if (nofiles)
      useage();
#ifdef rsx
   if(splflg)                                   /* If we're to spool, */
      fspool(lst);                              /* Cross your fingers. */
#endif
   exit(IO_SUCCESS);                            /* Exit closing files */
   }                                            /***** END MAIN *****/


/*
 *
 * Listing control routines. Newpage also used by prtree.
 *
 */

newpage()                                       /* Start new page */
   {
   ++pageno;                                    /* Increment page number */
   linpg = 0;                                   /* Reset line-in-page count */
   fprintf(lst,"%s%d\n\n", pghead, pageno);     /* Output page heading */
   }

lstline()                                       /* Write listing line out */
   {
   if(++linpg > MAXLIN)
      newpage();
   fprintf(lst, "%4d:\t%s", lineno, scanbf);
   }

