AwakeMUD-0.8.18B/
AwakeMUD-0.8.18B/doc/
AwakeMUD-0.8.18B/lib/
AwakeMUD-0.8.18B/lib/etc/
AwakeMUD-0.8.18B/lib/etc/pfiles/
AwakeMUD-0.8.18B/lib/misc/
AwakeMUD-0.8.18B/lib/text/
AwakeMUD-0.8.18B/lib/text/help/
AwakeMUD-0.8.18B/lib/text/wizhelp/
AwakeMUD-0.8.18B/lib/veh/
AwakeMUD-0.8.18B/lib/world/
AwakeMUD-0.8.18B/lib/world/mob/
AwakeMUD-0.8.18B/lib/world/mtx/
AwakeMUD-0.8.18B/lib/world/qst/
AwakeMUD-0.8.18B/lib/world/shp/
AwakeMUD-0.8.18B/lib/world/veh/
// file: file.cpp
// author: Andrew Hynek
// contents: implementation of a simple file class

#include <stdio.h>
#include <string.h>
#include <time.h>   // for awake.h (time_t)

#include "file.h"
#include "awake.h"  // for MAX_STRING_LENGTH
#include "utils.h"  // for log()
#include <new>

File::File()
{
  fl = NULL;
  *filename = '\0';
  *mode = '\0';
}

File::File(const char *_filename, const char *_mode)
{
  fl = NULL;
  *filename = '\0';
  *mode = '\0';

  Open(_filename, _mode);
}

File::~File()
{
  Close();
}

bool File::EoF() const
{
  return feof(fl);
}

bool File::IsWriteable() const
{
  return (IsOpen() && (strchr(mode, 'w') || strchr(mode, 'a')));
}

bool File::Open(const char *_filename, const char *_mode)
{
  Close();

  fl = fopen(_filename, _mode);

  if (!fl)
    return false;

  memset(filename, 0, MAX_FILE_LENGTH);
  strncpy(filename, _filename, MAX_FILE_LENGTH);

  memset(mode, 0, 8);
  strncpy(mode, _mode, 8);

  line_num = 0;

  return true;
}

bool File::Close()
{
  if (IsOpen()) {
    fclose(fl);
    fl = NULL;
    *filename = '\0';
    *mode = '\0';

    return true;
  }

  return false;
}

void File::Rewind()
{
  rewind(fl);
  line_num = 0;
}

int  File::Seek(long offset, int origin)
{
  return fseek(fl, offset, origin);
}

bool File::GetLine(char *buf, size_t buf_size, bool blank)
{
  while (!feof(fl)) {
    fgets(buf, buf_size, fl);
    line_num++;

    if (*buf && *buf != '*' && (blank ? TRUE : *buf != '\n')) {
      char *ptr = strchr(buf, '\n');

      if (ptr && ptr < (buf + buf_size))
        *ptr = '\0';

      break;
    }
  }

  return (!feof(fl));
}

char *File::ReadString()
{
  char buf[MAX_STRING_LENGTH+8];
  char line[512+8];
  size_t buf_len = 0;
  bool skip_to_end = false, done = false;

  memset(buf, 0, MAX_STRING_LENGTH+8);

  while (!done) {
    if (!GetLine(line, 512, FALSE)) {
      log("Error: format error in %s, line %d: expecting ~-terminated string",
          Filename(), LineNumber());
      break;
    }

    char *ptr = strchr(line, '~');

    // if we find '~', replace it with '\0' and break, otherwise cat "\r\n"
    if (ptr) {
      *ptr = '\0';
      done = true;
    } else
      strcat(line, "\r\n");

    size_t line_len = strlen(line);

    if ((buf_len + line_len) >= (size_t)MAX_STRING_LENGTH) {
      // we can handle this gracefully: just fill buf, then set skip_to_end

      log("Error: string too long (%s, line %d) -- truncating",
          Filename(), LineNumber());

      strncpy(buf+buf_len, line, MAX_STRING_LENGTH - buf_len);
      *(buf+MAX_STRING_LENGTH) = '\0';
      strcat(buf, "\r\n");

      // if line doesn't have the '~', then we need to find it later
      skip_to_end = (strchr(line, '~') == NULL);

      break;
    }

    strcat(buf, line);
    buf_len += line_len;
  }

  if (skip_to_end) {
    // if we're here, we need to find the '~'
    while (!EoF()) {
      if (!GetLine(line, 512, FALSE)) {
        log("Error: format error in %s, line %d: expecting ~-termed string",
            Filename(), LineNumber());
        break;
      }

      if (strchr(line, '~') != NULL)
        break;
    }
  }

  if (buf_len > 0) {
    char *res = new char[buf_len+1];
    strcpy(res, buf);

    return res;
  }

  return NULL;
}

int  File::Print(const char *format, ...)
{
#ifdef vfprintf

  va_list arg_list;

  va_start(arg_list, format);
  int res = vfprintf(fl, format, arg_list);
  va_end(arg_list);

  return res;
#else

  return 0;
#endif
}