Mon, 16 Feb 2004 18:50:28 +0100
trunk: changeset 1318
Switched to using spaces only for indentation. Simple automatic "\t"
-> " " conversion; may need tuning later.
| 61 | 1 | /* |
| 2 | * libtu/errorlog.c | |
| 3 | * | |
| 4 | * Copyright (c) Tuomo Valkonen 1999-2004. | |
| 5 | * | |
| 6 | * You may distribute and modify this library under the terms of either | |
| 7 | * the Clarified Artistic License or the GNU LGPL, version 2.1 or later. | |
| 8 | */ | |
| 9 | ||
| 10 | #include <string.h> | |
| 11 | #include <errno.h> | |
| 12 | #include <stdio.h> | |
| 13 | ||
| 14 | #include "util.h" | |
| 15 | #include "types.h" | |
| 16 | #include "output.h" | |
| 17 | #include "misc.h" | |
| 18 | #include "errorlog.h" | |
| 19 | ||
| 20 | static ErrorLog *current_log=NULL; | |
| 21 | ||
| 22 | static void add_to_log(ErrorLog *el, const char *message, int l) | |
| 23 | { | |
| 62 | 24 | if(message==NULL) |
| 25 | return; | |
| 26 | ||
| 27 | /* Also write to stderr */ | |
| 28 | fwrite(message, sizeof(char), l, stderr); | |
| 61 | 29 | |
| 62 | 30 | if(el==NULL) |
| 31 | return; | |
| 32 | ||
| 33 | if(el->file!=NULL){ | |
| 34 | el->errors=TRUE; | |
| 35 | fwrite(message, sizeof(char), l, el->file); | |
| 36 | return; | |
| 37 | } | |
| 61 | 38 | |
| 62 | 39 | if(el->msgs==NULL){ |
| 40 | el->msgs=ALLOC_N(char, ERRORLOG_MAX_SIZE); | |
| 41 | if(el->msgs==NULL){ | |
| 42 | fprintf(stderr, "%s: %s\n", prog_execname(), strerror(errno)); | |
| 43 | return; | |
| 44 | } | |
| 45 | el->msgs[0]=0; | |
| 46 | el->msgs_len=0; | |
| 47 | } | |
| 48 | ||
| 49 | el->errors=TRUE; | |
| 50 | ||
| 51 | if(l+el->msgs_len>ERRORLOG_MAX_SIZE-1){ | |
| 52 | int n=0; | |
| 53 | if(l<ERRORLOG_MAX_SIZE-1){ | |
| 54 | n=ERRORLOG_MAX_SIZE-1-l; | |
| 55 | memmove(el->msgs, el->msgs+el->msgs_len-n, n); | |
| 56 | } | |
| 57 | memcpy(el->msgs+n, message+l-(ERRORLOG_MAX_SIZE-1-n), | |
| 58 | ERRORLOG_MAX_SIZE-1-n); | |
| 59 | el->msgs[ERRORLOG_MAX_SIZE]='\0'; | |
| 60 | el->msgs_len=ERRORLOG_MAX_SIZE-1; | |
| 61 | }else{ | |
| 62 | memcpy(el->msgs+el->msgs_len, message, l); | |
| 63 | el->msgs[el->msgs_len+l]='\0'; | |
| 64 | el->msgs_len+=l; | |
| 65 | } | |
| 61 | 66 | } |
| 67 | ||
| 68 | ||
| 69 | static void log_warn_handler(const char *message) | |
| 70 | { | |
| 62 | 71 | const char *p=strchr(message, '\n'); |
| 72 | static int lineno=0; | |
| 73 | int alternat=0; | |
| 74 | ||
| 75 | add_to_log(current_log, lineno==0 ? ">> " : " ", 3); | |
| 76 | ||
| 77 | if(p!=NULL){ | |
| 78 | add_to_log(current_log, message, p-message+1); | |
| 79 | lineno++; | |
| 80 | log_warn_handler(p+1); | |
| 81 | lineno--; | |
| 82 | return; | |
| 83 | } | |
| 84 | ||
| 85 | add_to_log(current_log, message, strlen(message)); | |
| 86 | add_to_log(current_log, "\n", 1); | |
| 61 | 87 | } |
| 88 | ||
| 62 | 89 | |
| 61 | 90 | void errorlog_begin_file(ErrorLog *el, FILE *file) |
| 91 | { | |
| 62 | 92 | el->msgs=NULL; |
| 93 | el->msgs_len=0; | |
| 94 | el->file=file; | |
| 95 | el->prev=current_log; | |
| 96 | el->errors=FALSE; | |
| 97 | el->old_handler=set_warn_handler(log_warn_handler); | |
| 98 | current_log=el; | |
| 61 | 99 | } |
| 100 | ||
| 101 | ||
| 102 | void errorlog_begin(ErrorLog *el) | |
| 103 | { | |
| 62 | 104 | errorlog_begin_file(el, NULL); |
| 61 | 105 | } |
| 106 | ||
| 107 | ||
| 108 | bool errorlog_end(ErrorLog *el) | |
| 109 | { | |
| 62 | 110 | current_log=el->prev; |
| 111 | set_warn_handler(el->old_handler); | |
| 112 | el->prev=NULL; | |
| 113 | el->old_handler=NULL; | |
| 114 | return el->errors; | |
| 61 | 115 | } |
| 116 | ||
| 117 | ||
| 118 | void errorlog_deinit(ErrorLog *el) | |
| 119 | { | |
| 62 | 120 | if(el->msgs!=NULL) |
| 121 | free(el->msgs); | |
| 122 | el->msgs=NULL; | |
| 123 | el->msgs_len=0; | |
| 124 | el->file=NULL; | |
| 125 | el->errors=FALSE; | |
| 61 | 126 | } |
| 127 |