shithub: riscv

Download patch

ref: 0c50e1bc3d63f8a62986bbd140f9aef48a0cb076
parent: 1447b95555d6afa39f7ab04f04f1415f8937d899
author: aiju <devnull@localhost>
date: Sun Sep 18 21:20:28 EDT 2016

pc(1): add pb (thanks, BurnZeZ); add bit numbering

--- a/sys/man/1/pc
+++ b/sys/man/1/pc
@@ -65,6 +65,9 @@
 .I hex(n)
 Display \fIn\fR in hexadecimal.
 .TP
+.I pb(n, b)
+Display \fIn\fR in base \fIb\fR (currently must be one of 0, 2, 8, 10, 16; 0 uses the defined output base).
+.TP
 .I abs(n)
 Absolute value of \fIn\fR.
 .TP
@@ -135,6 +138,10 @@
 Use truncating division (same as C).
 \fIa\fR / \fIb\fR is rounded towards zero.
 \fIa\fR % \fIb\fR can be negative.
+.TP
+\fL\'\fR 1
+Enable numbering bits (disable with 0).
+If the base is a power of two, print the number of the corresponding bit above each digit.
 .SH SOURCE
 .B /sys/src/cmd/pc.y
 .SH "SEE ALSO"
--- a/sys/src/cmd/pc.y
+++ b/sys/src/cmd/pc.y
@@ -7,7 +7,7 @@
 #include <thread.h>
 #include <libsec.h>
 
-int inbase = 10, outbase, divmode, sep, fail, prompt;
+int inbase = 10, outbase, divmode, sep, heads, fail, prompt;
 enum { MAXARGS = 16 };
 
 typedef struct Num Num;
@@ -228,11 +228,38 @@
 	return *p;
 }
 
+static void
+printhead(int n, int s, int sp, char *t)
+{
+	char *q;
+	int i, j, k;
+	
+	for(i = 1; i < n; i *= 10)
+		;
+	while(i /= 10, i != 0){
+		q = t;
+		*--q = 0;
+		for(j = 0, k = 0; j < n; j += s, k++){
+			if(k == sep && sep != 0){
+				*--q = ' ';
+				k = 0;
+			}
+			if(j >= i || j == 0 && i == 1)
+				*--q = '0' + j / i % 10;
+			else
+				*--q = ' ';
+		}
+		for(j = 0; j < sp; j++)
+			*--q = ' ';
+		print("%s\n", q);
+	}
+}
+
 void
 numprint(Num *n)
 {
 	int b;
-	int l, i;
+	int l, i, st, sp;
 	char *s, *t, *p, *q;
 
 	if(n == nil) return;
@@ -246,6 +273,18 @@
 	l = strlen(s);
 	t = emalloc(l * 2 + 4);
 	q = t + l * 2 + 4;
+	if(heads){
+		switch(b){
+		case 16: st = 4; sp = 2; break;
+		case 8: st = 3; sp = 1; break;
+		case 2: st = 1; sp = 2; break;
+		default: st = 0; sp = 0;
+		}
+		if(n->sign < 0)
+			sp++;
+		if(st != 0)
+			printhead(mpsignif(n), st, sp, q);
+	}
 	*--q = 0;
 	for(p = s + l - 1, i = 0; p >= s && *p != '-'; p--, i++){
 		if(sep != 0 && i == sep){
@@ -409,6 +448,19 @@
 		numdecref(last);
 		last = nil;
 	}
+	| '\'' { save = inbase; inbase = 10; } expr {
+		inbase = save;
+		save = heads;
+		if(!fail) 
+			heads = mptoi($3);
+		if(heads != 0 && heads != 1){
+			error("no.");
+			heads = save;
+		}
+		numdecref($3);
+		numdecref(last);
+		last = nil;
+	}
 	| error
 
 expr: LNUM
@@ -639,6 +691,30 @@
 }
 
 Num *
+fnpb(int, Num **a)
+{
+	Num *r;
+	int b;
+	
+	if(toint(a[1], &b, 1)){
+	out:
+		numdecref(a[0]);
+		numdecref(a[1]);
+		return nil;
+	}
+	if(b != 0 && b != 2 && b != 8 && b != 10 && b != 16){
+		error("unsupported base");
+		goto out;
+	}
+	r = nummod(a[0]);
+	if(b == 0)
+		r->b = 0;
+	else
+		r->b = STRONG | b;
+	return r;
+}
+
+Num *
 fnabs(int, Num **a)
 {
 	Num *r;
@@ -903,6 +979,7 @@
 	regfunc("dec", fndec, 1);
 	regfunc("oct", fnoct, 1);
 	regfunc("bin", fnbin, 1);
+	regfunc("pb", fnpb, 2);
 	regfunc("abs", fnabs, 1);
 	regfunc("round", fnround, 2);
 	regfunc("floor", fnfloor, 2);