home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
disks
/
disk427.lzh
/
STV
/
source
/
file.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-01-09
|
8KB
|
302 lines
/*********************************
* FILE 01/02/91
* Source file for STV
* © Copyright 1990 Timm Martin
* All Rights Reserved Worldwide
**********************************/
#include <exec/types.h>
#include <functions.h>
#include <intuition/intuition.h>
#include <libraries/dos.h>
#include <stdio.h>
#include <workbench/startup.h>
#include "func.h"
#include "main.h"
/*************************
* FILE BUFFER STRUCTURE
**************************/
struct FileBuffer current_file = /* GLOBAL */
{
/* char * Name */ NULL,
/* char * Partial */ NULL,
/* char * Buffer */ NULL,
/* char ** Table */ NULL,
/* long BufferSize */ 0,
/* long FileSize */ 0,
/* long TableSize */ 0,
/* long Lines */ 0,
};
/*
need 1 extra byte for a newline to terminate the final line if it doesn't
already have one
*/
#define EXTRA 1
/*************
* FILE FREE
**************/
/*
This procedure frees the memory used by the file buffer and line table and
sets the corresponding pointers to NULL.
*/
void file_free( void )
{
if (current_file.Buffer)
{
FreeMem( current_file.Buffer, current_file.BufferSize );
current_file.Buffer = NULL;
}
if (current_file.Table)
{
FreeMem( current_file.Table, current_file.TableSize );
current_file.Table = NULL;
}
/* so prop gadget won't be misadjusted */
current_file.Lines = 0;
}
/*************
* FILE LOAD
**************/
/*
This procedure attempts to load the specified file, returning YES or NO
whether it was successful.
*/
BOOL file_load( void )
{
REG char *c; /* position in file */
char *end; /* end of the buffer */
struct FileHandle *fp; /* pointer to text file */
REG long lines; /* number of lines in file (or current line) */
REG char *s; /* start of current line */
long size; /* size of the file in bytes */
/* add extra byte needed */
current_file.BufferSize = current_file.FileSize + EXTRA;
/* allocate memory to hold the file */
if (current_file.Buffer = AllocMem( current_file.BufferSize, NULL ))
{
/* try to open the file */
if (fp = Open( current_file.Name, MODE_OLDFILE ))
{
/* try to read entire file into buffer */
size = current_file.FileSize =
Read( fp, current_file.Buffer, current_file.FileSize );
/* find the end of the file */
end = current_file.Buffer + size;
/* need to count how many lines there are */
for (lines = 0, c = current_file.Buffer; c < end; c++)
if (*c == '\n')
lines++;
/* if the very last character is not a newline, the last line won't
* be counted as a line, so need to count it and terminate it with
* a newline so that its length will be calculated. If the file is
* empty, one blank line will be created.
*/
if (!lines || *(c-1) != '\n')
{
*(c-1) = '\n'; /* add a newline */
end++; /* increment end of the file */
lines++; /* there's another line */
}
/* record number of lines */
current_file.Lines = lines;
/* add 1 extra line--the last line recorded is false */
current_file.TableSize = (lines + 1) * sizeof(char *);
/* try to allocate memory to hold table--will always have at least one
* line
*/
if (current_file.Table = AllocMem( current_file.TableSize, NULL ))
{
current_file.Table[0] = current_file.Buffer;
/* need to get pointer to beginning of each line */
for (lines = 1, c = current_file.Buffer; c < end; c++)
{
/* if reached end of this line */
if (*c == '\n')
{
/* get pointer to beginning of next line */
current_file.Table[lines++] = c + 1;
/* change newline to null */
*c = '\0';
}
}
} /* if allocated table memory */
Close( fp );
} /* if opened file */
} /* if allocated file memory */
/* if didn't make it this far, something went wrong */
return (current_file.Table != NULL);
}
/*************
* FILE NAME
**************/
/*
This procedure saves the full path name, then tries to determine just the
name of the file itself.
*/
void file_name( char *name )
{
REG char *c;
int i;
current_file.Name = name;
/* find the end of the string */
for (c = name, i = 0; *c; c++, i++);
/* go backwards until reach beginning of string or a colon or slash */
while (i >= 0 && *c != '/' && *c != ':') { c--; i--; };
/* file name itself begins just after the slash or colon */
current_file.Partial = c + 1;
}
/*************
* FILE READ
**************/
/*
This function tries to read the specified file, displaying it in the window,
and letting the user view it. It returns when the user has presses ESCape or
clicked on the close window gadget. Either SELECT_STOP, SELECT_PREV, or
SELECT_NEXT is returned (as returned by window_input()).
*/
#define IGNORE (void *)-1L
SELECT file_read( char *name, SELECT prev, SELECT next )
{
char buffer[80]; /* to hold title */
SELECT file; /* which file does user want next? */
/* let user know loading file */
file_name( name );
sprintf( buffer, "Loading %s...", current_file.Partial );
SetWindowTitles( win, buffer, IGNORE );
/* adjust the prev and next menu items */
menu_prevnext( prev, next );
/* clear existing display, if any */
SetAPen( rp, BLUE );
RectFill( rp, (long)stats.LeftEdge, (long)stats.TopEdge,
(long)stats.RightEdge, (long)stats.BottomEdge );
/* get file size and try to load it */
if (file_size() && file_load())
sprintf( buffer, "%s (%ld lines, %ld bytes)",
current_file.Partial, current_file.Lines, current_file.FileSize );
else
{
sprintf( buffer, "Could not read %s!", current_file.Partial );
/* do this now so won't read partial file and mess things up */
file_free();
}
/* let the user know what happened */
SetWindowTitles( win, buffer, IGNORE );
/* set prop gadgets */
initialize();
/* display text */
text_display();
/* get window input */
file = input_window( prev, next );
/* get rid of file */
file_free();
return (file);
}
/***************
* FILE SELECT
****************/
/*
This procedure handles the selection of the current file.
*/
void file_select( void )
{
SELECT current = 0; /* current file--start with first one */
SELECT file = SELECT_SOME; /* whether to stop or keep going */
char *name; /* name of the file to be loaded */
SELECT next; /* is there a next file? */
SELECT prev; /* is there a previous file? */
/* while want to keep going */
while (file != SELECT_STOP)
{
/* if not working on file 0, there must be a previous file */
prev = current > 0 ? SELECT_SOME : SELECT_NONE;
/* if not working on last file, there must be a next file */
next = current < arguments.Files - 1 ? SELECT_SOME : SELECT_NONE;
/* if from workbench */
if (arguments.ArgList)
{
/* need to change directory to that of file */
CurrentDir( (struct FileLock *)arguments.ArgList[current].wa_Lock );
name = arguments.ArgList[current].wa_Name;
}
else
/* else from CLI--just grab file name */
name = arguments.Names[current];
/* read this file and find out what user wants to do next */
file = file_read( name, prev, next );
/* will add or subtract 1 based on whether NEXT or PREV */
current += file;
}
}
/*************
* FILE SIZE
**************/
/*
This function returns YES or NO whether the file size could be calculated.
The file size is placed in current_file.FileSize.
*/
#define INFO_SIZE (long)sizeof(struct FileInfoBlock)
#define FAILED -1
BOOL file_size( void )
{
struct FileInfoBlock *info; /* to hold file information */
struct FileLock *lock; /* need to lock file to get info */
/* assume that this won't work */
current_file.FileSize = FAILED;
if (lock = Lock( current_file.Name, ACCESS_READ ))
{
if (info = AllocMem( INFO_SIZE, NULL ))
{
if (Examine( lock, info ))
current_file.FileSize = info->fib_Size;
FreeMem( info, INFO_SIZE );
}
UnLock( lock );
}
return (current_file.FileSize != FAILED);
}