4139N/A<span id="id1"></span><h1>Tutorial<a class="headerlink" href="#tutorial" title="Permalink to this headline">¶</a></h1>
4139N/Aof a repository in <a class="reference external" href="https://github.com/">GitHub</a> over the web. <a class="reference external" href="http://developer.github.com/">GitHub API</a> uses JSON, so
4139N/A<a class="reference download internal" href="_downloads/github_commits.c"><tt class="xref download docutils literal"><span class="pre">github_commits.c</span></tt></a>. To compile it (on Unix-like systems with
4139N/A<div class="highlight-c"><div class="highlight"><pre><span class="n">gcc</span> <span class="o">-</span><span class="n">o</span> <span class="n">github_commits</span> <span class="n">github_commits</span><span class="p">.</span><span class="n">c</span> <span class="o">-</span><span class="n">ljansson</span> <span class="o">-</span><span class="n">lcurl</span>
4139N/A<p><a class="reference external" href="http://curl.haxx.se/">libcurl</a> is used to communicate over the web, so it is required to
4139N/A<div class="highlight-c"><div class="highlight"><pre><span class="n">github_commits</span> <span class="n">USER</span> <span class="n">REPOSITORY</span>
4139N/A<p><tt class="docutils literal"><span class="pre">USER</span></tt> is a GitHub user ID and <tt class="docutils literal"><span class="pre">REPOSITORY</span></tt> is the repository
4139N/A<span id="tutorial-github-commits-api"></span><h2>The GitHub Repo Commits API<a class="headerlink" href="#the-github-repo-commits-api" title="Permalink to this headline">¶</a></h2>
4139N/A<p>The <a class="reference external" href="http://developer.github.com/v3/repos/commits/">GitHub Repo Commits API</a> is used by sending HTTP requests to
4139N/AURLs like <tt class="docutils literal"><span class="pre">https://api.github.com/repos/USER/REPOSITORY/commits</span></tt>,
4139N/Awhere <tt class="docutils literal"><span class="pre">USER</span></tt> and <tt class="docutils literal"><span class="pre">REPOSITORY</span></tt> are the GitHub user ID and the name
4139N/A<div class="highlight-c"><div class="highlight"><pre><span class="k">static</span> <span class="kt">char</span> <span class="o">*</span><span class="nf">request</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">url</span><span class="p">);</span>
4139N/Areturn value is <em>NULL</em>. For full details, refer to <a class="reference download internal" href="_downloads/github_commits.c"><tt class="xref download docutils literal"><span class="pre">the</span> <span class="pre">code</span></tt></a>, as the actual implementation is not important
4139N/A<span id="tutorial-the-program"></span><h2>The Program<a class="headerlink" href="#the-program" title="Permalink to this headline">¶</a></h2>
4139N/A<div class="highlight-c"><div class="highlight"><pre><span class="cp">#include <string.h></span>
4139N/A<div class="highlight-c"><div class="highlight"><pre><span class="cp">#define URL_FORMAT "https:</span><span class="c1">//api.github.com/repos/%s/%s/commits"</span>
4139N/A<div class="highlight-c"><div class="highlight"><pre><span class="cm">/* Return the offset of the first newline in text or the length of</span>
4139N/A<span class="k">static</span> <span class="kt">int</span> <span class="nf">newline_offset</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">text</span><span class="p">)</span>
4139N/A <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">newline</span> <span class="o">=</span> <span class="n">strchr</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="sc">'\n'</span><span class="p">);</span>
4139N/A <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">newline</span><span class="p">)</span>
4139N/A <span class="k">return</span> <span class="n">strlen</span><span class="p">(</span><span class="n">text</span><span class="p">);</span>
4139N/A <span class="k">return</span> <span class="p">(</span><span class="kt">int</span><span class="p">)(</span><span class="n">newline</span> <span class="o">-</span> <span class="n">text</span><span class="p">);</span>
4139N/A<div class="highlight-c"><div class="highlight"><pre><span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">int</span> <span class="n">argc</span><span class="p">,</span> <span class="kt">char</span> <span class="o">*</span><span class="n">argv</span><span class="p">[])</span>
4139N/A <span class="kt">char</span> <span class="o">*</span><span class="n">text</span><span class="p">;</span>
4139N/A <span class="kt">char</span> <span class="n">url</span><span class="p">[</span><span class="n">URL_SIZE</span><span class="p">];</span>
4139N/A <span class="kt">json_t</span> <span class="o">*</span><span class="n">root</span><span class="p">;</span>
4139N/A <span class="k">if</span><span class="p">(</span><span class="n">argc</span> <span class="o">!=</span> <span class="mi">3</span><span class="p">)</span>
4139N/A <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"usage: %s USER REPOSITORY</span><span class="se">\n\n</span><span class="s">"</span><span class="p">,</span> <span class="n">argv</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
4139N/A <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"List commits at USER's REPOSITORY.</span><span class="se">\n\n</span><span class="s">"</span><span class="p">);</span>
4139N/A<div class="highlight-c"><div class="highlight"><pre><span class="n">snprintf</span><span class="p">(</span><span class="n">url</span><span class="p">,</span> <span class="n">URL_SIZE</span><span class="p">,</span> <span class="n">URL_FORMAT</span><span class="p">,</span> <span class="n">argv</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">argv</span><span class="p">[</span><span class="mi">2</span><span class="p">]);</span>
4139N/A<p>This uses the <tt class="docutils literal"><span class="pre">URL_SIZE</span></tt> and <tt class="docutils literal"><span class="pre">URL_FORMAT</span></tt> constants defined above.
4139N/A<div class="highlight-c"><div class="highlight"><pre><span class="n">text</span> <span class="o">=</span> <span class="n">request</span><span class="p">(</span><span class="n">url</span><span class="p">);</span>
4139N/A<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">text</span><span class="p">)</span>
4139N/A<p>If an error occurs, our function <tt class="docutils literal"><span class="pre">request</span></tt> prints the error and
4139N/A<p>Next we’ll call <a class="reference internal" href="apiref.html#c.json_loads" title="json_loads"><tt class="xref c c-func docutils literal"><span class="pre">json_loads()</span></tt></a> to decode the JSON text we got
4139N/A<div class="highlight-c"><div class="highlight"><pre><span class="n">root</span> <span class="o">=</span> <span class="n">json_loads</span><span class="p">(</span><span class="n">text</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">&</span><span class="n">error</span><span class="p">);</span>
4139N/A<span class="n">free</span><span class="p">(</span><span class="n">text</span><span class="p">);</span>
4139N/A<span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">root</span><span class="p">)</span>
4139N/A <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"error: on line %d: %s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">error</span><span class="p">.</span><span class="n">line</span><span class="p">,</span> <span class="n">error</span><span class="p">.</span><span class="n">text</span><span class="p">);</span>
4139N/A<p>We don’t need the JSON text anymore, so we can free the <tt class="docutils literal"><span class="pre">text</span></tt>
4139N/Avariable right after decoding it. If <a class="reference internal" href="apiref.html#c.json_loads" title="json_loads"><tt class="xref c c-func docutils literal"><span class="pre">json_loads()</span></tt></a> fails, it
4139N/Areturns <em>NULL</em> and sets error information to the <a class="reference internal" href="apiref.html#c.json_error_t" title="json_error_t"><tt class="xref c c-type docutils literal"><span class="pre">json_error_t</span></tt></a>
4139N/A<a class="reference internal" href="#tutorial-github-commits-api"><em>The GitHub Repo Commits API</em></a>.</p>
4139N/A<div class="highlight-c"><div class="highlight"><pre><span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">json_is_array</span><span class="p">(</span><span class="n">root</span><span class="p">))</span>
4139N/A <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"error: root is not an array</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span>
4139N/A <span class="n">json_decref</span><span class="p">(</span><span class="n">root</span><span class="p">);</span>
4139N/A<div class="highlight-c"><div class="highlight"><pre><span class="k">for</span><span class="p">(</span><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">json_array_size</span><span class="p">(</span><span class="n">root</span><span class="p">);</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
4139N/A <span class="kt">json_t</span> <span class="o">*</span><span class="n">data</span><span class="p">,</span> <span class="o">*</span><span class="n">sha</span><span class="p">,</span> <span class="o">*</span><span class="n">commit</span><span class="p">,</span> <span class="o">*</span><span class="n">message</span><span class="p">;</span>
4139N/A <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">message_text</span><span class="p">;</span>
4139N/A <span class="n">data</span> <span class="o">=</span> <span class="n">json_array_get</span><span class="p">(</span><span class="n">root</span><span class="p">,</span> <span class="n">i</span><span class="p">);</span>
4139N/A <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">json_is_object</span><span class="p">(</span><span class="n">data</span><span class="p">))</span>
4139N/A <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"error: commit data %d is not an object</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
4139N/A <span class="n">json_decref</span><span class="p">(</span><span class="n">root</span><span class="p">);</span>
4139N/A<p>The function <a class="reference internal" href="apiref.html#c.json_array_size" title="json_array_size"><tt class="xref c c-func docutils literal"><span class="pre">json_array_size()</span></tt></a> returns the size of a JSON
4139N/Ai’th element of the <tt class="docutils literal"><span class="pre">root</span></tt> array using <a class="reference internal" href="apiref.html#c.json_array_get" title="json_array_get"><tt class="xref c c-func docutils literal"><span class="pre">json_array_get()</span></tt></a>.
4139N/A<div class="highlight-c"><div class="highlight"><pre> <span class="n">sha</span> <span class="o">=</span> <span class="n">json_object_get</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="s">"sha"</span><span class="p">);</span>
4139N/A <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">json_is_string</span><span class="p">(</span><span class="n">sha</span><span class="p">))</span>
4139N/A <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"error: commit %d: sha is not a string</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
4139N/A <span class="n">json_decref</span><span class="p">(</span><span class="n">root</span><span class="p">);</span>
4139N/A <span class="n">commit</span> <span class="o">=</span> <span class="n">json_object_get</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="s">"commit"</span><span class="p">);</span>
4139N/A <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">json_is_object</span><span class="p">(</span><span class="n">commit</span><span class="p">))</span>
4139N/A <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"error: commit %d: commit is not an object</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
4139N/A <span class="n">json_decref</span><span class="p">(</span><span class="n">root</span><span class="p">);</span>
4139N/A <span class="n">message</span> <span class="o">=</span> <span class="n">json_object_get</span><span class="p">(</span><span class="n">commit</span><span class="p">,</span> <span class="s">"message"</span><span class="p">);</span>
4139N/A <span class="k">if</span><span class="p">(</span><span class="o">!</span><span class="n">json_is_string</span><span class="p">(</span><span class="n">message</span><span class="p">))</span>
4139N/A <span class="n">fprintf</span><span class="p">(</span><span class="n">stderr</span><span class="p">,</span> <span class="s">"error: commit %d: message is not a string</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
4139N/A <span class="n">json_decref</span><span class="p">(</span><span class="n">root</span><span class="p">);</span>
4139N/Afrom a JSON string using <a class="reference internal" href="apiref.html#c.json_string_value" title="json_string_value"><tt class="xref c c-func docutils literal"><span class="pre">json_string_value()</span></tt></a>:</p>
4139N/A<div class="highlight-c"><div class="highlight"><pre> <span class="n">message_text</span> <span class="o">=</span> <span class="n">json_string_value</span><span class="p">(</span><span class="n">message</span><span class="p">);</span>
4139N/A <span class="n">printf</span><span class="p">(</span><span class="s">"%.8s %.*s</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span>
4139N/A <span class="n">json_string_value</span><span class="p">(</span><span class="n">id</span><span class="p">),</span>
4139N/A <span class="n">newline_offset</span><span class="p">(</span><span class="n">message_text</span><span class="p">),</span>
4139N/A<a class="reference internal" href="apiref.html#c.json_loads" title="json_loads"><tt class="xref c c-func docutils literal"><span class="pre">json_loads()</span></tt></a>, remember? It returns a <em>new reference</em> to the
4139N/Ato decrease the reference count using <a class="reference internal" href="apiref.html#c.json_decref" title="json_decref"><tt class="xref c c-func docutils literal"><span class="pre">json_decref()</span></tt></a>. This way
4139N/A<div class="highlight-c"><div class="highlight"><pre><span class="n">json_decref</span><span class="p">(</span><span class="n">root</span><span class="p">);</span>
4139N/A<a class="reference internal" href="apiref.html#apiref-reference-count"><em>Reference Count</em></a> in <a class="reference internal" href="apiref.html#apiref"><em>API Reference</em></a>.</p>
4139N/A<h2>Conclusion<a class="headerlink" href="#conclusion" title="Permalink to this headline">¶</a></h2>
4139N/A<a class="reference internal" href="apiref.html#apiref"><em>API Reference</em></a> to explore all features of Jansson.</p>