1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// <system_error>
10
11// class error_category
12
13// const error_category& system_category();
14
15#include <system_error>
16#include <cassert>
17#include <string>
18#include <cerrno>
19
20#include "test_macros.h"
21
22// See https://llvm.org/D65667
23struct StaticInit {
24 const std::error_category* ec;
25 ~StaticInit() {
26 std::string str = ec->name();
27 assert(str == "system");
28 }
29};
30static StaticInit foo;
31
32int main(int, char**) {
33 {
34 const std::error_category& e_cat1 = std::system_category();
35 std::error_condition e_cond = e_cat1.default_error_condition(i: 5);
36#ifdef _WIN32
37 // Windows' system error 5 is ERROR_ACCESS_DENIED, which maps to generic code permission_denied.
38 LIBCPP_ASSERT(e_cond.value() == static_cast<int>(std::errc::permission_denied));
39#else
40 LIBCPP_ASSERT(e_cond.value() == 5);
41#endif
42 LIBCPP_ASSERT(e_cond.category() == std::generic_category());
43 assert(e_cat1.equivalent(5, e_cond));
44
45 e_cond = e_cat1.default_error_condition(i: 5000);
46 LIBCPP_ASSERT(e_cond.value() == 5000);
47 LIBCPP_ASSERT(e_cond.category() == std::system_category());
48 assert(e_cat1.equivalent(5000, e_cond));
49 }
50
51 // Test the result of message(int cond) when given a bad error condition
52 {
53 errno = E2BIG; // something that message will never generate
54 const std::error_category& e_cat1 = std::system_category();
55 const std::string msg = e_cat1.message(-1);
56 // Exact message format varies by platform. We can't detect
57 // some of these (Musl in particular) using the preprocessor,
58 // so accept a few sensible messages. Newlib unfortunately
59 // responds with an empty message, which we probably want to
60 // treat as a failure code otherwise, but we can detect that
61 // with the preprocessor.
62#if defined(_NEWLIB_VERSION)
63 const bool is_newlib = true;
64#else
65 const bool is_newlib = false;
66#endif
67 (void)is_newlib;
68 LIBCPP_ASSERT(msg.rfind(s: "Error -1 occurred", pos: 0) == 0 // AIX
69 || msg.rfind(s: "No error information", pos: 0) == 0 // Musl
70 || msg.rfind(s: "Unknown error", pos: 0) == 0 // Glibc
71 || (is_newlib && msg.empty()));
72 assert(errno == E2BIG);
73 }
74
75 {
76 foo.ec = &std::system_category();
77 std::string m = foo.ec->name();
78 assert(m == "system");
79 }
80
81 return 0;
82}
83

source code of libcxx/test/std/diagnostics/syserr/syserr.errcat/syserr.errcat.objects/system_category.pass.cpp