Browse Source

Plan 9 from Bell Labs 2013-05-21

David du Colombier 11 years ago
parent
commit
b377a116d1
4 changed files with 121 additions and 45 deletions
  1. 1 0
      sys/games/lib/fortunes
  2. 8 1
      sys/man/1/xd
  3. 2 2
      sys/src/cmd/sort.c
  4. 110 42
      sys/src/cmd/xd.c

+ 1 - 0
sys/games/lib/fortunes

@@ -4310,3 +4310,4 @@ If it is good information which comes from nowhere it is all right but this is w
 I fixed their fix and it does work.  - forsyth
 To maintain backward compatibility, the relationships between the many options are quite complex.  - ls(1) OS X Manual Page
 qemu: could not open serial device 'dev': Success
+DSM Terminator [ ABORT ] Finished [ 0 request(s) + 0 call(s) distributed in 5ms]

+ 8 - 1
sys/man/1/xd

@@ -58,7 +58,7 @@ Decimal.
 .PD
 .PP
 Other options are
-.TP \w'\fL-a\fIstyle\fLXX'u
+.TP \w'\fL-a\fIstyle\fLX'u
 .B -c
 Format as
 .B 1x
@@ -66,6 +66,13 @@ but print
 .SM ASCII
 representations or C escape sequences where possible.
 .TP
+.B -R
+Format as
+.B 1x
+but print
+.B Rune
+representations or C escape sequences where possible.
+.TP
 .BI -a style
 Print file addresses in the given style (and size 4).
 .TP

+ 2 - 2
sys/src/cmd/sort.c

@@ -71,7 +71,7 @@ struct	Field
 	int	end2;
 
 	long	flags;
-	uchar	mapto[1+0xffff];	/* this is not Runemax to keep this table small */
+	uchar	mapto[1+255];
 
 	void	(*dokey)(Key*, uchar*, uchar*, Field*);
 };
