blob: cc42d476687f441e6a26f2fd5bae21c24088d08c [file] [edit]
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// Implementation of regerror.
///
//===----------------------------------------------------------------------===//
#include "src/regex/regerror.h"
#include "hdr/regex_macros.h"
#include "src/__support/CPP/string_view.h"
#include "src/__support/common.h"
#include "src/__support/macros/config.h"
#include "src/string/memory_utils/inline_memcpy.h"
namespace LIBC_NAMESPACE_DECL {
LLVM_LIBC_FUNCTION(size_t, regerror,
(int errcode, const regex_t *__restrict preg,
char *__restrict errbuf, size_t errbuf_size)) {
(void)preg; // preg is reserved for implementation-specific messages.
cpp::string_view msg = [errcode]() -> const char * {
switch (errcode) {
case 0:
return "Success";
case REG_NOMATCH:
return "No match";
case REG_BADPAT:
return "Invalid regular expression";
case REG_ECOLLATE:
return "Invalid collating element";
case REG_ECTYPE:
return "Invalid character class";
case REG_EESCAPE:
return "Trailing backslash";
case REG_ESUBREG:
return "Invalid backreference";
case REG_EBRACK:
return "Missing ']'";
case REG_EPAREN:
return "Missing ')'";
case REG_EBRACE:
return "Missing '}'";
case REG_BADBR:
return "Invalid repetition count";
case REG_ERANGE:
return "Invalid range end";
case REG_ESPACE:
return "Out of memory";
case REG_BADRPT:
return "Invalid preceding expression";
default:
return "Unknown error";
}
}();
size_t msg_len = msg.size() + 1; // include NUL
if (errbuf_size > 0 && errbuf) {
size_t copy_len = msg_len < errbuf_size ? msg_len : errbuf_size;
inline_memcpy(errbuf, msg.data(), copy_len - 1);
errbuf[copy_len - 1] = '\0';
}
// POSIX requires returning the size needed to hold the full NUL-terminated
// string, even if it was truncated in the buffer.
return msg_len;
}
} // namespace LIBC_NAMESPACE_DECL