Re: ROL and ROR for RPN

Steve Shipway <[email protected]> Tue, 6 May 2014 02:43:26 +0000
Newsgroups gmane.comp.db.rrdtool.devel
Message-ID <5820DC553954E44FA1A36C78323AD1483A31EC42@uxcn10-6.UoA.auckland.ac.nz>
--===============1911597917==
Content-Language: en-US
Content-Type: multipart/signed; protocol="application/x-pkcs7-signature";
	micalg=SHA1; boundary="----=_NextPart_000_001C_01CF6939.89EB3820"

------=_NextPart_000_001C_01CF6939.89EB3820
Content-Type: multipart/mixed;
	boundary="----=_NextPart_001_001D_01CF6939.89EB3820"


------=_NextPart_001_001D_01CF6939.89EB3820
Content-Type: text/plain;
	charset="us-ascii"
Content-Transfer-Encoding: 7bit

So, I have a patch (unified context diff) to add the RPN operators ROLL,
INDEX, COPY and DEPTH.

DEPTH: push the number of stack elements onto the stack
  1,2,3,DEPTH ==> 1,2,3,3
COPY: pop the top value form the stack.  Copy that number of elements on the
stack.  So, DUP is the same as 1,COPY
   1,2,3,2,COPY ==>  1,2,3,2,3
INDEX: identify the item that far down the stack and copy it onto the top of
the stack (1-based). So, DUP is the same as 1,INDEX
 1,2,3,4,5,2,INDEX ==> 1,2,3,4,5,4
ROLL: rotate the top n items by s steps (can be positive or negative) So
EXCH is the same as 2,1,ROLL or 2,-1,ROLL
 1,2,3,4,5,3,-1,ROLL ==> 1,2,4,5,3

This should allow much more extensive stack manipulation.  Stack underflow
and overflow are handled.

Thanks for the feedback from the group on making ROLL more generic, and
adding DEPTH, INDEX and COPY.  These functions may benefit from more
extensive testing as properly debugging the RPN engine is awkward.  More
feedback always welcome.

Steve
  
Steve Shipway
[email protected]



------=_NextPart_001_001D_01CF6939.89EB3820
Content-Type: application/octet-stream;
	name="rpn.patch"
Content-Transfer-Encoding: quoted-printable
Content-Disposition: attachment;
	filename="rpn.patch"

--- rrd_rpncalc.h.orig	2014-04-28 10:37:48.135588326 +1200=0A=
+++ rrd_rpncalc.h	2014-05-01 09:20:45.512089617 +1200=0A=
@@ -19,7 +19,8 @@=0A=
     OP_ATAN, OP_SQRT, OP_SORT, OP_REV, OP_TREND, OP_TRENDNAN,=0A=
     OP_ATAN2, OP_RAD2DEG, OP_DEG2RAD,=0A=
     OP_PREDICT,OP_PREDICTSIGMA,=0A=
-    OP_AVG, OP_ABS, OP_ADDNAN=0A=
+    OP_AVG, OP_ABS, OP_ADDNAN,=0A=
+    OP_ROLL, OP_INDEX, OP_COPY, OP_DEPTH=0A=
 };=0A=
 =0A=
 typedef struct rpnp_t {=0A=
--- rrd_rpncalc.c.orig	2014-04-28 10:37:52.886321588 +1200=0A=
+++ rrd_rpncalc.c	2014-05-01 15:40:49.523610173 +1200=0A=
@@ -185,6 +185,12 @@=0A=
             add_op(OP_AVG, AVG)=0A=
             add_op(OP_ABS, ABS)=0A=
             add_op(OP_ADDNAN, ADDNAN)=0A=
+/* SJS START */=0A=
+            add_op(OP_ROLL, ROLL)=0A=
+            add_op(OP_INDEX, INDEX)=0A=
+            add_op(OP_COPY, COPY)=0A=
+            add_op(OP_DEPTH, DEPTH)=0A=
+/* SJS END */=0A=
 #undef add_op=0A=
     }=0A=
     (*str)[offset] =3D '\0';=0A=
@@ -385,6 +391,12 @@=0A=
             match_op(OP_AVG, AVG)=0A=
             match_op(OP_ABS, ABS)=0A=
             match_op(OP_ADDNAN, ADDNAN)=0A=
