summaryrefslogtreecommitdiff
path: root/rrdformat/rpn.go
blob: 883a730dd439dc1a66026f06412a4b74f951a3f6 (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
//go:generate stringer -type=Op -trimprefix=OP_ -linecomment

package rrdformat

import (
	"fmt"
	"strings"

	"git.lukeshu.com/go/librrd/rrdformat/rrdbinary"
)

type Op uint8

const (
	// rrdtool 1.1.x 2001-03-10
	OP_NUMBER Op = iota
	OP_VARIABLE
	OP_INF
	OP_PREV
	OP_NEGINF
	OP_UNKN
	OP_NOW
	OP_TIME
	OP_ADD // +
	OP_MOD // %
	OP_SUB // -
	OP_MUL // *
	OP_DIV // /
	OP_SIN
	OP_DUP
	OP_EXC
	OP_POP
	OP_COS
	OP_LOG
	OP_EXP
	OP_LT
	OP_LE
	OP_GT
	OP_GE
	OP_EQ
	OP_IF
	OP_MIN
	OP_MAX
	OP_LIMIT
	OP_FLOOR
	OP_CEIL
	OP_UN
	OP_END
	OP_LTIME
	// rrdtool 1.1.x 2002-03-10
	OP_NE
	OP_ISINF
	// rrdtool 1.1.x 2002-07-06
	OP_PREV_OTHER
	// rrdtool 1.1.x 2003-07-14
	OP_COUNT
	// rrdtool 1.1.x 2004-05-04
	OP_ATAN
	// rrdtool 1.1.x 2004-08-24
	OP_SQRT
	OP_SORT
	OP_REV
	// rrdtool 1.1.x 2004-09-24
	OP_TREND
	// rrdtool 1.3.0 -- Problematic: Wasn't inserted at end
	OP_TRENDNAN
	// rrdtool 1.2.10 -- Problematic: Definition in [1.2.10,1.3.0) differs from current
	OP_ATAN2
	OP_RAD2DEG
	OP_DEG2RAD
	// rrdtool 1.4.0 -- Problematic: Wasn't inserted at end
	OP_PREDICT
	OP_PREDICTSIGMA
	// rrdtool 1.2.14 -- Problematic: Definition in [1.2.14,1.4.0) differs from current
	OP_AVG
	OP_ABS
	// rrdtool 1.3.0 -- Problematic: Definition in [1.3.0,1.4.0) differs from current
	OP_ADDNAN
	// rrdtool 1.5.0 -- Problematic: Wasn't inserted at end
	OP_MINNAN
	OP_MAXNAN
	// rrdtool 1.5.0 -- Problematic: Definition in [1.5.0-pre.2012.06.01,1.5.0-pre.2014.02.07) differs from current
	OP_MEDIAN
	// rrdtool 1.5.0
	OP_PREDICTPERC
	OP_DEPTH
	OP_COPY
	OP_ROLL
	OP_INDEX
	// rrdtool 1.5.4
	OP_STEPWIDTH
	OP_NEWDAY
	OP_NEWWEEK
	OP_NEWMONTH
	OP_NEWYEAR
	// rrdtool 1.6.0
	OP_SMIN
	OP_SMAX
	OP_STDEV
	OP_PERCENT
	OP_POW
)

func (rrd RRD) RPNCompactToString(rpnps []rrdbinary.RPNToken) (string, error) {
	strs := make([]string, len(rpnps))
	for _, rpnp := range rpnps {
		switch Op(rpnp.Op) {
		case OP_NUMBER:
			strs = append(strs, fmt.Sprintf("%d", rpnp.Val))
		case OP_VARIABLE:
			if rpnp.Val < 0 || int(rpnp.Val) >= len(rrd.DSDefs) {
				return "", fmt.Errorf("out-of-bounds %s %d", Op(rpnp.Op), rpnp.Val)
			}
			strs = append(strs, string(rrd.DSDefs[int(rpnp.Val)].DSName))
		case OP_PREV_OTHER:
			if rpnp.Val < 0 || int(rpnp.Val) >= len(rrd.DSDefs) {
				return "", fmt.Errorf("out-of-bounds %s %d", Op(rpnp.Op), rpnp.Val)
			}
			strs = append(strs, fmt.Sprintf("PREV(%s)", rrd.DSDefs[int(rpnp.Val)].DSName))
		case OP_END:
			break
		default:
			strs = append(strs, Op(rpnp.Op).String())
		}
	}
	return strings.Join(strs, ","), nil
}