/* Shared functions related to mangling names for the GNU compiler
   for the Java(TM) language.
   Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GCC 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING.  If not, write to
the Free Software Foundation, 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. 

Java and all Java-based marks are trademarks or registered trademarks
of Sun Microsystems, Inc. in the United States and other countries.
The Free Software Foundation is independent of Sun Microsystems, Inc.  */

/* Written by Alexandre Petit-Bianco <apbianco@cygnus.com> */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "jcf.h"
#include "tree.h"
#include "java-tree.h"
#include "obstack.h"
#include "toplev.h"

static void append_unicode_mangled_name (const char *, int);
#ifndef HAVE_AS_UTF8
static int  unicode_mangling_length (const char *, int);
#endif

extern struct obstack *mangle_obstack;

/* If the assembler doesn't support UTF8 in symbol names, some
   characters might need to be escaped.  */

#ifndef HAVE_AS_UTF8

/* Assuming (NAME, LEN) is a Utf8-encoding string, emit the string
   appropriately mangled (with Unicode escapes if needed) to
   MANGLE_OBSTACK.  Note that `java', `lang' and `Object' are used so
   frequently that they could be cached.  */

void
append_gpp_mangled_name (const char *name, int len)
{
  int encoded_len = unicode_mangling_length (name, len);
  int needs_escapes = encoded_len > 0;
  char buf[6];

  sprintf (buf, "%d", (needs_escapes ? encoded_len : len));
  obstack_grow (mangle_obstack, buf, strlen (buf));

  if (needs_escapes)
    append_unicode_mangled_name (name, len);
  else
    obstack_grow (mangle_obstack, name, len);
}

/* Assuming (NAME, LEN) is a Utf8-encoded string, emit the string
   appropriately mangled (with Unicode escapes) to MANGLE_OBSTACK.
   Characters needing an escape are encoded `__UNN_' to `__UNNNN_', in
   which case `__U' will be mangled `__U_'.  */

static void
append_unicode_mangled_name (const char *name, int len)
{
  const unsigned char *ptr;
  const unsigned char *limit = (const unsigned char *)name + len;
  int uuU = 0;
  for (ptr = (const unsigned char *) name;  ptr < limit;  )
    {
      int ch = UTF8_GET(ptr, limit);

      if ((ISALNUM (ch) && ch != 'U') || ch == '$')
	obstack_1grow (mangle_obstack, ch);
      /* Everything else needs encoding */
      else
	{
	  char buf [9];
	  if (ch == '_' || ch == 'U')
	    {
	      /* Prepare to recognize __U */
	      if (ch == '_' && (uuU < 3))
		{
		  uuU++;
		  obstack_1grow (mangle_obstack, ch);
		}
	      /* We recognize __U that we wish to encode
                 __U_. Finish the encoding. */
	      else if (ch == 'U' && (uuU == 2))
		{
		  uuU = 0;
		  obstack_grow (mangle_obstack, "U_", 2);
		}
	      /* Otherwise, just reset uuU and emit the character we
                 have. */
	      else
		{
		  uuU = 0;
		  obstack_1grow (mangle_obstack, ch);
		}
	      continue;
	    }
	  sprintf (buf, "__U%x_", ch);
	  obstack_grow (mangle_obstack, buf, strlen (buf));
	  uuU = 0;
	}
    }
}

/* Assuming (NAME, LEN) is a Utf8-encoding string, calculate the
   length of the string as mangled (a la g++) including Unicode
   escapes.  If no escapes are needed, return 0.  */

static int
unicode_mangling_length (const char *name, int len)
{
  const unsigned char *ptr;
  const unsigned char *limit = (const unsigned char *)name + len;
  int need_escapes = 0;		/* Whether we need an escape or not */
  int num_chars = 0;		/* Number of characters in the mangled name */
  int uuU = 0;			/* Help us to find __U. 0: '_', 1: '__' */
  for (ptr = (const unsigned char *) name;  ptr < limit;  )
    {
      int ch = UTF8_GET(ptr, limit);

      if (ch < 0)
	error ("internal error - invalid Utf8 name");
      if ((ISALNUM (ch) && ch != 'U') || ch == '$')
	num_chars++;
      /* Everything else needs encoding */
      else
	{
	  int encoding_length = 2;

	  if (ch == '_' || ch == 'U')
	    {
	      /* It's always at least one character. */
	      num_chars++;

	      /* Prepare to recognize __U */
	      if (ch == '_' && (uuU < 3))
		uuU++;

	      /* We recognize __U that we wish to encode __U_, we
	         count one more character. */
	      else if (ch == 'U' && (uuU == 2))
		{
		  num_chars++;
		  need_escapes = 1;
		  uuU = 0;
		}
	      /* Otherwise, just reset uuU */
	      else
		uuU = 0;

	      continue;
	    }
	  
	  if (ch > 0xff)
	    encoding_length++;
	  if (ch > 0xfff)
	    encoding_length++;
	  
	  num_chars += (4 + encoding_length);
	  need_escapes = 1;
	  uuU = 0;
	}
    }
  if (need_escapes)
    return num_chars;
  else
    return 0;
}

#else

/* The assembler supports UTF8, we don't use escapes. Mangling is
   simply <N>NAME. <N> is the number of UTF8 encoded characters that
   are found in NAME. Note that `java', `lang' and `Object' are used
   so frequently that they could be cached.  */

void
append_gpp_mangled_name (const char *name, int len)
{
  const unsigned char *ptr;
  const unsigned char *limit = (const unsigned char *)name + len;
  int encoded_len;
  char buf [6];
  
  /* Compute the length of the string we wish to mangle. */
  for (encoded_len =  0, ptr = (const unsigned char *) name;
       ptr < limit; encoded_len++)
    {
      int ch = UTF8_GET(ptr, limit);

      if (ch < 0)
	error ("internal error - invalid Utf8 name");
    }

  sprintf (buf, "%d", encoded_len);
  obstack_grow (mangle_obstack, buf, strlen (buf));
  obstack_grow (mangle_obstack, name, len);
}

#endif /* HAVE_AS_UTF8 */
