/* gppdemid.c

   Copyright 1993 Eberhard Mattes
   
This file is part of the GPPDEMID library.
GPPDEMID is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.

GPPDEMID 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
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
License along with libiberty; see the file COPYING.LIB.  If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA.  */

/* Note: This is 16-bit code! */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INCL_DOSMEMMGR
#define INCL_DOSPROCESS
#include <os2.h>
#include "demangle.h"

/* Do not pull-in the MSC startup code. */

int _acrtused = 0;

/* These functions are imported by cplus-de.c.  Don't do error
   checking.  setjmp() and longjmp() could be used to make DEMANGLEID
   return 0 if out of memory.  Note: allocate one more byte and change
   the offset to 1 to work around a bug in string_prependn. */

char *xmalloc (size_t n)
{
  SEL sel;

  if (DosAllocSeg (n + 1, &sel, SEG_NONSHARED) != 0)
    return NULL;
  return MAKEP (sel, 1);
}


char *xrealloc (void *p, size_t n)
{
  if (DosReallocSeg (n + 1, SELECTOROF (p)) != 0)
    return (NULL);
  return p;
}


void free (void *p)
{
  DosFreeSeg (SELECTOROF (p));
}


void abort (void)
{
  DosExit (EXIT_PROCESS, 17);
}


/* Initialization. */

unsigned short pascal INITDEMANGLEID (const char *init)
{
  return 1;                     /* Success */
}

/* Demangler. */

unsigned short pascal DEMANGLEID (const char *src, char *dst,
                                  unsigned long dst_size)
{
  char *result;
  char mangled[256];
  size_t len;

  len = ((const unsigned char *)src)[0];
  memcpy (mangled, src+1, len);
  mangled[len] = 0;

  result = cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI);
  if (result == NULL)
    return 0;                   /* Error */
  len = strlen (result);
  if ((unsigned long)len >= dst_size)
    return 0;                   /* Error */
  memcpy (dst, result, len + 1);
  free (result);
  return 1;                     /* Success */
}
