/*
 * Copyright (C) 2017 The Android Open Source Project
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <string.h>
#include <xlocale.h>

//
// Core functionality.
//

#if !defined(__x86_64__)
void* memccpy(void* dst, const void* src, int c, size_t n) {
  const char* p = static_cast<const char*>(memchr(src, c, n));
  if (p != nullptr) {
    n = p - static_cast<const char*>(src) + 1;
    memcpy(dst, src, n);
    return static_cast<char*>(dst) + n;
  }
  memcpy(dst, src, n);
  return nullptr;
}
#endif

void* mempcpy(void* dst, const void* src, size_t n) {
  return reinterpret_cast<char*>(memcpy(dst, src, n)) + n;
}

// https://github.com/ARM-software/optimized-routines/issues/89
#if defined(__aarch64__)
char* strcat(char* dst, const char* src) {
  strcpy(dst + strlen(dst), src);
  return dst;
}
#endif

#if defined(__arm__) || defined(__aarch64__) || defined(__riscv)
__attribute__((__flatten__))
char* stpncpy(char* dst, const char* src, size_t dst_n) {
  size_t src_n = strnlen(src, dst_n);
  memcpy(dst, src, src_n);
  memset(dst + src_n, 0, dst_n - src_n);
  return dst + src_n;
}
#endif

#if defined(__arm__) || defined(__aarch64__)
__attribute__((__flatten__))
char* strncpy(char* dst, const char* src, size_t n) {
  stpncpy(dst, src, n);
  return dst;
}
#endif

// If you have a fast memchr(), but not a strnlen().
#if defined(__x86_64__)
size_t strnlen(const char* s, size_t n) {
  const char* nul = static_cast<const char*>(memchr(s, '\0', n));
  return nul ? (nul - s) : n;
}
#endif

//
// String delimiter functions.
//

// The approach here is to optimize strcspn()/strspn() and write everything
// else in terms of those two.

// Benchmarking shows that bool[] works better than a bitset,
// and 256 bytes of stack (the latter half of which is never used in practice)
// doesn't seem unreasonable.
static_assert(sizeof(bool) == 1);
static inline void init_delimiter_set(bool* set, const char* delims) {
  for (const uint8_t* d = reinterpret_cast<const uint8_t*>(delims); *d; ++d) {
    set[*d] = true;
  }
}

__attribute__((__flatten__))
size_t strspn(const char* ss, const char* delims) {
  const uint8_t* s = reinterpret_cast<const uint8_t*>(ss);
  const uint8_t* p = s;
  if (delims[0] == '\0') return 0;
  if (delims[1] == '\0') {
    // The common case is a single delimiter, where the set is worse.
    while (*p == delims[0]) ++p;
  } else {
    bool set[256] = {};
    init_delimiter_set(set, delims);
    while (set[*p]) ++p;
  }
  return p - s;
}

__attribute__((__flatten__))
size_t strcspn(const char* ss, const char* delims) {
  const uint8_t* s = reinterpret_cast<const uint8_t*>(ss);
  const uint8_t* p = s;
  if (delims[0] == '\0' || delims[1] == '\0') {
    // The common case is a single delimiter, where the set is far worse.
    // On arm64 strchrnul() is faster than open coding even for small distances,
    // and orders of magnitude better for large distances.
    return strchrnul(ss, delims[0]) - ss;
  } else {
    bool set[256] = {};
    init_delimiter_set(set, delims);
    while (*p && !set[*p]) ++p;
  }
  return p - s;
}

__attribute__((__flatten__))
char* strpbrk(const char* s, const char* delims) {
  size_t i = strcspn(s, delims);
  if (s[i] != '\0') return const_cast<char*>(s) + i;
  return nullptr;
}

__attribute__((__flatten__))
char* strsep(char** last, const char* delims) {
  // Already finished?
  char* start = *last;
  if (start == nullptr) return nullptr;

  // Find end of token (first delimiter).
  char* end = start + strcspn(start, delims);
  if (*end != '\0') {
    // Replace delimiter with NUL, point past it.
    *end = '\0';
    *last = end + 1;
  } else {
    // Token ends at end of string.
    // Signal that to next invocation.
    *last = nullptr;
  }

  // Return pointer to start of token.
  return start;
}

__attribute__((__flatten__))
char* strtok_r(char* s, const char* delims, char** last) {
  // Already finished?
  if (s == nullptr && (s = *last) == nullptr) {
    return nullptr;
  }

  // Skip leading delimiters with optimized strspn().
  s += strspn(s, delims);

  // Finished now (no non-delimiters)?
  if (*s == '\0') {
    *last = nullptr;
    return nullptr;
  }

  // Find next delimiter with optimized strcspn().
  *last = s + strcspn(s, delims);
  if (**last != '\0') {
    // Replace delimiter with NUL, point past it.
    **last = '\0';
    *last += 1;
  } else {
    // Token ends at end of string.
    // Signal that to next invocation.
    *last = nullptr;
  }

  // Return pointer to start of token.
  return s;
}

__attribute__((__flatten__))
char* strtok(char* s, const char* delims) {
  static char* last;
  return strtok_r(s, delims, &last);
}

//
// No-op i18n stuff.
//

int strcoll(const char* lhs, const char* rhs) {
  return strcmp(lhs, rhs);
}
__strong_alias(strcoll_l, strcoll);

size_t strxfrm(char* dst, const char* src, size_t n) {
  return strlcpy(dst, src, n);
}
__strong_alias(strxfrm_l, strxfrm);
