utils.go 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. package yaml
  2. import (
  3. "fmt"
  4. "io"
  5. "strconv"
  6. "strings"
  7. )
  8. // SafeString returns a string which is sufficiently quoted and escaped for YAML.
  9. func SafeString(str string) string {
  10. str = strings.Replace(str, "\\", "\\\\", -1)
  11. str = strings.Replace(str, "\"", "\\\"", -1)
  12. return "\"" + str + "\""
  13. }
  14. // PrintMatrix outputs a rectangular integer matrix in YAML text format.
  15. //
  16. // `indent` is the current YAML indentation level - the number of spaces.
  17. // `name` is the name of the corresponding YAML block. If empty, no separate block is created.
  18. // `fixNegative` changes all negative values to 0.
  19. func PrintMatrix(writer io.Writer, matrix [][]int64, indent int, name string, fixNegative bool) {
  20. // determine the maximum length of each value
  21. var maxnum int64 = -(1 << 32)
  22. var minnum int64 = 1 << 32
  23. for _, status := range matrix {
  24. for _, val := range status {
  25. if val > maxnum {
  26. maxnum = val
  27. }
  28. if val < minnum {
  29. minnum = val
  30. }
  31. }
  32. }
  33. width := len(strconv.FormatInt(maxnum, 10))
  34. if !fixNegative && minnum < 0 {
  35. negativeWidth := len(strconv.FormatInt(minnum, 10))
  36. if negativeWidth > width {
  37. width = negativeWidth
  38. }
  39. }
  40. last := len(matrix[len(matrix)-1])
  41. if name != "" {
  42. fmt.Fprintf(writer, "%s%s: |-\n", strings.Repeat(" ", indent), SafeString(name))
  43. indent += 2
  44. }
  45. // print the resulting triangular matrix
  46. first := true
  47. for _, status := range matrix {
  48. fmt.Fprint(writer, strings.Repeat(" ", indent-1))
  49. for i := 0; i < last; i++ {
  50. var val int64
  51. if i < len(status) {
  52. val = status[i]
  53. // not sure why this sometimes happens...
  54. // TODO(vmarkovtsev): find the root cause of tiny negative balances
  55. if fixNegative && val < 0 {
  56. val = 0
  57. }
  58. }
  59. if !first {
  60. fmt.Fprintf(writer, " %[1]*[2]d", width, val)
  61. } else {
  62. first = false
  63. fmt.Fprintf(writer, " %d%s", val, strings.Repeat(" ", width-len(strconv.FormatInt(val, 10))))
  64. }
  65. }
  66. fmt.Fprintln(writer)
  67. }
  68. }