/* Copyright (C) 2001 Michael Leonhard
 * Mike Leonhard
 * mike at tamale dot net
 * http://tamale.net/
 */

#include <assert.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include "ascorbic.h"

int File_CloseOutput( struct Ascorbic *asc ) {
	int ret;
	
	assert( asc );
	assert( asc->out );
	
	/* close the output stream */
	ret = fclose( asc->out );
	
	/* close failed */
	if( ret == EOF ) return Ascorbic_PError( asc, "closing output stream produced error" );

	return 1;
	}

int File_OpenOutput( struct Ascorbic *asc, char *outname ) {
	int fh;
	
	assert( asc );
	assert( asc->out == NULL );
	
	/* open the output file */
	fh = open( outname, O_WRONLY | O_CREAT | O_EXCL, 0664 );
	
	/* open failed */
	if( fh == -1 ) return Ascorbic_PError( asc, "could not open file for writing" );
	
	/* create stream on output file */
	asc->out = (FILE *)fdopen( fh, "w" );
	
	/* stream creation failed */
	if( asc->out == NULL ) return Ascorbic_PError( asc, "could not create stream on output file" );
	
	return 1;
	}

int File_ReadSource( struct Ascorbic *asc ) {
	struct stat finfo;
	int fd, ret, len;
	
	assert( asc );
	assert( asc->filename );
	
	/* open file */
	fd = open( asc->filename, O_RDONLY );
	
	/* open failed */
	if( fd == -1 ) return Ascorbic_PError( asc, "could not open file for reading" );
	
	/* read file characteristics */
	ret = fstat( fd, &finfo );
	
	/* fstat failed */
	if( ret == -1 ) return Ascorbic_PError( asc, "fstat failed" );
	
	/* length of the source code */
	len = finfo.st_size;
	
	/* zero source code length */
	if( len == 0 ) return Ascorbic_Error( asc, "source code file is empty" );

	/* allocate for source code */
	asc->source = (char *)malloc( len + 1 );
	assert( asc->source );
	
	/* read source code from file */
	ret = read( fd, asc->source, len );
	
	/* read failed */
	if( ret == -1 ) return Ascorbic_PError( asc, "read failed" );
	
	/* incomplete read */
	if( ret != len ) return Ascorbic_Error( asc, "incomplete read" );
	
	/* check for illegal null bytes in source code */
	for( ret = 0; ret < len; ret++ ) if( asc->source[ret] == 0 ) break;
	
	/* source code contains null byte */
	if( ret != len ) return Ascorbic_Error( asc, "source code contains null byte" );
	
	/* null terminate */
	asc->source[ret] = 0;
	
	/* clean up */
	close( fd );
	
	return 1;
	}
