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==--