Top   Types   Functions   Classes   Index   Sources 

include/error/printf.h


  1  /* -*- Mode: C -*- */
  2  
  3  #ifndef HT_ERROR_EPRINTF_H
  4  #define HT_ERROR_EPRINTF_H
  5  
  6  #include <stdio.h>
  7  #include <stdarg.h>
  8  #include <time.h>
  9  
 10  #ifdef IN_LIBERROR_COMPILING
 11  #  include "error/erwin/defs.h"
 12  #  include "error/erwin/forwards.h"
 13  #else
 14  #  include <error/erwin/defs.h>
 15  #  include <error/erwin/forwards.h>
 16  #endif
 17  
 18  /* Printing */
 19  
 20  /* ********************************************************************** */
 21  
 22  /* for the address type, we will not have a configure option for 32bit
 23   * addresses, since printing errors is a task that needs no speed
 24   * optimisations */
 25  #ifdef ERWIN_UNSIGNED_LONG_LONG
 26  typedef ERWIN_UNSIGNED_LONG_LONG err_address_t;
 27  #define ERR_FORMAT_ADDRESS "0x%Lx"
 28  #else
 29  typedef unsigned long err_address_t;
 30  #define ERR_FORMAT_ADDRESS "0x%lx"
 31  #endif
 32  
 33  /* ********************************************************************** */
 34  
 35  struct err_ext_address_t;
 36  #ifdef __cplusplus
 37  typedef struct err_ext_address_t ErrExtAddress;
 38  #else
 39  typedef struct err_ext_address_t err_ext_address_t;
 40  #endif
 41  
 42  enum err_preposition_t {
 43      ERR_PREP_NONE,
 44      ERR_PREP_CAPITAL_AT,
 45      ERR_PREP_CAPITAL_FROM,
 46      ERR_PREP_CAPITAL_TO,
 47      ERR_PREP_LOWER_AT,
 48      ERR_PREP_LOWER_FROM,
 49      ERR_PREP_LOWER_TO
 50  };
 51  #ifdef __cplusplus
 52  typedef enum err_preposition_t ErrPreposition;
 53  #else
 54  typedef enum err_preposition_t err_preposition_t;
 55  #endif
 56  
 57  enum err_format_style_t {
 58      ERR_FS_HUMAN,       /* readable for humans: this should be the old behaviour before
 59                           * this type was introduced. */
 60      ERR_FS_ADDRESS,     /* only the plain address information */
 61      ERR_FS_LOCATION_ID, /* if known, the location id */
 62      ERR_FS_ROUTINE,     /* if known, the routine name */
 63      ERR_FS_ROUTINE_ID   /* if known, the routine id */
 64  };
 65  #ifdef __cplusplus
 66  typedef enum err_format_style_t ErrFormatStyle;
 67  #else
 68  typedef enum err_format_style_t err_format_style_t;
 69  #endif
 70  
 71  struct err_position_t;
 72  #ifdef __cplusplus
 73  typedef struct err_position_t ErrPosition;
 74  #else
 75  typedef struct err_position_t err_position_t;
 76  #endif
 77  
 78  struct err_ext_address_class_t {
 79      void                 (* destruct)    (err_ext_address_t *);
 80  
 81      err_ext_address_t *  (* clone)       (err_ext_address_t const *);
 82  
 83      void                 (* format)      (err_v_char_t *,
 84                                            err_ext_address_t const *,
 85                                            err_preposition_t);
 86  
 87      err_address_t        (* to_linear)   (err_ext_address_t const *);
 88  
 89      /* The following one may be NULL: */
 90      void                 (* resolve)     (int /*tag*/,
 91                                            int /*orig_tag*/,
 92                                            int /*number*/,
 93                                            err_position_t * /*pos*/);
 94  
 95      void                 (* format_ext)  (err_v_char_t *,
 96                                            err_ext_address_t const *,
 97                                            err_preposition_t,
 98                                            err_format_style_t);
 99          /* if non-null, preferred over format, otherwise, format is tried.
100           * if this is non-null, liberror will never invoke the old-style function,
101           * so it may be NULL. */
102  };
103  
104  #ifdef __cplusplus
105  typedef struct err_ext_address_class_t ErrExtAddressClass;
106  #else
107  typedef struct err_ext_address_class_t err_ext_address_class_t;
108  #endif
109  
110  struct err_ext_address_t {
111      err_ext_address_class_t const *klass;
112  #ifdef __cplusplus
113      err_ext_address_t (err_ext_address_class_t const *a):
114          klass  (a)
115      {}
116  
117      /* Redirect the virtual functions to the C interface: */
118      void destruct ()
119          { if (this) klass->destruct (this); }
120  
121      err_ext_address_t *clone() const
122          { return klass->clone (this); }
123  
124      void format (err_v_char_t *v,
125                   ErrPreposition p = ERR_PREP_NONE,
126                   ErrFormatStyle s = ERR_FS_HUMAN) const
127          {
128              if (this) {
129                 if (klass->format_ext)
130                     klass->format_ext (v, this, p, s);
131                 else
132                 if (s == ERR_FS_HUMAN)
133                     klass->format (v, this, p);
134                 /* otherwise we print nothing since we cannot format this correctly. */
135              }
136          }
137  
138      ErrVChar to_vchar(ErrPreposition p = ERR_PREP_NONE) const;
139  
140      err_address_t to_linear (void) const
141         { return klass->to_linear (this); }
142  
143      void resolve (int tag, int orig_tag, int number, err_position_t *pos) const
144         { if (this && klass->resolve)
145               klass->resolve (tag, orig_tag, number, pos);
146         }
147  #endif
148  };
149  
150  #ifdef __cplusplus
151  extern "C" {
152  #endif
153  
154  /* and the class: */
155  extern err_ext_address_class_t const err_normal_address_class_s;
156  #define err_normal_address_class (&err_normal_address_class_s)
157  
158  #ifdef __cplusplus
159  }
160  #endif
161  
162  struct err_normal_address_t {
163      err_ext_address_t super;
164      err_address_t address;
165  #ifdef __cplusplus
166      err_normal_address_t (err_address_t a):
167          super (err_normal_address_class),
168          address (a)
169      {}
170  #endif
171  };
172  #ifdef __cplusplus
173  typedef struct err_normal_address_t ErrNormalAddress;
174  #else
175  typedef struct err_normal_address_t err_normal_address_t;
176  #endif
177  
178  /* In the way err_normal_address_t is defined, you can define your own addresses. */
179  
180  
181  struct err_area_t;
182  #ifdef __cplusplus
183  typedef struct err_area_t ErrArea;
184  #else
185  typedef struct err_area_t err_area_t;
186  #endif
187  
188  struct err_location_t;
189  #ifdef __cplusplus
190  typedef struct err_location_t ErrLocation;
191  #else
192  typedef struct err_location_t err_location_t;
193  #endif
194  
195  /* Do not use err_position_t directly from C, only from C++ or via the
196   * err_set_... functions. */
197  struct err_position_t {
198      int  *refcount; /* Reference counter deciding when to copy/free file and address */
199      char *file;
200      err_ext_address_t *address;
201      int line;
202      int pos;
203  #ifdef __cplusplus
204  private:
205      void release ();
206      void import (char const *,  int, int, ErrExtAddress *);  /* always makes a full copy */
207      void import (int *, char *, int, int, ErrExtAddress *);  /* shares the data */
208  public:
209      err_position_t (char const * = NULL, int = 0, int = 0);
210      err_position_t (err_address_t);
211      err_position_t (err_ext_address_t const &);
212      err_position_t (err_ext_address_t const *);
213  
214      void set_position (char const * = NULL, int = 0, int = 0);
215  
216      err_position_t (err_position_t const &);
217  
218      void operator= (err_position_t const &);
219      void operator= (err_area_t const &);     /* for msvc 6.0 which does not find the conversion */
220      void operator= (err_location_t const &); /* for msvc 6.0 which does not find the conversion */
221  
222      ~err_position_t ();
223  
224      bool valid() const { return file != NULL || address != NULL; }
225  
226      operator err_position_t const *() const { return this; }
227  
228      operator err_area_t const *() const;
229      operator err_area_t () const;
230  
231      operator err_location_t const *() const;
232      operator err_location_t () const;
233  #endif
234  };
235  
236  struct err_area_t {
237      err_position_t first;
238      err_position_t last;
239  #ifdef __cplusplus
240      err_area_t (err_position_t const &);
241      err_area_t (err_address_t);
242      err_area_t (err_ext_address_t const &);
243      err_area_t (err_ext_address_t const *);
244      err_area_t (char const * = NULL, int = 0, int = 0);
245          /* An error location is actually an error area.   You can define the start here
246           * and add the end using upto(). */
247  
248      err_area_t (err_position_t const &, err_position_t const &);
249          /* To set both at the same time, start and end, use this. */
250  
251      err_area_t &upto (char const *a= NULL, int b= 0, int c= 0)
252      {
253          last= ErrPosition (a, b, c);
254          return *this;
255      }
256  
257      err_area_t &upto (err_address_t a)
258      {
259          last= ErrPosition (a);
260          return *this;
261      }
262  
263      err_area_t (err_area_t const &);
264      void operator= (err_position_t const &); /* for msvc 6.0 which does not find the conversion */
265      void operator= (err_area_t const &);
266      void operator= (err_location_t const &); /* for msvc 6.0 which does not find the conversion */
267      ~err_area_t ();
268  
269      operator err_position_t const *() const { return &first; }
270      operator err_position_t const &() const { return first; }
271  
272      operator err_area_t const *() const     { return this;  }
273  
274      operator err_location_t const *() const;
275      operator err_location_t () const;
276  
277      bool valid() const { return first.valid(); }
278  #endif
279  };
280  
281  typedef void (*ErrLocationPrinter)(err_v_char_t *, err_location_t const *);
282  typedef ErrLocationPrinter err_location_printer_t;
283  
284  struct err_location_t {
285      err_area_t here;
286      err_area_t orig;
287          /* original position (e.g. found by #line directives)
288           *
289           * more complex error locations have to be modelled by several invocations
290           * of eprintf(C_TAG_MORE, ...) or by the extension mechanism using next_loc
291           * and print_next.  See set_next(). */
292  
293      err_location_t *next_loc;
294  
295      ErrLocationPrinter print_next;
296          /* extension mechanism: if next_loc is != NULL, if is appended
297           * to messages and print_next is invoked to print a text that
298           * describes that other location.
299           *
300           * Always use set_next() to set these.
301           *
302           * Note that next_loc is automatically properly copied. */
303  
304  #ifdef __cplusplus
305      /* To set the primary position (either an address or an explicit area): */
306      err_location_t (err_area_t const &);
307      err_location_t (err_position_t const &);
308      err_location_t (err_address_t);
309      err_location_t (err_ext_address_t const &);
310      err_location_t (err_ext_address_t const *);
311      err_location_t (char const * = NULL, int = 0, int = 0);
312          /* An error location is actually an error area.   You can define the start here
313           * and add the end using upto().   Further, you can add the original position
314           * by using originally(...).upto(). */
315  
316      err_location_t (err_position_t const &, err_position_t const &);
317          /* To set both at the same time, start and end, use this. */
318  
319      err_location_t (err_area_t const &, err_area_t const &);
320          /* To set both, the normal and the original position. */
321  
322      /* The following upto() functions change the original location if
323       * that is valid, and the normal location otherwise.  Therefore, you
324       * can use a sequence of member calls like the following:
325       *    ErrLocation(...).upto(...).originally(...).upto(...)
326       * this also works:
327       *    ErrLocation(...).originally(...).upto(...).originally()
328       * If that scheme is not enough for your application, you need to add
329       * more calls to eprintf(C_TAG_MORE, ...).
330       */
331      err_area_t &free_upto()
332      {
333          return here.last.valid() ? orig : here;
334      }
335  
336      err_position_t &free_orig()
337      {
338          return orig.first.valid() ? orig.last : orig.first;
339      }
340  
341      err_location_t &upto (char const *a, int b= 0, int c= 0)
342      {
343          free_upto().last= ErrPosition (a, b, c);
344          return *this;
345      }
346  
347      /* Upto in the same file (pos must be given so that this constructor can be
348       * distinguished from the following one*/
349      err_location_t &upto (int a, int b)
350      {
351          free_upto().last= ErrPosition (free_upto().first.file, a, b);
352          return *this;
353      }
354  
355      err_location_t &upto (err_address_t a)
356      {
357          free_upto().last= ErrPosition (a);
358          return *this;
359      }
360  
361      err_location_t &originally (char const *a, int b= 0, int c= 0)
362      {
363          free_orig()= ErrPosition (a, b, c);
364          return *this;
365      }
366  
367      err_location_t &originally (int a, int b)
368      {
369          free_orig()= ErrPosition (orig.first.file, a, b);
370          return *this;
371      }
372  
373      err_location_t &originally (err_address_t a)
374      {
375          free_orig()= ErrPosition (a);
376          return *this;
377      }
378  
379      err_location_t &set_next (
380          err_location_t const *,
381          ErrLocationPrinter);
382          /* returns the pointer to the internal copy */
383  
384      err_location_t (err_location_t const &);
385  
386      void operator= (err_position_t const &); /* for msvc 6.0 which does not find the conversion */
387      void operator= (err_area_t const &);     /* for msvc 6.0 which does not find the conversion */
388      void operator= (err_location_t const &);
389  
390      ~err_location_t ();
391  
392      operator err_position_t const *() const { return &here.first; }
393      operator err_position_t const &() const { return here.first; }
394  
395      operator err_area_t     const *() const { return &here; }
396      operator err_area_t     const &() const { return here; }
397  
398      operator err_location_t const *() const { return this; }
399  
400      bool valid() const { return here.valid(); }
401  #endif
402  };
403  
404  struct err_msg_info_t;
405  #ifdef __cplusplus
406  typedef struct err_msg_info_t ErrMsgInfo;
407  #else
408  typedef struct err_msg_info_t err_msg_info_t;
409  #endif
410  
411  struct err_msg_info_t {
412      time_t issue_time;
413  #ifdef __cplusplus
414      err_msg_info_t ():
415           issue_time (time(NULL))
416      {}
417  #endif
418  };
419  
420  /* ********************************************************************** */
421  
422  #ifdef __cplusplus
423  extern "C" {
424  #endif
425  
426  /* C interface for the super class: currently only _init: */
427  extern void err_ext_address_init (err_ext_address_t *, err_ext_address_class_t const *);
428  
429  /* virtual functions and class of the standard implementation: */
430  extern void err_normal_address_destruct (err_ext_address_t *);
431  extern err_ext_address_t *err_normal_address_clone (err_ext_address_t const *);
432  extern void err_normal_address_format (
433      err_v_char_t *, err_ext_address_t const *, err_preposition_t);
434  extern void err_normal_address_format_ext (
435      err_v_char_t *, err_ext_address_t const *, err_preposition_t, err_format_style_t);
436  extern err_address_t err_normal_address_to_linear (err_ext_address_t const *);
437  extern void err_normal_address_format_preposition (err_v_char_t *, err_preposition_t);
438  
439  /*
440   * The following return a reference to a static variable, so you
441   * cannot invoke these twice in the same expression.
442   *
443   * When using C++, use ErrPosition(...) instead, this does
444   * not have this problem.
445   */
446  extern err_location_t *err_in_file     (char const *);
447  extern err_location_t *err_in_line     (char const *, int);
448  extern err_location_t *err_at_position (char const *, int, int);
449  extern err_location_t *err_at_address  (err_address_t);
450  extern err_location_t *err_at_ext_address  (err_ext_address_t const *);
451     /* These define an error position
452      * Info: this function returns a pointer to a static variable!
453      */
454  
455  extern err_location_t *err_location_copy (err_location_t const *) ATTR_MALLOC;
456  extern void            err_location_delete (err_location_t *);
457  
458  extern err_location_t *err_upto_file        (err_location_t *, char const *);
459  extern err_location_t *err_upto_line        (err_location_t *, char const *, int);
460  extern err_location_t *err_upto_position    (err_location_t *, char const *, int, int);
461  extern err_location_t *err_upto_address     (err_location_t *, err_address_t);
462  extern err_location_t *err_upto_ext_address (err_location_t *, err_ext_address_t const *);
463     /* These adds the end of the error area */
464  
465  extern err_location_t *err_originally_in_file (err_location_t *, err_location_t *, char const *);
466  extern err_location_t *err_originally_in_line (err_location_t *, char const *, int);
467  extern err_location_t *err_originally_at_position   (err_location_t *, char const *, int, int);
468  extern err_location_t *err_originally_at_address    (err_location_t *, err_address_t);
469  extern err_location_t *err_originally_at_ext_address(err_location_t *, err_ext_address_t const *);
470     /* These adds the original position of the error which can also be modified
471      * by the upto functions. */
472  
473  extern err_location_t *err_set_next_loc (
474      err_location_t *,
475      err_location_t const *,
476      err_location_printer_t);
477  
478  extern void err_set_in_file     (err_position_t *, char const *);
479  extern void err_set_in_line     (err_position_t *, char const *, int);
480  extern void err_set_at_position (err_position_t *, char const *, int, int);
481     /* for modification of a position (e.g. during resolving of addresses) */
482  
483  /* ********************************************************************** */
484  
485  extern int fxprintf   (FILE *, char const *format, ...)          ATTR_FORMAT_PRINTF (2,3);
486    /*
487     * *xprintf family: extended printf implemented with Erwin's VectorChar::format.
488     *
489     * By using Erwin for printing:
490     *    - %Lx is supported
491     *    - %s prints NULL safely
492     *    - etc.
493     *
494     * And they are NULL-safe: if either the file, string or the format is NULL, the
495     * functions simply return 0.
496     *
497     */
498  
499  extern int vfxprintf  (FILE *, char const *format, va_list)      ATTR_FORMAT_VPRINTF(2);
500    /* Varargs version of fxprintf */
501  
502  extern int foxprintf  (FILE *, int, char const *format, ...)     ATTR_FORMAT_PRINTF (3,4);
503    /* Like fxprintf with Erwin format options. */
504  
505  extern int vfoxprintf (FILE *, int, char const *format, va_list) ATTR_FORMAT_VPRINTF(3);
506    /* Varargs version of fxprintf with Erwin format options */
507  
508  #ifdef ERR_HAVE_STDERR
509  
510  extern int xprintf   (char const *format, ...)          ATTR_FORMAT_PRINTF (1,2);
511    /* like fxprintf with stream == stdout */
512  
513  extern int vxprintf  (char const *format, va_list)      ATTR_FORMAT_VPRINTF(1);
514    /* like vfxprintf with stream == stdout */
515  
516  extern int oxprintf  (int, char const *format, ...)     ATTR_FORMAT_PRINTF (2,3);
517    /* like foxprintf with stream == stdout */
518  
519  extern int voxprintf (int, char const *format, va_list) ATTR_FORMAT_VPRINTF(2);
520    /* like vfoxprintf with stream == stdout */
521  
522  #endif /* defined ERR_HAVE_STDERR */
523  
524  extern int snxprintf   (char *, int, char const *format, ...)          ATTR_FORMAT_PRINTF (3,4);
525     /* Like snprintf, but implemented with Erwin and buffer overflow safe.
526      *
527      * Well, better use Erwin directly than this family of functions.  They
528      * are here for convenience only.  However, they work. :-)
529      *
530      * Also, sprintf should never be used (-> buffer overflow), so its equivalent
531      * is not implemented here.
532      */
533  
534  extern int vsnxprintf  (char *, int, char const *format, va_list)      ATTR_FORMAT_VPRINTF(3);
535     /* Varargs version of snxprintf */
536  
537  extern int snoxprintf  (char *, int, int, char const *format, ...)     ATTR_FORMAT_PRINTF (4,5);
538     /* Like snxprintf with Erwin format options. */
539  
540  extern int vsnoxprintf (char *, int, int, char const *format, va_list) ATTR_FORMAT_VPRINTF(4);
541     /* Varargs version of snxprintf with Erwin format options. */
542  
543  /*
544   * Main routines for printing messages. */
545  
546  #ifdef IN_LIBERROR_COMPILE
547  #  include "error/printf-gen.h"
548  #else
549  #  include <error/printf-gen.h>
550  #endif
551  
552  /* err-renumber */
553  extern int voleprintf (
554      int tag, int number, int /*options*/, err_location_t const *,
555      char const *, va_list) ATTR_FORMAT_VPRINTF(5);
556     /* Many variants if eprintf() and deprintf():
557      *
558      * The name is a concatenation of (in that very order):
559      *
560      *   a) The argument passing type:
561      *         - "":    by ...
562      *                    : eprintf  (tag, num, format, ...)
563      *         - "v":   by va_list e.g.
564      *                    : veprintf (tag, num, format, va)
565      *
566      *   b) The option argument to Erwin format:
567      *         - "":    options are 0:
568      *                    : eprintf (tag, num, format, ...)
569      *         - "q":   options are ERR_FO_QUOTE_C_STRING:
570      *                    : qeprintf  (tag, num, format, ...)
571      *                    : vqeprintf (tag, num, format, va)
572      *         - "o":   options are passed before the format string:
573      *                    : oeprintf  (tag, num, options, format, ...)
574      *                    : voeprintf (tag, num, options, format, va)
575      *
576      *   c) The location argument:
577      *         - "":    no location:
578      *                    :  eprintf (tag, num, format, ...)
579      *         - "fl":  file and line are given:
580      *                    :  fleprintf   (tag, num, file, line, format, ...)
581      *                    :  vofleprintf (tag, num, file, line, options, format, va)
582      *         - "flp": file, line and position (=column) are given:
583      *                    :  flpeprintf   (tag, num, file, line, pos, format, ...)
584      *                    :  voflpeprintf (tag, num, file, line, pos, options, format, va)
585      *         - "p":   an err_location_t const * argument is passed.  This pointer
586      *                  may always be a local reference even if the message is buffered.
587      *                  The library copies the contents if needed.
588      *                    :  leprintf   (tag, num, loc, format, ...)
589      *                    :  voleprintf (tag, num, loc, options, format, va)
590      *
591      *   d) The debugging indicator:
592      *         - "":    not a debugging version
593      *                    :  eprintf (tag, num, format, ...)
594      *         - "d":  debugging version
595      *                    :  deprintf (tag, num, format, ...)
596      *                 This marks the message as a developer message by
597      *                 adding C_TAG_DEBUG to the tag.  Further, with
598      *                 either -DNDEBUG or -DRELEASE, these functions will
599      *                 not produce any message at all (it fact, the calls
600      *                 will not even produce any code, so you can safely
601      *                 use these without fearing that shipped code contains
602      *                 debug code for generating the arguments).
603      *
604      * The tag is a single bit C_TAG_xyz constant (see error/tags.h).  You may
605      * add a subsystem and/or group classification to it by using err_group()
606      * and err_subsystem:
607      *
608      *   : eprintf (C_TAG_ERROR | err_subsystem("lexer"), 0, "blahblah");
609      *
610      * If num == 0, the number it is not printed.
611      * You can use the errcodes script to insert the numbers automatically and
612      * to check them into CVS.
613      *
614      * Note: the error message will automatically be ensured to end in
615      * \n.  You, therefore, cannot issue one message using several
616      * eprintf() calls.  This is vital for the internal handling of
617      * error messages anyway: one call = one message.  However,
618      * multi-line messages with additional lines that give additional
619      * information can be implemented with the special error tag
620      * C_TAG_MORE.
621      *
622      * Options are Erwin vector options (e.g. ERR_FO_QUOTE_C_STRING etc.)
623      * (The Erwin library of this error library has the prefix err_/ERR_/Err.)
624      *
625      * The functions print the progname, PID, possible color tag, and a prefix
626      * depending on the kind of message.
627      *
628      * If tag == C_TAG_MORE and num == 0, the previous number is used.  The same
629      * holds for the tag in this case, which is replaced by the previous tag for
630      * formatting.  However, C_TAG_MORE may have a different number to allow
631      * separate filtering etc.
632      *
633      * The q-functions use the ERR_FO_QUOTE_C_STRING as options for printing (this is a
634      * convenience abbreviation).
635      *
636      * The fl types print a file and a line number in front of the message.
637      *
638      * The flp types print a file, a line number and a line position.
639      *
640      * The a types print an address or, if they can look up that address, the corresponding
641      * file, a line number and possibly a line position.
642      *
643      * Note that because of the compatibility with the fprintf family, these
644      * routines return the number of characters that were printed, althought
645      * this is really quite uninteresting information most of the time.
646      * To be precise, the functions return the number of characters printed
647      * without the automatic prefix (file, line, etc.), but the amount of
648      * characters that resulted from formatting the user format string with
649      * its arguments:
650      *
651      *   : fleprintf (C_TAG_ERROR, 0, "hello.c", 24, "abc");
652      *
653      * returns 3 (the length of "abc")
654      *
655      * The de-variants (instead of e-variants) are for development and are not
656      * compiled in when NDEBUG is defined.  Messages issued using the de-family
657      * never change the message counters, because counting would change in the
658      * development version.  Further, bodies of messages printed with de-variants
659      * are colored using the C_TAG_DEBUG color.
660      *
661      * Note that the de-family does not return a value.  (This is due to some
662      * compilers that do not support macro varargs.)
663      *
664      * C_TAG_FATAL should be used with de-printf, since the call-back that
665      * exits the program will not be invoked with NDEBUG.
666      *
667      * Note: the tag C_TAG_DEBUG is a different message classification:
668      * deprintf is thought to be for all kinds of messages that are
669      * interesting to the developer, but not to users.  E.g. a message
670      * might indicate that some strange situation was encountered so that
671      * an algorithm is not used, while in the production line of the
672      * program, the algorithm is silently not used.  C_TAG_DEBUG is more meant
673      * to be for larger loads of messages that issue state information
674      * about the algorithm during debugging, while deprintf is for messages
675      * that are issued when unexpected things happend while you think that
676      * an algorithm works.
677      */
678  
679  #ifdef __cplusplus
680  }
681  #endif
682  
683  #endif /* !defined HT_ERROR_EPRINTF_H */

Index

Stoppt die Vorratsdatenspeicherung
November 26th, 2007
Comments? Suggestions? Corrections? You can drop me a line.
zpentrabvagiktu@theiling.de
Schwerpunktpraxis