暂无描述

c++filt.go 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // Copyright 2015 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // +build ignore
  5. // This is a program that works like the GNU c++filt program.
  6. // It's here for testing purposes and as an example.
  7. package main
  8. import (
  9. "bufio"
  10. "flag"
  11. "fmt"
  12. "io"
  13. "os"
  14. "strings"
  15. "unicode"
  16. "github.com/ianlancetaylor/demangle"
  17. )
  18. func flagUsage() {
  19. usage(os.Stderr, 2)
  20. }
  21. func usage(w io.Writer, status int) {
  22. fmt.Fprintf(w, "Usage: %s [options] [mangled names]\n", os.Args[0])
  23. flag.CommandLine.SetOutput(w)
  24. flag.PrintDefaults()
  25. fmt.Fprintln(w, `Demangled names are displayed to stdout
  26. If a name cannot be demangled it is just echoed to stdout.
  27. If no names are provided on the command line, stdin is read.`)
  28. os.Exit(status)
  29. }
  30. var stripUnderscore = flag.Bool("_", false, "Ignore first leading underscore")
  31. var noParams = flag.Bool("p", false, "Do not display function argument types")
  32. var noVerbose = flag.Bool("i", false, "Do not show implementation details (if any)")
  33. var help = flag.Bool("h", false, "Display help information")
  34. var debug = flag.Bool("d", false, "Display debugging information for strings on command line")
  35. // Unimplemented c++filt flags:
  36. // -n (opposite of -_)
  37. // -t (demangle types)
  38. // -s (set demangling style)
  39. // -V (print version information)
  40. // Characters considered to be part of a symbol.
  41. const symbolChars = "_$."
  42. func main() {
  43. flag.Usage = func() { usage(os.Stderr, 1) }
  44. flag.Parse()
  45. if *help {
  46. usage(os.Stdout, 0)
  47. }
  48. out := bufio.NewWriter(os.Stdout)
  49. if flag.NArg() > 0 {
  50. for _, f := range flag.Args() {
  51. if *debug {
  52. a, err := demangle.ToAST(f, options()...)
  53. if err != nil {
  54. fmt.Fprintf(os.Stderr, "%s: %v\n", f, err)
  55. } else {
  56. fmt.Fprintf(out, "%#v\n", a)
  57. }
  58. } else {
  59. doDemangle(out, f)
  60. }
  61. out.WriteByte('\n')
  62. }
  63. if err := out.Flush(); err != nil {
  64. fmt.Fprintln(os.Stderr, err)
  65. os.Exit(2)
  66. }
  67. return
  68. }
  69. scanner := bufio.NewScanner(bufio.NewReader(os.Stdin))
  70. for scanner.Scan() {
  71. line := scanner.Text()
  72. start := -1
  73. for i, c := range line {
  74. if unicode.IsLetter(c) || unicode.IsNumber(c) || strings.ContainsRune(symbolChars, c) {
  75. if start < 0 {
  76. start = i
  77. }
  78. } else {
  79. if start >= 0 {
  80. doDemangle(out, line[start:i])
  81. }
  82. out.WriteRune(c)
  83. start = -1
  84. }
  85. }
  86. if start >= 0 {
  87. doDemangle(out, line[start:])
  88. start = -1
  89. }
  90. out.WriteByte('\n')
  91. if err := out.Flush(); err != nil {
  92. fmt.Fprintln(os.Stderr, err)
  93. os.Exit(2)
  94. }
  95. }
  96. }
  97. // Demangle a string just as the GNU c++filt program does.
  98. func doDemangle(out *bufio.Writer, name string) {
  99. skip := 0
  100. if name[0] == '.' || name[0] == '$' {
  101. skip++
  102. }
  103. if *stripUnderscore && name[skip] == '_' {
  104. skip++
  105. }
  106. result := demangle.Filter(name[skip:], options()...)
  107. if result == name[skip:] {
  108. out.WriteString(name)
  109. } else {
  110. if name[0] == '.' {
  111. out.WriteByte('.')
  112. }
  113. out.WriteString(result)
  114. }
  115. }
  116. // options returns the demangling options to use based on the command
  117. // line flags.
  118. func options() []demangle.Option {
  119. var options []demangle.Option
  120. if *noParams {
  121. options = append(options, demangle.NoParams)
  122. }
  123. if !*noVerbose {
  124. options = append(options, demangle.Verbose)
  125. }
  126. return options
  127. }