// Copyright 2009, 2010 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" #include "arch.h" #include "malloc.h" #include "go-string.h" #include "race.h" #define charntorune(pv, str, len) __go_get_rune(str, len, pv) const String runtime_emptystring; intgo runtime_findnull(const byte *s) { if(s == nil) return 0; return __builtin_strlen((const char*) s); } intgo runtime_findnullw(const uint16 *s) { intgo l; if(s == nil) return 0; for(l=0; s[l]!=0; l++) ; return l; } static String gostringsize(intgo l, byte** pmem) { String s; byte *mem; if(l == 0) { *pmem = nil; return runtime_emptystring; } // leave room for NUL for C runtime (e.g., callers of getenv) mem = runtime_mallocgc(l+1, 0, FlagNoScan|FlagNoZero); s.str = mem; s.len = l; mem[l] = 0; *pmem = mem; return s; } String runtime_gostring(const byte *str) { intgo l; String s; byte *mem; l = runtime_findnull(str); s = gostringsize(l, &mem); runtime_memmove(mem, str, l); return s; } String runtime_gostringnocopy(const byte *str) { String s; s.str = str; s.len = runtime_findnull(str); return s; } String runtime_cstringToGo(byte*) __asm__ (GOSYM_PREFIX "runtime.cstringToGo"); String runtime_cstringToGo(byte *str) { return runtime_gostringnocopy(str); } enum { Runeself = 0x80, }; func stringiter(s String, k int) (retk int) { 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 int) (retk int, 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: }