345 lines
8.8 KiB
C++
345 lines
8.8 KiB
C++
/*
|
|
* fileparse.cpp
|
|
*
|
|
* Copyright (C) 2001 Matt Ownby
|
|
*
|
|
* This file is part of DAPHNE, a laserdisc arcade game emulator
|
|
*
|
|
* DAPHNE is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* DAPHNE is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
// fileparse.cpp
|
|
// by Matt Ownby
|
|
|
|
// some basic file-parsing functions which should be safe enough to prevent daphne from ever
|
|
// segfaulting, even if the file is totally corrupt
|
|
|
|
#include "fileparse.h"
|
|
#include "conout.h"
|
|
|
|
// copies into buf everything from the current position in the file until the end of a
|
|
// line and positions the file stream at the beginning of the next line.
|
|
// returns how many bytes were copied
|
|
int read_line(mpo_io *io, string &buf)
|
|
{
|
|
unsigned char ch = 0;
|
|
MPO_BYTES_READ bytes_read = 0;
|
|
|
|
buf = ""; // initalize it with an empty string
|
|
|
|
// go until we reach EOF (or we reach the end of the line)
|
|
while (!io->eof)
|
|
{
|
|
if (mpo_read(&ch, 1, &bytes_read, io))
|
|
{
|
|
if (bytes_read == 0) break; // if we hit EOF, then break
|
|
|
|
// if we have hit the end of the line
|
|
if ((ch == 10) || (ch == 13))
|
|
{
|
|
// keep reading until we get passed the end of line chars
|
|
while (((ch == 10) || (ch == 13)) && (bytes_read != 0))
|
|
{
|
|
mpo_read(&ch, 1, &bytes_read, io);
|
|
}
|
|
|
|
// if we still have more of the file to read in, then move back one character
|
|
// so that we are at the beginning of the next line
|
|
if (bytes_read != 0)
|
|
{
|
|
// if seek was successful
|
|
if (mpo_seek(-1, MPO_SEEK_CUR, io) == true)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
printline("fileparse.cpp : mpo_seek function failed when it shouldn't have");
|
|
}
|
|
}
|
|
|
|
break; // we're done
|
|
}
|
|
|
|
// if the character is part of the current line then add it
|
|
else
|
|
{
|
|
buf = buf + (char) ch;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
printline("fileparse.cpp ERROR : mpo_read function failed");
|
|
break;
|
|
}
|
|
}
|
|
|
|
return buf.length();
|
|
}
|
|
|
|
|
|
// copies into buf everything from the current position in the file until the end of a
|
|
// line and positions the file stream at the beginning of the next line. Contents are also
|
|
// null-terminated.
|
|
// Returns the # of bytes copied into the buf.
|
|
// buf_size is the total size of the buf to prevent buffer overflow
|
|
int read_line(mpo_io *io, char *buf, int buf_size)
|
|
{
|
|
int index = 0;
|
|
unsigned char ch = 0;
|
|
MPO_BYTES_READ bytes_read = 0;
|
|
|
|
// while we haven't overflowed the buffer
|
|
// (we do -1 to leave space for null character at the end)
|
|
while (index < (buf_size - 1))
|
|
{
|
|
if (mpo_read(&ch, 1, &bytes_read, io))
|
|
{
|
|
if (bytes_read == 0) break; // if we hit EOF, then break
|
|
|
|
// if we have hit the end of the line
|
|
if ((ch == 10) || (ch == 13))
|
|
{
|
|
// keep reading until we get passed the end of line chars
|
|
while (((ch == 10) || (ch == 13)) && (bytes_read != 0))
|
|
{
|
|
mpo_read(&ch, 1, &bytes_read, io);
|
|
}
|
|
|
|
// if we still have more of the file to read in, then move back one character
|
|
// so that we are at the beginning of the next line
|
|
if (bytes_read != 0)
|
|
{
|
|
// if seek was successful
|
|
if (mpo_seek(-1, MPO_SEEK_CUR, io) == true)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
printline("fileparse.cpp : mpo_seek function failed when it shouldn't have");
|
|
}
|
|
}
|
|
|
|
break; // we're done
|
|
}
|
|
|
|
// if the character is part of the current line
|
|
else
|
|
{
|
|
buf[index++] = (unsigned char) ch;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
printline("fileparse.cpp ERROR : mpo_read function failed");
|
|
break;
|
|
}
|
|
}
|
|
buf[index] = 0;
|
|
|
|
return (index + 1); // + 1 to indicate # of bytes actually copied
|
|
}
|
|
|
|
int read_line(FILE *F, char *buf, int buf_size)
|
|
{
|
|
int index = 0;
|
|
int ch = 0;
|
|
|
|
// while we haven't overflowed the buffer
|
|
// (we do -1 to leave space for null character at the end)
|
|
while (index < (buf_size - 1))
|
|
{
|
|
ch = fgetc(F);
|
|
|
|
if (ch == EOF) break; // if we hit the end of file, then break
|
|
|
|
// if we have hit the end of the line
|
|
if ((ch == 10) || (ch == 13))
|
|
{
|
|
// keep reading until we get passed the end of line chars
|
|
while (((ch == 10) || (ch == 13)) && (ch != EOF))
|
|
{
|
|
ch = getc(F);
|
|
}
|
|
|
|
// if we still have more of the file to read in, then move back one character
|
|
// so that we are at the beginning of the next line
|
|
if (ch != EOF)
|
|
{
|
|
fseek(F, -1, SEEK_CUR);
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
// if the character is part of the current line
|
|
else
|
|
{
|
|
buf[index++] = (unsigned char) ch;
|
|
}
|
|
}
|
|
buf[index] = 0;
|
|
|
|
return (index + 1); // + 1 to indicate # of bytes actually copied
|
|
}
|
|
|
|
|
|
const char *read_line(const char *pszInBuf, string &line)
|
|
{
|
|
const char *result = NULL;
|
|
unsigned char ch = 0;
|
|
int idx = 0;
|
|
|
|
line = ""; // initalize it with an empty string
|
|
|
|
// go until we reach end of the buffer (or end of line)
|
|
while (pszInBuf[idx] != 0)
|
|
{
|
|
ch = pszInBuf[idx];
|
|
|
|
// if we have hit the end of the line
|
|
if ((ch == 10) || (ch == 13))
|
|
{
|
|
// keep reading until we get passed the end of line chars
|
|
while (((ch == 10) || (ch == 13)) && (ch != 0))
|
|
{
|
|
++idx;
|
|
ch = pszInBuf[idx];
|
|
}
|
|
|
|
break; // we got our line
|
|
}
|
|
|
|
// if the character is part of the current line then add it
|
|
else
|
|
{
|
|
line = line + (char) ch;
|
|
}
|
|
++idx;
|
|
}
|
|
|
|
// if we aren't at the end of the buffer, return pointer to first character of next line
|
|
if (pszInBuf[idx] != 0) result = pszInBuf + idx;
|
|
|
|
return result;
|
|
}
|
|
|
|
|
|
// takes a pathname (relative or absolute) + a filename and removes the filename itself
|
|
// therefore it returns just the path (stored in 'path')
|
|
// returns false if there is an error (such as the file having no path)
|
|
bool get_path_of_file(string file_with_path, string &path)
|
|
{
|
|
bool success = false;
|
|
int index = file_with_path.length() - 1; // start on last character
|
|
|
|
// make sure the file_with_path is at least 2 characters long
|
|
// because otherwise our proceeding calculations could cause a segfault
|
|
if (index > 0)
|
|
{
|
|
// locate the preceeding / or \ character
|
|
while ((index >= 0) && (file_with_path[index] != '/') && (file_with_path[index] != '\\'))
|
|
{
|
|
index--;
|
|
}
|
|
|
|
// if we found a leading / or \ character
|
|
if (index >= 0)
|
|
{
|
|
path = file_with_path.substr(0, index+1);
|
|
success = true;
|
|
}
|
|
}
|
|
|
|
return success;
|
|
}
|
|
|
|
// Isolates a word within an arbitrary string (src_buf)
|
|
// 'word' will contain the word it found, 'remaining_line' will contain the rest of the line that has yet to be examined
|
|
// !!!NOTE : 'src_buf' is assumed to be a single line with no linefeed/carriage return characters!!!
|
|
// Returns 'true' if a word was found, or 'false' if a word could not be found (ie if the string was empty)
|
|
bool find_word(const char *src_buf, string &word, string &remaining_line)
|
|
{
|
|
bool result = false;
|
|
int index = 0;
|
|
int start_index = 0;
|
|
|
|
// find beginning of word, skip spaces or tabs
|
|
while (my_is_whitespace(src_buf[index]))
|
|
{
|
|
index++;
|
|
}
|
|
|
|
// make sure we aren't at the end of the string already
|
|
if (src_buf[index] != 0)
|
|
{
|
|
start_index = index;
|
|
|
|
// now go to the end of the current word
|
|
while ((!my_is_whitespace(src_buf[index])) && (src_buf[index] != 0))
|
|
{
|
|
index++;
|
|
}
|
|
|
|
// this section is a little tricky, so verify that it actually works :)
|
|
word = src_buf;
|
|
remaining_line = word.substr(index, word.length() - index);
|
|
word = word.substr(start_index, index-start_index);
|
|
result = true;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// Isolates a word within an arbitrary string (src_buf)
|
|
// 'word_begin' will point to the beginning of the word, and 'word_length' will be how long the word is
|
|
// !!!NOTE : 'src_buf' is assumed to be a single line with no linefeed/carriage return characters!!!
|
|
// Returns 'true' if a word was found, or 'false' if a word could not be found (ie if the string was empty)
|
|
bool find_word(const char *src_buf, const char **word_begin, int *word_length)
|
|
{
|
|
bool result = false;
|
|
int index = 0;
|
|
|
|
*word_length = 0;
|
|
*word_begin = NULL;
|
|
|
|
// find beginning of word, skip spaces or tabs
|
|
while (my_is_whitespace(src_buf[index]))
|
|
{
|
|
index++;
|
|
}
|
|
|
|
// make sure we aren't at the end of the string already
|
|
if (src_buf[index] != 0)
|
|
{
|
|
*word_begin = &src_buf[index]; // point to beginning of word occurance
|
|
|
|
// now go to the end of the current word
|
|
while ((!my_is_whitespace(src_buf[index])) && (src_buf[index] != 0))
|
|
{
|
|
(*word_length)++;
|
|
index++;
|
|
}
|
|
result = true;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
// miniature version of isspace() because we don't want to consider linefeeds/carriage returns to be whitespace
|
|
bool my_is_whitespace(char ch)
|
|
{
|
|
if ((ch == ' ') || (ch == '\t')) return true;
|
|
else return false;
|
|
}
|