Added Magiedit to makefile
This commit is contained in:
352
deps/odoors/historic/odtips3/FILEVIEW.C
vendored
Normal file
352
deps/odoors/historic/odtips3/FILEVIEW.C
vendored
Normal file
@@ -0,0 +1,352 @@
|
||||
/* fileview.c - File viewing door that demonstrates the use of the */
|
||||
/* PagedViewer() function. This door can be setup to */
|
||||
/* to display a single text file, or any file from an */
|
||||
/* entire directory of text files. The program accepts */
|
||||
/* a single command-line argument, which if present, */
|
||||
/* specifies the filename or wildcard of the files to */
|
||||
/* display. If this argument is not present, all files */
|
||||
/* in the current directory will be available for */
|
||||
/* viewing. If there is more than one possible file to */
|
||||
/* be displayed, this program will display a list of */
|
||||
/* files that the user can choose from to display. If */
|
||||
/* there is only one possible file, that file is */
|
||||
/* is displayed. This program uses PagedViewer() for two */
|
||||
/* seperate uses - the list of available files, and for */
|
||||
/* viewing the file itself. */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "bpfind.h"
|
||||
#include "opendoor.h"
|
||||
#include "pageview.h"
|
||||
|
||||
|
||||
/* Configurable constants. */
|
||||
#define FILENAME_SIZE 75
|
||||
#define PATH_CHARS (FILENAME_SIZE - 13)
|
||||
#define LINE_SIZE 80
|
||||
#define ARRAY_GROW_SIZE 20
|
||||
|
||||
|
||||
/* Global variables. */
|
||||
int nTotalFiles = 0;
|
||||
int nFileArraySize = 0;
|
||||
char *paszFileArray = NULL;
|
||||
|
||||
FILE *pfCurrentFile;
|
||||
int nTotalLines = 0;
|
||||
int nLineArraySize = 0;
|
||||
long *palLineOffset = NULL;
|
||||
|
||||
|
||||
/* Function prototypes. */
|
||||
void AddFilesMatching(char *pszFileSpec);
|
||||
char *GetFilename(int nIndex);
|
||||
int AddFilename(char *pszFilename);
|
||||
void GetDirOnly(char *pszOutDirName, const char *pszInPathName);
|
||||
int DirExists(const char *pszDirName);
|
||||
void BuildPath(char *pszOut, char *pszPath, char *pszFilename);
|
||||
void FreeFileList(void);
|
||||
void DisplayFileName(int nLine, void *pCallbackData);
|
||||
void DisplayFile(char *pszFilename);
|
||||
void DisplayFileLine(int nLine, void *pCallbackData);
|
||||
int AddOffsetToArray(long lOffset);
|
||||
void FreeLineArray(void);
|
||||
|
||||
|
||||
/* Program execution begins here. */
|
||||
int main(int nArgCount, char *papszArgument[])
|
||||
{
|
||||
int nArg;
|
||||
int nChoice;
|
||||
|
||||
od_init();
|
||||
|
||||
/* Get file specifiction from command-line, if any. */
|
||||
if(nArgCount >= 2)
|
||||
{
|
||||
for(nArg = 1; nArg < nArgCount; ++nArg)
|
||||
{
|
||||
AddFilesMatching(papszArgument[nArg]);
|
||||
}
|
||||
}
|
||||
|
||||
/* If there are no command-line parameters, use *.* */
|
||||
else
|
||||
{
|
||||
AddFilesMatching("*.*");
|
||||
}
|
||||
|
||||
/* If there are no matching files, display error. */
|
||||
if(nTotalFiles == 0)
|
||||
{
|
||||
od_printf("No files were found.\n\r\n\r");
|
||||
od_printf("Press [Enter] to continue.\n\r");
|
||||
od_get_answer("\n\r");
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* If only one file was found, then display it. */
|
||||
else if(nTotalFiles == 1)
|
||||
{
|
||||
DisplayFile(GetFilename(0));
|
||||
}
|
||||
|
||||
/* If more than one file was found, allow user to choose file */
|
||||
/* to display. */
|
||||
else
|
||||
{
|
||||
/* Loop until user chooses to quit. */
|
||||
nChoice = 0;
|
||||
for(;;)
|
||||
{
|
||||
/* Get user's selection. */
|
||||
nChoice = PagedViewer(nChoice, nTotalFiles, DisplayFileName,
|
||||
NULL, TRUE, "Choose A File To Display", 19);
|
||||
|
||||
/* If user chose to quit, then exit door. */
|
||||
if(nChoice == NO_LINE) break;
|
||||
|
||||
/* Otherwise, display the file that the user chose. */
|
||||
DisplayFile(GetFilename(nChoice));
|
||||
}
|
||||
}
|
||||
|
||||
FreeFileList();
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
void AddFilesMatching(char *pszFileSpec)
|
||||
{
|
||||
struct ffblk DirEntry;
|
||||
int bNoMoreFiles;
|
||||
char szDirName[PATH_CHARS + 1];
|
||||
char szFileName[FILENAME_SIZE];
|
||||
|
||||
/* Check that file specification is not too long. */
|
||||
if(strlen(pszFileSpec) > PATH_CHARS)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get directory name from path. */
|
||||
GetDirOnly(szDirName, pszFileSpec);
|
||||
|
||||
bNoMoreFiles = findfirst(pszFileSpec, &DirEntry, FA_RDONLY);
|
||||
while(!bNoMoreFiles)
|
||||
{
|
||||
BuildPath(szFileName, szDirName, DirEntry.ff_name);
|
||||
|
||||
AddFilename(szFileName);
|
||||
|
||||
bNoMoreFiles = findnext(&DirEntry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GetDirOnly(char *pszOutDirName, const char *pszInPathName)
|
||||
{
|
||||
char *pchBackslashChar;
|
||||
|
||||
/* Default dir name is entire path. */
|
||||
strcpy(pszOutDirName, pszInPathName);
|
||||
|
||||
/* If there is a backslash in the string. */
|
||||
pchBackslashChar = strrchr(pszOutDirName, '\\');
|
||||
if(pchBackslashChar != NULL)
|
||||
{
|
||||
/* Remove all character beginning at last backslash from path. */
|
||||
*pchBackslashChar = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If there is no backslash in the filename, then the dir name */
|
||||
/* is empty. */
|
||||
pszOutDirName[0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BuildPath(char *pszOut, char *pszPath, char *pszFilename)
|
||||
{
|
||||
/* Copy path to output filename. */
|
||||
strcpy(pszOut, pszPath);
|
||||
|
||||
/* Ensure there is a trailing backslash. */
|
||||
if(strlen(pszOut) > 0 && pszOut[strlen(pszOut) - 1] != '\\')
|
||||
{
|
||||
strcat(pszOut, "\\");
|
||||
}
|
||||
|
||||
/* Append base filename. */
|
||||
strcat(pszOut, pszFilename);
|
||||
}
|
||||
|
||||
|
||||
char *GetFilename(int nIndex)
|
||||
{
|
||||
return(paszFileArray + (nIndex * FILENAME_SIZE));
|
||||
}
|
||||
|
||||
|
||||
int AddFilename(char *pszFilename)
|
||||
{
|
||||
int nNewArraySize;
|
||||
char *paszNewArray;
|
||||
char *pszNewString;
|
||||
|
||||
/* If array is full, then try to grow it. */
|
||||
if(nTotalFiles == nFileArraySize)
|
||||
{
|
||||
nNewArraySize = nFileArraySize + ARRAY_GROW_SIZE;
|
||||
if((paszNewArray =
|
||||
realloc(paszFileArray, nNewArraySize * FILENAME_SIZE)) == NULL)
|
||||
{
|
||||
return(FALSE);
|
||||
}
|
||||
nFileArraySize = nNewArraySize;
|
||||
paszFileArray = paszNewArray;
|
||||
}
|
||||
|
||||
/* Get address to place new string at, while incrementing total number */
|
||||
/* of filenames. */
|
||||
pszNewString = GetFilename(nTotalFiles++);
|
||||
|
||||
/* Copy up to the maximum number of filename characters to the string. */
|
||||
strncpy(pszNewString, pszFilename, FILENAME_SIZE - 1);
|
||||
pszNewString[FILENAME_SIZE - 1] = '\0';
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
void FreeFileList(void)
|
||||
{
|
||||
if(nFileArraySize > 0)
|
||||
{
|
||||
free(paszFileArray);
|
||||
nFileArraySize = 0;
|
||||
nTotalFiles = 0;
|
||||
paszFileArray = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void DisplayFileName(int nLine, void *pCallbackData)
|
||||
{
|
||||
(void)pCallbackData;
|
||||
|
||||
od_printf(GetFilename(nLine));
|
||||
}
|
||||
|
||||
|
||||
void DisplayFile(char *pszFilename)
|
||||
{
|
||||
char szLine[LINE_SIZE];
|
||||
long lnOffset;
|
||||
|
||||
/* Clear the screen. */
|
||||
od_clr_scr();
|
||||
|
||||
/* Attempt to open the file. */
|
||||
pfCurrentFile = fopen(pszFilename, "r");
|
||||
if(pfCurrentFile == NULL)
|
||||
{
|
||||
od_printf("Unable to open file.\n\r\n\r");
|
||||
od_printf("Press [Enter] to continue.\n\r");
|
||||
od_get_answer("\n\r");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get file offsets of each line and total line count from file. */
|
||||
for(;;)
|
||||
{
|
||||
lnOffset = fTell(pfCurrentFile);
|
||||
|
||||
if(fgets(szLine, LINE_SIZE, pfCurrentFile) == NULL) break;
|
||||
|
||||
AddOffsetToArray(lnOffset);
|
||||
}
|
||||
|
||||
/* Use PagedViewer() to view the file. */
|
||||
PagedViewer(0, nTotalLines, DisplayFileLine, NULL, FALSE, NULL, 21);
|
||||
|
||||
/* Deallocate array of line offsets. */
|
||||
FreeLineArray();
|
||||
|
||||
/* Close the file. */
|
||||
fclose(pfCurrentFile);
|
||||
}
|
||||
|
||||
|
||||
void DisplayFileLine(int nLine, void *pCallbackData)
|
||||
{
|
||||
char szLine[LINE_SIZE];
|
||||
long lnTargetOffset = palLineOffset[nLine];
|
||||
int nLineLen;
|
||||
|
||||
(void)pCallbackData;
|
||||
|
||||
/* Move to proper offset in file. */
|
||||
if(lnTargetOffset != ftell(pfCurrentFile))
|
||||
{
|
||||
fseek(pfCurrentFile, lnTargetOffset, SEEK_SET);
|
||||
}
|
||||
|
||||
/* Get line from line. */
|
||||
if(fgets(szLine, LINE_SIZE, pfCurrentFile) != NULL)
|
||||
{
|
||||
/* Remote any trailing CR/LF sequence from line. */
|
||||
nLineLen = strlen(szLine);
|
||||
while(nLineLen > 0
|
||||
&& (szLine[nLineLen - 1] == '\r' || szLine[nLineLen - 1] == '\n'))
|
||||
{
|
||||
szLine[--nLineLen] = '\0';
|
||||
}
|
||||
|
||||
/* Display the line on the screen. */
|
||||
od_disp_str(szLine);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int AddOffsetToArray(long lOffset)
|
||||
{
|
||||
long *palNewArray;
|
||||
int nNewArraySize;
|
||||
|
||||
/* If array is full, then grow it. */
|
||||
if(nTotalLines == nLineArraySize)
|
||||
{
|
||||
nNewArraySize = nLineArraySize + ARRAY_GROW_SIZE;
|
||||
|
||||
if((palNewArray =
|
||||
realloc(palLineOffset, nNewArraySize * sizeof(long))) == NULL)
|
||||
{
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
nLineArraySize = nNewArraySize;
|
||||
palLineOffset = palNewArray;
|
||||
}
|
||||
|
||||
palLineOffset[nTotalLines++] = lOffset;
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
|
||||
void FreeLineArray(void)
|
||||
{
|
||||
if(nLineArraySize > 0)
|
||||
{
|
||||
nTotalLines = 0;
|
||||
nLineArraySize = 0;
|
||||
free(palLineOffset);
|
||||
palLineOffset = NULL;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user