1*8f0ba417SAndroid Build Coastguard Worker /* 2*8f0ba417SAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project 3*8f0ba417SAndroid Build Coastguard Worker * 4*8f0ba417SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*8f0ba417SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*8f0ba417SAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*8f0ba417SAndroid Build Coastguard Worker * 8*8f0ba417SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*8f0ba417SAndroid Build Coastguard Worker * 10*8f0ba417SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*8f0ba417SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*8f0ba417SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*8f0ba417SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*8f0ba417SAndroid Build Coastguard Worker * limitations under the License. 15*8f0ba417SAndroid Build Coastguard Worker */ 16*8f0ba417SAndroid Build Coastguard Worker 17*8f0ba417SAndroid Build Coastguard Worker // Portable error handling functions. This is only necessary for host-side 18*8f0ba417SAndroid Build Coastguard Worker // code that needs to be cross-platform; code that is only run on Unix should 19*8f0ba417SAndroid Build Coastguard Worker // just use errno and strerror() for simplicity. 20*8f0ba417SAndroid Build Coastguard Worker // 21*8f0ba417SAndroid Build Coastguard Worker // There is some complexity since Windows has (at least) three different error 22*8f0ba417SAndroid Build Coastguard Worker // numbers, not all of which share the same type: 23*8f0ba417SAndroid Build Coastguard Worker // * errno: for C runtime errors. 24*8f0ba417SAndroid Build Coastguard Worker // * GetLastError(): Windows non-socket errors. 25*8f0ba417SAndroid Build Coastguard Worker // * WSAGetLastError(): Windows socket errors. 26*8f0ba417SAndroid Build Coastguard Worker // errno can be passed to strerror() on all platforms, but the other two require 27*8f0ba417SAndroid Build Coastguard Worker // special handling to get the error string. Refer to Microsoft documentation 28*8f0ba417SAndroid Build Coastguard Worker // to determine which error code to check for each function. 29*8f0ba417SAndroid Build Coastguard Worker 30*8f0ba417SAndroid Build Coastguard Worker #pragma once 31*8f0ba417SAndroid Build Coastguard Worker 32*8f0ba417SAndroid Build Coastguard Worker #include <assert.h> 33*8f0ba417SAndroid Build Coastguard Worker 34*8f0ba417SAndroid Build Coastguard Worker #include <string> 35*8f0ba417SAndroid Build Coastguard Worker 36*8f0ba417SAndroid Build Coastguard Worker namespace android { 37*8f0ba417SAndroid Build Coastguard Worker namespace base { 38*8f0ba417SAndroid Build Coastguard Worker 39*8f0ba417SAndroid Build Coastguard Worker // Returns a string describing the given system error code. |error_code| must 40*8f0ba417SAndroid Build Coastguard Worker // be errno on Unix or GetLastError()/WSAGetLastError() on Windows. Passing 41*8f0ba417SAndroid Build Coastguard Worker // errno on Windows has undefined behavior. 42*8f0ba417SAndroid Build Coastguard Worker std::string SystemErrorCodeToString(int error_code); 43*8f0ba417SAndroid Build Coastguard Worker 44*8f0ba417SAndroid Build Coastguard Worker } // namespace base 45*8f0ba417SAndroid Build Coastguard Worker } // namespace android 46*8f0ba417SAndroid Build Coastguard Worker 47*8f0ba417SAndroid Build Coastguard Worker // Convenient macros for evaluating a statement, checking if the result is error, and returning it 48*8f0ba417SAndroid Build Coastguard Worker // to the caller. If it is ok then the inner value is unwrapped (if applicable) and returned. 49*8f0ba417SAndroid Build Coastguard Worker // 50*8f0ba417SAndroid Build Coastguard Worker // Usage with Result<T>: 51*8f0ba417SAndroid Build Coastguard Worker // 52*8f0ba417SAndroid Build Coastguard Worker // Result<Foo> getFoo() {...} 53*8f0ba417SAndroid Build Coastguard Worker // 54*8f0ba417SAndroid Build Coastguard Worker // Result<Bar> getBar() { 55*8f0ba417SAndroid Build Coastguard Worker // Foo foo = OR_RETURN(getFoo()); 56*8f0ba417SAndroid Build Coastguard Worker // return Bar{foo}; 57*8f0ba417SAndroid Build Coastguard Worker // } 58*8f0ba417SAndroid Build Coastguard Worker // 59*8f0ba417SAndroid Build Coastguard Worker // Usage with status_t: 60*8f0ba417SAndroid Build Coastguard Worker // 61*8f0ba417SAndroid Build Coastguard Worker // status_t getFoo(Foo*) {...} 62*8f0ba417SAndroid Build Coastguard Worker // 63*8f0ba417SAndroid Build Coastguard Worker // status_t getBar(Bar* bar) { 64*8f0ba417SAndroid Build Coastguard Worker // Foo foo; 65*8f0ba417SAndroid Build Coastguard Worker // OR_RETURN(getFoo(&foo)); 66*8f0ba417SAndroid Build Coastguard Worker // *bar = Bar{foo}; 67*8f0ba417SAndroid Build Coastguard Worker // return OK; 68*8f0ba417SAndroid Build Coastguard Worker // } 69*8f0ba417SAndroid Build Coastguard Worker // 70*8f0ba417SAndroid Build Coastguard Worker // Actually this can be used for any type as long as the OkOrFail<T> contract is satisfied. See 71*8f0ba417SAndroid Build Coastguard Worker // below. 72*8f0ba417SAndroid Build Coastguard Worker // If implicit conversion compilation errors occur involving a value type with a templated 73*8f0ba417SAndroid Build Coastguard Worker // forwarding ref ctor, compilation with cpp20 or explicitly converting to the desired 74*8f0ba417SAndroid Build Coastguard Worker // return type is required. 75*8f0ba417SAndroid Build Coastguard Worker #define OR_RETURN(expr) \ 76*8f0ba417SAndroid Build Coastguard Worker UNWRAP_OR_DO(__or_return_expr, expr, { return ok_or_fail::Fail(std::move(__or_return_expr)); }) 77*8f0ba417SAndroid Build Coastguard Worker 78*8f0ba417SAndroid Build Coastguard Worker // Same as OR_RETURN, but aborts if expr is a failure. 79*8f0ba417SAndroid Build Coastguard Worker #if defined(__BIONIC__) 80*8f0ba417SAndroid Build Coastguard Worker #define OR_FATAL(expr) \ 81*8f0ba417SAndroid Build Coastguard Worker UNWRAP_OR_DO(__or_fatal_expr, expr, { \ 82*8f0ba417SAndroid Build Coastguard Worker __assert(__FILE__, __LINE__, ok_or_fail::ErrorMessage(__or_fatal_expr).c_str()); \ 83*8f0ba417SAndroid Build Coastguard Worker }) 84*8f0ba417SAndroid Build Coastguard Worker #else 85*8f0ba417SAndroid Build Coastguard Worker #define OR_FATAL(expr) \ 86*8f0ba417SAndroid Build Coastguard Worker UNWRAP_OR_DO(__or_fatal_expr, expr, { \ 87*8f0ba417SAndroid Build Coastguard Worker fprintf(stderr, "%s:%d: assertion \"%s\" failed", __FILE__, __LINE__, \ 88*8f0ba417SAndroid Build Coastguard Worker ok_or_fail::ErrorMessage(__or_fatal_expr).c_str()); \ 89*8f0ba417SAndroid Build Coastguard Worker abort(); \ 90*8f0ba417SAndroid Build Coastguard Worker }) 91*8f0ba417SAndroid Build Coastguard Worker #endif 92*8f0ba417SAndroid Build Coastguard Worker 93*8f0ba417SAndroid Build Coastguard Worker // Variant for use in gtests, which aborts the test function with an assertion failure on error. 94*8f0ba417SAndroid Build Coastguard Worker // This is akin to ASSERT_OK_AND_ASSIGN for absl::Status, except the assignment is external. It 95*8f0ba417SAndroid Build Coastguard Worker // assumes the user depends on libgmock and includes gtest/gtest.h. 96*8f0ba417SAndroid Build Coastguard Worker #define OR_ASSERT_FAIL(expr) \ 97*8f0ba417SAndroid Build Coastguard Worker UNWRAP_OR_DO(__or_assert_expr, expr, { \ 98*8f0ba417SAndroid Build Coastguard Worker FAIL() << "Value of: " << #expr << "\n" \ 99*8f0ba417SAndroid Build Coastguard Worker << " Actual: " << __or_assert_expr.error().message() << "\n" \ 100*8f0ba417SAndroid Build Coastguard Worker << "Expected: is ok\n"; \ 101*8f0ba417SAndroid Build Coastguard Worker }) 102*8f0ba417SAndroid Build Coastguard Worker 103*8f0ba417SAndroid Build Coastguard Worker // Generic macro to execute any statement(s) on error. Execution should never reach the end of them. 104*8f0ba417SAndroid Build Coastguard Worker // result_var is assigned expr and is only visible to on_error_stmts. 105*8f0ba417SAndroid Build Coastguard Worker #define UNWRAP_OR_DO(result_var, expr, on_error_stmts) \ 106*8f0ba417SAndroid Build Coastguard Worker ({ \ 107*8f0ba417SAndroid Build Coastguard Worker decltype(expr)&& result_var = (expr); \ 108*8f0ba417SAndroid Build Coastguard Worker typedef android::base::OkOrFail<std::remove_reference_t<decltype(result_var)>> ok_or_fail; \ 109*8f0ba417SAndroid Build Coastguard Worker if (!ok_or_fail::IsOk(result_var)) { \ 110*8f0ba417SAndroid Build Coastguard Worker { \ 111*8f0ba417SAndroid Build Coastguard Worker on_error_stmts; \ 112*8f0ba417SAndroid Build Coastguard Worker } \ 113*8f0ba417SAndroid Build Coastguard Worker __builtin_unreachable(); \ 114*8f0ba417SAndroid Build Coastguard Worker } \ 115*8f0ba417SAndroid Build Coastguard Worker ok_or_fail::Unwrap(std::move(result_var)); \ 116*8f0ba417SAndroid Build Coastguard Worker }) 117*8f0ba417SAndroid Build Coastguard Worker 118*8f0ba417SAndroid Build Coastguard Worker namespace android { 119*8f0ba417SAndroid Build Coastguard Worker namespace base { 120*8f0ba417SAndroid Build Coastguard Worker 121*8f0ba417SAndroid Build Coastguard Worker // The OkOrFail contract for a type T. This must be implemented for a type T if you want to use 122*8f0ba417SAndroid Build Coastguard Worker // OR_RETURN(stmt) where stmt evalues to a value of type T. 123*8f0ba417SAndroid Build Coastguard Worker template <typename T, typename = void> 124*8f0ba417SAndroid Build Coastguard Worker struct OkOrFail { 125*8f0ba417SAndroid Build Coastguard Worker // Checks if T is ok or fail. 126*8f0ba417SAndroid Build Coastguard Worker static bool IsOk(const T&); 127*8f0ba417SAndroid Build Coastguard Worker 128*8f0ba417SAndroid Build Coastguard Worker // Turns T into the success value. 129*8f0ba417SAndroid Build Coastguard Worker template <typename U> 130*8f0ba417SAndroid Build Coastguard Worker static U Unwrap(T&&); 131*8f0ba417SAndroid Build Coastguard Worker 132*8f0ba417SAndroid Build Coastguard Worker // Moves T into OkOrFail<T>, so that we can convert it to other types 133*8f0ba417SAndroid Build Coastguard Worker OkOrFail(T&& v); 134*8f0ba417SAndroid Build Coastguard Worker OkOrFail() = delete; 135*8f0ba417SAndroid Build Coastguard Worker OkOrFail(const T&) = delete; 136*8f0ba417SAndroid Build Coastguard Worker 137*8f0ba417SAndroid Build Coastguard Worker // And there need to be one or more conversion operators that turns the error value of T into a 138*8f0ba417SAndroid Build Coastguard Worker // target type. For example, for T = Result<V, E>, there can be ... 139*8f0ba417SAndroid Build Coastguard Worker // 140*8f0ba417SAndroid Build Coastguard Worker // // for the case where OR_RETURN is called in a function expecting E 141*8f0ba417SAndroid Build Coastguard Worker // operator E()&& { return val_.error().code(); } 142*8f0ba417SAndroid Build Coastguard Worker // 143*8f0ba417SAndroid Build Coastguard Worker // // for the case where OR_RETURN is called in a function expecting Result<U, E> 144*8f0ba417SAndroid Build Coastguard Worker // template <typename U> 145*8f0ba417SAndroid Build Coastguard Worker // operator Result<U, E>()&& { return val_.error(); } 146*8f0ba417SAndroid Build Coastguard Worker 147*8f0ba417SAndroid Build Coastguard Worker // And there needs to be a method that returns the string representation of the fail value. 148*8f0ba417SAndroid Build Coastguard Worker // static const std::string& ErrorMessage(const T& v); 149*8f0ba417SAndroid Build Coastguard Worker // or 150*8f0ba417SAndroid Build Coastguard Worker // static std::string ErrorMessage(const T& v); 151*8f0ba417SAndroid Build Coastguard Worker }; 152*8f0ba417SAndroid Build Coastguard Worker 153*8f0ba417SAndroid Build Coastguard Worker } // namespace base 154*8f0ba417SAndroid Build Coastguard Worker } // namespace android 155