+/* SJS START */=0A=
+            match_op(OP_ROLL, ROLL)=0A=
+            match_op(OP_INDEX, INDEX)=0A=
+            match_op(OP_COPY, COPY)=0A=
+            match_op(OP_DEPTH, DEPTH)=0A=
+/* SJS END */=0A=
 #undef match_op=0A=
             else if ((sscanf(expr, DEF_NAM_FMT "%n", vname, &pos) =
=3D=3D 1)=0A=
                      && ((rpnp[steps].ptr =3D (*lookup) (key_hash, =
vname)) !=3D=0A=
@@ -649,6 +661,67 @@=0A=
                 rpnstack->s[stptr - 1] =3D dummy;=0A=
             }=0A=
             break;=0A=
+/* SJS START */=0A=
+        case OP_ROLL:=0A=
+            stackunderflow(1);=0A=
+            {=0A=
+                int step =3D (int) rpnstack->s[stptr--];=0A=
+                int base =3D (int) rpnstack->s[stptr--];=0A=
+                int i =3D base;=0A=
+                int j =3D i + step;=0A=
+                double *tmp_stack;=0A=
+                stackunderflow(base-1);=0A=
+                tmp_stack =3D (double *)malloc(sizeof(double)*base);=0A=
+                if(!tmp_stack) { =0A=
+                    rrd_set_error("RPN out of memory (allocating %i =
objects)",base);=0A=
+                    return -1;=0A=
+                }=0A=
+                memcpy(tmp_stack,rpnstack->s + =
stptr,(sizeof(double)*base));=0A=
+                while(i--) {=0A=
+                    j--; =0A=
+                    while(j<0) { j +=3D base; }=0A=
+                    while(j>=3Dbase) { j -=3D base; }=0A=
+                    rpnstack->s[stptr-i] =3D tmp_stack[j];=0A=
+                }=0A=
+                free(tmp_stack);=0A=
+            }=0A=
+            break;=0A=
+        case OP_INDEX:=0A=
+            stackunderflow(0);=0A=
+            {=0A=
+                int i =3D (int) rpnstack->s[stptr];=0A=
+                stackunderflow(i);=0A=
+                rpnstack->s[stptr] =3D rpnstack->s[stptr - i];=0A=
+            }=0A=
+            break;=0A=
+        case OP_COPY:=0A=
+            {=0A=
+                int base =3D (int) rpnstack->s[stptr--];=0A=
+                int i =3D base;=0A=
+                stackunderflow(base - 1);=0A=
+                /* allocate or grow the stack */=0A=
+                while (stptr + base > rpnstack->dc_stacksize) {=0A=
+                    /* could move this to a separate function */=0A=
+                    rpnstack->dc_stacksize +=3D rpnstack->dc_stackblock;=0A=
+                    rpnstack->s =3D (double*)rrd_realloc(rpnstack->s,=0A=
+                                      (rpnstack->dc_stacksize) *=0A=
+                                      sizeof(*(rpnstack->s)));=0A=
+                    if (rpnstack->s =3D=3D NULL) {=0A=
+                        rrd_set_error("RPN stack overflow");=0A=
+                        return -1;=0A=
+                    }=0A=
+                }=0A=
+                while(i--) {=0A=
+		  stptr++;=0A=
+                  rpnstack->s[stptr] =3D rpnstack->s[stptr - base];=0A=
+                }=0A=
+            }=0A=
+            break;=0A=
+        case OP_DEPTH:=0A=
+            stptr++;=0A=
+            rpnstack->s[stptr] =3D stptr;=0A=
+            break;=0A=
+/* SJS END */=0A=
         case OP_EXP:=0A=
             stackunderflow(0);=0A=
             rpnstack->s[stptr] =3D exp(rpnstack->s[stptr]);=0A=

------=_NextPart_001_001D_01CF6939.89EB3820--

------=_NextPart_000_001C_01CF6939.89EB3820
Content-Type: application/pkcs7-signature; name="smime.p7s"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="smime.p7s"

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
xCZU7wO94CTLVBowHQYDVR0OBBYEFImCZ33EnSZwAEu0UEh83j2uBG59MA4GA1UdDwEB/wQEAwIB
BjAPBgNVHRMBAf8EBTADAQH/MBEGA1UdIAQKMAgwBgYEVR0gADBEBgNVHR8EPTA7MDmgN6A1hjNo
dHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vQWRkVHJ1c3RFeHRlcm5hbENBUm9vdC5jcmwwNQYIKwYB
BQUHAQEEKTAnMCUGCCsGAQUFBzABhhlodHRwOi8vb2NzcC51c2VydHJ1c3QuY29tMA0GCSqGSIb3
DQEBBQUAA4IBAQABvJzjYyiw8zEBwt973WKgAZ0jMQ+cknNTUeofTPrWn8TKL2d+eDMPdBa5kYeR
9Yom+mRwANge+QsEYlCHk4HU2vUj2zS7hVa0cDRueIM3HoUcxREVkl+HF72sav3xwtHMiV+xfPA+
UfI183zsYJhrOivg79+zfYbrtRv1W+yifJgT1wBQudEtc94DeHThBYUxXsuauZ2UxrmUN3Vy3ET7
Z+jw+iUeUqfaJelH4KDHPKBOsQo2+3dIn++Xivu0/uOUFKiDvFwtP9JgcWDuwnGCDOmINuPaILSj
oGyqlku4gI51ykkH9jsUut/cBdmf2+Cy5k2geCbn5y1uf1/GHogVMIIE+jCCA+KgAwIBAgIQTeet
POPA8yxwTfdxoSmSpDANBgkqhkiG9w0BAQUFADCBrjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVU
MRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3Jr
MSEwHwYDVQQLExhodHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xNjA0BgNVBAMTLVVUTi1VU0VSRmly
c3QtQ2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBFbWFpbDAeFw0wOTA5MjkwMDAwMDBaFw0yMDA1
MzAxMDQ4MzhaMFoxCzAJBgNVBAYTAkFVMRAwDgYDVQQKEwdBdXNDRVJUMR0wGwYDVQQLExRDZXJ0
aWZpY2F0ZSBTZXJ2aWNlczEaMBgGA1UEAxMRQXVzQ0VSVCBDbGllbnQgQ0EwggEiMA0GCSqGSIb3
DQEBAQUAA4IBDwAwggEKAoIBAQDQ73z/SV77d6q1waTZsbnMaLYnnIRsNMBjRf7KxjwAb9JsK3ip
q3zBon7ww5JxYkWqL805PlGFUxEJDshFs9nn7XR/RTwr2dDDmdhKVdvcRZ2NKabr1/VuJjLVeMmT
o2VHxP5WO2vsFJ18J7hw6PwIDRIiRL8nGErXYU8D8CSOGg4qVjPI18Pm9uGbW1/iwLeNG3iWOmQn
MLhGI3pICBdwcydhfVe0k4CuKukYeockj53g3XGTdWsxghN6HjaI9OeW+z+2MLypli7L7xgoOy9y
FnbOOEJ+OdYPg6Zk6H1hqCrfnlu9dcCLCjeLpeH9Cp3VcLgNxzkX4FJm54ZnIpZnAgMBAAGjggFl
MIIBYTAfBgNVHSMEGDAWgBSJgmd9xJ0mcABLtFBIfN49rgRufTAdBgNVHQ4EFgQUV5Hh4AwtLcT8
v0SQnMRr6fInxoswDgYDVR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwKwYDVR0gBCQw
IjAPBg0rBgEEAYG3PQUBAQABMA8GDSsGAQQBgbc9BQEBAAMwWAYDVR0fBFEwTzBNoEugSYZHaHR0
cDovL2NybC51c2VydHJ1c3QuY29tL1VUTi1VU0VSRmlyc3QtQ2xpZW50QXV0aGVudGljYXRpb25h
bmRFbWFpbC5jcmwwdAYIKwYBBQUHAQEEaDBmMD0GCCsGAQUFBzAChjFodHRwOi8vY3J0LnVzZXJ0
cnVzdC5jb20vVVROQWRkVHJ1c3RDbGllbnRfQ0EuY3J0MCUGCCsGAQUFBzABhhlodHRwOi8vb2Nz
cC51c2VydHJ1c3QuY29tMA0GCSqGSIb3DQEBBQUAA4IBAQCBoyxPNHRgMVF5/RzJnemHY5521htn
s83+nP0uD8pJWWntvbbkqECmH2fwGPPZEM7vQksu8OuVRdd7FptR8OujcePhCCfOG6pJbktYOInx
dOGxdzDMhmixoTJZfybz6DVeOQlsYvcrlu4A9rIiuQNW/QKnlv6Aazr4syM0N/JJE+v8dqabCklP
qcP57Lb3bbTTmAI+A+Mz6VQxfyS57YLwZpH5SMnjLdQfDYi91SjVcmm8yZ9QJfzg+rSafGREQz/f
8moJtHPPYYkRlDOpVZQ+gDUGgLJ0JTgvEFKQXsJ3Hg6TWpDJM7Xx5JkX/FMau8F/yaZU4Ie5uFi1
drqo6iHiMIIFVjCCBD6gAwIBAgIQLR9Dnaz25cE+YpRN+zboADANBgkqhkiG9w0BAQUFADBaMQsw
CQYDVQQGEwJBVTEQMA4GA1UEChMHQXVzQ0VSVDEdMBsGA1UECxMUQ2VydGlmaWNhdGUgU2Vydmlj
ZXMxGjAYBgNVBAMTEUF1c0NFUlQgQ2xpZW50IENBMB4XDTEyMDExMzAwMDAwMFoXDTE1MDExMjIz
NTk1OVowgccxDTALBgNVBBETBDExNDIxIzAhBgNVBAoTGlRoZSBVbml2ZXJzaXR5IG9mIEF1Y2ts
YW5kMRowGAYDVQQJExFQcml2YXRlIEJhZyA5MjAxOTEUMBIGA1UECBMLTmV3IFplYWxhbmQxETAP
BgNVBAcTCEF1Y2tsYW5kMQswCQYDVQQGEwJOWjEWMBQGA1UEAxMNU3RldmUgU2hpcHdheTEnMCUG
CSqGSIb3DQEJARYYcy5zaGlwd2F5QGF1Y2tsYW5kLmFjLm56MIIBIjANBgkqhkiG9w0BAQEFAAOC
AQ8AMIIBCgKCAQEA4oIzeCM4B+iiiqXfNO3JkO/VGilk1EPpfOsIc8mwnEtmRVaSY4hQpSDx8Fsx
wjshmbfW4suRC+TKrg2whwzvrZhsqzrz6qQBo1GKCjZ8Abjtsd03MWsAMr9RxpQ/GzlxbgZx+Nv2
ODh+3S55HawjBvg1EmjwFNnSkIR76lY04NE2U8i0CkxcmG4vXQdTAH19jXp8VdtKQ3NfxV2VmRtr
/RhUNo1SOGmMcXDeDBBoJ7OqnnfAAEKgonlk4BsLRiZWkUPr0pOXFWyfp9JXUHXQN0zM4cjP1RB2
vXGTT+VM3x0J44v50yA4RH0NJ+yuPI3e71gUMklPLnof74HBMh+cXQIDAQABo4IBqDCCAaQwHwYD
VR0jBBgwFoAUV5Hh4AwtLcT8v0SQnMRr6fInxoswHQYDVR0OBBYEFOW9jM1TFCxLbaBO7yV75b8a
6/pjMA4GA1UdDwEB/wQEAwIFoDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMEBggr
BgEFBQcDAjAaBgNVHSAEEzARMA8GDSsGAQQBgbc9BQEBAAEwQQYDVR0fBDowODA2oDSgMoYwaHR0
cDovL2NybC5jcy5hdXNjZXJ0Lm9yZy5hdS9BdXNDRVJUQ2xpZW50Q0EuY3JsMHcGCCsGAQUFBwEB
BGswaTA8BggrBgEFBQcwAoYwaHR0cDovL2NydC5jcy5hdXNjZXJ0Lm9yZy5hdS9BdXNDRVJUQ2xp
ZW50Q0EuY3J0MCkGCCsGAQUFBzABhh1odHRwOi8vb2NzcC5jcy5hdXNjZXJ0Lm9yZy5hdTBNBgNV
HREERjBEoCgGCisGAQQBgjcUAgOgGgwYcy5zaGlwd2F5QGF1Y2tsYW5kLmFjLm56gRhzLnNoaXB3
YXlAYXVja2xhbmQuYWMubnowDQYJKoZIhvcNAQEFBQADggEBALNXdMpsE9RY8k0vx1JVsPCuAFML
S+OcEfuU2+du37H9nCqUkvZi8cGU4mlmfgIGOF532wY9m0N41o+esbOxR6townr9f5xKg3WoVA/w
AOzD4n563ByQtH8+3VuM4WLlsR1JSGE/UdR/VTQS9VLitWpf6eczQofvnjjXnE1zmCpooO3QtiH8
Xha569NFgSpzUWmIwGmCiX3g70WrmPc3W+6KxcR0EhYWZFEDuiP1N33wUn8OnpfQUUkOEsS/Ei4h
Y5QRO3tf5qnehEr4PJZUlDL0sLSMWDSxcBrIMCBLSL9vYYub1DHSxKCP2vAhkAXfAdt51jHX3MFo
fGup40cjtJgxggOkMIIDoAIBATBuMFoxCzAJBgNVBAYTAkFVMRAwDgYDVQQKEwdBdXNDRVJUMR0w
GwYDVQQLExRDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEaMBgGA1UEAxMRQXVzQ0VSVCBDbGllbnQgQ0EC
EC0fQ52s9uXBPmKUTfs26AAwCQYFKw4DAhoFAKCCAgswGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEH
ATAcBgkqhkiG9w0BCQUxDxcNMTQwNTA2MDI0MzI2WjAjBgkqhkiG9w0BCQQxFgQUpOxSE/IAviWc
FOxWRE8Vii7G9hEwfQYJKwYBBAGCNxAEMXAwbjBaMQswCQYDVQQGEwJBVTEQMA4GA1UEChMHQXVz
Q0VSVDEdMBsGA1UECxMUQ2VydGlmaWNhdGUgU2VydmljZXMxGjAYBgNVBAMTEUF1c0NFUlQgQ2xp
ZW50IENBAhAtH0OdrPblwT5ilE37NugAMH8GCyqGSIb3DQEJEAILMXCgbjBaMQswCQYDVQQGEwJB
VTEQMA4GA1UEChMHQXVzQ0VSVDEdMBsGA1UECxMUQ2VydGlmaWNhdGUgU2VydmljZXMxGjAYBgNV
BAMTEUF1c0NFUlQgQ2xpZW50IENBAhAtH0OdrPblwT5ilE37NugAMIGrBgkqhkiG9w0BCQ8xgZ0w
gZowCwYJYIZIAWUDBAEqMAsGCWCGSAFlAwQBFjAKBggqhkiG9w0DBzALBglghkgBZQMEAQIwDgYI
KoZIhvcNAwICAgCAMAcGBSsOAwIHMA0GCCqGSIb3DQMCAgFAMA0GCCqGSIb3DQMCAgEoMAcGBSsO
AwIaMAsGCWCGSAFlAwQCAzALBglghkgBZQMEAgIwCwYJYIZIAWUDBAIBMA0GCSqGSIb3DQEBAQUA
BIIBAODvdH39OBxpJcYhMAWvpPBlNOvPjWbT+qF5/cqRfxjfhf5//4f9Eg2Q9zPg/uZkHgYyea8H
llORl7pj04JBui/xRHlFlL4RD5l9bjiw3hmIA4wDzZqj9PMo2K8BYCNzHzqnAiLVV3iubu5d6ohv
2SxjUCjxCqWmm284MLn75l5Zajz4xI72/RKBVdEnjaQNTlQqmThmJ+qzm1esIxocAMn6FBv/bJ5H
NslU/kWlWx0VYi6izJyNbkFDl1Bt9/rniPt1JHfFxKZ5Fx59TxdAVByEagkEjFmErxxzHhx3gwHH
TKmg3arMJSxT4M7PVEoTmfibSML7iv8C3c2zamAYZy8AAAAAAAA=

------=_NextPart_000_001C_01CF6939.89EB3820--


--===============1911597917==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
rrd-developers mailing list
[email protected]
https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers

--===============1911597917==--