code: plan9front

Download patch

ref: b122f2c4b8c3ebf69ce46347bf752ef0d75fadc8
parent: 5cf570664db90871b62decf0f0c34512573932c2
author: Jacob Moody <moody@posixcafe.org>
date: Sat Jan 7 23:18:28 EST 2023

look: add -b for specifying numeric base

--- a/sys/man/1/look
+++ b/sys/man/1/look
@@ -4,9 +4,17 @@
 .SH SYNOPSIS
 .B look
 [
-.BI -dfnixt c
+.BI -dfnix
 ]
 [
+.B -t
+.I c
+]
+[
+.B -b
+.I base
+]
+[
 .I string
 ]
 [
@@ -52,6 +60,11 @@
 .B -n
 Numeric comparison with initial string of digits, optional minus sign,
 and optional decimal point.
+.TP
+.B -b \f2base\f1
+Change the base for numeric comparison. Implies the
+.B -n
+flag.
 .TP
 .BR -t [ \f2c\f1 ]
 Character
--- a/sys/src/cmd/look.c
+++ b/sys/src/cmd/look.c
@@ -8,10 +8,8 @@
 #define	isalpha(r)	(isupper(r) || islower(r))
 #define	islatin1(r)	(0xC0 <= (r) && (r) <= 0xFF)
 
-#define	isdigit(r)	(L'0' <= (r) && (r) <= L'9')
+#define	isalnum(r)	(isalpha(r) || (L'0' <= (r) && (r) <= L'9'))
 
-#define	isalnum(r)	(isalpha(r) || isdigit(r))
-
 #define	isspace(r)	((r) == L' ' || (r) == L'\t' \
 			|| (0x0A <= (r) && (r) <= 0x0D))
 
@@ -18,6 +16,7 @@
 #define	tolower(r)	((r)-'A'+'a')
 
 #define	sgn(v)		((v) < 0 ? -1 : ((v) > 0 ? 1 : 0))
+#define	notcase(v)	(v != L'a'-L'A' && v != L'A'-L'a')
 
 #define	WORDSIZ	4000
 char	*filename = "/lib/words";
@@ -29,6 +28,7 @@
 int	direc;
 int	exact;
 int	iflag;
+int	base;
 int	rev = 1;	/*-1 for reverse-ordered file, not implemented*/
 int	(*compare)(Rune*, Rune*);
 Rune	tab = '\t';
@@ -65,6 +65,7 @@
 void	torune(char*, Rune*);
 void	rcanon(Rune*, Rune*);
 int	ncomp(Rune*, Rune*);
+int	isdigit(Rune);
 
 void
 usage(void)
@@ -81,7 +82,12 @@
 	Binit(&bin, 0, OREAD);
 	Binit(&bout, 1, OWRITE);
 	compare = acomp;
+	base = 10;
 	ARGBEGIN{
+	case 'b':
+		base = atoi(EARGF(usage()));
+		compare = ncomp;
+		break;
 	case 'd':
 		direc++;
 		break;
@@ -299,7 +305,7 @@
 	a = 0;
 	if(ssgn == tsgn)
 		while(it>t && is>s)
-			if(b = *--it - *--is)
+			if((b = *--it - *--is) && notcase(b))
 				a = b;
 	while(is > s)
 		if(*--is != '0')
@@ -315,7 +321,7 @@
 		t++;
 	if(ssgn == tsgn)
 		while(isdigit(*s) && isdigit(*t))
-			if(a = *t++ - *s++)
+			if((a = *t++ - *s++) && notcase(a))
 				return sgn(a)*ssgn;
 	while(isdigit(*s))
 		if(*s++ != '0')
@@ -342,5 +348,22 @@
 		*rp++ = c;
 	}
 	fprint(2, "Look: word too long.  Bailing out.\n");
+	return 0;
+}
+
+int
+isdigit(Rune r)
+{
+	int v;
+
+	v = base;
+	if(L'0'<=r && r<=L'9')
+		v = r - L'0';
+	else if(L'a'<=r && r<=L'z')
+		v = r - L'a' + 10;
+	else if(L'A'<=r && r<=L'Z')
+		v = r - L'A' + 10;
+	if(v < base)
+		return 1;
 	return 0;
 }