
#include <exec/types.h>
#include <libraries/dos.h>
#include <functions.h>

#include <stdio.h>
#include <string.h>

#include "dos37em.h"

#define entries_in(x) (sizeof (x) / sizeof (*(x)))

struct error_entry
  {
    LONG first;
    LONG size;
    char **strings;
  };

static char *error_strings_1[] =
  {
    NULL,
    NULL,
    NULL,
    "not enough memory",
    "process table full",
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    "bad template",
    "bad number",
    "required argument missing",
    "argument after '=' missing",
    "too many arguments",
    "unmatched quotes",
    "argument line invalid or too long",
    "file is not executable",
    "invalid resident library"
  };

static char *error_strings_2[] =
  {
    NULL,
    NULL,
    "object is in use",
    "object already exists",
    "directory not found",
    "object not found",
    "invalid window description",
    NULL,
    NULL,
    "packet request type unknown",
    "object name invalid",
    "invalid object lock",
    "object is not of required type",
    "disk not validated",
    "disk is write-protected",
    "rename across devices attempted",
    "directory not empty",
    "too many levels",
    "device (or volume) is not mounted",
    "seek error",
    "comment is too long",
    "disk is full",
    "object is protected from deletion",
    "file is write protected",
    "file is read protected",
    "not a valid DOS disk",
    "no disk in drive",
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    "no more entries in directory",
    "object is soft link"
  };

static struct error_entry error_table[] =
  {
    {100, entries_in (error_strings_1), error_strings_1},
    {200, entries_in (error_strings_2), error_strings_2},
    {0, 0, NULL}
  };

static char *
dos_error_string (error)
{
  struct error_entry *entry;

  entry = error_table;
  while (entry->strings)
    {
      if (error >= entry->first && error < entry->first + entry->size)
	break;
      ++entry;
    }
  if (!entry->strings)
    return NULL;
  return entry->strings[error - entry->first];
}

BOOL
ryb_Fault (LONG code, UBYTE *header, UBYTE *buffer, LONG len)
{
  int header_len = 0;
  char *string;
  char number[20];

  if (header && header[0])
    {
      header_len = strlen ((char *) header);
      if (header_len + 3 > len)
	return DOSFALSE;
      strcpy ((char *) buffer, (char *) header);
      buffer[header_len++] = ':';
      buffer[header_len++] = ' ';
    }
  string = dos_error_string (code);
  if (string)
    {
      if (strlen (string) + header_len + 1 > len)
	return DOSFALSE;
      strcpy ((char *) buffer + header_len, string);
    }
  else
    {
      sprintf (number, "Error %d", code);
      if (strlen (number) + header_len + 1 > len)
	return DOSFALSE;
      strcpy ((char *) buffer + header_len, number);
    }
  return DOSTRUE;
}
