History

libc: update various libc functions (from 9front)

cinap_lenrek committed 8 years ago

Commit 91d57061 parent 0fbac088 files · +187 −92Browse files

Unified · Split

8 files
  1. libc/cleanname.c +14 −3
  2. libc/crypt.c +0 −1
  3. libc/nrand.c +3 −0
  4. libc/rune.c +120 −82
  5. libc/runestrdup.c +3 −3
  6. libc/runestrecpy.c +2 −2
  7. libc/runetype.c +44 −0
  8. libc/utfecpy.c +1 −1
libc/cleanname.c+14−3
@@ -9,9 +9,10 @@ char* · 8 unmodified lines
99 cleanname(char *name)
1010 {
1111 char *p, *q, *dotdot;
12− int rooted;
12+ int rooted, erasedprefix;
1313
1414 rooted = name[0] == '/';
15+ erasedprefix = 0;
1516
1617 /*
1718 * invariants:
@@ -24,9 +25,11 @@ cleanname(char *name) · 6 unmodified lines
2425 while(*p) {
2526 if(p[0] == '/') /* null element */
2627 p++;
27− else if(p[0] == '.' && SEP(p[1]))
28+ else if(p[0] == '.' && SEP(p[1])) {
29+ if(p == name)
30+ erasedprefix = 1;
2831 p += 1; /* don't count the separator in case it is nul */
29− else if(p[0] == '.' && p[1] == '.' && SEP(p[2])) {
32+ } else if(p[0] == '.' && p[1] == '.' && SEP(p[2])) {
3033 p += 2;
3134 if(q > dotdot) { /* can backtrack */
3235 while(--q > dotdot && *q != '/')
@@ -38,6 +41,8 @@ cleanname(char *name) · 5 unmodified lines
3841 *q++ = '.';
3942 dotdot = q;
4043 }
44+ if(q == name)
45+ erasedprefix = 1; /* erased entire path via dotdot */
4146 } else { /* real path element */
4247 if(q != name+rooted)
4348 *q++ = '/';
@@ -48,5 +53,11 @@ cleanname(char *name) · 4 unmodified lines
4853 if(q == name) /* empty string is really ``.'' */
4954 *q++ = '.';
5055 *q = '\0';
56+ if(erasedprefix && name[0] == '#'){
57+ /* this was not a #x device path originally - make it not one now */
58+ memmove(name+2, name, strlen(name)+1);
59+ name[0] = '.';
60+ name[1] = '/';
61+ }
5162 return name;
5263 }
libc/crypt.c+0−1
@@ -9,7 +9,6 @@ · 8 unmodified lines
99 */
1010 #include <u.h>
1111 #include <libc.h>
12−#include <auth.h>
1312 #include <libsec.h>
1413
1514 /*
libc/nrand.c+3−0
@@ -10,6 +10,9 @@ nrand(int n) · 9 unmodified lines
1010
1111 if(n < 0)
1212 return n;
13+ if(n == 1)
14+ return 0;
15+ /* and if n == 0, you deserve what you get */
1316 slop = MASK % n;
1417 do
1518 v = lrand();
libc/rune.c+120−82
@@ -1,24 +1,29 @@
11 #include <u.h>
22 #include <libc.h>
33
4−#define Bit(i) (7-(i))
5−/* N 0's preceded by i 1's, T(Bit(2)) is 1100 0000 */
6−#define T(i) (((1 << (Bit(i)+1))-1) ^ 0xFF)
7−/* 0000 0000 0000 0111 1111 1111 */
8−#define RuneX(i) ((1 << (Bit(i) + ((i)-1)*Bitx))-1)
9−
104 enum
115 {
12− Bitx = Bit(1),
13−
14− Tx = T(1), /* 1000 0000 */
15− Rune1 = (1<<(Bit(0)+0*Bitx))-1, /* 0000 0000 0000 0000 0111 1111 */
16−
17− Maskx = (1<<Bitx)-1, /* 0011 1111 */
18− Testx = Maskx ^ 0xFF, /* 1100 0000 */
19−
20− SurrogateMin = 0xD800,
21− SurrogateMax = 0xDFFF,
6+ Bit1 = 7,
7+ Bitx = 6,
8+ Bit2 = 5,
9+ Bit3 = 4,
10+ Bit4 = 3,
11+ Bit5 = 2,
12+
13+ T1 = ((1<<(Bit1+1))-1) ^ 0xFF, /* 0000 0000 */
14+ Tx = ((1<<(Bitx+1))-1) ^ 0xFF, /* 1000 0000 */
15+ T2 = ((1<<(Bit2+1))-1) ^ 0xFF, /* 1100 0000 */
16+ T3 = ((1<<(Bit3+1))-1) ^ 0xFF, /* 1110 0000 */
17+ T4 = ((1<<(Bit4+1))-1) ^ 0xFF, /* 1111 0000 */
18+ T5 = ((1<<(Bit5+1))-1) ^ 0xFF, /* 1111 1000 */
19+
20+ Rune1 = (1<<(Bit1+0*Bitx))-1, /* 0000 0000 0000 0000 0111 1111 */
21+ Rune2 = (1<<(Bit2+1*Bitx))-1, /* 0000 0000 0000 0111 1111 1111 */
22+ Rune3 = (1<<(Bit3+2*Bitx))-1, /* 0000 0000 1111 1111 1111 1111 */
23+ Rune4 = (1<<(Bit4+3*Bitx))-1, /* 0011 1111 1111 1111 1111 1111 */
24+
25+ Maskx = (1<<Bitx)-1, /* 0011 1111 */
26+ Testx = Maskx ^ 0xFF, /* 1100 0000 */
2227
2328 Bad = Runeerror,
2429 };
@@ -26,41 +31,67 @@ enum · 1 unmodified line
2631 int
2732 chartorune(Rune *rune, char *str)
2833 {
29− int c[UTFmax], i;
30− Rune l;
34+ int c, c1, c2, c3;
35+ long l;
3136
3237 /*
33− * N character sequence
38+ * one character sequence
3439 * 00000-0007F => T1
35− * 00080-007FF => T2 Tx
36− * 00800-0FFFF => T3 Tx Tx
37− * 10000-10FFFF => T4 Tx Tx Tx
3840 */
39−
40− c[0] = *(uchar*)(str);
41− if(c[0] < Tx){
42− *rune = c[0];
41+ c = *(uchar*)str;
42+ if(c < Tx) {
43+ *rune = c;
4344 return 1;
4445 }
45− l = c[0];
4646
47− for(i = 1; i < UTFmax; i++) {
48− c[i] = *(uchar*)(str+i);
49− c[i] ^= Tx;
50− if(c[i] & Testx)
47+ /*
48+ * two character sequence
49+ * 0080-07FF => T2 Tx
50+ */
51+ c1 = *(uchar*)(str+1) ^ Tx;
52+ if(c1 & Testx)
53+ goto bad;
54+ if(c < T3) {
55+ if(c < T2)
56+ goto bad;
57+ l = ((c << Bitx) | c1) & Rune2;
58+ if(l <= Rune1)
59+ goto bad;
60+ *rune = l;
61+ return 2;
62+ }
63+
64+ /*
65+ * three character sequence
66+ * 0800-FFFF => T3 Tx Tx
67+ */
68+ c2 = *(uchar*)(str+2) ^ Tx;
69+ if(c2 & Testx)
70+ goto bad;
71+ if(c < T4) {
72+ l = ((((c << Bitx) | c1) << Bitx) | c2) & Rune3;
73+ if(l <= Rune2)
5174 goto bad;
52− l = (l << Bitx) | c[i];
53− if(c[0] < T(i + 2)) {
54− l &= RuneX(i + 1);
55− if(i == 1) {
56− if(c[0] < T(2) || l <= Rune1)
57− goto bad;
58− } else if(l <= RuneX(i) || l > Runemax)
75+ *rune = l;
76+ return 3;
77+ }
78+
79+ /*
80+ * four character sequence
81+ * 10000-10FFFF => T4 Tx Tx Tx
82+ */
83+ if(UTFmax >= 4) {
84+ c3 = *(uchar*)(str+3) ^ Tx;
85+ if(c3 & Testx)
86+ goto bad;
87+ if(c < T5) {
88+ l = ((((((c << Bitx) | c1) << Bitx) | c2) << Bitx) | c3) & Rune4;
89+ if(l <= Rune3)
5990 goto bad;
60− if (i == 2 && SurrogateMin <= l && l <= SurrogateMax)
91+ if(l > Runemax)
6192 goto bad;
6293 *rune = l;
63− return i + 1;
94+ return 4;
6495 }
6596 }
6697
@@ -75,52 +106,58 @@ bad: · 8 unmodified lines
75106 int
76107 runetochar(char *str, Rune *rune)
77108 {
78− int i, j;
79− Rune c;
109+ long c;
80110
81111 c = *rune;
112+ if(c > Runemax)
113+ c = Runeerror;
114+
115+ /*
116+ * one character sequence
117+ * 00000-0007F => 00-7F
118+ */
82119 if(c <= Rune1) {
83120 str[0] = c;
84121 return 1;
85122 }
86123
87124 /*
88− * one character sequence
89− * 00000-0007F => 00-7F
90125 * two character sequence
91126 * 0080-07FF => T2 Tx
127+ */
128+ if(c <= Rune2) {
129+ str[0] = T2 | (c >> 1*Bitx);
130+ str[1] = Tx | (c & Maskx);
131+ return 2;
132+ }
133+
134+ /*
92135 * three character sequence
93136 * 0800-FFFF => T3 Tx Tx
94− * four character sequence (21-bit value)
95− * 10000-1FFFFF => T4 Tx Tx Tx
96− * If the Rune is out of range or a surrogate half,
97− * convert it to the error rune.
98− * Do this test when i==3 because the error rune encodes to three bytes.
99− * Doing it earlier would duplicate work, since an out of range
100− * Rune wouldn't have fit in one or two bytes.
101137 */
102− for(i = 2; i < UTFmax + 1; i++){
103− if(i == 3){
104− if(c > Runemax)
105− c = Runeerror;
106− if(SurrogateMin <= c && c <= SurrogateMax)
107− c = Runeerror;
108− }
109− if (c <= RuneX(i) || i == UTFmax ) {
110− str[0] = T(i) | (c >> (i - 1)*Bitx);
111− for(j = 1; j < i; j++)
112− str[j] = Tx | ((c >> (i - j - 1)*Bitx) & Maskx);
113− return i;
114− }
138+ if(c <= Rune3) {
139+ str[0] = T3 | (c >> 2*Bitx);
140+ str[1] = Tx | ((c >> 1*Bitx) & Maskx);
141+ str[2] = Tx | (c & Maskx);
142+ return 3;
115143 }
116− return UTFmax;
144+
145+ /*
146+ * four character sequence
147+ * 10000-1FFFFF => T4 Tx Tx Tx
148+ */
149+ str[0] = T4 | (c >> 3*Bitx);
150+ str[1] = Tx | ((c >> 2*Bitx) & Maskx);
151+ str[2] = Tx | ((c >> 1*Bitx) & Maskx);
152+ str[3] = Tx | (c & Maskx);
153+ return 4;
117154 }
118155
119156 int
120157 runelen(long c)
121158 {
122159 Rune rune;
123− char str[10];
160+ char str[UTFmax];
124161
125162 rune = c;
126163 return runetochar(str, &rune);
@@ -129,21 +166,21 @@ runelen(long c) · 2 unmodified lines
129166 int
130167 runenlen(Rune *r, int nrune)
131168 {
132− int nb, i;
133− Rune c;
169+ int nb, c;
134170
135171 nb = 0;
136172 while(nrune--) {
137173 c = *r++;
138− if(c <= Rune1){
174+ if(c <= Rune1)
139175 nb++;
140− } else {
141− for(i = 2; i < UTFmax + 1; i++)
142− if(c <= RuneX(i) || i == UTFmax){
143− nb += i;
144− break;
145− }
146− }
176+ else
177+ if(c <= Rune2)
178+ nb += 2;
179+ else
180+ if(c <= Rune3 || c > Runemax)
181+ nb += 3;
182+ else
183+ nb += 4;
147184 }
148185 return nb;
149186 }
@@ -151,16 +188,17 @@ runenlen(Rune *r, int nrune) · 1 unmodified line
151188 int
152189 fullrune(char *str, int n)
153190 {
154− int i;
155− Rune c;
191+ int c;
156192
157193 if(n <= 0)
158194 return 0;
159195 c = *(uchar*)str;
160196 if(c < Tx)
161197 return 1;
162− for(i = 3; i < UTFmax + 1; i++)
163− if(c < T(i))
164− return n >= i - 1;
165− return n >= UTFmax;
198+ if(c < T3)
199+ return n >= 2;
200+ if(UTFmax == 3 || c < T4)
201+ return n >= 3;
202+ return n >= 4;
166203 }
204+
libc/runestrdup.c+3−3
@@ -2,13 +2,13 @@ · 1 unmodified line
22 #include <libc.h>
33
44 Rune*
5−runestrdup(Rune *s)
6−{
5+runestrdup(Rune *s)
6+{
77 Rune *ns;
88
99 ns = malloc(sizeof(Rune)*(runestrlen(s) + 1));
1010 if(ns == 0)
1111 return 0;
12−
12+ setmalloctag(ns, getcallerpc(&s));
1313 return runestrcpy(ns, s);
1414 }
libc/runestrecpy.c+2−2
@@ -9,9 +9,9 @@ runestrecpy(Rune *s1, Rune *es1, Rune *s2) · 8 unmodified lines
99
1010 while(*s1++ = *s2++){
1111 if(s1 == es1){
12− *--s1 = '\0';
12+ s1[-1] = '\0';
1313 break;
1414 }
1515 }
16− return s1;
16+ return s1-1;
1717 }
libc/runetype.c+44−0
@@ -211,9 +211,14 @@ Rune _space2[] = · 210 unmodified lines
211211 {
212212 0x0009, 0x000a, /* tab and newline */
213213 0x0020, 0x0020, /* space */
214+ 0x0085, 0x0085,
214215 0x00a0, 0x00a0, /*   */
216+ 0x1680, 0x1680,
217+ 0x180e, 0x180e,
215218 0x2000, 0x200b, /*   - ​ */
216219 0x2028, 0x2029, /* 
 - 
 */
220+ 0x202f, 0x202f,
221+ 0x205f, 0x205f,
217222 0x3000, 0x3000, /*   */
218223 0xfeff, 0xfeff, /*  */
219224 };
@@ -611,6 +616,34 @@ Rune _toupper1[] = · 391 unmodified lines
611616 0x1ff3, 509, /* ῳ ῼ */
612617 };
613618
619+static Rune __isdigitr[] = {
620+ 0x0030, 0x0039,
621+ 0x0660, 0x0669,
622+ 0x06f0, 0x06f9,
623+ 0x07c0, 0x07c9,
624+ 0x0966, 0x096f,
625+ 0x09e6, 0x09ef,
626+ 0x0a66, 0x0a6f,
627+ 0x0ae6, 0x0aef,
628+ 0x0b66, 0x0b6f,
629+ 0x0be6, 0x0bef,
630+ 0x0c66, 0x0c6f,
631+ 0x0ce6, 0x0cef,
632+ 0x0d66, 0x0d6f,
633+ 0x0e50, 0x0e59,
634+ 0x0ed0, 0x0ed9,
635+ 0x0f20, 0x0f29,
636+ 0x1040, 0x1049,
637+ 0x17e0, 0x17e9,
638+ 0x1810, 0x1819,
639+ 0x1946, 0x194f,
640+ 0x19d0, 0x19d9,
641+ 0x1b50, 0x1b59,
642+ 0xff10, 0xff19,
643+ 0x104a0, 0x104a9,
644+ 0x1d7ce, 0x1d7ff,
645+};
646+
614647 /*
615648 * upper case ranges
616649 * 3rd col is conversion excess 500
@@ -1136,3 +1169,14 @@ isspacerune(Rune c) · 519 unmodified lines
11361169 return 1;
11371170 return 0;
11381171 }
1172+
1173+int
1174+isdigitrune(Rune c)
1175+{
1176+ Rune *p;
1177+
1178+ p = bsearch(c, __isdigitr, nelem(__isdigitr)/2, 2);
1179+ if(p && c >= p[0] && c <= p[1])
1180+ return 1;
1181+ return 0;
1182+}
libc/utfecpy.c+1−1
@@ -10,7 +10,7 @@ utfecpy(char *to, char *e, char *from) · 9 unmodified lines
1010 return to;
1111 end = memccpy(to, from, '\0', e - to);
1212 if(end == nil){
13− end = e-1;
13+ end = e;
1414 while(end>to && (*--end&0xC0)==0x80)
1515 ;
1616 *end = '\0';

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t