summaryrefslogtreecommitdiffstats
path: root/src/util/util.go
blob: e7e4f3138bcd48f1680a442535df27598fa230ff (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package util

// #include <unistd.h>
import "C"

import (
	"os"
	"time"
	"unicode/utf8"
)

// Max returns the largest integer
func Max(first int, items ...int) int {
	max := first
	for _, item := range items {
		if item > max {
			max = item
		}
	}
	return max
}

// Min32 returns the smallest 32-bit integer
func Min32(first int32, second int32) int32 {
	if first <= second {
		return first
	}
	return second
}

// Max32 returns the largest 32-bit integer
func Max32(first int32, second int32) int32 {
	if first > second {
		return first
	}
	return second
}

// Constrain32 limits the given 32-bit integer with the upper and lower bounds
func Constrain32(val int32, min int32, max int32) int32 {
	if val < min {
		return min
	}
	if val > max {
		return max
	}
	return val
}

// Constrain limits the given integer with the upper and lower bounds
func Constrain(val int, min int, max int) int {
	if val < min {
		return min
	}
	if val > max {
		return max
	}
	return val
}

// DurWithin limits the given time.Duration with the upper and lower bounds
func DurWithin(
	val time.Duration, min time.Duration, max time.Duration) time.Duration {
	if val < min {
		return min
	}
	if val > max {
		return max
	}
	return val
}

// IsTty returns true is stdin is a terminal
func IsTty() bool {
	return int(C.isatty(C.int(os.Stdin.Fd()))) != 0
}

// TrimRight returns rune array with trailing white spaces cut off
func TrimRight(runes []rune) []rune {
	var i int
	for i = len(runes) - 1; i >= 0; i-- {
		char := runes[i]
		if char != ' ' && char != '\t' {
			break
		}
	}
	return runes[0 : i+1]
}

// BytesToRunes converts byte array into rune array
func BytesToRunes(bytea []byte) []rune {
	runes := make([]rune, 0, len(bytea))
	for i := 0; i < len(bytea); {
		if bytea[i] < utf8.RuneSelf {
			runes = append(runes, rune(bytea[i]))
			i++
		} else {
			r, sz := utf8.DecodeRune(bytea[i:])
			i += sz
			runes = append(runes, r)
		}
	}
	return runes
}

// TrimLen returns the length of trimmed rune array
func TrimLen(runes []rune) int {
	var i int
	for i = len(runes) - 1; i >= 0; i-- {
		char := runes[i]
		if char != ' ' && char != '\t' {
			break
		}
	}
	// Completely empty
	if i < 0 {
		return 0
	}

	var j int
	for j = 0; j < len(runes); j++ {
		char := runes[j]
		if char != ' ' && char != '\t' {
			break
		}
	}
	return i - j + 1
}