(root)/
binutils-2.41/
binutils/
cxxfilt.c
       1  /* Demangler for GNU C++ - main program
       2     Copyright (C) 1989-2023 Free Software Foundation, Inc.
       3     Written by James Clark (jjc@jclark.uucp)
       4     Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
       5     Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
       6  
       7     This file is part of GNU Binutils.
       8  
       9     This program is free software; you can redistribute it and/or modify
      10     it under the terms of the GNU General Public License as published by
      11     the Free Software Foundation; either version 3 of the License, or (at
      12     your option) any later version.
      13  
      14     This program is distributed in the hope that it will be useful,
      15     but WITHOUT ANY WARRANTY; without even the implied warranty of
      16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17     GNU General Public License for more details.
      18  
      19     You should have received a copy of the GNU General Public License
      20     along with GCC; see the file COPYING.  If not, write to the Free
      21     Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
      22     02110-1301, USA.  */
      23  
      24  #include "sysdep.h"
      25  #include "bfd.h"
      26  #include "libiberty.h"
      27  #include "demangle.h"
      28  #include "getopt.h"
      29  #include "safe-ctype.h"
      30  #include "bucomm.h"
      31  
      32  static int flags = DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE;
      33  static int strip_underscore = TARGET_PREPENDS_UNDERSCORE;
      34  
      35  static const struct option long_options[] =
      36  {
      37    {"strip-underscore", no_argument, NULL, '_'},
      38    {"format", required_argument, NULL, 's'},
      39    {"help", no_argument, NULL, 'h'},
      40    {"no-params", no_argument, NULL, 'p'},
      41    {"no-strip-underscores", no_argument, NULL, 'n'},
      42    {"no-verbose", no_argument, NULL, 'i'},
      43    {"types", no_argument, NULL, 't'},
      44    {"version", no_argument, NULL, 'v'},
      45    {"recurse-limit", no_argument, NULL, 'R'},
      46    {"recursion-limit", no_argument, NULL, 'R'},
      47    {"no-recurse-limit", no_argument, NULL, 'r'},
      48    {"no-recursion-limit", no_argument, NULL, 'r'},
      49    {NULL, no_argument, NULL, 0}
      50  };
      51  
      52  static void
      53  demangle_it (char *mangled_name)
      54  {
      55    char *result;
      56    unsigned int skip_first = 0;
      57  
      58    /* _ and $ are sometimes found at the start of function names
      59       in assembler sources in order to distinguish them from other
      60       names (eg register names).  So skip them here.  */
      61    if (mangled_name[0] == '.' || mangled_name[0] == '$')
      62      ++skip_first;
      63    if (strip_underscore && mangled_name[skip_first] == '_')
      64      ++skip_first;
      65  
      66    result = cplus_demangle (mangled_name + skip_first, flags);
      67  
      68    if (result == NULL)
      69      printf ("%s", mangled_name);
      70    else
      71      {
      72        if (mangled_name[0] == '.')
      73  	putchar ('.');
      74        printf ("%s", result);
      75        free (result);
      76      }
      77  }
      78  
      79  static void
      80  print_demangler_list (FILE *stream)
      81  {
      82    const struct demangler_engine *demangler;
      83  
      84    fprintf (stream, "{%s", libiberty_demanglers->demangling_style_name);
      85  
      86    for (demangler = libiberty_demanglers + 1;
      87         demangler->demangling_style != unknown_demangling;
      88         ++demangler)
      89      fprintf (stream, ",%s", demangler->demangling_style_name);
      90  
      91    fprintf (stream, "}");
      92  }
      93  
      94  ATTRIBUTE_NORETURN static void
      95  usage (FILE *stream, int status)
      96  {
      97    fprintf (stream, "\
      98  Usage: %s [options] [mangled names]\n", program_name);
      99    fprintf (stream, "\
     100  Options are:\n\
     101    [-_|--strip-underscore]     Ignore first leading underscore%s\n",
     102  	   TARGET_PREPENDS_UNDERSCORE ? " (default)" : "");
     103    fprintf (stream, "\
     104    [-n|--no-strip-underscore]  Do not ignore a leading underscore%s\n",
     105  	   TARGET_PREPENDS_UNDERSCORE ? "" : " (default)");
     106    fprintf (stream, "\
     107    [-p|--no-params]            Do not display function arguments\n\
     108    [-i|--no-verbose]           Do not show implementation details (if any)\n\
     109    [-R|--recurse-limit]        Enable a limit on recursion whilst demangling.  [Default]\n\
     110    ]-r|--no-recurse-limit]     Disable a limit on recursion whilst demangling\n\
     111    [-t|--types]                Also attempt to demangle type encodings\n\
     112    [-s|--format ");
     113    print_demangler_list (stream);
     114    fprintf (stream, "]\n");
     115  
     116    fprintf (stream, "\
     117    [@<file>]                   Read extra options from <file>\n\
     118    [-h|--help]                 Display this information\n\
     119    [-v|--version]              Show the version information\n\
     120  Demangled names are displayed to stdout.\n\
     121  If a name cannot be demangled it is just echoed to stdout.\n\
     122  If no names are provided on the command line, stdin is read.\n");
     123    if (REPORT_BUGS_TO[0] && status == 0)
     124      fprintf (stream, _("Report bugs to %s.\n"), REPORT_BUGS_TO);
     125    exit (status);
     126  }
     127  
     128  /* Return the string of non-alnum characters that may occur
     129     as a valid symbol component, in the standard assembler symbol
     130     syntax.  */
     131  
     132  static const char *
     133  standard_symbol_characters (void)
     134  {
     135    return "_$.";
     136  }
     137  
     138  extern int main (int, char **);
     139  
     140  int
     141  main (int argc, char **argv)
     142  {
     143    int c;
     144    const char *valid_symbols;
     145    enum demangling_styles style = auto_demangling;
     146  
     147    program_name = argv[0];
     148    xmalloc_set_program_name (program_name);
     149    bfd_set_error_program_name (program_name);
     150  
     151    expandargv (&argc, &argv);
     152  
     153    while ((c = getopt_long (argc, argv, "_hinprRs:tv", long_options, (int *) 0)) != EOF)
     154      {
     155        switch (c)
     156  	{
     157  	case '?':
     158  	  usage (stderr, 1);
     159  	  break;
     160  	case 'h':
     161  	  usage (stdout, 0);
     162  	case 'n':
     163  	  strip_underscore = 0;
     164  	  break;
     165  	case 'p':
     166  	  flags &= ~ DMGL_PARAMS;
     167  	  break;
     168  	case 'r':
     169  	  flags |= DMGL_NO_RECURSE_LIMIT;
     170  	  break;
     171  	case 'R':
     172  	  flags &= ~ DMGL_NO_RECURSE_LIMIT;
     173  	  break;
     174  	case 't':
     175  	  flags |= DMGL_TYPES;
     176  	  break;
     177  	case 'i':
     178  	  flags &= ~ DMGL_VERBOSE;
     179  	  break;
     180  	case 'v':
     181  	  print_version ("c++filt");
     182  	  return 0;
     183  	case '_':
     184  	  strip_underscore = 1;
     185  	  break;
     186  	case 's':
     187  	  style = cplus_demangle_name_to_style (optarg);
     188  	  if (style == unknown_demangling)
     189  	    {
     190  	      fprintf (stderr, "%s: unknown demangling style `%s'\n",
     191  		       program_name, optarg);
     192  	      return 1;
     193  	    }
     194  	  cplus_demangle_set_style (style);
     195  	  break;
     196  	}
     197      }
     198  
     199    if (optind < argc)
     200      {
     201        for ( ; optind < argc; optind++)
     202  	{
     203  	  demangle_it (argv[optind]);
     204  	  putchar ('\n');
     205  	}
     206  
     207        return 0;
     208      }
     209  
     210    switch (current_demangling_style)
     211      {
     212      case auto_demangling:
     213      case gnu_v3_demangling:
     214      case java_demangling:
     215      case gnat_demangling:
     216      case dlang_demangling:
     217      case rust_demangling:
     218         valid_symbols = standard_symbol_characters ();
     219        break;
     220      default:
     221        /* Folks should explicitly indicate the appropriate alphabet for
     222  	 each demangling.  Providing a default would allow the
     223  	 question to go unconsidered.  */
     224        fatal ("Internal error: no symbol alphabet for current style");
     225      }
     226  
     227    for (;;)
     228      {
     229        static char mbuffer[32767];
     230        unsigned i = 0;
     231  
     232        c = getchar ();
     233        /* Try to read a mangled name.  */
     234        while (c != EOF && (ISALNUM (c) || strchr (valid_symbols, c)))
     235  	{
     236  	  if (i >= sizeof (mbuffer) - 1)
     237  	    break;
     238  	  mbuffer[i++] = c;
     239  	  c = getchar ();
     240  	}
     241  
     242        if (i > 0)
     243  	{
     244  	  mbuffer[i] = 0;
     245  	  demangle_it (mbuffer);
     246  	}
     247  
     248        if (c == EOF)
     249  	break;
     250  
     251        /* Echo the whitespace characters so that the output looks
     252  	 like the input, only with the mangled names demangled.  */
     253        putchar (c);
     254        if (c == '\n')
     255  	fflush (stdout);
     256      }
     257  
     258    fflush (stdout);
     259    return 0;
     260  }