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
9cleanname(char *name)9cleanname(char *name)
10{10{
11 char *p, *q, *dotdot;11 char *p, *q, *dotdot;
12 int rooted;12 int rooted, erasedprefix;
13 13
14 rooted = name[0] == '/';14 rooted = name[0] == '/';
15 erasedprefix = 0;
15 16
16 /*17 /*
17 * invariants:18 * invariants:
@@ -24,9 +25,11 @@ cleanname(char *name) · 6 unmodified lines
24 while(*p) {25 while(*p) {
25 if(p[0] == '/') /* null element */26 if(p[0] == '/') /* null element */
26 p++;27 p++;
27 else if(p[0] == '.' && SEP(p[1]))28 else if(p[0] == '.' && SEP(p[1])) {
29 if(p == name)
30 erasedprefix = 1;
28 p += 1; /* don't count the separator in case it is nul */31 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])) {
30 p += 2;33 p += 2;
31 if(q > dotdot) { /* can backtrack */34 if(q > dotdot) { /* can backtrack */
32 while(--q > dotdot && *q != '/')35 while(--q > dotdot && *q != '/')
@@ -38,6 +41,8 @@ cleanname(char *name) · 5 unmodified lines
38 *q++ = '.';41 *q++ = '.';
39 dotdot = q;42 dotdot = q;
40 }43 }
44 if(q == name)
45 erasedprefix = 1; /* erased entire path via dotdot */
41 } else { /* real path element */46 } else { /* real path element */
42 if(q != name+rooted)47 if(q != name+rooted)
43 *q++ = '/';48 *q++ = '/';
@@ -48,5 +53,11 @@ cleanname(char *name) · 4 unmodified lines
48 if(q == name) /* empty string is really ``.'' */53 if(q == name) /* empty string is really ``.'' */
49 *q++ = '.';54 *q++ = '.';
50 *q = '\0';55 *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 }
51 return name;62 return name;
52}63}
libc/crypt.c+0−1
@@ -9,7 +9,6 @@ · 8 unmodified lines
9 */9 */
10#include <u.h>10#include <u.h>
11#include <libc.h>11#include <libc.h>
12#include <auth.h>
13#include <libsec.h>12#include <libsec.h>
14 13
15/*14/*
libc/nrand.c+3−0
@@ -10,6 +10,9 @@ nrand(int n) · 9 unmodified lines
10 10
11 if(n < 0)11 if(n < 0)
12 return n;12 return n;
13 if(n == 1)
14 return 0;
15 /* and if n == 0, you deserve what you get */
13 slop = MASK % n;16 slop = MASK % n;
14 do17 do
15 v = lrand();18 v = lrand();
libc/rune.c+120−82
@@ -1,24 +1,29 @@
1#include <u.h>1#include <u.h>
2#include <libc.h>2#include <libc.h>
3 3
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
10enum4enum
11{5{
12 Bitx = Bit(1),6 Bit1 = 7,
13 7 Bitx = 6,
14 Tx = T(1), /* 1000 0000 */8 Bit2 = 5,
15 Rune1 = (1<<(Bit(0)+0*Bitx))-1, /* 0000 0000 0000 0000 0111 1111 */9 Bit3 = 4,
16 10 Bit4 = 3,
17 Maskx = (1<<Bitx)-1, /* 0011 1111 */11 Bit5 = 2,
18 Testx = Maskx ^ 0xFF, /* 1100 0000 */12
19 13 T1 = ((1<<(Bit1+1))-1) ^ 0xFF, /* 0000 0000 */
20 SurrogateMin = 0xD800,14 Tx = ((1<<(Bitx+1))-1) ^ 0xFF, /* 1000 0000 */
21 SurrogateMax = 0xDFFF,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 */
22 27
23 Bad = Runeerror,28 Bad = Runeerror,
24};29};
@@ -26,41 +31,67 @@ enum · 1 unmodified line
26int31int
27chartorune(Rune *rune, char *str)32chartorune(Rune *rune, char *str)
28{33{
29 int c[UTFmax], i;34 int c, c1, c2, c3;
30 Rune l;35 long l;
31 36
32 /*37 /*
33 * N character sequence38 * one character sequence
34 * 00000-0007F => T139 * 00000-0007F => T1
35 * 00080-007FF => T2 Tx
36 * 00800-0FFFF => T3 Tx Tx
37 * 10000-10FFFF => T4 Tx Tx Tx
38 */40 */
39 41 c = *(uchar*)str;
40 c[0] = *(uchar*)(str);42 if(c < Tx) {
41 if(c[0] < Tx){43 *rune = c;
42 *rune = c[0];
43 return 1;44 return 1;
44 }45 }
45 l = c[0];
46 46
47 for(i = 1; i < UTFmax; i++) {47 /*
48 c[i] = *(uchar*)(str+i);48 * two character sequence
49 c[i] ^= Tx;49 * 0080-07FF => T2 Tx
50 if(c[i] & Testx)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)
51 goto bad;74 goto bad;
52 l = (l << Bitx) | c[i];75 *rune = l;
53 if(c[0] < T(i + 2)) {76 return 3;
54 l &= RuneX(i + 1);77 }
55 if(i == 1) {78
56 if(c[0] < T(2) || l <= Rune1)79 /*
57 goto bad;80 * four character sequence
58 } else if(l <= RuneX(i) || l > Runemax)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)
59 goto bad;90 goto bad;
60 if (i == 2 && SurrogateMin <= l && l <= SurrogateMax)91 if(l > Runemax)
61 goto bad;92 goto bad;
62 *rune = l;93 *rune = l;
63 return i + 1;94 return 4;
64 }95 }
65 }96 }
66 97
@@ -75,52 +106,58 @@ bad: · 8 unmodified lines
75int106int
76runetochar(char *str, Rune *rune)107runetochar(char *str, Rune *rune)
77{108{
78 int i, j;109 long c;
79 Rune c;
80 110
81 c = *rune;111 c = *rune;
112 if(c > Runemax)
113 c = Runeerror;
114
115 /*
116 * one character sequence
117 * 00000-0007F => 00-7F
118 */
82 if(c <= Rune1) {119 if(c <= Rune1) {
83 str[0] = c;120 str[0] = c;
84 return 1;121 return 1;
85 }122 }
86 123
87 /*124 /*
88 * one character sequence
89 * 00000-0007F => 00-7F
90 * two character sequence125 * two character sequence
91 * 0080-07FF => T2 Tx126 * 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 /*
92 * three character sequence135 * three character sequence
93 * 0800-FFFF => T3 Tx Tx136 * 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.
101 */137 */
102 for(i = 2; i < UTFmax + 1; i++){138 if(c <= Rune3) {
103 if(i == 3){139 str[0] = T3 | (c >> 2*Bitx);
104 if(c > Runemax)140 str[1] = Tx | ((c >> 1*Bitx) & Maskx);
105 c = Runeerror;141 str[2] = Tx | (c & Maskx);
106 if(SurrogateMin <= c && c <= SurrogateMax)142 return 3;
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 }
115 }143 }
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;
117}154}
118 155
119int156int
120runelen(long c)157runelen(long c)
121{158{
122 Rune rune;159 Rune rune;
123 char str[10];160 char str[UTFmax];
124 161
125 rune = c;162 rune = c;
126 return runetochar(str, &rune);163 return runetochar(str, &rune);
@@ -129,21 +166,21 @@ runelen(long c) · 2 unmodified lines
129int166int
130runenlen(Rune *r, int nrune)167runenlen(Rune *r, int nrune)
131{168{
132 int nb, i;169 int nb, c;
133 Rune c;
134 170
135 nb = 0;171 nb = 0;
136 while(nrune--) {172 while(nrune--) {
137 c = *r++;173 c = *r++;
138 if(c <= Rune1){174 if(c <= Rune1)
139 nb++;175 nb++;
140 } else {176 else
141 for(i = 2; i < UTFmax + 1; i++)177 if(c <= Rune2)
142 if(c <= RuneX(i) || i == UTFmax){178 nb += 2;
143 nb += i;179 else
144 break;180 if(c <= Rune3 || c > Runemax)
145 }181 nb += 3;
146 }182 else
183 nb += 4;
147 }184 }
148 return nb;185 return nb;
149}186}
@@ -151,16 +188,17 @@ runenlen(Rune *r, int nrune) · 1 unmodified line
151int188int
152fullrune(char *str, int n)189fullrune(char *str, int n)
153{190{
154 int i;191 int c;
155 Rune c;
156 192
157 if(n <= 0)193 if(n <= 0)
158 return 0;194 return 0;
159 c = *(uchar*)str;195 c = *(uchar*)str;
160 if(c < Tx)196 if(c < Tx)
161 return 1;197 return 1;
162 for(i = 3; i < UTFmax + 1; i++)198 if(c < T3)
163 if(c < T(i))199 return n >= 2;
164 return n >= i - 1;200 if(UTFmax == 3 || c < T4)
165 return n >= UTFmax;201 return n >= 3;
202 return n >= 4;
166}203}
204
libc/runestrdup.c+3−3
@@ -2,13 +2,13 @@ · 1 unmodified line
2#include <libc.h>2#include <libc.h>
3 3
4Rune*4Rune*
5runestrdup(Rune *s) 5runestrdup(Rune *s)
6{ 6{
7 Rune *ns;7 Rune *ns;
8 8
9 ns = malloc(sizeof(Rune)*(runestrlen(s) + 1));9 ns = malloc(sizeof(Rune)*(runestrlen(s) + 1));
10 if(ns == 0)10 if(ns == 0)
11 return 0;11 return 0;
12 12 setmalloctag(ns, getcallerpc(&s));
13 return runestrcpy(ns, s);13 return runestrcpy(ns, s);
14}14}
libc/runestrecpy.c+2−2
@@ -9,9 +9,9 @@ runestrecpy(Rune *s1, Rune *es1, Rune *s2) · 8 unmodified lines
9 9
10 while(*s1++ = *s2++){10 while(*s1++ = *s2++){
11 if(s1 == es1){11 if(s1 == es1){
12 *--s1 = '\0';12 s1[-1] = '\0';
13 break;13 break;
14 }14 }
15 }15 }
16 return s1;16 return s1-1;
17}17}
libc/runetype.c+44−0
@@ -211,9 +211,14 @@ Rune _space2[] = · 210 unmodified lines
211{211{
212 0x0009, 0x000a, /* tab and newline */212 0x0009, 0x000a, /* tab and newline */
213 0x0020, 0x0020, /* space */213 0x0020, 0x0020, /* space */
214 0x0085, 0x0085,
214 0x00a0, 0x00a0, /*   */215 0x00a0, 0x00a0, /*   */
216 0x1680, 0x1680,
217 0x180e, 0x180e,
215 0x2000, 0x200b, /*   - ​ */218 0x2000, 0x200b, /*   - ​ */
216 0x2028, 0x2029, /* 
 - 
 */219 0x2028, 0x2029, /* 
 - 
 */
220 0x202f, 0x202f,
221 0x205f, 0x205f,
217 0x3000, 0x3000, /*   */222 0x3000, 0x3000, /*   */
218 0xfeff, 0xfeff, /*  */223 0xfeff, 0xfeff, /*  */
219};224};
@@ -611,6 +616,34 @@ Rune _toupper1[] = · 391 unmodified lines
611 0x1ff3, 509, /* ῳ ῼ */616 0x1ff3, 509, /* ῳ ῼ */
612};617};
613 618
619static 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
614/*647/*
615 * upper case ranges648 * upper case ranges
616 * 3rd col is conversion excess 500649 * 3rd col is conversion excess 500
@@ -1136,3 +1169,14 @@ isspacerune(Rune c) · 519 unmodified lines
1136 return 1;1169 return 1;
1137 return 0;1170 return 0;
1138}1171}
1172
1173int
1174isdigitrune(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
10 return to;10 return to;
11 end = memccpy(to, from, '\0', e - to);11 end = memccpy(to, from, '\0', e - to);
12 if(end == nil){12 if(end == nil){
13 end = e-1;13 end = e;
14 while(end>to && (*--end&0xC0)==0x80)14 while(end>to && (*--end&0xC0)==0x80)
15 ;15 ;
16 *end = '\0';16 *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