LEFT | RIGHT |
(no file at all) | |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 #include "runtime.h" | 5 package runtime |
6 #include "arch_GOARCH.h" | |
7 #include "malloc.h" | |
8 #include "race.h" | |
9 #include "textflag.h" | |
10 | 6 |
11 String» runtime·emptystring; | 7 import "unsafe" |
12 | 8 |
13 #pragma textflag NOSPLIT | 9 //go:nosplit |
14 intgo | 10 func findnull(s *byte) int { |
15 runtime·findnull(byte *s) | 11 » if s == nil { |
16 { | 12 » » return 0 |
17 » intgo l; | 13 » } |
18 | 14 » p := (*[_MaxMem/2 - 1]byte)(unsafe.Pointer(s)) |
19 » if(s == nil) | 15 » l := 0 |
20 » » return 0; | 16 » for p[l] != 0 { |
21 » for(l=0; s[l]!=0; l++) | 17 » » l++ |
22 » » ; | 18 » } |
23 » return l; | 19 » return l |
24 } | 20 } |
25 | 21 |
26 intgo | 22 func findnullw(s *uint16) int { |
27 runtime·findnullw(uint16 *s) | 23 » if s == nil { |
28 { | 24 » » return 0 |
29 » intgo l; | 25 » } |
30 | 26 » p := (*[_MaxMem/2/2 - 1]uint16)(unsafe.Pointer(s)) |
31 » if(s == nil) | 27 » l := 0 |
32 » » return 0; | 28 » for p[l] != 0 { |
33 » for(l=0; s[l]!=0; l++) | 29 » » l++ |
34 » » ; | 30 » } |
35 » return l; | 31 » return l |
36 } | 32 } |
37 | 33 |
38 uintptr runtime·maxstring = 256; // a hint for print | 34 var maxstring uintptr = 256 // a hint for print |
39 | 35 |
40 #pragma textflag NOSPLIT | 36 //go:nosplit |
41 String | 37 func gostringnocopy(str *byte) string { |
42 runtime·gostringnocopy(byte *str) | 38 » var s string |
43 { | 39 » sp := (*stringStruct)(unsafe.Pointer(&s)) |
44 » String s; | 40 » sp.str = unsafe.Pointer(str) |
45 » uintptr ms; | 41 » sp.len = findnull(str) |
46 »······· | 42 » for { |
47 » s.str = str; | 43 » » ms := maxstring |
48 » s.len = runtime·findnull(str); | 44 » » if uintptr(len(s)) <= ms || casuintptr(&maxstring, ms, uintptr(l
en(s))) { |
49 » while(true) { | 45 » » » break |
50 » » ms = runtime·maxstring; | 46 » » } |
51 » » if(s.len <= ms || runtime·casp((void**)&runtime·maxstring, (void
*)ms, (void*)s.len)) | 47 » } |
52 » » » return s; | 48 » return s |
| 49 } |
| 50 |
| 51 func gostringw(strw *uint16) string { |
| 52 » var buf [8]byte |
| 53 » str := (*[_MaxMem/2/2 - 1]uint16)(unsafe.Pointer(strw)) |
| 54 » n1 := 0 |
| 55 » for i := 0; str[i] != 0; i++ { |
| 56 » » n1 += runetochar(buf[:], rune(str[i])) |
| 57 » } |
| 58 » s, b := rawstring(n1 + 4) |
| 59 » n2 := 0 |
| 60 » for i := 0; str[i] != 0; i++ { |
| 61 » » // check for race |
| 62 » » if n2 >= n1 { |
| 63 » » » break |
| 64 » » } |
| 65 » » n2 += runetochar(b[n2:], rune(str[i])) |
| 66 » } |
| 67 » b[n2] = 0 // for luck |
| 68 » return s[:n2] |
| 69 } |
| 70 |
| 71 func strcmp(s1, s2 *byte) int32 { |
| 72 » p1 := (*[_MaxMem/2 - 1]byte)(unsafe.Pointer(s1)) |
| 73 » p2 := (*[_MaxMem/2 - 1]byte)(unsafe.Pointer(s2)) |
| 74 |
| 75 » for i := uintptr(0); ; i++ { |
| 76 » » c1 := p1[i] |
| 77 » » c2 := p2[i] |
| 78 » » if c1 < c2 { |
| 79 » » » return -1 |
| 80 » » } |
| 81 » » if c1 > c2 { |
| 82 » » » return +1 |
| 83 » » } |
| 84 » » if c1 == 0 { |
| 85 » » » return 0 |
| 86 » » } |
53 } | 87 } |
54 } | 88 } |
55 | 89 |
56 // TODO: move this elsewhere | 90 func strncmp(s1, s2 *byte, n uintptr) int32 { |
57 enum | 91 » p1 := (*[_MaxMem/2 - 1]byte)(unsafe.Pointer(s1)) |
58 { | 92 » p2 := (*[_MaxMem/2 - 1]byte)(unsafe.Pointer(s2)) |
59 » Bit1» = 7, | |
60 » Bitx» = 6, | |
61 » Bit2» = 5, | |
62 » Bit3» = 4, | |
63 » Bit4» = 3, | |
64 » Bit5» = 2, | |
65 | 93 |
66 » Tx» = ((1<<(Bitx+1))-1) ^ 0xFF,» /* 1000 0000 */ | 94 » for i := uintptr(0); i < n; i++ { |
67 » T2» = ((1<<(Bit2+1))-1) ^ 0xFF,» /* 1100 0000 */ | 95 » » c1 := p1[i] |
68 » T3» = ((1<<(Bit3+1))-1) ^ 0xFF,» /* 1110 0000 */ | 96 » » c2 := p2[i] |
69 » T4» = ((1<<(Bit4+1))-1) ^ 0xFF,» /* 1111 0000 */ | 97 » » if c1 < c2 { |
70 | 98 » » » return -1 |
71 » Rune1» = (1<<(Bit1+0*Bitx))-1,»» /* 0000 0000 0111 1111 */ | 99 » » } |
72 » Rune2» = (1<<(Bit2+1*Bitx))-1,»» /* 0000 0111 1111 1111 */ | 100 » » if c1 > c2 { |
73 » Rune3» = (1<<(Bit3+2*Bitx))-1,»» /* 1111 1111 1111 1111 */ | 101 » » » return +1 |
74 | 102 » » } |
75 » Maskx» = (1<<Bitx)-1,» » » /* 0011 1111 */ | 103 » » if c1 == 0 { |
76 | 104 » » » break |
77 » Runeerror» = 0xFFFD, | |
78 | |
79 » SurrogateMin = 0xD800, | |
80 » SurrogateMax = 0xDFFF, | |
81 | |
82 » Runemax»= 0x10FFFF,» /* maximum rune value */ | |
83 }; | |
84 | |
85 static int32 | |
86 runetochar(byte *str, int32 rune) /* note: in original, arg2 was pointer */ | |
87 { | |
88 » /* Runes are signed, so convert to unsigned for range check. */ | |
89 » uint32 c; | |
90 | |
91 » /* | |
92 » * one character sequence | |
93 » *» 00000-0007F => 00-7F | |
94 » */ | |
95 » c = rune; | |
96 » if(c <= Rune1) { | |
97 » » str[0] = c; | |
98 » » return 1; | |
99 » } | |
100 | |
101 » /* | |
102 » * two character sequence | |
103 » *» 0080-07FF => T2 Tx | |
104 » */ | |
105 » if(c <= Rune2) { | |
106 » » str[0] = T2 | (c >> 1*Bitx); | |
107 » » str[1] = Tx | (c & Maskx); | |
108 » » return 2; | |
109 » } | |
110 | |
111 » /* | |
112 » * If the Rune is out of range or a surrogate half, convert it to the er
ror rune. | |
113 » * Do this test here because the error rune encodes to three bytes. | |
114 » * Doing it earlier would duplicate work, since an out of range | |
115 » * Rune wouldn't have fit in one or two bytes. | |
116 » */ | |
117 » if (c > Runemax) | |
118 » » c = Runeerror; | |
119 » if (SurrogateMin <= c && c <= SurrogateMax) | |
120 » » c = Runeerror; | |
121 | |
122 » /* | |
123 » * three character sequence | |
124 » *» 0800-FFFF => T3 Tx Tx | |
125 » */ | |
126 » if (c <= Rune3) { | |
127 » » str[0] = T3 | (c >> 2*Bitx); | |
128 » » str[1] = Tx | ((c >> 1*Bitx) & Maskx); | |
129 » » str[2] = Tx | (c & Maskx); | |
130 » » return 3; | |
131 » } | |
132 | |
133 » /* | |
134 » * four character sequence (21-bit value) | |
135 » * 10000-1FFFFF => T4 Tx Tx Tx | |
136 » */ | |
137 » str[0] = T4 | (c >> 3*Bitx); | |
138 » str[1] = Tx | ((c >> 2*Bitx) & Maskx); | |
139 » str[2] = Tx | ((c >> 1*Bitx) & Maskx); | |
140 » str[3] = Tx | (c & Maskx); | |
141 » return 4; | |
142 } | |
143 | |
144 String runtime·gostringsize(intgo); | |
145 | |
146 String | |
147 runtime·gostringw(uint16 *str) | |
148 { | |
149 » intgo n1, n2, i; | |
150 » byte buf[8]; | |
151 » String s; | |
152 | |
153 » n1 = 0; | |
154 » for(i=0; str[i]; i++) | |
155 » » n1 += runetochar(buf, str[i]); | |
156 » s = runtime·gostringsize(n1+4); | |
157 » n2 = 0; | |
158 » for(i=0; str[i]; i++) { | |
159 » » // check for race | |
160 » » if(n2 >= n1) | |
161 » » » break; | |
162 » » n2 += runetochar(s.str+n2, str[i]); | |
163 » } | |
164 » s.len = n2; | |
165 » s.str[s.len] = 0; | |
166 » return s; | |
167 } | |
168 | |
169 int32 | |
170 runtime·strcmp(byte *s1, byte *s2) | |
171 { | |
172 » uintptr i; | |
173 » byte c1, c2; | |
174 | |
175 » for(i=0;; i++) { | |
176 » » c1 = s1[i]; | |
177 » » c2 = s2[i]; | |
178 » » if(c1 < c2) | |
179 » » » return -1; | |
180 » » if(c1 > c2) | |
181 » » » return +1; | |
182 » » if(c1 == 0) | |
183 » » » return 0; | |
184 » } | |
185 } | |
186 | |
187 int32 | |
188 runtime·strncmp(byte *s1, byte *s2, uintptr n) | |
189 { | |
190 » uintptr i; | |
191 » byte c1, c2; | |
192 | |
193 » for(i=0; i<n; i++) { | |
194 » » c1 = s1[i]; | |
195 » » c2 = s2[i]; | |
196 » » if(c1 < c2) | |
197 » » » return -1; | |
198 » » if(c1 > c2) | |
199 » » » return +1; | |
200 » » if(c1 == 0) | |
201 » » » break; | |
202 » } | |
203 » return 0; | |
204 } | |
205 | |
206 byte* | |
207 runtime·strstr(byte *s1, byte *s2) | |
208 { | |
209 » byte *sp1, *sp2; | |
210 | |
211 » if(*s2 == 0) | |
212 » » return s1; | |
213 » for(; *s1; s1++) { | |
214 » » if(*s1 != *s2) | |
215 » » » continue; | |
216 » » sp1 = s1; | |
217 » » sp2 = s2; | |
218 » » for(;;) { | |
219 » » » if(*sp2 == 0) | |
220 » » » » return s1; | |
221 » » » if(*sp1++ != *sp2++) | |
222 » » » » break; | |
223 } | 105 } |
224 } | 106 } |
225 » return nil; | 107 » return 0 |
226 } | 108 } |
LEFT | RIGHT |