home *** CD-ROM | disk | FTP | other *** search
- /*********************************
- * 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);
- }
-