From c007ce824d9a4fccb148f9204e04c23ed2984b71 Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Mon, 8 Sep 2014 00:08:51 -0400 Subject: build: move package sources from src/pkg to src Preparation was in CL 134570043. This CL contains only the effect of 'hg mv src/pkg/* src'. For more about the move, see golang.org/s/go14nopkg. --- src/runtime/string.c | 288 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 288 insertions(+) create mode 100644 src/runtime/string.c (limited to 'src/runtime/string.c') diff --git a/src/runtime/string.c b/src/runtime/string.c new file mode 100644 index 0000000000..4f25adf8e3 --- /dev/null +++ b/src/runtime/string.c @@ -0,0 +1,288 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +#include "runtime.h" +#include "arch_GOARCH.h" +#include "malloc.h" +#include "race.h" +#include "textflag.h" + +String runtime·emptystring; + +#pragma textflag NOSPLIT +intgo +runtime·findnull(byte *s) +{ + intgo l; + + if(s == nil) + return 0; + for(l=0; s[l]!=0; l++) + ; + return l; +} + +intgo +runtime·findnullw(uint16 *s) +{ + intgo l; + + if(s == nil) + return 0; + for(l=0; s[l]!=0; l++) + ; + return l; +} + +uintptr runtime·maxstring = 256; // a hint for print + +static String +gostringsize(intgo l) +{ + String s; + uintptr ms; + + if(l == 0) + return runtime·emptystring; + s.str = runtime·mallocgc(l, 0, FlagNoScan|FlagNoZero); + s.len = l; + for(;;) { + ms = runtime·maxstring; + if((uintptr)l <= ms || runtime·casp((void**)&runtime·maxstring, (void*)ms, (void*)l)) + break; + } + return s; +} + +String +runtime·gostring(byte *str) +{ + intgo l; + String s; + + l = runtime·findnull(str); + s = gostringsize(l); + runtime·memmove(s.str, str, l); + return s; +} + +String +runtime·gostringn(byte *str, intgo l) +{ + String s; + + s = gostringsize(l); + runtime·memmove(s.str, str, l); + return s; +} + +// used by cmd/cgo +Slice +runtime·gobytes(byte *p, intgo n) +{ + Slice sl; + + sl.array = runtime·mallocgc(n, 0, FlagNoScan|FlagNoZero); + sl.len = n; + sl.cap = n; + runtime·memmove(sl.array, p, n); + return sl; +} + +#pragma textflag NOSPLIT +String +runtime·gostringnocopy(byte *str) +{ + String s; + + s.str = str; + s.len = runtime·findnull(str); + return s; +} + +// TODO: move this elsewhere +enum +{ + Bit1 = 7, + Bitx = 6, + Bit2 = 5, + Bit3 = 4, + Bit4 = 3, + Bit5 = 2, + + 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 */ + + Rune1 = (1<<(Bit1+0*Bitx))-1, /* 0000 0000 0111 1111 */ + Rune2 = (1<<(Bit2+1*Bitx))-1, /* 0000 0111 1111 1111 */ + Rune3 = (1<<(Bit3+2*Bitx))-1, /* 1111 1111 1111 1111 */ + + Maskx = (1< 00-7F + */ + c = rune; + if(c <= Rune1) { + str[0] = c; + return 1; + } + + /* + * two character sequence + * 0080-07FF => T2 Tx + */ + if(c <= Rune2) { + str[0] = T2 | (c >> 1*Bitx); + str[1] = Tx | (c & Maskx); + return 2; + } + + /* + * If the Rune is out of range or a surrogate half, convert it to the error rune. + * Do this test here 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. + */ + if (c > Runemax) + c = Runeerror; + if (SurrogateMin <= c && c <= SurrogateMax) + c = Runeerror; + + /* + * three character sequence + * 0800-FFFF => T3 Tx Tx + */ + if (c <= Rune3) { + str[0] = T3 | (c >> 2*Bitx); + str[1] = Tx | ((c >> 1*Bitx) & Maskx); + str[2] = Tx | (c & Maskx); + return 3; + } + + /* + * four character sequence (21-bit value) + * 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; +} + +String +runtime·gostringw(uint16 *str) +{ + intgo n1, n2, i; + byte buf[8]; + String s; + + n1 = 0; + for(i=0; str[i]; i++) + n1 += runetochar(buf, str[i]); + s = gostringsize(n1+4); + n2 = 0; + for(i=0; str[i]; i++) { + // check for race + if(n2 >= n1) + break; + n2 += runetochar(s.str+n2, str[i]); + } + s.len = n2; + s.str[s.len] = 0; + return s; +} + +String +runtime·catstring(String s1, String s2) +{ + String s3; + + if(s1.len == 0) + return s2; + if(s2.len == 0) + return s1; + + s3 = gostringsize(s1.len + s2.len); + runtime·memmove(s3.str, s1.str, s1.len); + runtime·memmove(s3.str+s1.len, s2.str, s2.len); + return s3; +} + +int32 +runtime·strcmp(byte *s1, byte *s2) +{ + uintptr i; + byte c1, c2; + + for(i=0;; i++) { + c1 = s1[i]; + c2 = s2[i]; + if(c1 < c2) + return -1; + if(c1 > c2) + return +1; + if(c1 == 0) + return 0; + } +} + +int32 +runtime·strncmp(byte *s1, byte *s2, uintptr n) +{ + uintptr i; + byte c1, c2; + + for(i=0; i c2) + return +1; + if(c1 == 0) + break; + } + return 0; +} + +byte* +runtime·strstr(byte *s1, byte *s2) +{ + byte *sp1, *sp2; + + if(*s2 == 0) + return s1; + for(; *s1; s1++) { + if(*s1 != *s2) + continue; + sp1 = s1; + sp2 = s2; + for(;;) { + if(*sp2 == 0) + return s1; + if(*sp1++ != *sp2++) + break; + } + } + return nil; +} -- cgit v1.3