ref: ec737b6a2e464330946d5800841a1e631cd36acd
parent: b86bb35c7d82f097e6572d400527046245b877fd
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat May 23 13:44:30 EDT 2020
libaml: implement ToDecimalString and ToHexString operations
--- a/sys/src/libaml/aml.c
+++ b/sys/src/libaml/aml.c
@@ -152,7 +152,7 @@
Oif, Oelse, Owhile, Obreak, Oret, Ocall,
Ostore, Oderef, Osize, Oref, Ocref, Ocat,
Oacq, Orel, Ostall, Osleep, Oload, Ounload,
- Otoint,
+ Otodec, Otohex, Otoint,
};
static Op optab[];
@@ -682,13 +682,62 @@
return p;
}
+static char*
+todecstr(uchar *buf, int len, int sep)
+{
+ char *r, *d;
+ int i, v;
+
+ r = d = mk('s', len*4 + 1);
+ if(len == 0){
+ *d = 0;
+ return r;
+ }
+ if(sep == 0)
+ sep = ' ';
+ for(i=0; i<len; i++){
+ v = buf[i];
+ if((*d = '0' + ((v/100) % 10)) != '0')
+ d++;
+ if((*d = '0' + ((v/10) % 10)) != '0')
+ d++;
+ *d++ = '0' + (v % 10);
+ *d++ = sep;
+ }
+ d[-1] = 0;
+ return r;
+}
+
+static char hex[] = "0123456789ABCDEF";
+
+static char*
+tohexstr(uchar *buf, int len, int sep)
+{
+ char *r, *d;
+ int i;
+
+ r = d = mk('s', len*3 + 1);
+ if(len == 0){
+ *d = 0;
+ return r;
+ }
+ if(sep == 0)
+ sep = ' ';
+ for(i=0; i<len; i++){
+ *d++ = hex[buf[i] >> 4];
+ *d++ = hex[buf[i] & 0xF];
+ *d++ = sep;
+ }
+ d[-1] = 0;
+ return r;
+}
+
static void*
copy(int tag, void *s)
{
- static char hex[] = "0123456789ABCDEF";
uvlong v;
void *d;
- int i, n;
+ int n;
if(tag == 0){
if(s == nil)
@@ -723,16 +772,8 @@
n = SIZE(s);
switch(tag){
case 's':
- if(TAG(s) == 'b'){
- d = mk(tag, n*3 + 1);
- for(i=0; i<n; i++){
- ((char*)d)[i*3 + 0] = hex[((uchar*)s)[i] >> 4];
- ((char*)d)[i*3 + 1] = hex[((uchar*)s)[i] & 0xF];
- ((char*)d)[i*3 + 2] = ' ';
- }
- ((char*)d)[n*3] = 0;
- return d;
- }
+ if(TAG(s) == 'b')
+ return tohexstr(s, n, ' ');
/* no break */
case 'b':
if(TAG(s) == 's'){
@@ -1903,15 +1944,40 @@
static void*
evalconv(void)
{
- void *r;
+ void *r, *a;
r = nil;
+ a = FP->arg[0];
switch(FP->op - optab){
+ case Otodec:
+ if(a == nil)
+ break;
+ if(TAG(a) == 's'){
+ r = a;
+ break;
+ }
+ if(TAG(a) == 'b'){
+ r = todecstr(a, SIZE(a), ',');
+ break;
+ }
+ break;
+ case Otohex:
+ if(a == nil)
+ break;
+ if(TAG(a) == 's'){
+ r = a;
+ break;
+ }
+ if(TAG(a) == 'b'){
+ r = tohexstr(a, SIZE(a), ',');
+ break;
+ }
+ break;
case Otoint:
- if(FP->arg[0] != nil && TAG(FP->arg[0]) == 's')
- r = mki(strtoull((char*)FP->arg[0], 0, 0));
+ if(a != nil && TAG(a) == 's')
+ r = mki(strtoull((char*)a, 0, 0));
else
- r = mki(ival(FP->arg[0]));
+ r = mki(ival(a));
break;
}
store(r, FP->arg[1]);
@@ -2012,6 +2078,8 @@
[Oload] "Load", "*@}", evalload,
[Ounload] "Unload", "@", evalnop,
+ [Otodec] "ToDecimalString", "*@", evalconv,
+ [Otohex] "ToHexString", "*@", evalconv,
[Otoint] "ToInteger", "*@", evalconv,
};
@@ -2034,8 +2102,8 @@
/* 78 */ Odiv, Oshl, Oshr, Oand, Onand, Oor, Onor, Oxor,
/* 80 */ Onot, Olbit, Orbit, Oderef, Obad, Omod, Obad, Osize,
/* 88 */ Oindex, Omatch, Ocfld4, Ocfld2, Ocfld1, Ocfld0, Obad, Ocfld8,
-/* 90 */ Oland, Olor, Olnot, Oleq, Olgt, Ollt, Obad, Obad,
-/* 98 */ Obad, Otoint, Obad, Obad, Obad, Obad, Obad, Obad,
+/* 90 */ Oland, Olor, Olnot, Oleq, Olgt, Ollt, Obad, Otodec,
+/* 98 */ Otohex, Otoint, Obad, Obad, Obad, Obad, Obad, Obad,
/* A0 */ Oif, Oelse, Owhile, Onop, Oret, Obreak, Obad, Obad,
/* A8 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
/* B0 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,