/*
 * (c) Copyright 1993 by Panagiotis Tsirigotis
 * All rights reserved.  The file named COPYRIGHT specifies the terms 
 * and conditions for redistribution.
 */

static char RCSid[] = "$Id: main.c,v 1.4 1993/02/19 21:58:29 panos Exp $" ;
static char version[] = VERSION ;

#include <fcntl.h>

void exit() ;

#include "sio.h"
#include "str.h"

#include "options.h"

#include "defs.h"

int line_count = 1 ;

typedef void (*ps_process)() ;

/*
 * Available processes
 */
void dvi_process() ;
void psdit_process() ;
void troff_process() ;
void ditroff_process() ;
void wordperfect_process() ;
void groff_process() ;



struct process_string
{
	char *ps_string ;
	char *ps_name ;
	ps_process ps_func ;
	strs_h ps_sh ;
} ;

static struct process_string procstr[] =
	{
		{	".dvi",		"dvi file",						dvi_process				},
		{	"/wpdict",	"wordperfect document",		wordperfect_process	},
		{	"idraw",		"idraw",							troff_process			},
		{	"psdit",		"ditroff through psdit",	psdit_process			},
		{	"tpscript",	"Kolstad's hack",				ditroff_process		},
		{	"ditroff",	"ditroff file",				ditroff_process		},
		{	"troff",		"troff file",					troff_process			},
		{	"groff",		"GNU groff file",				groff_process			},
		{	NULL }
	} ;


struct process_name
	{
		char *pn_name ;
		ps_process pn_func ;
	} ;


static struct process_name procnames[] =
	{
		{	"dvi",		dvi_process				},
		{	"psdit",		psdit_process			},
		{	"dit",		ditroff_process		},
		{	"troff",		troff_process			},
		{	"wp",			wordperfect_process	},
		{	"groff",		groff_process			},
		{ NULL }
	} ;


int main( argc, argv )
	int argc ;
	char *argv[] ;
{
	int first_arg = opt_recognize( argc, argv ) ;
	int in_fd ;
	ps_process process ;
	ps_process find_process() ;
	void printout_flush() ;

	if ( argc - first_arg > 1 )		/* at most 1 arg */
		usage() ;

	if ( first_arg == argc )
		in_fd = 0 ;
	else
	{
		extern int errno ;
		char *file = argv[ first_arg ] ;

		in_fd = open( file, O_RDONLY ) ;
		if ( in_fd == -1 )
			error( "Failed to open file %s (errno = %d)\n", file, errno ) ;
	}
	
	if ( l_option )
	{
		struct process_name *pnp ;

		Sprint( 1, "Recognized process types:\n" );
		for ( pnp = procnames ; pnp->pn_name ; pnp++ )
			Sprint( 1, "\t%s\n", pnp->pn_name ) ;
		exit( 0 ) ;
	}

	if ( d_option )
		Sbuftype( 1, SIO_NOBUF ) ;

	if ( p_option )
	{
		struct process_name *pnp ;

		for ( pnp = procnames ;; pnp++ )
		{
			if ( pnp->pn_name == NULL )
				error( "Unknown process: %s\n", p_option_arg ) ;
			if ( strcmp( pnp->pn_name, p_option_arg ) == 0 )
			{
				process = pnp->pn_func ;
				break ;
			}
		}
	}
	else
		process = find_process( in_fd ) ;

	if ( ! n_option )
	{
		(*process)( in_fd ) ;
		printout_flush() ;
	}

	exit( 0 ) ;
	/* NOTREACHED */
}

/*
 * Determine what process to use to parse this file.
 */
PRIVATE ps_process find_process( fd )
	int fd ;
{
	char *line ;
	struct process_string *psp ;
	struct process_string *found = NULL ;

	/*
	 * Create string matchers
	 */
	for ( psp = procstr ; psp->ps_string ; psp++ )
	{
		psp->ps_sh = strs_setup( STRS_BF + STRS_NOMALLOC, psp->ps_string ) ;
		if ( psp->ps_sh == NULL )
			error( "out of memory\n" ) ;
	}

	/*
	 * Try to determine how the file was derived.
	 * Method:
	 *		Read lines looking for one of the identifier strings
	 *		If an identifier string is found, continue reading lines
	 * 	until a non-comment line is found.
	 */
	while ( line = Srdline( fd ) )
	{
		line_count++ ;
		if ( line[ 0 ] != '%' && found )
			break ;
		
		/*
		 * Check what process (if any) is identified by this line
		 */
		for ( psp = procstr ; psp->ps_string ; psp++ )
			if ( strs_match( psp->ps_sh, line, SIOLINELEN( fd ) ) )
			{
				/*
				 * psdit process takes precedence over ditroff_process
				 */
				if ( ! found || found->ps_func == ditroff_process && 
														psp->ps_func == psdit_process )
					found = psp ;
			}
	}
	if (e_option)
		exit(!found);
	if ( ! found ) {
		error( "Failed to identify how this file was derived\n" ) ;
	}
	if ( v_option )
		Sprint( 2, "Postscript file derived from %s\n", found->ps_name ) ;
	return( found->ps_func ) ;
}

