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 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
|
/* *
* This file is part of the ESO UVES Pipeline *
* Copyright (C) 2004,2005 European Southern Observatory *
* *
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the Free Software *
* Foundation, 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA *
* */
/*
* $Author: amodigli $
* $Date: 2013-07-01 15:36:29 $
* $Revision: 1.31 $
* $Name: not supported by cvs2svn $
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <uves_msg.h>
#include <cpl.h>
#include <stdarg.h>
#include <stdio.h>
/*----------------------------------------------------------------------------*/
/**
* @defgroup uves_msg Messaging
*
* CPL's info message level is expanded to a set of relative message level.
* The functions uves_msg_louder() and uves_msg_softer() are used to turn up/down
* the message volume level (instead of setting the verbosity to an absolute level
* using @c cpl_msg_info() or @c cpl_msg_debug()).
* These two functions should be used consistently, so that the volume level is
* always the same on function exit as it was on function entry.
*
* These messaging functions never fail, but might print warnings if called
* inconsistently.
*/
/*----------------------------------------------------------------------------*/
#undef DEBUG_CALLER /* Define whether to check consistency
of msg_louder/softer calls */
/* #define DEBUG_CALLER */
#define MAXLEVEL 256
#define MAXSTRINGLENGTH 1000
static int level = 0; /* Current message & indentation level from 0 to MAXLEVEL-1.
0 is the most verbose level. */
static int outlevel = -1; /* Only print message if level is in {0, 1, ..., outlevel}.
Always print if outlevel = - 1 */
#ifdef DEBUG_CALLER
static const char *callers[MAXLEVEL]; /* Check the consistency of calls to softer/louder */
#endif
static char printbuffer[MAXSTRINGLENGTH]; /* Used to pass variable argument list
to cpl_msg_info() */
static const char *domain = "Undefined domain";
/* This is to support getting the current domain
* which is currently not available in CPL
*/
static bool initialized = false;
static int number_of_warnings = 0; /* Coun't the number of warnings
since initialization */
/**@{*/
/*-----------------------------------------------------------------------------
Implementation
-----------------------------------------------------------------------------*/
//static void signal_handler(int signum)
//{
// fprintf(stderr, "Panic! Signal %d caught, I'll just dump a trace and die\n", signum);
//
// abort();
//}
/*----------------------------------------------------------------------------*/
/**
@brief Initialize messaging
@param olevel The output level
@param dom The message domain
Only messages at levels 0 (most important) to @em outlevel are printed as 'info'.
Messages at levels above @em outlevel are printed as 'debug'.
Therefore, set @em outlevel = 0 to print fewest messages. Increase @em outlevel
to increase verbosity.
To print all messages as 'info' set @em outlevel to the special value -1
(which substitutes for infinity).
*/
/*----------------------------------------------------------------------------*/
void uves_msg_init(int olevel, const char *dom)
{
/* Initialize per recipe: */
number_of_warnings = 0;
// signal(SIGSEGV, signal_handler);
// raise(SIGSEGV);
if (!initialized)
{
/* Initialize once: */
outlevel = olevel;
cpl_msg_set_indentation(2);
/* CPL message format is
* [Time][Verbosity][domain][component] message
*
* Don't show the (variable length and wildly
* fluctuating) component. It interferes with
* indentation. The component is available anyway
* on CPL_MSG_DEBUG_MODE level.
*
* Don't show the time. This is available on
* the DEBUG_MODE level. Use esorex --time to time
* a recipe.
*/
#if WANT_TIME_MEASURE
cpl_msg_set_time_on();
#else
cpl_msg_set_time_off();
#endif
uves_msg_set_domain(dom);
cpl_msg_set_domain_on();
cpl_msg_set_component_off();
initialized = true;
}
}
/*----------------------------------------------------------------------------*/
/**
@brief Set output level
@param olevel The output level
See @c uves_msg_init() .
*/
/*----------------------------------------------------------------------------*/
void uves_msg_set_level(int olevel)
{
outlevel = olevel;
}
/*----------------------------------------------------------------------------*/
/**
@brief Decrease message volume
@param fct Identity of calling function
Don't call this function directly, use @c uves_msg_softer().
*/
/*----------------------------------------------------------------------------*/
void uves_msg_softer_macro(const char *fct)
{
if (level + 1 < MAXLEVEL)
{
level++;
cpl_msg_indent_more();
#ifdef DEBUG_CALLER
callers[level] = fct;
#else
fct = fct; /* Satisfy compiler */
#endif
}
}
/*----------------------------------------------------------------------------*/
/**
@brief Increase message volume
@param fct Identity of calling function
Don't call this function directly, use @c uves_msg_louder().
*/
/*----------------------------------------------------------------------------*/
void uves_msg_louder_macro(const char *fct)
{
if (level == 0)
{
/* 0 is the loudest, ignore request */
return;
}
/* Only make louder, if called from the same function which called
uves_msg_softer. (disable check if level is more than MAXLEVEL)
*/
#ifdef DEBUG_CALLER
if (level >= MAXLEVEL || strcmp(callers[level], fct) == 0)
#else
fct = fct; /* Satisfy compiler */
#endif
{
level--;
cpl_msg_indent_less();
}
#ifdef DEBUG_CALLER
else
{
uves_msg_warning("Message level decreased by '%s' but increased by '%s'",
callers[level], fct);
}
#endif
}
/*----------------------------------------------------------------------------*/
/**
@brief Print a message on 'info' or 'debug' level
@param fct Identity of calling function
@param format A printf()-like format string
Don't call this function directly, use @c uves_msg().
If the current level (which is often equal to the current depth
of the function call-tree) is less than the output level, the message printed
on the 'info' level, otherwise it is printed on the 'debug' level.
*/
/*----------------------------------------------------------------------------*/
void uves_msg_macro(const char *fct, const char *format, ...)
{
va_list al;
va_start(al, format);
vsnprintf(printbuffer, MAXSTRINGLENGTH - 1, format, al);
va_end(al);
printbuffer[MAXSTRINGLENGTH - 1] = '\0';
if (outlevel < 0 || level <= outlevel)
{
//#undef cpl_msg_info
cpl_msg_info(fct, "%s", printbuffer);
//#define cpl_msg_info(...) use__uves_msg__instead__of__cpl_msg_info
}
else
{
cpl_msg_debug(fct, "%s", printbuffer);
}
}
/*----------------------------------------------------------------------------*/
/**
@brief Get number of warnings printed so far
@return Number of warnings since initialization of messaging
*/
/*----------------------------------------------------------------------------*/
int uves_msg_get_warnings(void)
{
return number_of_warnings;
}
/*----------------------------------------------------------------------------*/
/**
@brief Accumulate warnings
@param n Number of warnings to add
The (internal) number of warnings (returned by @c uves_msg_get_warnings())
is increased by @em n, but without actually printing any warnings.
*/
/*----------------------------------------------------------------------------*/
void uves_msg_add_warnings(int n)
{
number_of_warnings += n;
}
/*----------------------------------------------------------------------------*/
/**
@brief Print a warning message
@param fct Identity of calling function
@param format A printf()-like format string
Don't call this function directly, use @c uves_msg_warning().
This function is used instead of @c cpl_msg_warning(), and saves
the user from typing the calling function name.
Additionally, record is kept on the total number of warnings printed
(see @c uves_msg_get_warnings()).
This function does not read or write the cpl_error_code
*/
/*----------------------------------------------------------------------------*/
void uves_msg_warning_macro(const char *fct, const char *format, ...)
{
va_list al;
va_start(al, format);
vsnprintf(printbuffer, MAXSTRINGLENGTH - 1, format, al);
va_end(al);
printbuffer[MAXSTRINGLENGTH - 1] = '\0';
cpl_msg_warning(fct, "%s", printbuffer);
number_of_warnings += 1;
}
/*----------------------------------------------------------------------------*/
/**
@brief Get current message domain
@return The current message domain set by @c uves_msg_init() or @c uves_msg_set_domain().
*/
/*----------------------------------------------------------------------------*/
const char *uves_msg_get_domain(void)
{
return domain;
}
/*----------------------------------------------------------------------------*/
/**
@brief Set message domain
@param d The new message domain
*/
/*----------------------------------------------------------------------------*/
void uves_msg_set_domain(const char *d)
{
/* Set domain and remember */
cpl_msg_set_domain(d);
domain = d;
}
/**@}*/
|