/************************************************************************
 *									*
 *				X R F					*
 *									*
 ************************************************************************
 *									*
 *	XRF is a cross reference utility for C source programs.		*
 *	This version, written by Bob Denny of Creative Systems		*
 *	design, was extracted from a DECUS C distribution kit in	*
 *	April 1983 and modified to run on the Callan Data Systems	*
 *	Unistar 200.							*
 *									*
 *					Fred Fish			*
 *					Engineering Software Tools	*
 *					Tempe, Ariz 85281		*
 *					(602) 966-8871			*
 *									*
 ************************************************************************
 */

/*
 *              ***************
 *              * 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 [-dn] [-o out_file] in_files
 *
 *	Flags:
 *
 *		-d	Enable debugging outputs.
 *
 *		-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
 *
 */

#include <stdio.h>
#include "xrf.h"

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

/************************************************************************
 *									*
 *				M A I N					*
 *									*
 ************************************************************************
 *									*
 *  Begin Main								*
 *	Initialize debug flag to FALSE.					*
 *	Initialize list file argument pointer to NULL.			*
 *	For each argument in the command line				*
 *	    Initialize argument character scan pointer to first char.	*
 *	    If this command line argument is a switch string then	*
 *		While there is a switch character to process		*
 *		    Switch on the specific character			*
 *		    Case 'Outfile specified':				*
 *			Erase command line argument containing switch	*
 *			If there is no argument following it then	*
 *			    Abort with a usage message.			*
 *			Else						*
 *			    Save pointer to the argument.		*
 *			    Erase the output file name from args.	*
 *			    Go get the next argument.			*
 *			Endif						*
 *		    Case 'Narrow output':				*
 *			Set references per output line.			*
 *			Break						*
 *		    Default:						*
 *			Abort with usage message.			*
 *		    End switch						*
 *		End while						*
 *		Erase the switch argument.				*
 *	    End if							*
 *	End for								*
 *	Set the "no output file open yet" flag.				*
 *	For each command argument which was specified			*
 *	    If the command argument was erased then			*
 *		Skip this argument and go to next.			*
 *	    Else							*
 *		Save the input file name pointer.			*
 *		Initialize the input file.				*
 *		If there is no output file open yet then		*
 *		    Initialize the output file.				*
 *		    Reset the "no output file open yet" flag.		*
 *		End if							*
 *		Initialize the page number.				*
 *		Initialize the line number.				*
 *		Clear out any storage.					*
 *		Set current tree to NULL.				*
 *		Start first output page.				*
 *		While there is a line of source to process		*
 *		    Increment the line number.				*
 *		    Set line scan pointer to first character.		*
 *		    While there is an identifier found in line		*
 *		        Process the identifier.				*
 *		    End while						*
 *		    List the current line				*
 *		End while						*
 *		Start index on a new output page.			*
 *	        Print the index.					*
 *	    End if							*
 *	End for								*
 *	If no file was output then					*
 *	    Abort with usage message.					*
 *	End if								*
 *  End Main								*
 *									*
 ************************************************************************
 */

main (argc,argv)
int argc;
char *argv[];
{
    register int i;		/* Arg count */
    register int c;		/* Switch character code */
    register char *p;		/* Fast arg pointer */
    char tolower();		/* Convert a character to lowercase */
    int nofiles;		/* Flag "got a file" */
    struct idt *search();

    debug = FALSE;
    lst_arg = NULL;
    for( i=1; i<argc; ++i ) {
        p = argv[i];
        if( *p++ == '-' ) {
            while( c = *p++ ) {
                switch(tolower(c)) {
		case 'd':
		    debug = TRUE;
	 	    break;	
	        case 'n':
		    rperline = (80 - 16)/RSIZE;
		    break;
	        case 'o':
		    argv[i] = 0;
		    if (++i >= argc) {
			useage();
		    } else {
			lst_arg = argv[i];
		        argv[i] = 0;
		        goto nextarg;
		    }
                default :
                    useage();
                }
	    }
	    argv[i] = 0;
	}
nextarg:;
    } 
    nofiles = 1;
    for( i = 1; i < argc; i++) {
        if (argv[i] == 0) {
	    continue;
	} else {
	    src_arg = argv[i];
	    if (debug) {printf("xrf: processing %s\n",src_arg);}
	    initinfile();
            if (nofiles) {
 	        initoutfile();
                nofiles = 0;
	    }
            pageno = 0;
	    lineno = 0;
	    myfree();
            root = NULL;
            newpage();
            while(fgets(scanbf, LWIDTH, src) != NULL) {
                ++lineno;
                scanp = scanbf;
		if (debug) {printf("xrf: %s\n",scanbf);}
                while(getid()) {
                    root = search(idbuf, root);
		}
                lstline();                
            }
            newpage(); 
            prtree(root);
	    if (debug) {printf("xrf: processing %s done\n",src_arg);}
        }
    }
    if (nofiles) {
        useage();
    }
} 

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

newpage()
{
    ++pageno; 
    linpg = 0;
    fprintf(lst,"%s%d\n\n", pghead, pageno);
}

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

char tolower(ch)	/* FNF 26-Apr-83 Quick and dirty "tolower" */
char ch;
{
    if ('A' <= ch && ch <= 'Z') {
	return (ch + 040);
    } else {
	return (ch);
    }
}

char *cpystr(out,in)
char *out;
char *in;
{
    while ((*out++ = *in++) != NULL) {;}
    return(--out);
}

