github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/third_party/gofrontend/libgo/runtime/string.goc (about)

     1  // Copyright 2009, 2010 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  package runtime
     6  #include "runtime.h"
     7  #include "arch.h"
     8  #include "malloc.h"
     9  #include "go-string.h"
    10  
    11  #define charntorune(pv, str, len) __go_get_rune(str, len, pv)
    12  
    13  const String	runtime_emptystring;
    14  
    15  intgo
    16  runtime_findnull(const byte *s)
    17  {
    18  	if(s == nil)
    19  		return 0;
    20  	return __builtin_strlen((const char*) s);
    21  }
    22  
    23  intgo
    24  runtime_findnullw(const uint16 *s)
    25  {
    26  	intgo l;
    27  
    28  	if(s == nil)
    29  		return 0;
    30  	for(l=0; s[l]!=0; l++)
    31  		;
    32  	return l;
    33  }
    34  
    35  static String
    36  gostringsize(intgo l, byte** pmem)
    37  {
    38  	String s;
    39  	byte *mem;
    40  
    41  	if(l == 0) {
    42  		*pmem = nil;
    43  		return runtime_emptystring;
    44  	}
    45  	mem = runtime_mallocgc(l, 0, FlagNoScan|FlagNoZero);
    46  	s.str = mem;
    47  	s.len = l;
    48  	*pmem = mem;
    49  	return s;
    50  }
    51  
    52  String
    53  runtime_gostring(const byte *str)
    54  {
    55  	intgo l;
    56  	String s;
    57  	byte *mem;
    58  
    59  	l = runtime_findnull(str);
    60  	s = gostringsize(l, &mem);
    61  	runtime_memmove(mem, str, l);
    62  	return s;
    63  }
    64  
    65  String
    66  runtime_gostringnocopy(const byte *str)
    67  {
    68  	String s;
    69  	
    70  	s.str = str;
    71  	s.len = runtime_findnull(str);
    72  	return s;
    73  }
    74  
    75  func cstringToGo(str *byte) (s String) {
    76  	s = runtime_gostringnocopy(str);
    77  }
    78  
    79  enum
    80  {
    81  	Runeself	= 0x80,
    82  };
    83  
    84  func stringiter(s String, k int) (retk int) {
    85  	int32 l;
    86  
    87  	if(k >= s.len) {
    88  		// retk=0 is end of iteration
    89  		retk = 0;
    90  		goto out;
    91  	}
    92  
    93  	l = s.str[k];
    94  	if(l < Runeself) {
    95  		retk = k+1;
    96  		goto out;
    97  	}
    98  
    99  	// multi-char rune
   100  	retk = k + charntorune(&l, s.str+k, s.len-k);
   101  
   102  out:
   103  }
   104  
   105  func stringiter2(s String, k int) (retk int, retv int32) {
   106  	if(k >= s.len) {
   107  		// retk=0 is end of iteration
   108  		retk = 0;
   109  		retv = 0;
   110  		goto out;
   111  	}
   112  
   113  	retv = s.str[k];
   114  	if(retv < Runeself) {
   115  		retk = k+1;
   116  		goto out;
   117  	}
   118  
   119  	// multi-char rune
   120  	retk = k + charntorune(&retv, s.str+k, s.len-k);
   121  
   122  out:
   123  }