@@ -1292,7 +1292,7 @@ dokey_dfi(Key *k, uchar *lp, uchar *lpe, Field *f)
 		/*
 		 * for characters out of range,
 		 * the table does not do Rflag.
-		 * ignore is based on mapto[nelem(f->mapto)]
+		 * ignore is based on mapto[nelem(f->mapto)-1]
 		 */
 		if(c != 0 && c < nelem(f->mapto)) {
 			c = f->mapto[c];

+ 110 - 42
sys/src/cmd/xd.c

@@ -2,10 +2,11 @@
 #include <libc.h>
 #include <bio.h>
 
-unsigned char	odata[16];
-unsigned char	data[16];
+uchar		odata[16];
+uchar		data[32];
 int		ndata;
-unsigned long	addr;
+int		nread;
+ulong		addr;
 int		repeats;
 int		swizzle;
 int		flush;
@@ -14,13 +15,17 @@ int		xd(char *, int);
 void		xprint(char *, ...);
 void		initarg(void), swizz(void);
 enum{
-	Narg=10
+	Narg=10,
+
+	TNone=0,
+	TAscii,
+	TRune,
 };
 typedef struct Arg Arg;
 typedef void fmtfn(char *);
 struct Arg
 {
-	int	ascii;		/* 0==none, 1==ascii */
+	int	chartype;		/* TNone, TAscii, TRunes */
 	int	loglen;		/* 0==1, 1==2, 2==4, 3==8 */
 	int	base;		/* 0==8, 1==10, 2==16 */
 	fmtfn	*fn;		/* function to call with data */
@@ -29,7 +34,7 @@ struct Arg
 }arg[Narg];
 int	narg;
 
-fmtfn	fmt0, fmt1, fmt2, fmt3, fmtc;
+fmtfn	fmt0, fmt1, fmt2, fmt3, fmtc, fmtr;
 fmtfn *fmt[4] = {
 	fmt0,
 	fmt1,
@@ -50,6 +55,10 @@ char *cfmt[3][3] = {
 	" %.3uo",	" %.3ud",	" %.2ux",
 };
 
+char *rfmt[1][1] = {
+	" %2.2C",
+};
+
 char *afmt[2][3] = {
 	"%.7luo ",	"%.7lud ",	"%.7lux ",
 	"%7luo ",	"%7lud ",	"%7lux ",
@@ -113,7 +122,13 @@ main(int argc, char *argv[])
 		while(argv[0][0]){
 			switch(argv[0][0]){
 			case 'c':
-				ap->ascii = 1;
+				ap->chartype = TAscii;
+				ap->loglen = 0;
+				if(argv[0][1] || argv[0][-1]!='-')
+					goto Usage;
+				break;
+			case 'R':
+				ap->chartype = TRune;
 				ap->loglen = 0;
 				if(argv[0][1] || argv[0][-1]!='-')
 					goto Usage;
@@ -150,7 +165,9 @@ main(int argc, char *argv[])
 			}
 			argv[0]++;
 		}
-		if(ap->ascii)
+		if(ap->chartype == TRune)
+			ap->fn = fmtr;
+		else if(ap->chartype == TAscii)
 			ap->fn = fmtc;
 		else
 			ap->fn = fmt[ap->loglen];
@@ -178,7 +195,7 @@ initarg(void)
 		fprint(2, "xd: too many formats (max %d)\n", Narg);
 		exits("usage");
 	}
-	ap->ascii = 0;
+	ap->chartype = TNone;
 	ap->loglen = 2;
 	ap->base = 2;
 	ap->fn = fmt2;
@@ -190,7 +207,7 @@ int
 xd(char *name, int title)
 {
 	int fd;
-	int i, star;
+	int i, star, nsee, nleft;
 	Arg *ap;
 	Biobuf *bp;
 
@@ -209,19 +226,27 @@ xd(char *name, int title)
 		xprint("%s\n", name);
 	addr = 0;
 	star = 0;
-	while((ndata=Bread(bp, data, 16)) >= 0){
-		if(ndata < 16)
-			for(i=ndata; i<16; i++)
+	nsee = 16;
+	nleft = 0;
+	/* read 32 but see only 16 so that runes are happy */
+	while((ndata=Bread(bp, data + nleft, 32 - nleft)) >= 0){
+		ndata += nleft;
+		nleft = 0;
+		nread = ndata;
+		if(ndata>nsee)
+			ndata = nsee;
+		else if(ndata<nsee)
+			for(i=ndata; i<nsee; i++)
 				data[i] = 0;
 		if(swizzle)
 			swizz();
-		if(ndata==16 && repeats){
+		if(ndata==nsee && repeats){
 			if(addr>0 && data[0]==odata[0]){
-				for(i=1; i<16; i++)
+				for(i=1; i<nsee; i++)
 					if(data[i] != odata[i])
 						break;
-				if(i == 16){
-					addr += 16;
+				if(i == nsee){
+					addr += nsee;
 					if(star == 0){
 						star++;
 						xprint("*\n", 0);
@@ -229,7 +254,7 @@ xd(char *name, int title)
 					continue;
 				}
 			}
-			for(i=0; i<16; i++)
+			for(i=0; i<nsee; i++)
 				odata[i] = data[i];
 			star = 0;
 		}
@@ -241,13 +266,17 @@ xd(char *name, int title)
 				Bflush(&bout);
 		}
 		addr += ndata;
-		if(ndata<16){
+		if(ndata<nsee){
 			xprint(afmt[0][abase], addr);
 			xprint("\n", 0);
 			if(flush)
 				Bflush(&bout);
 			break;
 		}
+		if(nread>nsee){
+			nleft = nread - nsee;
+			memmove(data, data + nsee, nleft);
+		}
 	}
 	Bterm(bp);
 	return 0;
@@ -288,7 +317,7 @@ void
 fmt1(char *f)
 {
 	int i;
-	for(i=0; i<ndata; i+=sizeof(unsigned short))
+	for(i=0; i<ndata; i+=sizeof(ushort))
 		xprint(f, (data[i]<<8)|data[i+1]);
 }
 
@@ -296,7 +325,7 @@ void
 fmt2(char *f)
 {
 	int i;
-	for(i=0; i<ndata; i+=sizeof(unsigned long))
+	for(i=0; i<ndata; i+=sizeof(ulong))
 		xprint(f, (data[i]<<24)|(data[i+1]<<16)|(data[i+2]<<8)|data[i+3]);
 }
 
@@ -304,8 +333,9 @@ void
 fmt3(char *f)
 {
 	int i;
-	unsigned long long v;
-	for(i=0; i<ndata; i+=sizeof(unsigned long long)){
+	uvlong v;
+
+	for(i=0; i<ndata; i+=sizeof(uvlong)){
 		v = (data[i]<<24)|(data[i+1]<<16)|(data[i+2]<<8)|data[i+3];
 		v <<= 32;
 		v |= (data[i+4]<<24)|(data[i+1+4]<<16)|(data[i+2+4]<<8)|data[i+3+4];
@@ -316,6 +346,31 @@ fmt3(char *f)
 	}
 }
 
+void
+onefmtc(uchar c)
+{
+	switch(c){
+	case '\t':
+		xprint(cfmt[1][2], "\\t");
+		break;
+	case '\r':
+		xprint(cfmt[1][2], "\\r");
+		break;
+	case '\n':
+		xprint(cfmt[1][2], "\\n");
+		break;
+	case '\b':
+		xprint(cfmt[1][2], "\\b");
+		break;
+	default:
+		if(c>=0x7F || ' '>c)
+			xprint(cfmt[2][2], c);
+		else
+			xprint(cfmt[0][2], c);
+		break;
+	}
+}
+
 void
 fmtc(char *f)
 {
@@ -323,26 +378,39 @@ fmtc(char *f)
 
 	USED(f);
 	for(i=0; i<ndata; i++)
-		switch(data[i]){
-		case '\t':
-			xprint(cfmt[1][2], "\\t");
-			break;
-		case '\r':
-			xprint(cfmt[1][2], "\\r");
-			break;
-		case '\n':
-			xprint(cfmt[1][2], "\\n");
-			break;
-		case '\b':
-			xprint(cfmt[1][2], "\\b");
-			break;
-		default:
-			if(data[i]>=0x7F || ' '>data[i])
-				xprint(cfmt[2][2], data[i]);
-			else
-				xprint(cfmt[0][2], data[i]);
-			break;
+		onefmtc(data[i]);
+}
+
+void
+fmtr(char *f)
+{
+	int i, w, cw;
+	Rune r;
+	static int nstart;
+
+	USED(f);
+	if(nstart)	
+		xprint("%*c", 3*nstart, ' ');
+	for(i=nstart; i<ndata; )
+		if(data[i] < Runeself)
+			onefmtc(data[i++]);
+		else{
+			w = chartorune(&r, (char *)data+i);
+			if(w == 1 || i + w>nread)
+				onefmtc(data[i++]);
+			else{
+				cw = w;
+				if(i + w>ndata)
+					cw = ndata - i;
+				xprint(rfmt[0][0], r);	
+				xprint("%*c", 3*cw-3, ' ');
+				i += w;
+			}
 		}
+	if(i > ndata)
+		nstart = i - ndata;
+	else
+		nstart = 0;
 }
 
 void