utils.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. package lua
  2. import (
  3. "bufio"
  4. "fmt"
  5. "io"
  6. "reflect"
  7. "strconv"
  8. "strings"
  9. "time"
  10. "unsafe"
  11. )
  12. func intMin(a, b int) int {
  13. if a < b {
  14. return a
  15. } else {
  16. return b
  17. }
  18. }
  19. func intMax(a, b int) int {
  20. if a > b {
  21. return a
  22. } else {
  23. return b
  24. }
  25. }
  26. func defaultFormat(v interface{}, f fmt.State, c rune) {
  27. buf := make([]string, 0, 10)
  28. buf = append(buf, "%")
  29. for i := 0; i < 128; i++ {
  30. if f.Flag(i) {
  31. buf = append(buf, string(rune(i)))
  32. }
  33. }
  34. if w, ok := f.Width(); ok {
  35. buf = append(buf, strconv.Itoa(w))
  36. }
  37. if p, ok := f.Precision(); ok {
  38. buf = append(buf, "."+strconv.Itoa(p))
  39. }
  40. buf = append(buf, string(c))
  41. format := strings.Join(buf, "")
  42. fmt.Fprintf(f, format, v)
  43. }
  44. type flagScanner struct {
  45. flag byte
  46. start string
  47. end string
  48. buf []byte
  49. str string
  50. Length int
  51. Pos int
  52. HasFlag bool
  53. ChangeFlag bool
  54. }
  55. func newFlagScanner(flag byte, start, end, str string) *flagScanner {
  56. return &flagScanner{flag, start, end, make([]byte, 0, len(str)), str, len(str), 0, false, false}
  57. }
  58. func (fs *flagScanner) AppendString(str string) { fs.buf = append(fs.buf, str...) }
  59. func (fs *flagScanner) AppendChar(ch byte) { fs.buf = append(fs.buf, ch) }
  60. func (fs *flagScanner) String() string { return string(fs.buf) }
  61. func (fs *flagScanner) Next() (byte, bool) {
  62. c := byte('\000')
  63. fs.ChangeFlag = false
  64. if fs.Pos == fs.Length {
  65. if fs.HasFlag {
  66. fs.AppendString(fs.end)
  67. }
  68. return c, true
  69. } else {
  70. c = fs.str[fs.Pos]
  71. if c == fs.flag {
  72. if fs.Pos < (fs.Length-1) && fs.str[fs.Pos+1] == fs.flag {
  73. fs.HasFlag = false
  74. fs.AppendChar(fs.flag)
  75. fs.Pos += 2
  76. return fs.Next()
  77. } else if fs.Pos != fs.Length-1 {
  78. if fs.HasFlag {
  79. fs.AppendString(fs.end)
  80. }
  81. fs.AppendString(fs.start)
  82. fs.ChangeFlag = true
  83. fs.HasFlag = true
  84. }
  85. }
  86. }
  87. fs.Pos++
  88. return c, false
  89. }
  90. var cDateFlagToGo = map[byte]string{
  91. 'a': "mon", 'A': "Monday", 'b': "Jan", 'B': "January", 'c': "02 Jan 06 15:04 MST", 'd': "02",
  92. 'F': "2006-01-02", 'H': "15", 'I': "03", 'm': "01", 'M': "04", 'p': "PM", 'P': "pm", 'S': "05",
  93. 'x': "15/04/05", 'X': "15:04:05", 'y': "06", 'Y': "2006", 'z': "-0700", 'Z': "MST"}
  94. func strftime(t time.Time, cfmt string) string {
  95. sc := newFlagScanner('%', "", "", cfmt)
  96. for c, eos := sc.Next(); !eos; c, eos = sc.Next() {
  97. if !sc.ChangeFlag {
  98. if sc.HasFlag {
  99. if v, ok := cDateFlagToGo[c]; ok {
  100. sc.AppendString(t.Format(v))
  101. } else {
  102. switch c {
  103. case 'w':
  104. sc.AppendString(fmt.Sprint(int(t.Weekday())))
  105. default:
  106. sc.AppendChar('%')
  107. sc.AppendChar(c)
  108. }
  109. }
  110. sc.HasFlag = false
  111. } else {
  112. sc.AppendChar(c)
  113. }
  114. }
  115. }
  116. return sc.String()
  117. }
  118. func isInteger(v LNumber) bool {
  119. return float64(v) == float64(int64(v))
  120. //_, frac := math.Modf(float64(v))
  121. //return frac == 0.0
  122. }
  123. func isArrayKey(v LNumber) bool {
  124. return isInteger(v) && v < LNumber(int((^uint(0))>>1)) && v > LNumber(0) && v < LNumber(MaxArrayIndex)
  125. }
  126. func parseNumber(number string) (LNumber, error) {
  127. var value LNumber
  128. number = strings.Trim(number, " \t\n")
  129. if v, err := strconv.ParseInt(number, 0, LNumberBit); err != nil {
  130. if v2, err2 := strconv.ParseFloat(number, LNumberBit); err2 != nil {
  131. return LNumber(0), err2
  132. } else {
  133. value = LNumber(v2)
  134. }
  135. } else {
  136. value = LNumber(v)
  137. }
  138. return value, nil
  139. }
  140. func popenArgs(arg string) (string, []string) {
  141. cmd := "/bin/sh"
  142. args := []string{"-c"}
  143. if LuaOS == "windows" {
  144. cmd = "C:\\Windows\\system32\\cmd.exe"
  145. args = []string{"/c"}
  146. }
  147. args = append(args, arg)
  148. return cmd, args
  149. }
  150. func isGoroutineSafe(lv LValue) bool {
  151. switch v := lv.(type) {
  152. case *LFunction, *LUserData, *LState:
  153. return false
  154. case *LTable:
  155. return v.Metatable == LNil
  156. default:
  157. return true
  158. }
  159. }
  160. func readBufioSize(reader *bufio.Reader, size int64) ([]byte, error, bool) {
  161. result := []byte{}
  162. read := int64(0)
  163. var err error
  164. var n int
  165. for read != size {
  166. buf := make([]byte, size-read)
  167. n, err = reader.Read(buf)
  168. if err != nil {
  169. break
  170. }
  171. read += int64(n)
  172. result = append(result, buf[:n]...)
  173. }
  174. e := err
  175. if e != nil && e == io.EOF {
  176. e = nil
  177. }
  178. return result, e, len(result) == 0 && err == io.EOF
  179. }
  180. func readBufioLine(reader *bufio.Reader) ([]byte, error, bool) {
  181. result := []byte{}
  182. var buf []byte
  183. var err error
  184. var isprefix bool = true
  185. for isprefix {
  186. buf, isprefix, err = reader.ReadLine()
  187. if err != nil {
  188. break
  189. }
  190. result = append(result, buf...)
  191. }
  192. e := err
  193. if e != nil && e == io.EOF {
  194. e = nil
  195. }
  196. return result, e, len(result) == 0 && err == io.EOF
  197. }
  198. func int2Fb(val int) int {
  199. e := 0
  200. x := val
  201. for x >= 16 {
  202. x = (x + 1) >> 1
  203. e++
  204. }
  205. if x < 8 {
  206. return x
  207. }
  208. return ((e + 1) << 3) | (x - 8)
  209. }
  210. func strCmp(s1, s2 string) int {
  211. len1 := len(s1)
  212. len2 := len(s2)
  213. for i := 0; ; i++ {
  214. c1 := -1
  215. if i < len1 {
  216. c1 = int(s1[i])
  217. }
  218. c2 := -1
  219. if i != len2 {
  220. c2 = int(s2[i])
  221. }
  222. switch {
  223. case c1 < c2:
  224. return -1
  225. case c1 > c2:
  226. return +1
  227. case c1 < 0:
  228. return 0
  229. }
  230. }
  231. }
  232. func unsafeFastStringToReadOnlyBytes(s string) (bs []byte) {
  233. sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
  234. bh := (*reflect.SliceHeader)(unsafe.Pointer(&bs))
  235. bh.Data = sh.Data
  236. bh.Cap = sh.Len
  237. bh.Len = sh.Len
  238. return
  239. }