ansi_c_escapes.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. // License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>
  2. package shlex
  3. import (
  4. "fmt"
  5. "strconv"
  6. "strings"
  7. )
  8. var _ = fmt.Print
  9. type state int
  10. const (
  11. normal state = iota
  12. control_char
  13. backslash
  14. hex_digit
  15. oct_digit
  16. )
  17. type ansi_c struct {
  18. state state
  19. max_num_of_digits, digit_idx int
  20. digits [16]rune
  21. output strings.Builder
  22. }
  23. func is_hex_char(ch rune) bool {
  24. return ('0' <= ch && ch <= '9') || ('a' <= ch && ch <= 'f') || ('A' <= ch && ch <= 'F')
  25. }
  26. func is_oct_char(ch rune) bool {
  27. return '0' <= ch && ch <= '7'
  28. }
  29. func (self *ansi_c) write_digits(base int) {
  30. if self.digit_idx > 0 {
  31. text := string(self.digits[:self.digit_idx])
  32. val, err := strconv.ParseUint(text, base, 32)
  33. if err == nil {
  34. self.output.WriteRune(rune(val))
  35. }
  36. }
  37. self.digit_idx = 0
  38. self.state = normal
  39. }
  40. func (self *ansi_c) parse(ch rune) {
  41. switch self.state {
  42. case normal:
  43. if ch == '\\' {
  44. self.state = backslash
  45. } else {
  46. self.output.WriteRune(ch)
  47. }
  48. case control_char:
  49. self.output.WriteRune(ch & 0x1f)
  50. self.state = normal
  51. case hex_digit:
  52. if self.digit_idx < self.max_num_of_digits && is_hex_char(ch) {
  53. self.digits[self.digit_idx] = ch
  54. self.digit_idx++
  55. } else {
  56. self.write_digits(16)
  57. self.parse(ch)
  58. }
  59. case oct_digit:
  60. if self.digit_idx < self.max_num_of_digits && is_oct_char(ch) {
  61. self.digits[self.digit_idx] = ch
  62. self.digit_idx++
  63. } else {
  64. self.write_digits(8)
  65. self.parse(ch)
  66. }
  67. case backslash:
  68. self.state = normal
  69. switch ch {
  70. default:
  71. self.output.WriteRune('\\')
  72. self.output.WriteRune(ch)
  73. case 'a':
  74. self.output.WriteRune(7)
  75. case 'b':
  76. self.output.WriteRune(8)
  77. case 'c':
  78. self.state = control_char
  79. case 'e', 'E':
  80. self.output.WriteRune(27)
  81. case 'f':
  82. self.output.WriteRune(12)
  83. case 'n':
  84. self.output.WriteRune(10)
  85. case 'r':
  86. self.output.WriteRune(13)
  87. case 't':
  88. self.output.WriteRune(9)
  89. case 'v':
  90. self.output.WriteRune(11)
  91. case 'x':
  92. self.max_num_of_digits, self.digit_idx, self.state = 2, 0, hex_digit
  93. case 'u':
  94. self.max_num_of_digits, self.digit_idx, self.state = 4, 0, hex_digit
  95. case 'U':
  96. self.max_num_of_digits, self.digit_idx, self.state = 8, 0, hex_digit
  97. case '0', '1', '2', '3', '4', '5', '6', '7':
  98. self.max_num_of_digits, self.digit_idx, self.state = 3, 1, oct_digit
  99. self.digits[0] = ch
  100. case '\\':
  101. self.output.WriteRune('\\')
  102. case '?':
  103. self.output.WriteRune('?')
  104. case '"':
  105. self.output.WriteRune('"')
  106. case '\'':
  107. self.output.WriteRune('\'')
  108. }
  109. }
  110. }
  111. func (self *ansi_c) finish() string {
  112. switch self.state {
  113. case hex_digit:
  114. self.write_digits(16)
  115. case oct_digit:
  116. self.write_digits(8)
  117. case backslash:
  118. self.output.WriteRune('\\')
  119. case control_char:
  120. self.output.WriteString("\\c")
  121. }
  122. self.state = normal
  123. self.digit_idx = 0
  124. s := self.output.String()
  125. self.output.Reset()
  126. return s
  127. }
  128. func ExpandANSICEscapes(src string) string {
  129. p := ansi_c{}
  130. p.output.Grow(len(src))
  131. for _, ch := range src {
  132. p.parse(ch)
  133. }
  134. return p.finish()
  135. }