1 /*****************************************************************************
2  * Author:   Valient Gough <vgough@pobox.com>
3  *
4  *****************************************************************************
5  * Copyright (c) 2002-2003, Valient Gough
6  *
7  * This library is free software; you can distribute it and/or modify it under
8  * the terms of the GNU Lesser General Public License (LGPL), as published by
9  * the Free Software Foundation; either version 2.1 of the License, or (at your
10  * option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the LGPL in the file COPYING for more
15  * details.
16  *
17  */
18 
19 
20 #include "rlog.h"
21 #include "rloglocation.h"
22 #include "RLogPublisher.h"
23 
24 #include <stdio.h>
25 #include <stdarg.h>
26 
27 #include "RLogChannel.h"
28 #include "Error.h"
29 
30 #include "Lock.h"
31 
32 #define UNUSED(x) (void)(x)
33 
34 #if USE_VALGRIND
35 #include <valgrind/valgrind.h>
36 #endif
37 
38 using namespace std;
39 using namespace rlog;
40 
41 
42 extern "C"
RLogVersion()43 int RLogVersion()
44 {
45     return CURRENT_RLOG_VERSION;
46 }
47 
~PublishLoc()48 PublishLoc::~PublishLoc()
49 {
50     disable();
51     if(pub != NULL)
52     {
53 	delete pub;
54 	pub = NULL;
55     }
56 }
57 
RLog_Register(PublishLoc * loc,RLogChannel * channel,const char * format,...)58 void rlog::RLog_Register(PublishLoc *loc, RLogChannel *channel,
59 	const char *format, ... )
60 {
61     static Mutex registrationLock;
62     Lock lock( &registrationLock );
63 
64     loc->channel = channel;
65 
66     RLogPublisher *pub = new RLogPublisher(loc);
67 
68     loc->pub = pub;
69     loc->publish = RLogPublisher::Publish;
70 
71     if(pub->enabled())
72     {
73 	loc->enable();
74 
75 	// pass through to the publication function since it is active at
76 	// birth.
77 	va_list args;
78 	va_start (args, format);
79 	RLogPublisher::PublishVA( loc, channel, format, args );
80 	va_end( args );
81     } else
82 	loc->disable();
83 }
84 
85 /*
86     throw an error structure with the file/line/ component data, etc.
87 */
rAssertFailed(const char * component,const char * file,const char * function,int line,const char * conditionStr)88 void rlog::rAssertFailed(const char *component, const char *file,
89 	const char *function, int line, const char *conditionStr)
90 {
91 #if USE_VALGRIND
92     VALGRIND_PRINTF_BACKTRACE("Assert failed: %s", conditionStr);
93 #endif
94     throw Error( component, file, function, line, conditionStr );
95 }
96 
97 
98 #if !C99_VARIADAC_MACROS && !PREC99_VARIADAC_MACROS
99 
_rMessageProxy(rlog::RLogChannel * channel,rlog::PublishLoc * loc)100 _rMessageProxy::_rMessageProxy( rlog::RLogChannel *channel,
101 				rlog::PublishLoc *loc )
102 {
103     this->loc = loc;
104     loc->channel = channel;
105 }
106 
log(const char * format,...)107 void _rMessageProxy::log(const char *format, ...)
108 {
109     va_list ap;
110     va_start( ap, format );
111     doLog(format, ap);
112     va_end( ap );
113 }
114 
doLog(const char * format,va_list ap)115 void _rMessageProxy::doLog(const char *format, va_list ap)
116 {
117     if(!loc->pub)
118     {
119 	loc->publish = RLogPublisher::Publish;
120 
121 	RLogPublisher *pub = new RLogPublisher(loc);
122 	loc->pub = pub;
123 
124 	if(pub->enabled())
125 	    loc->enable();
126 	else
127 	    loc->disable();
128     }
129 
130     if(loc->isEnabled())
131 	RLogPublisher::PublishVA( loc, loc->channel, format, ap );
132 }
133 
log(RLogChannel * channel,const char * format,...)134 void _rMessageProxy::log(RLogChannel *channel, const char *format, ...)
135 {
136     loc->channel = channel;
137     va_list ap;
138     va_start( ap, format );
139     doLog(format, ap);
140     va_end( ap );
141 }
142 
143 #endif
144