github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/src/runtime/string.c (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 #include "runtime.h" 6 #include "arch_GOARCH.h" 7 #include "malloc.h" 8 #include "race.h" 9 #include "textflag.h" 10 11 String runtime·emptystring; 12 13 #pragma textflag NOSPLIT 14 intgo 15 runtime·findnull(byte *s) 16 { 17 intgo l; 18 19 if(s == nil) 20 return 0; 21 for(l=0; s[l]!=0; l++) 22 ; 23 return l; 24 } 25 26 intgo 27 runtime·findnullw(uint16 *s) 28 { 29 intgo l; 30 31 if(s == nil) 32 return 0; 33 for(l=0; s[l]!=0; l++) 34 ; 35 return l; 36 } 37 38 uintptr runtime·maxstring = 256; // a hint for print 39 40 #pragma textflag NOSPLIT 41 String 42 runtime·gostringnocopy(byte *str) 43 { 44 String s; 45 uintptr ms; 46 47 s.str = str; 48 s.len = runtime·findnull(str); 49 while(true) { 50 ms = runtime·maxstring; 51 if(s.len <= ms || runtime·casp((void**)&runtime·maxstring, (void*)ms, (void*)s.len)) 52 return s; 53 } 54 } 55 56 // TODO: move this elsewhere 57 enum 58 { 59 Bit1 = 7, 60 Bitx = 6, 61 Bit2 = 5, 62 Bit3 = 4, 63 Bit4 = 3, 64 Bit5 = 2, 65 66 Tx = ((1<<(Bitx+1))-1) ^ 0xFF, /* 1000 0000 */ 67 T2 = ((1<<(Bit2+1))-1) ^ 0xFF, /* 1100 0000 */ 68 T3 = ((1<<(Bit3+1))-1) ^ 0xFF, /* 1110 0000 */ 69 T4 = ((1<<(Bit4+1))-1) ^ 0xFF, /* 1111 0000 */ 70 71 Rune1 = (1<<(Bit1+0*Bitx))-1, /* 0000 0000 0111 1111 */ 72 Rune2 = (1<<(Bit2+1*Bitx))-1, /* 0000 0111 1111 1111 */ 73 Rune3 = (1<<(Bit3+2*Bitx))-1, /* 1111 1111 1111 1111 */ 74 75 Maskx = (1<<Bitx)-1, /* 0011 1111 */ 76 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 error 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 } 224 } 225 return nil; 226 }