home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1279 < prev    next >
Internet Message Format  |  1990-12-28  |  3KB

  1. From: robwah@auto-trol.UUCP (Robert Wahl)
  2. Newsgroups: comp.lang.c,comp.unix.wizards,alt.sources,comp.sources.d,misc.misc
  3. Subject: Re: #define DEBUG... (using printf for debugging)
  4. Message-ID: <1104@auto-trol.UUCP>
  5. Date: 7 May 90 22:00:03 GMT
  6.  
  7. William Silver writes:
  8. >Is there a way to define Debug so that Debug(x, y, z,...) can optionally
  9. >either do nothing or generate fprintf(stderr, x, y, z,...) with an
  10. >arbitrary number of arguments?  Crawford's method still requires
  11. >specific mention of stderr in each debug line.
  12.  
  13. Consider the basic setup which is required to use a variable argument list in
  14. a macro.  The list must be used as the argument list of a function call, and
  15. no other arguments can be added.  However, that function need not be printf:
  16.  
  17. #ifdef DEBUG
  18. #define DPRINTF(list) (dprintf list)
  19. #else
  20. #define DPRINTF(list) (1) /* Allows use of DPRINTF in expressions */
  21. #endif
  22.  
  23. DPRINTF ((fmtstr, arg1, arg2, arg3));
  24.  
  25. Writing "dprintf" is left as an exercise for the reader.  Using assembly
  26. language, it may be an easy thing to prepend stderr to the variable argument
  27. list and then call "fprintf".  Most likely, though, you will have to parse the
  28. format string for the number and type of arguments in order to set up the
  29. call to "fprintf".  If so, you might as well do it all in C (which at least
  30. is portable), and do your output in stages.
  31.  
  32. Here's a simply coded, but dreadfully hacky solution:  temporarily replace
  33. stdout with stderr, then use printf as suggested before.  This is inherently
  34. non-portable, inefficient, risky and generates lots of code.
  35.  
  36. #ifdef DEBUG
  37. static FILE dprintf_stdout;
  38. static int dprintf_retval;
  39. #define DPRINTF(list) (dprintf_stdout = *stdout, *stdout = *stderr, \
  40.     dprintf_retval = printf list, *stdout = dprintf_stdout), dprintf_retval)
  41. #else
  42. #define DPRINTF(list) (1) /* Allows use of DPRINTF in expressions */
  43. #endif
  44.  
  45. If you do use this method, forget that you heard of it from me.
  46.  
  47. Perhaps the best solution is just to use fixed argument lists; after all, how
  48. many values do you typically output in one debug statement?
  49.  
  50. #ifdef DEBUG
  51. #define Debug0(fmt)        (fprintf (stderr, fmt))
  52. #define Debug1(fmt,val1)    (fprintf (stderr, fmt, val1))
  53. #define Debug2(fmt,val1,val2)    (fprintf (stderr, fmt, val1, val2))
  54. ...
  55. #else
  56. #define Debug0(fmt)        (1)
  57. #define Debug1(fmt,val1)    (1)
  58. #define Debug2(fmt,val1,val2)    (1)
  59. ...
  60. #endif
  61.  
  62. Debug3 ("Name is %s, value is %d (0x%x)\n", name, val, val);
  63.     or
  64. Debug1 ("Name is %s, ", name);  /* Note lack of newline in format string */
  65. Debug2 ("value is %d (0x%x)\n", val, val);
  66. -- 
  67. Rob Wahl  =:->  {robwah@auto-trol.com | ...!ncar!ico!auto-trol|robwah}
  68.