github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/src/runtime/string.c (about)

     1  // Copyright 2009 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  #include "runtime.h"
     6  #include "arch_GOARCH.h"
     7  #include "malloc.h"
     8  #include "race.h"
     9  #include "textflag.h"
    10  
    11  String	runtime·emptystring;
    12  
    13  #pragma textflag NOSPLIT
    14  intgo
    15  runtime·findnull(byte *s)
    16  {
    17  	intgo l;
    18  
    19  	if(s == nil)
    20  		return 0;
    21  	for(l=0; s[l]!=0; l++)
    22  		;
    23  	return l;
    24  }
    25  
    26  intgo
    27  runtime·findnullw(uint16 *s)
    28  {
    29  	intgo l;
    30  
    31  	if(s == nil)
    32  		return 0;
    33  	for(l=0; s[l]!=0; l++)
    34  		;
    35  	return l;
    36  }
    37  
    38  uintptr runtime·maxstring = 256; // a hint for print
    39  
    40  #pragma textflag NOSPLIT
    41  String
    42  runtime·gostringnocopy(byte *str)
    43  {
    44  	String s;
    45  	uintptr ms;
    46  	
    47  	s.str = str;
    48  	s.len = runtime·findnull(str);
    49  	while(true) {
    50  		ms = runtime·maxstring;
    51  		if(s.len <= ms || runtime·casp((void**)&runtime·maxstring, (void*)ms, (void*)s.len))
    52  			return s;
    53  	}
    54  }
    55  
    56  // TODO: move this elsewhere
    57  enum
    58  {
    59  	Bit1	= 7,
    60  	Bitx	= 6,
    61  	Bit2	= 5,
    62  	Bit3	= 4,
    63  	Bit4	= 3,
    64  	Bit5	= 2,
    65  
    66  	Tx	= ((1<<(Bitx+1))-1) ^ 0xFF,	/* 1000 0000 */
    67  	T2	= ((1<<(Bit2+1))-1) ^ 0xFF,	/* 1100 0000 */
    68  	T3	= ((1<<(Bit3+1))-1) ^ 0xFF,	/* 1110 0000 */
    69  	T4	= ((1<<(Bit4+1))-1) ^ 0xFF,	/* 1111 0000 */
    70  
    71  	Rune1	= (1<<(Bit1+0*Bitx))-1,		/* 0000 0000 0111 1111 */
    72  	Rune2	= (1<<(Bit2+1*Bitx))-1,		/* 0000 0111 1111 1111 */
    73  	Rune3	= (1<<(Bit3+2*Bitx))-1,		/* 1111 1111 1111 1111 */
    74  
    75  	Maskx	= (1<<Bitx)-1,			/* 0011 1111 */
    76  
    77  	Runeerror	= 0xFFFD,
    78  
    79  	SurrogateMin = 0xD800,
    80  	SurrogateMax = 0xDFFF,
    81  
    82  	Runemax	= 0x10FFFF,	/* maximum rune value */
    83  };
    84  
    85  static int32
    86  runetochar(byte *str, int32 rune)  /* note: in original, arg2 was pointer */
    87  {
    88  	/* Runes are signed, so convert to unsigned for range check. */
    89  	uint32 c;
    90  
    91  	/*
    92  	 * one character sequence
    93  	 *	00000-0007F => 00-7F
    94  	 */
    95  	c = rune;
    96  	if(c <= Rune1) {
    97  		str[0] = c;
    98  		return 1;
    99  	}
   100  
   101  	/*
   102  	 * two character sequence
   103  	 *	0080-07FF => T2 Tx
   104  	 */
   105  	if(c <= Rune2) {
   106  		str[0] = T2 | (c >> 1*Bitx);
   107  		str[1] = Tx | (c & Maskx);
   108  		return 2;
   109  	}
   110  
   111  	/*
   112  	 * If the Rune is out of range or a surrogate half, convert it to the error rune.
   113  	 * Do this test here because the error rune encodes to three bytes.
   114  	 * Doing it earlier would duplicate work, since an out of range
   115  	 * Rune wouldn't have fit in one or two bytes.
   116  	 */
   117  	if (c > Runemax)
   118  		c = Runeerror;
   119  	if (SurrogateMin <= c && c <= SurrogateMax)
   120  		c = Runeerror;
   121  
   122  	/*
   123  	 * three character sequence
   124  	 *	0800-FFFF => T3 Tx Tx
   125  	 */
   126  	if (c <= Rune3) {
   127  		str[0] = T3 |  (c >> 2*Bitx);
   128  		str[1] = Tx | ((c >> 1*Bitx) & Maskx);
   129  		str[2] = Tx |  (c & Maskx);
   130  		return 3;
   131  	}
   132  
   133  	/*
   134  	 * four character sequence (21-bit value)
   135  	 *     10000-1FFFFF => T4 Tx Tx Tx
   136  	 */
   137  	str[0] = T4 | (c >> 3*Bitx);
   138  	str[1] = Tx | ((c >> 2*Bitx) & Maskx);
   139  	str[2] = Tx | ((c >> 1*Bitx) & Maskx);
   140  	str[3] = Tx | (c & Maskx);
   141  	return 4;
   142  }
   143  
   144  String runtime·gostringsize(intgo);
   145  
   146  String
   147  runtime·gostringw(uint16 *str)
   148  {
   149  	intgo n1, n2, i;
   150  	byte buf[8];
   151  	String s;
   152  
   153  	n1 = 0;
   154  	for(i=0; str[i]; i++)
   155  		n1 += runetochar(buf, str[i]);
   156  	s = runtime·gostringsize(n1+4);
   157  	n2 = 0;
   158  	for(i=0; str[i]; i++) {
   159  		// check for race
   160  		if(n2 >= n1)
   161  			break;
   162  		n2 += runetochar(s.str+n2, str[i]);
   163  	}
   164  	s.len = n2;
   165  	s.str[s.len] = 0;
   166  	return s;
   167  }
   168  
   169  int32
   170  runtime·strcmp(byte *s1, byte *s2)
   171  {
   172  	uintptr i;
   173  	byte c1, c2;
   174  
   175  	for(i=0;; i++) {
   176  		c1 = s1[i];
   177  		c2 = s2[i];
   178  		if(c1 < c2)
   179  			return -1;
   180  		if(c1 > c2)
   181  			return +1;
   182  		if(c1 == 0)
   183  			return 0;
   184  	}
   185  }
   186  
   187  int32
   188  runtime·strncmp(byte *s1, byte *s2, uintptr n)
   189  {
   190  	uintptr i;
   191  	byte c1, c2;
   192  
   193  	for(i=0; i<n; i++) {
   194  		c1 = s1[i];
   195  		c2 = s2[i];
   196  		if(c1 < c2)
   197  			return -1;
   198  		if(c1 > c2)
   199  			return +1;
   200  		if(c1 == 0)
   201  			break;
   202  	}
   203  	return 0;
   204  }
   205  
   206  byte*
   207  runtime·strstr(byte *s1, byte *s2)
   208  {
   209  	byte *sp1, *sp2;
   210  
   211  	if(*s2 == 0)
   212  		return s1;
   213  	for(; *s1; s1++) {
   214  		if(*s1 != *s2)
   215  			continue;
   216  		sp1 = s1;
   217  		sp2 = s2;
   218  		for(;;) {
   219  			if(*sp2 == 0)
   220  				return s1;
   221  			if(*sp1++ != *sp2++)
   222  				break;
   223  		}
   224  	}
   225  	return nil;
   226  }