1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "slicer/common.h"
18
19 #include <stdio.h>
20 #include <stdlib.h>
21
22 #include <iostream>
23 #include <sstream>
24 #include <set>
25 #include <utility>
26
27 namespace slicer {
28
log_(const std::string & msg)29 static void log_(const std::string& msg) {
30 printf("%s", msg.c_str());
31 fflush(stdout);
32 }
33
34 static logger_type log = log_;
35
set_logger(logger_type new_logger)36 void set_logger(logger_type new_logger) {
37 log = new_logger;
38 }
39
40 // Helper for the default SLICER_CHECK() policy
_checkFailed(const char * expr,int line,const char * file)41 void _checkFailed(const char* expr, int line, const char* file) {
42 std::stringstream ss;
43 ss << std::endl << "SLICER_CHECK failed [";
44 ss << expr << "] at " << file << ":" << line;
45 ss << std::endl << std::endl;
46 log(ss.str());
47 abort();
48 }
49
_checkFailedOp(const void * lhs,const void * rhs,const char * op,const char * suffix,int line,const char * file)50 void _checkFailedOp(const void* lhs, const void* rhs, const char* op, const char* suffix, int line,
51 const char* file) {
52 std::stringstream ss;
53 ss << std::endl << "SLICER_CHECK_" << suffix << " failed [";
54 ss << lhs << " " << op << " " << rhs;
55 ss << "] at " << file << ":" << line;
56 log(ss.str());
57 abort();
58 }
59
_checkFailedOp(uint32_t lhs,uint32_t rhs,const char * op,const char * suffix,int line,const char * file)60 void _checkFailedOp(uint32_t lhs, uint32_t rhs, const char* op, const char* suffix, int line,
61 const char* file) {
62 std::stringstream ss;
63 ss << std::endl << "SLICER_CHECK_" << suffix << " failed [";
64 ss << lhs << " " << op << " " << rhs;
65 ss << "] at " << file << ":" << line;
66 log(ss.str());
67 abort();
68 }
69
70 // keep track of the failures we already saw to avoid spamming with duplicates
71 thread_local std::set<std::pair<int, const char*>> weak_failures;
72
73 // Helper for the default SLICER_WEAK_CHECK() policy
74 //
75 // TODO: implement a modal switch (abort/continue)
76 //
_weakCheckFailed(const char * expr,int line,const char * file)77 void _weakCheckFailed(const char* expr, int line, const char* file) {
78 auto failure_id = std::make_pair(line, file);
79 if (weak_failures.find(failure_id) == weak_failures.end()) {
80 std::stringstream ss;
81 ss << std::endl << "SLICER_WEAK_CHECK failed [";
82 ss << expr << "] at " << file << ":";
83 ss << line << std::endl << std::endl;
84 log(ss.str());
85 weak_failures.insert(failure_id);
86 }
87 }
88
89 // Prints a formatted message and aborts
_fatal(const std::string & msg)90 void _fatal(const std::string& msg) {
91 log("SLICER_FATAL: " + msg);
92 abort();
93 }
94
95 } // namespace slicer
96
97