|  | /* bytealg.c -- gccgo implementations of bytealg functions | 
|  |  | 
|  | Copyright 2018 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.  */ | 
|  |  | 
|  | #include <stddef.h> | 
|  | #include <string.h> | 
|  |  | 
|  | #include "runtime.h" | 
|  | #include "array.h" | 
|  |  | 
|  | #ifndef HAVE_MEMMEM | 
|  |  | 
|  | #define memmem goMemmem | 
|  |  | 
|  | static const void *goMemmem(const void *in, size_t inl, const void *s, size_t sl) { | 
|  | const char *p; | 
|  | char first; | 
|  | const char *stop; | 
|  |  | 
|  | if (sl == 0) { | 
|  | return in; | 
|  | } | 
|  | if (inl < sl) { | 
|  | return nil; | 
|  | } | 
|  | first = *(const char *)(s); | 
|  | stop = (const char *)(in) + (inl - sl); | 
|  | for (p = (const char *)(in); p <= stop; p++) { | 
|  | if (*p == first && __builtin_memcmp(p + 1, (const char *)(s) + 1, sl - 1) == 0) { | 
|  | return (const void *)(p); | 
|  | } | 
|  | } | 
|  | return nil; | 
|  | } | 
|  |  | 
|  | #endif | 
|  |  | 
|  | intgo Compare(struct __go_open_array, struct __go_open_array) | 
|  | __asm__(GOSYM_PREFIX "internal_1bytealg.Compare") | 
|  | __attribute__((no_split_stack)); | 
|  |  | 
|  | intgo Compare(struct __go_open_array a, struct __go_open_array b) | 
|  | { | 
|  | intgo l; | 
|  |  | 
|  | l = a.__count; | 
|  | if (b.__count < l) { | 
|  | l = b.__count; | 
|  | } | 
|  | if (l > 0 && a.__values != b.__values) { | 
|  | int i; | 
|  |  | 
|  | i = __builtin_memcmp(a.__values, b.__values, (size_t)(l)); | 
|  | if (i < 0) { | 
|  | return -1; | 
|  | } else if (i > 0) { | 
|  | return 1; | 
|  | } | 
|  | } | 
|  | if (a.__count < b.__count) { | 
|  | return -1; | 
|  | } | 
|  | if (a.__count > b.__count) { | 
|  | return +1; | 
|  | } | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | intgo IndexByte(struct __go_open_array, byte) | 
|  | __asm__(GOSYM_PREFIX "internal_1bytealg.IndexByte") | 
|  | __attribute__((no_split_stack)); | 
|  |  | 
|  | intgo IndexByte(struct __go_open_array b, byte c) | 
|  | { | 
|  | const byte *p; | 
|  |  | 
|  | p = __builtin_memchr(b.__values, c, (size_t)(b.__count)); | 
|  | if (p == nil) { | 
|  | return -1; | 
|  | } | 
|  | return p - (byte *)(b.__values); | 
|  | } | 
|  |  | 
|  |  | 
|  | intgo IndexByteString(String, byte) | 
|  | __asm__(GOSYM_PREFIX "internal_1bytealg.IndexByteString") | 
|  | __attribute__((no_split_stack)); | 
|  |  | 
|  | intgo IndexByteString(String s, byte c) | 
|  | { | 
|  | const byte *p; | 
|  |  | 
|  | p = __builtin_memchr(s.str, c, (size_t)(s.len)); | 
|  | if (p == nil) { | 
|  | return -1; | 
|  | } | 
|  | return p - s.str; | 
|  | } | 
|  |  | 
|  | intgo Index(struct __go_open_array, struct __go_open_array) | 
|  | __asm__(GOSYM_PREFIX "internal_1bytealg.Index") | 
|  | __attribute__((no_split_stack)); | 
|  |  | 
|  | intgo Index(struct __go_open_array a, struct __go_open_array b) | 
|  | { | 
|  | const byte* p; | 
|  |  | 
|  | p = memmem(a.__values, a.__count, b.__values, b.__count); | 
|  | if (p == nil) { | 
|  | return -1; | 
|  | } | 
|  | return p - (const byte*)(a.__values); | 
|  | } | 
|  |  | 
|  | intgo IndexString(String, String) | 
|  | __asm__(GOSYM_PREFIX "internal_1bytealg.IndexString") | 
|  | __attribute__((no_split_stack)); | 
|  |  | 
|  | intgo IndexString(String a, String b) | 
|  | { | 
|  | const byte* p; | 
|  |  | 
|  | p = memmem(a.str, a.len, b.str, b.len); | 
|  | if (p == nil) { | 
|  | return -1; | 
|  | } | 
|  | return p - a.str; | 
|  | } |