1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in 12 * the documentation and/or other materials provided with the 13 * distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 #include <error.h> 30 31 #include <errno.h> 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <string.h> 35 36 unsigned int error_message_count = 0; 37 void (*error_print_progname)(void) = nullptr; 38 int error_one_per_line = 0; 39 40 static void __error_head() { 41 ++error_message_count; 42 43 if (error_print_progname != nullptr) { 44 error_print_progname(); 45 } else { 46 fflush(stdout); 47 fprintf(stderr, "%s:", getprogname()); 48 } 49 } 50 51 static void __error_tail(int status, int error) { 52 if (error != 0) { 53 fprintf(stderr, ": %s", strerror(error)); 54 } 55 56 putc('\n', stderr); 57 fflush(stderr); 58 59 if (status != 0) { 60 exit(status); 61 } 62 } 63 64 void error(int status, int error, const char* fmt, ...) { 65 __error_head(); 66 putc(' ', stderr); 67 68 va_list ap; 69 va_start(ap, fmt); 70 vfprintf(stderr, fmt, ap); 71 va_end(ap); 72 73 __error_tail(status, error); 74 } 75 76 void error_at_line(int status, int error, const char* file, unsigned int line, const char* fmt, ...) { 77 if (error_one_per_line) { 78 static const char* last_file; 79 static unsigned int last_line; 80 if (last_line == line && last_file != nullptr && strcmp(last_file, file) == 0) { 81 return; 82 } 83 last_file = file; 84 last_line = line; 85 } 86 87 __error_head(); 88 fprintf(stderr, "%s:%d: ", file, line); 89 90 va_list ap; 91 va_start(ap, fmt); 92 vfprintf(stderr, fmt, ap); 93 va_end(ap); 94 95 __error_tail(status, error); 96 } 97