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

📄 cplus-dem.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 4 页
字号:
  CONST char *p;  if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0)    {      /* Found a cfront style virtual table, get past ARM_VTABLE_STRING         and create the decl.  Note that we consume the entire mangled	 input string, which means that demangle_signature has no work	 to do. */      (*mangled) += ARM_VTABLE_STRLEN;      while (**mangled != '\0')	{	  n = consume_count (mangled);	  string_prependn (declp, *mangled, n);	  (*mangled) += n;	  if ((*mangled)[0] == '_' && (*mangled)[1] == '_')	    {	      string_prepend (declp, "::");	      (*mangled) += 2;	    }	}      string_append (declp, " virtual table");    }  else    {      success = 0;    }  return (success);}/*LOCAL FUNCTION	demangle_qualified -- demangle 'Q' qualified name stringsSYNOPSIS	static int	demangle_qualified (struct work_stuff *, const char *mangled,			    string *result, int isfuncname);DESCRIPTION	Demangle a qualified name, such as "Q25Outer5Inner" which is	the mangled form of "Outer::Inner".  The demangled output is	appended to the result string.	If isfuncname is nonzero, then the qualified name we are building	is going to be used as a member function name, so if it is a	constructor or destructor function, append an appropriate	constructor or destructor name.  I.E. for the above example,	the result for use as a constructor is "Outer::Inner::Inner"	and the result for use as a destructor is "Outer::Inner::~Inner".BUGS	Numeric conversion is ASCII dependent (FIXME). */static intdemangle_qualified (work, mangled, result, isfuncname)     struct work_stuff *work;     CONST char **mangled;     string *result;     int isfuncname;{  int qualifiers;  int namelength;  int success = 0;  qualifiers = (*mangled)[1] - '0';  if (qualifiers > 0 && qualifiers < 10)    {      /* Assume success until we discover otherwise.  Skip over the 'Q', the	 qualifier count, and any '_' between the qualifier count and the	 first name (cfront qualified names). */      success = 1;      if ((*mangled)[2] == '_')	{	  (*mangled)++;	}      (*mangled) += 2;      /* Pick off the names and append them to the result string as they	 are found, separated by '::'. */      while (qualifiers-- > 0)	{	  namelength = consume_count (mangled);	  if (strlen (*mangled) < namelength)	    {	      /* Simple sanity check failed */	      success = 0;	      break;	    }	  string_appendn (result, *mangled, namelength);	  if (qualifiers > 0)	    {	      string_appendn (result, "::", 2);	    }	  *mangled += namelength;	}      /* If we are using the result as a function name, we need to append	 the appropriate '::' separated constructor or destructor name.	 We do this here because this is the most convenient place, where	 we already have a pointer to the name and the length of the name. */      if (isfuncname && (work -> constructor || work -> destructor))	{	  string_appendn (result, "::", 2);	  if (work -> destructor)	    {	      string_append (result, "~");	    }	  string_appendn (result, (*mangled) - namelength, namelength);	}    }  return (success);}/*LOCAL FUNCTION	get_count -- convert an ascii count to integer, consuming tokensSYNOPSIS	static int	get_count (const char **type, int *count)DESCRIPTION	Return 0 if no conversion is performed, 1 if a string is converted.*/static intget_count (type, count)     CONST char **type;     int *count;{  CONST char *p;  int n;  if (!isdigit (**type))    {      return (0);    }  else    {      *count = **type - '0';      (*type)++;      if (isdigit (**type))	{	  p = *type;	  n = *count;	  do 	    {	      n *= 10;	      n += *p - '0';	      p++;	    } 	  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 (work, mangled, result)     struct work_stuff *work;     CONST char **mangled;     string *result;{  int n;  int done;  int success;  string decl;  CONST char *remembered_type;  int constp;  int volatilep;  string_init (&decl);  string_init (result);  done = 0;  success = 1;  while (success && !done)    {      int member;      switch (**mangled)	{	/* A pointer type */	case 'P':	  (*mangled)++;	  string_prepend (&decl, "*");	  break;	/* A reference type */	case 'R':	  (*mangled)++;	  string_prepend (&decl, "&");	  break;	/* A back reference to a previously seen type */	case 'T':	  (*mangled)++;	  if (!get_count (mangled, &n) || n >= work -> ntypes)	    {	      success = 0;	    }	  else	    {	      remembered_type = work -> typevec[n];	      mangled = &remembered_type;	    }	  break;	/* A function */	case 'F':	  (*mangled)++;	  if (!STRING_EMPTY (&decl) && decl.b[0] == '*')	    {	      string_prepend (&decl, "(");	      string_append (&decl, ")");	    }	  /* After picking off the function args, we expect to either find the	     function return type (preceded by an '_') or the end of the	     string. */	  if (!demangle_args (work, mangled, &decl)	      || (**mangled != '_' && **mangled != '\0'))	    {	      success = 0;	    }	  if (success && (**mangled == '_'))	    {	      (*mangled)++;	    }	  break;	case 'M':	case 'O':	  {	    constp = 0;	    volatilep = 0;	    member = **mangled == 'M';	    (*mangled)++;	    if (!isdigit (**mangled))	      {		success = 0;		break;	      }	    n = consume_count (mangled);	    if (strlen (*mangled) < n)	      {		success = 0;		break;	      }	    string_append (&decl, ")");	    string_prepend (&decl, "::");	    string_prependn (&decl, *mangled, n);	    string_prepend (&decl, "(");	    *mangled += n;	    if (member)	      {		if (**mangled == 'C')		  {		    (*mangled)++;		    constp = 1;		  }		if (**mangled == 'V')		  {		    (*mangled)++;		    volatilep = 1;		  }		if (*(*mangled)++ != 'F')		  {		    success = 0;		    break;		  }	      }	    if ((member && !demangle_args (work, mangled, &decl))		|| **mangled != '_')	      {		success = 0;		break;	      }	    (*mangled)++;	    if (! PRINT_ANSI_QUALIFIERS)	      {		break;	      }	    if (constp)	      {		APPEND_BLANK (&decl);		string_append (&decl, "const");	      }	    if (volatilep)	      {		APPEND_BLANK (&decl);		string_append (&decl, "volatile");	      }	    break;	  }	case 'C':	  if ((*mangled)[1] == 'P')	    {	      (*mangled)++;	      if (PRINT_ANSI_QUALIFIERS)		{		  if (!STRING_EMPTY (&decl))		    {		      string_prepend (&decl, " ");		    }		  string_prepend (&decl, "const");		}	      break;	    }	  /* fall through */	default:	  done = 1;	  break;	}    }  switch (**mangled)    {      /* A qualified name, such as "Outer::Inner". */      case 'Q':        success = demangle_qualified (work, mangled, result, 0);	break;      default:	success = demangle_fund_type (work, mangled, result);	break;    }  if (success)    {      if (!STRING_EMPTY (&decl))	{	  string_append (result, " ");	  string_appends (result, &decl);	}    }  else    {      string_delete (result);    }  string_delete (&decl);  return (success);}/* Given a pointer to a type string that represents a fundamental type   argument (int, long, unsigned int, etc) in TYPE, a pointer to the   string in which the demangled output is being built in RESULT, and   the WORK structure, decode the types and add them to the result.   For example:   	"Ci"	=>	"const int"	"Sl"	=>	"signed long"	"CUs"	=>	"const unsigned short"   */static intdemangle_fund_type (work, mangled, result)     struct work_stuff *work;     CONST char **mangled;     string *result;{  int done = 0;  int success = 1;  int n;  /* First pick off any type qualifiers.  There can be more than one. */  while (!done)    {      switch (**mangled)	{	  case 'C':	    (*mangled)++;	    if (PRINT_ANSI_QUALIFIERS)	      {		APPEND_BLANK (result);		string_append (result, "const");	      }	    break;	  case 'U':	    (*mangled)++;	    APPEND_BLANK (result);	    string_append (result, "unsigned");	    break;	  case 'S': /* signed char only */	    (*mangled)++;	    APPEND_BLANK (result);	    string_append (result, "signed");	    break;	  case 'V':	    (*mangled)++;	    if (PRINT_ANSI_QUALIFIERS)	      {		APPEND_BLANK (result);		string_append (result, "volatile");	      }	    break;	  default:	    done = 1;	    break;	}    }  /* Now pick off the fundamental type.  There can be only one. */  switch (**mangled)    {      case '\0':      case '_':	break;      case 'v':	(*mangled)++;	APPEND_BLANK (result);	string_append (result, "void");	break;      case 'x':	(*mangled)++;	APPEND_BLANK (result);	string_append (result, "long long");	break;      case 'l':	(*mangled)++;	APPEND_BLANK (result);	string_append (result, "long");	break;      case 'i':	(*mangled)++;	APPEND_BLANK (result);	string_append (result, "int");	break;      case 's':	(*mangled)++;	APPEND_BLANK (result);	string_append (result, "short");	break;      case 'c':	(*mangled)++;	APPEND_BLANK (result);	string_append (result, "char");	break;      case 'w':	(*mangled)++;	APPEND_BLANK (result);	string_append (result, "wchar_t");	break;      case 'r':	(*mangled)++;	APPEND_BLANK (result);	string_append (result, "long double");	break;      case 'd':	(*mangled)++;	APPEND_BLANK (result);	string_append (result, "double");	break;      case 'f':	(*mangled)++;	APPEND_BLANK (result);	string_append (result, "float");	break;      case 'G':	(*mangled)++;	if (!isdigit (**mangled))	  {	    success = 0;	    break;	  }	/* fall through */      /* An explicit type, such as "6mytype" or "7integer" */      case '0':      case '1':      case '2':      case '3':      case '4':      case '5':      case '6':      case '7':      case '8':      case '9':	n = consume_count (mangled);	if (strlen (*mangled) < n)	  {	    success = 0;	    break;	  }	APPEND_BLANK (result);	string_appendn (result, *mangled, n);	*mangled += n;	break;      default:	success = 0;	break;      }  return (success);}/* `result' will be initialized in do_type; it will be freed on failure */static intdo_arg (work, mangled, result)     struct work_stuff *work;     CONST char **mangled;     string *result;{  CONST char *start = *mangled;  if (!do_type (work, mangled, result))    {      return (0);    }  else    {      remember_type (work, start, *mangled - start);      return (1);    }}static voidremember_type (work, start, len)     struct work_stuff *work;     CONST char *start;     int len;{  char *tem;  if (work -> ntypes >= work -> typevec_size)    {      if (work -> typevec_size == 0)	{	  work -> typevec_size = 3;	  work -> typevec =	    (char **) xmalloc (sizeof (char *) * work -> typevec_size);	}      else	{	  work -> typevec_size *= 2;	  work -> typevec =	    (char **) xrealloc ((char *)work -> typevec,				sizeof (char *) * work -> typevec_size);	}    }  tem = xmalloc (len + 1);  memcpy (tem, start, len);  tem[len] = '\0';  work -> typevec[work -> ntypes++] = tem;}/* Forget the remembered types, but not the type vector itself. */static voidforget_types (work)     struct work_stuff *work;{  int i;

⌨️ 快捷键说明

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