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

extern	long	in_file, out_file;
extern  char	*out_file_name, *list_file_name;
struct	symbol	*sym_list_head;
struct	fname	*mod_list_head;
char		*module_name;
extern 	long	mod_buf[], DeleteFile();
extern	int	name_count;		/* number of user-supplied names */

struct fname 	*compare_symbol_names();
long		Open(), Write(), Output();
FILE		*list_file;
int		print_num = 0;
char		name_buf[33];


/* --------------------------------------------------------------------------
			DELETE_MODULE ROUTINES
---------------------------------------------------------------------------*/

delete_modules( file_list )
char	*file_list;
	{
	int		size;
	struct fname	*p;

	create_name_list( file_list );	/* get file list */

	while( (size = read_lib_module() ) )
		{
		if( (p = compare_symbol_names() ) )
			{
			name_count--;
			printf( ">> Deleting module: <%s>\n", p->name );

			*p->name = '\0';	/* kill the name */
			}
		else
			Write( out_file, mod_buf, (long) (size << 2) );
		}

	if ( name_count )	/* some no-matches found */
		print_nfound_modules();
	}



/* --------------------------------------------------------------------------
			REPLACE_MODULE ROUTINES
---------------------------------------------------------------------------*/

replace_modules( file_list)
char	*file_list;
	{
	int		size;
	struct fname	*p;
	long		longword, fp;


	create_name_list( file_list );	/* get file list */
	
	while( (size = read_lib_module() ) )
		{
		if( (p = compare_symbol_names() ) )
			{
			/* 
			  Attempt to open the file, read it in, and write it
			  out to the output file.
			*/

			name_count--;

			if( !(fp = Open( p->filename, MODE_OLDFILE ) ) )
				{
				printf( "ERROR: cannot open: <%s>\n", p->filename );
				}
			else
				{
				printf( ">> Replacing: <%s>\n", p->name );
				
				copy_lib( fp, out_file );
				Close( fp );
				}

			*p->name = '\0';
			}

		else
			Write( out_file, mod_buf, (long) (size << 2) );
		}

	if ( name_count )	/* some no-matches found */
		print_nfound_modules();
	}


/* --------------------------------------------------------------------------
			EXTRACT_MODULE_ROUTINES
---------------------------------------------------------------------------*/

extract_modules( file_list )
char	*file_list;
	{
	int		size;
	struct fname	*p;


	create_name_list( file_list );	/* get file list */
	
	while( (size = read_lib_module() ) )
		{
		if( !name_count )	/* all done? */
			break;

		if( (p = compare_symbol_names() ) )
			{
			name_count--;
			dump_module( p->name, size );
			*p->name = '\0';
			}
		}

	if ( name_count )	/* some no-matches found */
		print_nfound_modules();
	}




/* --------------------------------------------------------------------------
			INTERACTIVE ROUTINES
---------------------------------------------------------------------------*/

do_interactive_stuff()
	{
	int	size;
	char	choice;
	
	while( (size = read_lib_module() ) )
		{
		print_modules();
		printf( "\nChoice: Delete, Extract, Next, Quit, Abort " );
		
		choice = tolower( getchar() );
		getchar();
		printf( "\n" );

		if ( choice == 'd' )
			{
			printf( ">> Deleting module: <%s>\n", module_name );
			continue;
			}
			
		if ( choice == 'e' )
			{
			dump_module( module_name, size );
			}

		if ( choice == 'q' )
			{
			return;			
			}

		if ( choice == 'a' )
			{
			my_exit( EABORT );
			}

		if ( choice == 'n' )
			{
			}

		Write( out_file, mod_buf, (long) (size << 2) );
		}
	}



print_modules()
	{
	struct symbol	*p = sym_list_head->next;
	
	printf( "\nModules in this section: \n" );

	/*
	  We will have at least one name in the section. We pick the first
	  one for module_name.
	*/
	
	module_name = p->name;

	for ( ; p ; p = p->next )
		{
		printf( "\t%s\n", p->name );
		}
	}
	

dump_module( mod_name, module_size )
char	*mod_name;
int	module_size;
	{

	long	fp;
	char	file_name[34];

	/*
	  Add an '.obj', extension to the module name.
	*/
	
	strcpy( file_name, mod_name );
	strcat( file_name, ".obj" );

	printf( ">> Extracting: <%s> to: <%s>\n", mod_name, file_name );

	if( !(fp = Open( file_name, MODE_NEWFILE ) ) )
		{
		printf( "ERROR: Unable to extract: <%s>\n", mod_name );
		return( FALSE );
		}

	Write( fp, mod_buf, (long) (module_size << 2) );
	Close( fp );
	}


struct fname 	*compare_symbol_names()
	{
	/*
	  Hop down the list of user supplied names and see if any of them
	  match any of the names in the module list.
	*/

	struct symbol	*p;
	struct fname	*q;

	for( q = mod_list_head; q ; q = q->next )
		{
		for ( p = sym_list_head->next; p ; p = p->next )
			{
			if ( !strcmp( p->name, q->name ) )
				return( q );
			}
		}
		
	return( NULL );
	
	
	}


print_nfound_modules()
	{
	/* 
	  Print the list of modules that are not found. If we found the
	  module and performed the desired operation, the first char of
	  the name will be '\0'.
	*/
	
	struct fname	*p;
	
	printf( "WARNING: The following modules were not found: \n" );

	for( p = mod_list_head; p ; p = p->next )
		{
		if ( *p->name )
			printf( "\t%s\n", p->name );
		}
	}


/* --------------------------------------------------------------------------
				LIST_LIBRARY ROUTINES
---------------------------------------------------------------------------*/

list_library( list_file_name )
char	*list_file_name;

	{
	struct	 symbol	*p;
	
	/* 
	  If the first char of list_file_name is null, use the 
	  stdio device for output, else attempt to open the 
	  supplied file name.
	*/

	list_file = (*list_file_name) ? fopen( list_file_name, "w+" ) : stdout;

	if ( !list_file )
		{
		my_exit( ENOLIST, list_file_name );
		}

	printf( ">> Listing library to: <%s>\n", 
		(*list_file_name) ? list_file_name : "CON" );

	
	while( read_lib_module() )
		{
		/*
		  Print the external symbols in the symbol list.
		*/
		for( p = sym_list_head->next; p; p = p->next )
			fprintf( list_file, (++print_num % 2) ? 
				 "  %-44s" : "  %s\n", p->name );
		}


	/*
	  If we print an odd number of files, we must also print 
	  a newline character.
	*/

	if ( print_num % 2 )
		fprintf( list_file, "\n" );

	if ( *list_file_name ) 
		fclose( list_file );
		
	my_exit( 0 );
	}


