// 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. package runtime #include "runtime.h" String emptystring; int32 findnull(byte *s) { int32 l; if(s == nil) return 0; for(l=0; s[l]!=0; l++) ; return l; } int32 maxstring; String gostringsize(int32 l) { String s; if(l == 0) return emptystring; s.str = mal(l+1); // leave room for NUL for C runtime (e.g., callers of getenv) s.len = l; if(l > maxstring) maxstring = l; return s; } String gostring(byte *str) { int32 l; String s; l = findnull(str); s = gostringsize(l); mcpy(s.str, str, l); return s; } func catstring(s1 String, s2 String) (s3 String) { if(s1.len == 0) { s3 = s2; goto out; } if(s2.len == 0) { s3 = s1; goto out; } s3 = gostringsize(s1.len + s2.len); mcpy(s3.str, s1.str, s1.len); mcpy(s3.str+s1.len, s2.str, s2.len); out: } static void prbounds(int8* s, int32 a, int32 b, int32 c) { prints(s); prints(" "); runtime·printint(a); prints("<"); runtime·printint(b); prints(">"); runtime·printint(c); prints("\n"); throw("string bounds"); } uint32 cmpstring(String s1, String s2) { uint32 i, l; byte c1, c2; l = s1.len; if(s2.len < l) l = s2.len; for(i=0; i c2) return +1; } if(s1.len < s2.len) return -1; if(s1.len > s2.len) return +1; return 0; } func cmpstring(s1 String, s2 String) (v int32) { v = cmpstring(s1, s2); } int32 strcmp(byte *s1, byte *s2) { uint32 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; } } func slicestring(si String, lindex int32, hindex int32) (so String) { int32 l; if(lindex < 0 || lindex > si.len || hindex < lindex || hindex > si.len) { runtime·printpc(&si); prints(" "); prbounds("slice", lindex, si.len, hindex); } l = hindex-lindex; so.str = si.str + lindex; so.len = l; // alternate to create a new string // so = gostringsize(l); // mcpy(so.str, si.str+lindex, l); } func slicestring1(si String, lindex int32) (so String) { int32 l; if(lindex < 0 || lindex > si.len) { runtime·printpc(&si); prints(" "); prbounds("slice", lindex, si.len, si.len); } l = si.len-lindex; so.str = si.str + lindex; so.len = l; // alternate to create a new string // so = gostringsize(l); // mcpy(so.str, si.str+lindex, l); } func indexstring(s String, i int32) (b byte) { if(i < 0 || i >= s.len) { runtime·printpc(&s); prints(" "); prbounds("index", 0, i, s.len); } b = s.str[i]; } func intstring(v int64) (s String) { s = gostringsize(8); s.len = runetochar(s.str, v); } func slicebytetostring(b Slice) (s String) { s = gostringsize(b.len); mcpy(s.str, b.array, s.len); } func sliceinttostring(b Slice) (s String) { int32 siz1, siz2, i; int32 *a; byte dum[8]; a = (int32*)b.array; siz1 = 0; for(i=0; i= siz1) break; siz2 += runetochar(s.str+siz2, a[i]); } s.len = siz2; } enum { Runeself = 0x80, }; func stringiter(s String, k int32) (retk int32) { int32 l; if(k >= s.len) { // retk=0 is end of iteration retk = 0; goto out; } l = s.str[k]; if(l < Runeself) { retk = k+1; goto out; } // multi-char rune retk = k + charntorune(&l, s.str+k, s.len-k); out: } func stringiter2(s String, k int32) (retk int32, retv int32) { if(k >= s.len) { // retk=0 is end of iteration retk = 0; retv = 0; goto out; } retv = s.str[k]; if(retv < Runeself) { retk = k+1; goto out; } // multi-char rune retk = k + charntorune(&retv, s.str+k, s.len-k); out: }