shithub: drawterm

Download patch

ref: 91d5706eb0db886724e5635c97d1a3be09ca29be
parent: 0fbac08cd028f95c5f5e99e3f3dfd27a2f2858ab
author: cinap_lenrek <[email protected]>
date: Sun Dec 31 06:38:01 EST 2017

libc: update various libc functions (from 9front)

--- a/libc/cleanname.c
+++ b/libc/cleanname.c
@@ -9,9 +9,10 @@
 cleanname(char *name)
 {
 	char *p, *q, *dotdot;
-	int rooted;
+	int rooted, erasedprefix;
 
 	rooted = name[0] == '/';
+	erasedprefix = 0;
 
 	/*
 	 * invariants:
@@ -24,9 +25,11 @@
 	while(*p) {
 		if(p[0] == '/')	/* null element */
 			p++;
-		else if(p[0] == '.' && SEP(p[1]))
+		else if(p[0] == '.' && SEP(p[1])) {
+			if(p == name)
+				erasedprefix = 1;
 			p += 1;	/* don't count the separator in case it is nul */
-		else if(p[0] == '.' && p[1] == '.' && SEP(p[2])) {
+		} else if(p[0] == '.' && p[1] == '.' && SEP(p[2])) {
 			p += 2;
 			if(q > dotdot) {	/* can backtrack */
 				while(--q > dotdot && *q != '/')
@@ -38,6 +41,8 @@
 				*q++ = '.';
 				dotdot = q;
 			}
+			if(q == name)
+				erasedprefix = 1;	/* erased entire path via dotdot */
 		} else {	/* real path element */
 			if(q != name+rooted)
 				*q++ = '/';
@@ -48,5 +53,11 @@
 	if(q == name)	/* empty string is really ``.'' */
 		*q++ = '.';
 	*q = '\0';
+	if(erasedprefix && name[0] == '#'){
+		/* this was not a #x device path originally - make it not one now */
+		memmove(name+2, name, strlen(name)+1);
+		name[0] = '.';
+		name[1] = '/';
+	}
 	return name;
 }
--- a/libc/crypt.c
+++ b/libc/crypt.c
@@ -9,7 +9,6 @@
  */
 #include <u.h>
 #include <libc.h>
-#include <auth.h>
 #include <libsec.h>
 
 /*
--- a/libc/nrand.c
+++ b/libc/nrand.c
@@ -10,6 +10,9 @@
 
 	if(n < 0)
 		return n;
+	if(n == 1)
+		return 0;
+	/* and if n == 0, you deserve what you get */
 	slop = MASK % n;
 	do
 		v = lrand();
--- a/libc/rune.c
+++ b/libc/rune.c
@@ -1,24 +1,29 @@
 #include	<u.h>
 #include	<libc.h>
 
-#define Bit(i) (7-(i))
-/* N 0's preceded by i 1's, T(Bit(2)) is 1100 0000 */
-#define T(i) (((1 << (Bit(i)+1))-1) ^ 0xFF)
-/* 0000 0000 0000 0111 1111 1111 */
-#define	RuneX(i) ((1 << (Bit(i) + ((i)-1)*Bitx))-1)
-
 enum
 {
-	Bitx	= Bit(1),
+	Bit1	= 7,
+	Bitx	= 6,
+	Bit2	= 5,
+	Bit3	= 4,
+	Bit4	= 3,
+	Bit5	= 2,
 
-	Tx	= T(1),			/* 1000 0000 */
-	Rune1 = (1<<(Bit(0)+0*Bitx))-1,	/* 0000 0000 0000 0000 0111 1111 */
+	T1	= ((1<<(Bit1+1))-1) ^ 0xFF,	/* 0000 0000 */
+	Tx	= ((1<<(Bitx+1))-1) ^ 0xFF,	/* 1000 0000 */
+	T2	= ((1<<(Bit2+1))-1) ^ 0xFF,	/* 1100 0000 */
+	T3	= ((1<<(Bit3+1))-1) ^ 0xFF,	/* 1110 0000 */
+	T4	= ((1<<(Bit4+1))-1) ^ 0xFF,	/* 1111 0000 */
+	T5	= ((1<<(Bit5+1))-1) ^ 0xFF,	/* 1111 1000 */
 
-	Maskx	= (1<<Bitx)-1,		/* 0011 1111 */
-	Testx	= Maskx ^ 0xFF,		/* 1100 0000 */
+	Rune1	= (1<<(Bit1+0*Bitx))-1,		/* 0000 0000 0000 0000 0111 1111 */
+	Rune2	= (1<<(Bit2+1*Bitx))-1,		/* 0000 0000 0000 0111 1111 1111 */
+	Rune3	= (1<<(Bit3+2*Bitx))-1,		/* 0000 0000 1111 1111 1111 1111 */
+	Rune4	= (1<<(Bit4+3*Bitx))-1,		/* 0011 1111 1111 1111 1111 1111 */
 
-	SurrogateMin	= 0xD800,
-	SurrogateMax	= 0xDFFF,
+	Maskx	= (1<<Bitx)-1,			/* 0011 1111 */
+	Testx	= Maskx ^ 0xFF,			/* 1100 0000 */
 
 	Bad	= Runeerror,
 };
@@ -26,41 +31,67 @@
 int
 chartorune(Rune *rune, char *str)
 {
-	int c[UTFmax], i;
-	Rune l;
+	int c, c1, c2, c3;
+	long l;
 
 	/*
-	 * N character sequence
+	 * one character sequence
 	 *	00000-0007F => T1
-	 *	00080-007FF => T2 Tx
-	 *	00800-0FFFF => T3 Tx Tx
-	 *	10000-10FFFF => T4 Tx Tx Tx
 	 */
-
-	c[0] = *(uchar*)(str);
-	if(c[0] < Tx){
-		*rune = c[0];
+	c = *(uchar*)str;
+	if(c < Tx) {
+		*rune = c;
 		return 1;
 	}
-	l = c[0];
 
-	for(i = 1; i < UTFmax; i++) {
-		c[i] = *(uchar*)(str+i);
-		c[i] ^= Tx;
-		if(c[i] & Testx)
+	/*
+	 * two character sequence
+	 *	0080-07FF => T2 Tx
+	 */
+	c1 = *(uchar*)(str+1) ^ Tx;
+	if(c1 & Testx)
+		goto bad;
+	if(c < T3) {
+		if(c < T2)
 			goto bad;
-		l = (l << Bitx) | c[i];
-		if(c[0] < T(i + 2)) {
-			l &= RuneX(i + 1);
-			if(i == 1) {
-				if(c[0] < T(2) || l <= Rune1)
-					goto bad;
-			} else if(l <= RuneX(i) || l > Runemax)
+		l = ((c << Bitx) | c1) & Rune2;
+		if(l <= Rune1)
+			goto bad;
+		*rune = l;
+		return 2;
+	}
+
+	/*
+	 * three character sequence
+	 *	0800-FFFF => T3 Tx Tx
+	 */
+	c2 = *(uchar*)(str+2) ^ Tx;
+	if(c2 & Testx)
+		goto bad;
+	if(c < T4) {
+		l = ((((c << Bitx) | c1) << Bitx) | c2) & Rune3;
+		if(l <= Rune2)
+			goto bad;
+		*rune = l;
+		return 3;
+	}
+
+ 	/*
+	 * four character sequence
+	 *	10000-10FFFF => T4 Tx Tx Tx
+	 */
+	if(UTFmax >= 4) {
+		c3 = *(uchar*)(str+3) ^ Tx;
+		if(c3 & Testx)
+			goto bad;
+		if(c < T5) {
+			l = ((((((c << Bitx) | c1) << Bitx) | c2) << Bitx) | c3) & Rune4;
+			if(l <= Rune3)
 				goto bad;
-			if (i == 2 && SurrogateMin <= l && l <= SurrogateMax)
+			if(l > Runemax)
 				goto bad;
 			*rune = l;
-			return i + 1;
+			return 4;
 		}
 	}
 
@@ -75,10 +106,16 @@
 int
 runetochar(char *str, Rune *rune)
 {
-	int i, j;
-	Rune c;
+	long c;
 
 	c = *rune;
+	if(c > Runemax)
+		c = Runeerror;
+
+	/*
+	 * one character sequence
+	 *	00000-0007F => 00-7F
+	 */
 	if(c <= Rune1) {
 		str[0] = c;
 		return 1;
@@ -85,35 +122,35 @@
 	}
 
 	/*
-	 * one character sequence
-	 *	00000-0007F => 00-7F
 	 * two character sequence
 	 *	0080-07FF => T2 Tx
+	 */
+	if(c <= Rune2) {
+		str[0] = T2 | (c >> 1*Bitx);
+		str[1] = Tx | (c & Maskx);
+		return 2;
+	}
+
+	/*
 	 * three character sequence
 	 *	0800-FFFF => T3 Tx Tx
-	 * four character sequence (21-bit value)
-	 *     10000-1FFFFF => T4 Tx Tx Tx
-	 * If the Rune is out of range or a surrogate half,
-	 * convert it to the error rune.
-	 * Do this test when i==3 because the error rune encodes to three bytes.
-	 * Doing it earlier would duplicate work, since an out of range
-	 * Rune wouldn't have fit in one or two bytes.
 	 */
-	for(i = 2; i < UTFmax + 1; i++){
-		if(i == 3){
-			if(c > Runemax)
-				c = Runeerror;
-			if(SurrogateMin <= c && c <= SurrogateMax)
-				c = Runeerror;
-		}
-		if (c <= RuneX(i) || i == UTFmax ) {
-			str[0] = T(i) |  (c >> (i - 1)*Bitx);
-			for(j = 1; j < i; j++)
-				str[j] = Tx | ((c >> (i - j - 1)*Bitx) & Maskx);
-			return i;
-		}
+	if(c <= Rune3) {
+		str[0] = T3 |  (c >> 2*Bitx);
+		str[1] = Tx | ((c >> 1*Bitx) & Maskx);
+		str[2] = Tx |  (c & Maskx);
+		return 3;
 	}
-	return UTFmax;
+
+	/*
+	 * four character sequence
+	 *	10000-1FFFFF => T4 Tx Tx Tx
+	 */
+	str[0] = T4 |  (c >> 3*Bitx);
+	str[1] = Tx | ((c >> 2*Bitx) & Maskx);
+	str[2] = Tx | ((c >> 1*Bitx) & Maskx);
+	str[3] = Tx |  (c & Maskx);
+	return 4;
 }
 
 int
@@ -120,7 +157,7 @@
 runelen(long c)
 {
 	Rune rune;
-	char str[10];
+	char str[UTFmax];
 
 	rune = c;
 	return runetochar(str, &rune);
@@ -129,21 +166,21 @@
 int
 runenlen(Rune *r, int nrune)
 {
-	int nb, i;
-	Rune c;
+	int nb, c;
 
 	nb = 0;
 	while(nrune--) {
 		c = *r++;
-		if(c <= Rune1){
+		if(c <= Rune1)
 			nb++;
-		} else {
-			for(i = 2; i < UTFmax + 1; i++)
-				if(c <= RuneX(i) || i == UTFmax){
-					nb += i;
-					break;
-				}
-		}
+		else
+		if(c <= Rune2)
+			nb += 2;
+		else
+		if(c <= Rune3 || c > Runemax)
+			nb += 3;
+		else
+			nb += 4;
 	}
 	return nb;
 }
@@ -151,8 +188,7 @@
 int
 fullrune(char *str, int n)
 {
-	int  i;
-	Rune c;
+	int c;
 
 	if(n <= 0)
 		return 0;
@@ -159,8 +195,10 @@
 	c = *(uchar*)str;
 	if(c < Tx)
 		return 1;
-	for(i = 3; i < UTFmax + 1; i++)
-		if(c < T(i))
-			return n >= i - 1;
-	return n >= UTFmax;
+	if(c < T3)
+		return n >= 2;
+	if(UTFmax == 3 || c < T4)
+		return n >= 3;
+	return n >= 4;
 }
+
--- a/libc/runestrdup.c
+++ b/libc/runestrdup.c
@@ -2,13 +2,13 @@
 #include <libc.h>
 
 Rune*
-runestrdup(Rune *s) 
-{  
+runestrdup(Rune *s)
+{
 	Rune *ns;
 
 	ns = malloc(sizeof(Rune)*(runestrlen(s) + 1));
 	if(ns == 0)
 		return 0;
-
+	setmalloctag(ns, getcallerpc(&s));
 	return runestrcpy(ns, s);
 }
--- a/libc/runestrecpy.c
+++ b/libc/runestrecpy.c
@@ -9,9 +9,9 @@
 
 	while(*s1++ = *s2++){
 		if(s1 == es1){
-			*--s1 = '\0';
+			s1[-1] = '\0';
 			break;
 		}
 	}
-	return s1;
+	return s1-1;
 }
--- a/libc/runetype.c
+++ b/libc/runetype.c
@@ -211,9 +211,14 @@
 {
 	0x0009,	0x000a,	/* tab and newline */
 	0x0020,	0x0020,	/* space */
+	0x0085, 0x0085,
 	0x00a0,	0x00a0,	/*   */
+	0x1680, 0x1680,
+	0x180e, 0x180e,
 	0x2000,	0x200b,	/*   - ​ */
 	0x2028,	0x2029,	/* 
 - 
 */
+	0x202f, 0x202f,
+	0x205f, 0x205f,
 	0x3000,	0x3000,	/*   */
 	0xfeff,	0xfeff,	/*  */
 };
@@ -611,6 +616,34 @@
 	0x1ff3, 509,	/* ῳ ῼ */
 };
 
+static Rune __isdigitr[] = {
+	0x0030, 0x0039,
+	0x0660, 0x0669,
+	0x06f0, 0x06f9,
+	0x07c0, 0x07c9,
+	0x0966, 0x096f,
+	0x09e6, 0x09ef,
+	0x0a66, 0x0a6f,
+	0x0ae6, 0x0aef,
+	0x0b66, 0x0b6f,
+	0x0be6, 0x0bef,
+	0x0c66, 0x0c6f,
+	0x0ce6, 0x0cef,
+	0x0d66, 0x0d6f,
+	0x0e50, 0x0e59,
+	0x0ed0, 0x0ed9,
+	0x0f20, 0x0f29,
+	0x1040, 0x1049,
+	0x17e0, 0x17e9,
+	0x1810, 0x1819,
+	0x1946, 0x194f,
+	0x19d0, 0x19d9,
+	0x1b50, 0x1b59,
+	0xff10, 0xff19,
+	0x104a0, 0x104a9,
+	0x1d7ce, 0x1d7ff,
+};
+
 /*
  * upper case ranges
  *	3rd col is conversion excess 500
@@ -1132,6 +1165,17 @@
 	Rune *p;
 
 	p = bsearch(c, _space2, nelem(_space2)/2, 2);
+	if(p && c >= p[0] && c <= p[1])
+		return 1;
+	return 0;
+}
+
+int
+isdigitrune(Rune c)
+{
+	Rune *p;
+
+	p = bsearch(c, __isdigitr, nelem(__isdigitr)/2, 2);
 	if(p && c >= p[0] && c <= p[1])
 		return 1;
 	return 0;
--- a/libc/utfecpy.c
+++ b/libc/utfecpy.c
@@ -10,7 +10,7 @@
 		return to;
 	end = memccpy(to, from, '\0', e - to);
 	if(end == nil){
-		end = e-1;
+		end = e;
 		while(end>to && (*--end&0xC0)==0x80)
 			;
 		*end = '\0';