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