diff options
| author | Russ Cox <rsc@golang.org> | 2009-06-30 20:01:50 -0700 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2009-06-30 20:01:50 -0700 |
| commit | 60920f5a2c00702d7a62f80cbd444345b2235322 (patch) | |
| tree | fe1f69433f5df1b51a40faa084961b259806f6b7 /src/pkg/runtime/string.cgo | |
| parent | af736458bb44f892c35adf0533161fda7e452ae3 (diff) | |
| download | golang-60920f5a2c00702d7a62f80cbd444345b2235322.tar.gz | |
convert string runtime to use cgo.
now that cgo2c can handle it,
merge x.c and x_go.cgo into
a single x.cgo, for x=float,malloc,sema.
R=r
DELTA=1950 (954 added, 996 deleted, 0 changed)
OCL=30951
CL=30964
Diffstat (limited to 'src/pkg/runtime/string.cgo')
| -rw-r--r-- | src/pkg/runtime/string.cgo | 232 |
1 files changed, 232 insertions, 0 deletions
diff --git a/src/pkg/runtime/string.cgo b/src/pkg/runtime/string.cgo new file mode 100644 index 000000000..c91a7507e --- /dev/null +++ b/src/pkg/runtime/string.cgo @@ -0,0 +1,232 @@ +// 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 sys +#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(" "); + sys·printint(a); + prints("<"); + sys·printint(b); + prints(">"); + sys·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<l; i++) { + c1 = s1.str[i]; + c2 = s2.str[i]; + if(c1 < c2) + return -1; + if(c1 > 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) { + sys·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 indexstring(s String, i int32) (b byte) { + if(i < 0 || i >= s.len) { + sys·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 arraystring(b Array) (s String) { + s = gostringsize(b.nel); + mcpy(s.str, b.array, s.len); +} + + +func arraystringi(b Array) (s String) { + int32 siz1, siz2, i; + int32 *a; + byte dum[8]; + + a = (int32*)b.array; + siz1 = 0; + for(i=0; i<b.nel; i++) { + siz1 += runetochar(dum, a[i]); + } + + s = gostringsize(siz1+4); + siz2 = 0; + for(i=0; i<b.nel; i++) { + // check for race + if(siz2 >= 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: +} |
