/*

$Id: msgs,v 1.5 1999/10/05 22:03:04 joseph Exp $

*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include "memleak.h"
#include <string.h>

#include "swis.h"

#ifdef MemCheck_MEMCHECK
#include "MemCheck:MemCheck.h"
#endif

#include "CRstring.h"
#include "err.h"
#include "msgs.h"

MessagesFD msgs_descriptor;
#include "syslog.h"
const char *msgtrans_qlookup(const MessagesFD *desc, const char *token)
{
  char *result;
  if (_swix(MessageTrans_Lookup, _INR(0,2) | _OUT(2),
  	desc, token, 0, &result))
    result = NULL;

  return result;
}

const char *msgtrans_lookup4(const MessagesFD *desc, const char *token,
	const char *p0, const char *p1, const char *p2, const char *p3)
{
  static char *buffer = 0;
  static int buf_size = 0;
  int msglen;
  const char *s;

  s = msgtrans_qlookup(desc, token);
  if (!s)
    return 0;

  msglen = CRstrlen(s) + 1 +
  	CRstrlen(p0)+CRstrlen(p1)+CRstrlen(p2)+CRstrlen(p3);
  /* msglen not very accurate because doesn't discount unsubstituted parameters
     but at least it always errs on the large side */
  if (msglen > buf_size)
  {
    int newsize = (msglen < 128) ? 128 : msglen;

    buffer = buffer ? realloc(buffer, newsize) : malloc(newsize);
    if (!buffer)
    {
      E(msgs_nomem());
      return 0;
    }
    buf_size = newsize;
  }

  if (E(_swix(MessageTrans_Lookup, _INR(0,7) | _OUT(3),
  	desc, token, buffer, buf_size, p0, p1, p2, p3, &msglen)))
    return 0;

  buffer[msglen] = 0;

  return buffer;
}

_kernel_oserror *msgtrans_load(const char *filename, MessagesFD *desc,
	char **bufferout)
{
  int size;
  char *buffer;
  _kernel_oserror *result;
  result = _swix(MessageTrans_FileInfo, _IN(1) | _OUT(2), filename, &size);
  if (result)
    return result;
  buffer = malloc(size);
  if (!buffer)
    return msgs_nomem();
  if (!buffer)
    return 0;
  if (bufferout)
    *bufferout = buffer;
  memset(desc, 0, sizeof(MessagesFD));
  return _swix(MessageTrans_OpenFile, _INR(0,2), desc, filename, buffer);
}

_kernel_oserror *msgtrans_close(MessagesFD *desc)
{
  return _swix(MessageTrans_CloseFile, _IN(0), desc);
}

_kernel_oserror *msgtrans_error(MessagesFD *desc, const char *token)
{
  static _kernel_oserror err;
  err.errnum = 0;
  CRstrncpy(err.errmess, msgtrans_qlookup(desc, token), 252);
  return &err;
}

#ifdef MemCheck_MEMCHECK
void msgs_prime_memcheck()
{
  int ot;
  int size;
  const char *buffer;

  EF(_swix(OS_File, _INR(0,1) | _OUT(0) | _OUT(4),
  	5, TASK_DIR".Messages", &ot, &size));
  if (ot != 1)
    err_complain_fatal(0, "Can't register Messages with MemCheck");
  buffer = msgs_qlookup("_TaskName");
  if (!buffer)
    err_complain_fatal(0, "Can't register Messages with MemCheck");
  buffer -= sizeof("_TaskName:");
  MemCheck_RegisterMiscBlock(buffer, size + 1);
  MemCheck_SetBlockWritable(buffer, false);
}
#endif
