<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0">
<channel>
<title>Fun with ones and zeros - c</title>
<description><![CDATA[Barry's notes on computer software and hardware]]></description>
<link>/blog/tags/c</link>
<lastBuildDate>Thu, 28 May 2026 07:54:12 -0700</lastBuildDate>
<item>
<title>Simple debugging output in C</title>
<link>/blog/entries/simple-debugging-output-c</link>
<pubDate>Sun, 03 Apr 2011 18:35:29 -0700</pubDate>
<author>bp@barryp.org (Barry Pederson)</author>
<description><![CDATA[<p>I don't do a whole lot of C programming, but when I do it tends to be in difficult environments like Apache modules or Samba VFS modules, where you can't just do simple printfs to get some output from your program.<br />
</p>
<p>I've come up with this small chunk of code I can plop in a C file to allow for optionally writing out useful information to a file somewhere on the disk.</p>
<div class="source"><pre><span class="cp">#ifdef DEBUG_FILENAME</span>
<span class="cp">    #include &lt;stdarg.h&gt;</span>
<span class="cp">    #include &lt;stdio.h&gt;</span>
<span class="cp">    #include &lt;time.h&gt;</span>
<span class="cp">    #define QUOTE(name) #name</span>
<span class="cp">    #define STR(macro) QUOTE(macro)</span>

    <span class="k">static</span> <span class="kt">void</span> <span class="nf">debug_log</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">msg</span><span class="p">,</span> <span class="p">...)</span> <span class="p">{</span>
        <span class="kt">char</span> <span class="n">timestamp</span><span class="p">[</span><span class="mi">32</span><span class="p">];</span> <span class="c1">// really only need 21 bytes here</span>
        <span class="kt">time_t</span> <span class="n">now</span><span class="p">;</span>
        <span class="kt">va_list</span> <span class="n">ap</span><span class="p">;</span>
        <span class="kt">FILE</span> <span class="o">*</span><span class="n">f</span><span class="p">;</span>

        <span class="n">now</span> <span class="o">=</span> <span class="n">time</span><span class="p">(</span><span class="nb">NULL</span><span class="p">);</span>
        <span class="n">strftime</span><span class="p">(</span><span class="n">timestamp</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">timestamp</span><span class="p">),</span> <span class="s">&quot;%Y-%m-%d %H:%M:%S &quot;</span><span class="p">,</span> <span class="n">localtime</span><span class="p">(</span><span class="o">&amp;</span><span class="n">now</span><span class="p">));</span>

        <span class="n">f</span> <span class="o">=</span> <span class="n">fopen</span><span class="p">(</span><span class="n">STR</span><span class="p">(</span><span class="n">DEBUG_FILENAME</span><span class="p">),</span> <span class="s">&quot;a&quot;</span><span class="p">);</span>

        <span class="n">fputs</span><span class="p">(</span><span class="n">timestamp</span><span class="p">,</span> <span class="n">f</span><span class="p">);</span>

        <span class="n">va_start</span><span class="p">(</span><span class="n">ap</span><span class="p">,</span> <span class="n">msg</span><span class="p">);</span>
        <span class="n">vfprintf</span><span class="p">(</span><span class="n">f</span><span class="p">,</span> <span class="n">msg</span><span class="p">,</span> <span class="n">ap</span><span class="p">);</span>
        <span class="n">va_end</span><span class="p">(</span><span class="n">ap</span><span class="p">);</span>

        <span class="n">fputc</span><span class="p">(</span><span class="sc">&#39;\n&#39;</span><span class="p">,</span> <span class="n">f</span><span class="p">);</span>
        <span class="n">fclose</span><span class="p">(</span><span class="n">f</span><span class="p">);</span>
    <span class="p">}</span>
<span class="cp">#else</span>
<span class="cp">    #define debug_log</span>
<span class="cp">#endif</span>
</pre></div>

<p>Within your program, you'd just sprinkle in calls to <code>debug_log()</code> with a format string and optional arguments, such as:</p>
<div class="source"><pre><span class="n">x</span> <span class="o">=</span> <span class="mi">5</span><span class="p">;</span>
<span class="n">y</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
<span class="n">debug_log</span><span class="p">(</span><span class="s">&quot;Currently, x=%d, y=%d&quot;</span><span class="p">,</span> <span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">);</span>
</pre></div>

<p>The code can then be enabled and configured to output to <code>/tmp/foo.log</code> (for example), by adding either</p>
<div class="source"><pre><span class="cp">#define DEBUG_FILENAME /tmp/foo.log</span>
</pre></div>

<p>to the top of your source file, or even more slickly for some things, from the commandline with</p>
<pre><code>cc -DDEBUG_FILENAME=/tmp/foo.log myprogram.c
</code></pre>
<p>When the program is run, in your <code>/tmp/foo.log</code> file you'd find something like:</p>
<pre><code>2011-04-03 20:30:05 Currently, x=5, y=10
</code></pre>
<p>If you don't define <code>DEBUG_FILENAME</code>, the code basically goes away, shouldn't take up any space in your binary at all.</p>]]></description>
</item>
</channel>
</rss>