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: vtable.h
// author: Andrew Hynek
// contents: a value table (VTable) class

#ifndef __vtable_h__
#define __vtable_h__

class File;

class VTable
{
  static const int MAX_SECTION_LENGTH = 32;
  static const int MAX_FIELD_LENGTH = 32;
  static const int MAX_LINE_LENGTH = 256;

  struct field
  {
    char name[MAX_FIELD_LENGTH];
    char line[MAX_LINE_LENGTH];
    char *multiline;

    field() : multiline(NULL)
    {
      *name = '\0';
      *line = '\0';
    }

    ~field();

    field &operator=(const field &two)
    {
      // do a deep copy
      strcpy(name, two.name);
      strcpy(line, two.line);

      if (two.multiline) {
        if (!multiline) {
          multiline = new char[strlen(two.multiline)+1];
          strcpy(multiline, two.multiline);
        } else if (strcmp(multiline, two.multiline)) {
          delete [] multiline;
          multiline = new char[strlen(two.multiline)+1];
          strcpy(multiline, two.multiline);
        }
      } else if (multiline) {
        delete [] multiline;
        multiline = NULL;
      }

      return (*this);
    }
  };

  struct section
  {
    char name[MAX_SECTION_LENGTH]; // NULL for top
    section *parent;

    section *sub_tab;
    int sub_cnt;
    int sub_size;

    field *field_tab;
    int field_cnt;
    int field_size;

    section() : parent(NULL),
        sub_tab(NULL), sub_cnt(0), sub_size(0),
        field_tab(NULL), field_cnt(0), field_size(0)
    {
      *name = '\0';
    }

    ~section();

    section &operator=(const section &two)
    {
      strcpy(name, two.name);

      parent = two.parent;

      if (two.sub_tab && two.sub_cnt > 0) {
        sub_size = two.sub_size;
        sub_cnt = two.sub_cnt;

        if (sub_tab)
          delete [] sub_tab;

        sub_tab = new section[sub_size];

        for (int i = 0; i < sub_cnt; i++)
          sub_tab[i] = two.sub_tab[i];
      } else {
        sub_cnt = 0;
        sub_size = 0;

        if (sub_tab) {
          delete [] sub_tab;
          sub_tab = NULL;
        }
      }

      if (two.field_tab && two.field_cnt > 0) {
        field_size = two.field_size;
        field_cnt = two.field_cnt;

        if (field_tab)
          delete [] field_tab;

        field_tab = new field[field_size];

        for (int i = 0; i < field_cnt; i++)
          field_tab[i] = two.field_tab[i];
      } else {
        field_cnt = 0;
        field_size = 0;

        if (field_tab) {
          delete [] field_tab;
          field_tab = NULL;
        }
      }

      return (*this);
    }
  };

  section top;

public:
  int  NumSections() const;
  int  NumSubsections(const char *sect);
  int  NumFields(const char *sect_name);

  bool DoesSectionExist(const char *sect);
  bool DoesFieldExist(const char *where);

  // returns the number of fields successfully parsed
  int Parse(File *in);

  int GetInt(const char *where, int defawlt);
  long GetLong(const char *where, long defawlt);

  // assumes lookup_tab is "\n"-terminated, returns index of string in tab
  int LookupInt(const char *where, const char **lookup_tab, int defawlt);

  const char *GetString(const char *where, const char *defawlt);

  float GetFloat(const char *where, float defawlt);

  // returns a pointer (don't delete) to field name of nth field in section
  const char *GetIndexField(const char *sect_name, int n);

  // like GetIndexField, but for subsection names
  const char *GetIndexSection(const char *sect_name, int n);

  // returns the int of the nth field in section
  int GetIndexInt(const char *sect_name, int n, int defawlt);

  const char *GetIndexString(const char *sect_name, int n,
                             const char *defawlt);
  // float GetIndexFloat();

  // bool AddInt(const char *where, int n);
  // bool AddString(const char *where, const char *str);
  // bool AddFloat(const char *where, float f);

private:
  static void separate(const char *where,
                       char section[MAX_SECTION_LENGTH],
                       char field[MAX_FIELD_LENGTH]);

  void resize_subsection_tab(section *ptr, int empty = 5);
  void resize_field_tab(section *ptr, int empty = 5);

  field *find_field(const char *where);
  section *find_section(const char *sect);
  section *look_for_section(section *ptr, const char *name);

  int count_subsections(const section *ptr) const;
};

#endif // ifndef __vtable_h__