⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cp-dem.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Demangler for GNU C++    Copyright (C) 1989, 1992 Free Software Foundation, Inc.   written by James Clark (jjc@jclark.uucp)      This program 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.   This program 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 this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  *//* This is for g++ 1.36.1 (November 6 version). It will probably   require changes for any other version.   Modified for g++ 1.36.2 (November 18 version).   Modified for g++ 1.90.06 (December 31 version).   Modified for g++ 1.95.03 (November 13 version).  *//* This file exports one function   char *cplus_demangle (const char *name)   If NAME is a mangled function name produced by GNU C++, then   a pointer to a malloced string giving a C++ representation   of the name will be returned; otherwise NULL will be returned.   It is the caller's responsibility to free the string which   is returned.   For example,      cplus_demangle ("_foo__1Ai")      returns   "A::foo(int)"   This file imports xmalloc and xrealloc, which are like malloc and   realloc except that they generate a fatal error if there is no   available memory. *//* #define nounderscore 1 /* define this is names don't start with _ */#include <stdio.h>#include <ctype.h>#ifdef USG#include <memory.h>#else#define memcpy(s1, s2, n) bcopy ((s2), (s1), (n))#define memcmp(s1, s2, n) bcmp ((s2), (s1), (n))#endif/* This is '$' on systems where the assembler can deal with that.   Where the assembler can't, it's '.' (but on many systems '.' is   used for other things).  */#if !defined (CPLUS_MARKER)#define CPLUS_MARKER '$'#endif#ifndef __STDC__#define const#endif#ifdef __STDC__extern char *cplus_demangle (const char *type);#elseextern char *cplus_demangle ();#endif#ifdef __STDC__extern char *xmalloc (int);extern char *xrealloc (char *, int);extern void free (char *);#elseextern char *xmalloc ();extern char *xrealloc ();extern void free ();#endifstatic char **typevec = 0;static int ntypes = 0;static int typevec_size = 0;static struct {  const char *in;  const char *out;} optable[] = {  "nw", " new",			/* new (1.92, ansi) */  "dl", " delete",		/* new (1.92, ansi) */  "new", " new",		/* old (1.91) */  "delete", " delete",		/* old (1.91) */  "ne", "!=",			/* old, ansi */  "eq", "==",			/* old, ansi */  "ge", ">=",			/* old, ansi */  "gt", ">",			/* old, ansi */  "le", "<=",			/* old, ansi */  "lt", "<",			/* old, ansi */  "plus", "+",			/* old */  "pl", "+",			/* ansi */  "apl", "+=",			/* ansi */  "minus", "-",			/* old */  "mi", "-",			/* ansi */  "ami", "-=",			/* ansi */  "mult", "*",			/* old */  "ml", "*",			/* ansi */  "aml", "*=",			/* ansi */  "convert", "+",		/* old (unary +) */  "negate", "-",		/* old (unary -) */  "trunc_mod", "%",		/* old */  "md", "%",			/* ansi */  "amd", "%=",			/* ansi */  "trunc_div", "/",		/* old */  "dv", "/",			/* ansi */  "adv", "/=",			/* ansi */  "truth_andif", "&&",		/* old */  "aa", "&&",			/* ansi */  "truth_orif", "||",		/* old */  "oo", "||",			/* ansi */  "truth_not", "!",		/* old */  "nt", "!",			/* ansi */  "postincrement", "++",	/* old */  "pp", "++",			/* ansi */  "postdecrement", "--",	/* old */  "mm", "--",			/* ansi */  "bit_ior", "|",		/* old */  "or", "|",			/* ansi */  "aor", "|=",			/* ansi */  "bit_xor", "^",		/* old */  "er", "^",			/* ansi */  "aer", "^=",			/* ansi */  "bit_and", "&",		/* old */  "ad", "&",			/* ansi */  "aad", "&=",			/* ansi */  "bit_not", "~",		/* old */  "co", "~",			/* ansi */  "call", "()",			/* old */  "cl", "()",			/* ansi */  "cond", "?:",			/* old */  "alshift", "<<",		/* old */  "ls", "<<",			/* ansi */  "als", "<<=",			/* ansi */  "arshift", ">>",		/* old */  "rs", ">>",			/* ansi */  "ars", ">>=",			/* ansi */  "component", "->",		/* old */  "rf", "->",			/* ansi */  "indirect", "*",		/* old */  "method_call", "->()",	/* old */  "addr", "&",			/* old (unary &) */  "array", "[]",		/* old */  "vc", "[]",			/* ansi */  "compound", ",",		/* old */  "cm", ",",			/* ansi */  "nop", "",			/* old (for operator=) */  "as", "=",			/* ansi */};/* Beware: these aren't '\0' terminated. */typedef struct {  char *b;			/* pointer to start of string */  char *p;			/* pointer after last character */  char *e;			/* pointer after end of allocated space */} string;#ifdef __STDC__static void string_need (string *s, int n);static void string_delete (string *s);static void string_init (string *s);static void string_clear (string *s);static int string_empty (string *s);static void string_append (string *p, const char *s);static void string_appends (string *p, string *s);static void string_appendn (string *p, const char *s, int n);static void string_prepend (string *p, const char *s);#if 0static void string_prepends (string *p, string *s);#endifstatic void string_prependn (string *p, const char *s, int n);static int get_count (const char **type, int *count);static int do_args (const char **type, string *decl);static int do_type (const char **type, string *result);static int do_arg (const char **type, string *result);static int do_args (const char **type, string *decl);static void munge_function_name (string *name);static void remember_type (const char *type, int len);#elsestatic void string_need ();static void string_delete ();static void string_init ();static void string_clear ();static int string_empty ();static void string_append ();static void string_appends ();static void string_appendn ();static void string_prepend ();static void string_prepends ();static void string_prependn ();static int get_count ();static int do_args ();static int do_type ();static int do_arg ();static int do_args ();static void munge_function_name ();static void remember_type ();#endifintget_simple_count (type, res)     char **type;     int *res;{  int n = 0, success = 1;;    do    {      n *= 10;      n += **type - '0';      *type += 1;    }   while (isdigit (**type));  if (strlen (*type) < n)    {      success = 0;    }  *res = n;  return success;}char *cplus_demangle (type)     const char *type;{  string decl;  int n;  int success = 0;  int constructor = 0;  int destructor = 0;  int static_type = 0;  int const_flag = 0;  int i;  const char *p;#ifndef LONGERNAMES  const char *premangle;#endif  if (type == NULL || *type == '\0')    return NULL;#ifndef nounderscore  if (*type++ != '_')    return NULL;#endif  p = type;  while (*p != '\0' && !(*p == '_' && p[1] == '_'))    p++;  if (*p == '\0')    {      /* destructor */      if (type[0] == '_' && type[1] == CPLUS_MARKER && type[2] == '_')	{	  destructor = 1;	  p = type;	}      /* static data member */      else if (*type != '_' && (index (type, CPLUS_MARKER) != NULL))	{	  static_type = 1;	  p = type;	}      /* virtual table "_vt$"  */      else if (type[0] == '_' && type[1] == 'v' && type[2] == 't' && type[3] == CPLUS_MARKER)	{	  int n = strlen (type + 4) + 14 + 1;	  char *tem = (char *) xmalloc (n);	  strcpy (tem, type + 4);	  strcat (tem, " virtual table");	  return tem;	}      else return NULL;    }  string_init (&decl);  if (static_type)    {      if (!isdigit (p[0]) && ('t' != p[0]))	{	  string_delete (&decl);	  return NULL;	}    }  else if (destructor)    {      if (!isdigit (p[3])&& ('t' != p[3]))	{	  string_delete (&decl);	  return NULL;	}      p += 3;    }  else if (p == type)    {      if (!isdigit (p[2]) && ('t' != p[2]))	{	  p += 1;	  while (*p != '\0' && !(*p == '_' && p[1] == '_'))	    p++;	  string_appendn (&decl, type, p - type);	  	  string_appendn (&decl, "", 1);	  munge_function_name (&decl);	  if (decl.b[0] == '_')	    {	      string_delete (&decl);	      return NULL;	    }	  else	    p += 2;	}      else	{	  constructor = 1;	  p += 2;	}    }  else    {      string_appendn (&decl, type, p - type);      decl.p[0] = '0';      munge_function_name (&decl);      p += 2;    }#ifndef LONGERNAMES  premangle = p;#endif  switch (*p)    {    case 'C':      /* a const member function */      if (!isdigit (p[1]))	{	  string_delete (&decl);	  return NULL;	}      p += 1;      const_flag = 1;      /* fall through */    case '0':    case '1':    case '2':    case '3':    case '4':    case '5':    case '6':    case '7':    case '8':    case '9':      n = 0;      do	{	  n *= 10;	  n += *p - '0';	  p += 1;	}      while (isdigit (*p));      if (strlen (p) < n)	{	  string_delete (&decl);	  return NULL;	}      if (constructor || destructor)	{	  string_appendn (&decl, p, n);	  string_append (&decl, "::");	  if (destructor)	    string_append(&decl, "~");	  string_appendn (&decl, p, n);	}      else	{	  string_prepend (&decl, "::");	  string_prependn (&decl, p, n);	}      p += n;#ifndef LONGERNAMES      remember_type (premangle, p - premangle);#endif      if (static_type)	{	  string_append(&decl, p+1);	  p += strlen(p);	  success = 1;	}      else	success = do_args (&p, &decl);      if (const_flag)	string_append (&decl, " const");      break;    case 'F':      p += 1;      success = do_args (&p, &decl);      break;    /* template additions */    case 't':      p += 1;      {	int r, i;	string tname;	string trawname;		string temp;	int need_comma = 0;		string_init(&tname);	string_init(&trawname);		/* get template name */	if (!get_simple_count (&p, &r))	  {	    string_delete (&decl);	    return 0;	  }	string_appendn (&tname, p, r);	string_appendn (&trawname, p, r);	string_appendn (&trawname, "", 1);	p += r;	string_append (&tname, "<");	/* get size of template parameter list */	if (!get_count (&p, &r))	  return 0;	for (i = 0; i < r; i++)	  {	    if (need_comma)	      string_append (&tname, ", ");	    /* Z for type parameters */	    if (*p == 'Z')	      {		p += 1;				success = do_type (&p, &temp);		string_appendn (&temp, "", 1);		if (success)		  string_append (&tname, temp.b);		string_delete(&temp);		if (!success)		  break;	      }	    /* otherwise, value parameter */	    else	      {		const char *old_p  = p;		int is_pointer = 0;		int is_real = 0;		int is_integral = 0;		int done = 0;		success = do_type (&p, &temp);		string_appendn (&temp, "", 1);		if (success)		  string_append (&tname, temp.b);		string_delete(&temp);		if (!success)		  break;		string_append (&tname, "=");		while (*old_p && !done)		  {			    switch (*old_p)		      {		      case 'P':		      case 'R':			done = is_pointer = 1;			break;		      case 'C':	/* const */		      case 'U':	/* unsigned */		      case 'V':	/* volatile */		      case 'F':	/* function */		      case 'M':	/* member function */		      case 'O':	/* ??? */			old_p++;			continue;		      case 'Q':	/* repetition of following */		      case 'T':	/* remembered type */			abort();			break;		      case 'v':	/* void */			abort();			break;		      case 'x':	/* long long */		      case 'l':	/* long */		      case 'i':	/* int */		      case 's':	/* short */		      case 'c':	/* char */		      case 'w': /* wchar_t */			done = is_integral = 1;			break;		      case 'r':	/* long double */		      case 'd':	/* double */		      case 'f':	/* float */			done = is_real = 1;			break;		      default:			abort();		      }		  }		if (is_integral)		  {		    if (*p == 'm')		      {			string_appendn (&tname, "-", 1);			p++;		      }		    while (isdigit (*p))			      {			string_appendn (&tname, p, 1);			p++;		      }		  }		else if (is_real)		  {		    if (*p == 'm')		      {			string_appendn (&tname, "-", 1);			p++;		      }		    while (isdigit (*p))			      {			string_appendn (&tname, p, 1);			p++;		      }		    if (*p == '.') /* fraction */		      {			string_appendn (&tname, ".", 1);			p++;			while (isdigit (*p))				  {			    string_appendn (&tname, p, 1);			    p++;			  }		      }		    if (*p == 'e') /* exponent */		      {			string_appendn (&tname, "e", 1);			p++;			while (isdigit (*p))				  {			    string_appendn (&tname, p, 1);			    p++;			  }		      }		  }		else if (is_pointer)		  {		    int symbol_len;		    		    if (!get_count (&p, &symbol_len))		      {			success = 0;			break;		      }		    string_appendn (&tname, p, symbol_len);		    p += symbol_len;		  }	      }	    need_comma = 1;	  }	string_append (&tname, ">::");	if (destructor)	  string_append(&tname, "~");	if (constructor || destructor) {	  string_appendn (&trawname, "", 1);	  string_append (&tname, trawname.b);	}	string_delete(&trawname);		if (!success) {	  string_delete(&tname);	  return 0;	}	string_appendn (&tname, "", 1);	string_prepend (&decl, tname.b);	string_delete (&tname);	if (static_type)	  {	    string_append (&decl, p+1);	    p += strlen (p);	    success = 1;	  }	else	  success = do_args (&p, &decl);	break;      }    }  for (i = 0; i < ntypes; i++)    if (typevec[i] != NULL)      free (typevec[i]);  ntypes = 0;  if (typevec != NULL)    {      free ((char *)typevec);      typevec = NULL;      typevec_size = 0;    }  if (success)    {      string_appendn (&decl, "", 1);      return decl.b;    }  else    {      string_delete (&decl);      return NULL;    }}static intget_count (type, count)     const char **type;     int *count;{  if (!isdigit (**type))    return 0;  *count = **type - '0';  *type += 1;  /* see flush_repeats in cp-method.c */  if (isdigit (**type))    {      const char *p = *type;      int n = *count;      do 	{	  n *= 10;	  n += *p - '0';	  p += 1;	}       while (isdigit (*p));      if (*p == '_')	{	  *type = p + 1;	  *count = n;	}    }  return 1;}/* result will be initialised here; it will be freed on failure */static intdo_type (type, result)     const char **type;     string *result;{  int n;  int done;  int non_empty = 0;  int success;  string decl;  const char *remembered_type;  string_init (&decl);  string_init (result);  done = 0;  success = 1;  while (success && !done)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -