<?xml version="1.0"?>

<rss version="2.0">
  <channel>
    <title>Wandrian</title>
    <link>http://wandrian.net</link>
    <description>Various ramblings from a geek.</description>
    <language>en</language>
    <managingEditor>khaelin@gmail.com (Nicolas Martyanoff)</managingEditor>
    <webMaster>khaelin@gmail.com (Nicolas Martyanoff)</webMaster>
  <item>
    <title><![CDATA[Indentation of HTML S-expressions]]></title>
    <guid>http://wandrian.net/2012-06-16-1450-html-sexpr-indentation.html</guid>
    <link>http://wandrian.net/2012-06-16-1450-html-sexpr-indentation.html</link>
    <pubDate>Sat, 16 Jun 2012 14:50:00 +0200</pubDate>
    <description><![CDATA[

<p>I’m using <a href="http://weitz.de/cl-who">cl-who</a> to generate HTML pages using simple S-expressions:</p>
<p>The only problem I had was the way these expressions are indented in Emacs. For example, a simple table will be indented as follows:</p>
<pre class="sourceCode commonlisp"><code class="sourceCode commonlisp">(:table :id <span class="st">&quot;layout&quot;</span>
        (:tr
         (:td :class <span class="st">&quot;id&quot;</span>
              (:div :class <span class="st">&quot;box&quot;</span>
                    <span class="st">&quot;Content&quot;</span>))))</code></pre>
<p>This is quite annoying for large pages where the content of the page is quickly far too much indented.</p>
<p>Fortunately, with the <code>slime-cl-indent</code> module provided with Slime, it’s possible to customize indentation rules.</p>
<p>I use this small function to modify indentation rules:</p>
<pre class="sourceCode commonlisp"><code class="sourceCode commonlisp">(<span class="kw">defun</span><span class="fu"> nm-cl-indent </span>(<span class="kw">symbol</span> indent)
  <span class="st">&quot;Set the indentation of SYMBOL to INDENT.&quot;</span>
  (put <span class="kw">symbol</span> &#39;common-lisp-indent-function
       (<span class="kw">if</span> (<span class="kw">symbolp</span> indent)
           (<span class="kw">get</span> indent &#39;common-lisp-indent-function)
         indent)))</code></pre>
<p>Then I change the indentation rules for all HTML elements:</p>
<pre class="sourceCode commonlisp"><code class="sourceCode commonlisp">(<span class="kw">defvar</span><span class="fu"> *nm-cl-html-symbols*</span>
  (<span class="kw">list</span> :a :abbr :acronym :address :applet :area :article :aside :audio :b
        <span class="kw">:base</span> :basefont :bdi :bdo :big :blockquote :body :br :button :canvas
        :caption :center :cite :code :col :colgroup :command :datalist :dd
        :del :details :dfn :dir :div :dl :dt :em :embed :fieldset :figcaption
        :figure :font :footer :form :frame :frameset :h1 :h2 :h3 :h4 :h5 :h6
        :head :header :hgroup :hr :html :i :iframe :img <span class="kw">:input</span> :ins :keygen
        :kbd :label :legend :li :link :map :mark :menu :meta :meter :nav
        :noframes :noscript :object :ol :optgroup :option <span class="kw">:output</span> :p :param
        :pre :progress :q :rp :rt :ruby :s :samp :script :section :select
        :small :source :span :strike :strong :style :sub :summary :sup :table
        :tbody :td :textarea :tfoot :th :thead :time :title :tr :track :tt :u
        :ul :var :video :wbr))

(<span class="kw">dolist</span> (<span class="kw">symbol</span> *nm-cl-html-symbols*)
  (nm-cl-indent <span class="kw">symbol</span> &#39;(&amp;body)))</code></pre>
<p>HTML S-expressions are now more compact:</p>
<pre class="sourceCode commonlisp"><code class="sourceCode commonlisp">(:table :id <span class="st">&quot;layout&quot;</span>
  (:tr
    (:td :class <span class="st">&quot;id&quot;</span>
      (:div :class <span class="st">&quot;box&quot;</span>
        <span class="st">&quot;Content&quot;</span>))))</code></pre>]]></description>
  </item>
  <item>
    <title><![CDATA[Swank modules in cores]]></title>
    <guid>http://wandrian.net/2012-06-13-1610-swank-modules-in-core.html</guid>
    <link>http://wandrian.net/2012-06-13-1610-swank-modules-in-core.html</link>
    <pubDate>Wed, 13 Jun 2012 16:10:00 +0200</pubDate>
    <description><![CDATA[

<p>I have this application running from an executable core generated by SBCL. When it starts, it creates a Swank server. But when I connect to this server, Swank tries to load the Swank part of the slime modules I use in my Emacs configuration, and fails with the following error message:</p>
<pre><code>Can&#39;t locate module: SWANK-IO-PACKAGE::SWANK-MEDIA</code></pre>
<p>It’s not a problem if the Swank sources are on the machine the application runs on, but if it’s not the case, it’s possible to load the Swank modules in the core.</p>
<p>In the function which generates the core, I simply call the <code>swank-require</code> function of the <code>swank</code> system:</p>
<pre class="sourceCode commonlisp"><code class="sourceCode commonlisp">(swank:swank-require &#39;(swank-repl swank-asdf swank-fuzzy swank-indentation
                       swank-media))</code></pre>
<p>This way I don’t have to deploy any source file with my core.</p>]]></description>
  </item>
  <item>
    <title><![CDATA[Display images in Emacs from Common Lisp]]></title>
    <guid>http://wandrian.net/2012-05-14-2110-display-images-in-emacs-from-common-lisp.html</guid>
    <link>http://wandrian.net/2012-05-14-2110-display-images-in-emacs-from-common-lisp.html</link>
    <pubDate>Mon, 14 May 2012 21:10:00 +0200</pubDate>
    <description><![CDATA[

<p>The slime repl is used to interact with a Common Lisp process, and while printing textual information is good enough most of the time, being able to display an image can be really useful.</p>
<p>I used to simply call an external process, the image viewer <a href="http://feh.finalrewind.org">feh</a>, but the following method is more interesting.</p>
<p>You first need to load the <code>slime-media</code> module which is provided with slime, for example by adding it to the list of modules to load with slime:</p>
<pre class="sourceCode commonlisp"><code class="sourceCode commonlisp">(slime-setup &#39;(slime-repl
               slime-asdf
               slime-fuzzy
               slime-banner
               slime-indentation
               slime-media))</code></pre>
<p>You then have to authorize Slime to evaluate arbitrary lisp forms coming from the Common Lisp process:</p>
<pre class="sourceCode commonlisp"><code class="sourceCode commonlisp">(<span class="kw">setq</span> slime-enable-evaluate-in-emacs <span class="kw">t</span>)</code></pre>
<p>Let’s display an image:</p>
<center>
<img src="/img/slime-images/slime-images.png" />
</center>

<p>It looks pretty good, but I really wanted to have the return value printed below the image, and not on its right.</p>
<p>The following function is a modification of <code>slime-media-insert-image</code>; an end-of-line character is inserted just after the image. This way, the result value is printed below the image. Furthermore, when more than one image is displayed during the same call, it won’t be crammed on the same line.</p>
<pre class="sourceCode commonlisp"><code class="sourceCode commonlisp">(<span class="kw">defun</span><span class="fu"> nm-slime-media-insert-image </span>(image <span class="kw">string</span>)
  (with-current-buffer (slime-output-buffer)
    (<span class="kw">let</span> ((marker (slime-output-target-marker :repl-result)))
      (goto-char marker)
      (slime-propertize-region `(face slime-repl-result-face
                                      rear-nonsticky (face))
        (insert-image image <span class="kw">string</span>)
        (insert ?\n))
      <span class="co">;; Move the input-start marker after the REPL result.</span>
      (set-marker marker (point)))
    (slime-repl-show-maximum-output)))</code></pre>]]></description>
  </item>
  <item>
    <title><![CDATA[Colorizing the output of tcpdump]]></title>
    <guid>http://wandrian.net/2012-04-26-2033-colorizing-tcpdump-output.html</guid>
    <link>http://wandrian.net/2012-04-26-2033-colorizing-tcpdump-output.html</link>
    <pubDate>Thu, 26 Apr 2012 20:33:00 +0200</pubDate>
    <description><![CDATA[

<p>While <a href="http://www.tcpdump.org">tcpdump</a> is an excellent tool, his output is sometimes a bit difficult to read. The following perl script highlights various elements.</p>
<p>The code is ugly, inefficient, and there are highlighting errors, but it makes tcpdump logs far easier to read.</p>
<h2 id="screenshots">Screenshots</h2>
<center>
<a href="img/tcpdump-colorize/tcpdump-colorize-1.0-1.png"><img src="img/tcpdump-colorize/tcpdump-colorize-1.0-1-thumbnail.png" /></a> <a href="img/tcpdump-colorize/tcpdump-colorize-1.0-2.png"><img src="img/tcpdump-colorize/tcpdump-colorize-1.0-2-thumbnail.png" /></a>
</center>

<h2 id="source-code">Source code</h2>
<p><a href="download/tcpdump-colorize">Download</a></p>
<pre class="sourceCode perl"><code class="sourceCode perl"><span class="kw">#!/usr/bin/perl</span>

<span class="co">=pod</span>
<span class="co">tcpdump-colorize 1.0</span>
<span class="co">Nicolas Martyanoff &lt;khaelin@gmail.com&gt;</span>
<span class="co">This script is in the public domain.</span>
<span class="co">=cut</span>

<span class="kw">use</span> <span class="kw">strict</span>;
<span class="kw">use</span> <span class="kw">warnings</span>;

<span class="kw">my</span> <span class="dt">$hex</span> = <span class="kw">qr/</span><span class="ch">[</span><span class="bn">0-9a-f</span><span class="ch">]</span><span class="kw">/</span>;

<span class="kw">my</span> <span class="dt">$fqdn</span> = <span class="kw">qr/</span><span class="ch">(?:[</span><span class="bn">A-Za-z\d\-\.</span><span class="ch">]+</span><span class="ot">\.</span><span class="ch">[</span><span class="bn">a-z</span><span class="ch">]+)</span><span class="kw">/</span>;
<span class="kw">my</span> <span class="dt">$ipv4_addr</span> = <span class="kw">qr/</span><span class="ch">(?:(?:</span><span class="bn">\d</span><span class="ch">{1,3}</span><span class="ot">\.</span><span class="ch">){3}</span><span class="bn">\d</span><span class="ch">{1,3})</span><span class="kw">/</span>;
<span class="kw">my</span> <span class="dt">$ipv6_grp</span> = <span class="kw">qr/</span><span class="dt">$hex</span><span class="ch">{1,4}</span><span class="kw">/</span>;
<span class="kw">my</span> <span class="dt">$ipv6_addr</span> = <span class="kw">qr/</span><span class="ch">(?:::)?(?:$</span><span class="ot">{ipv6_grp}::</span><span class="ch">?)+$</span><span class="ot">{ipv6_grp}</span><span class="ch">(?:::)?</span><span class="kw">/</span>;
<span class="kw">my</span> <span class="dt">$ipv6_rev</span> = <span class="kw">qr/</span><span class="ch">(?:(?:</span><span class="dt">$hex</span><span class="ot">\.</span><span class="ch">){31}</span><span class="dt">$hex</span><span class="ch">)</span><span class="kw">/</span>;
   <span class="dt">$ipv6_addr</span> = <span class="kw">qr/</span><span class="ch">(?:</span><span class="dt">$ipv6_addr</span><span class="ch">|</span><span class="dt">$ipv6_rev</span><span class="ch">)</span><span class="kw">/</span>;
<span class="kw">my</span> <span class="dt">$port</span> = <span class="kw">qr/</span><span class="ch">(?:</span><span class="bn">\d</span><span class="ch">{1,5}|[</span><span class="bn">a-z\d\-\.</span><span class="ch">]+)</span><span class="kw">/</span>;

<span class="kw">while</span> (<span class="kw">&lt;STDIN&gt;</span>) {
    <span class="kw">if</span> (<span class="kw">m/</span><span class="ch">^((?:[</span><span class="bn">\d\-</span><span class="ch">]+</span><span class="bn">\s</span><span class="ch">)?[</span><span class="bn">\d:\.</span><span class="ch">]+</span><span class="ot"> </span><span class="ch">)?([</span><span class="bn">A-Z0-9</span><span class="ch">]{2,}(?:</span><span class="ot"> </span><span class="bn">\d</span><span class="ch">+</span><span class="ot">\.</span><span class="ch">[</span><span class="bn">\da-z</span><span class="ch">]+(?=</span><span class="ot">,</span><span class="ch">))?)([</span><span class="bn"> ,</span><span class="ch">]</span><span class="ot">.</span><span class="ch">*)</span><span class="kw">/</span>) {
        <span class="kw">my</span> <span class="dt">$timestamp</span> = <span class="dt">$1;</span>
        <span class="kw">my</span> <span class="dt">$protocol</span> = <span class="dt">$2;</span>
        <span class="dt">$_</span> = <span class="kw">&quot;</span><span class="dt">$3</span><span class="ch">\n</span><span class="kw">&quot;</span>;

        <span class="fu">print</span> <span class="kw">&quot;</span><span class="ch">\e</span><span class="st">[32m</span><span class="dt">$timestamp</span><span class="ch">\e</span><span class="st">[0m </span><span class="kw">&quot;</span> <span class="kw">if</span> <span class="dt">$timestamp;</span>
        <span class="fu">print</span> <span class="kw">&quot;</span><span class="ch">\e</span><span class="st">[33m</span><span class="dt">$protocol</span><span class="ch">\e</span><span class="st">[0m</span><span class="kw">&quot;</span>;
    }

    <span class="co"># Numeric IPV6 address and port</span>
    <span class="kw">s/</span><span class="ot"> </span><span class="dt">$ipv6_addr</span><span class="ot">\.\K</span><span class="dt">$port</span><span class="ch">(?=[</span><span class="bn"> :,</span><span class="ch">])?</span><span class="kw">/</span><span class="ch">\e</span><span class="st">[36m</span><span class="dt">$&amp;</span><span class="ch">\e</span><span class="st">[0m</span><span class="kw">/g</span>;
    <span class="kw">s/</span><span class="ch">(?&lt;!</span><span class="ot">seq</span><span class="ch">)</span><span class="ot"> \K</span><span class="dt">$ipv6_addr</span><span class="ch">(?=[</span><span class="bn"> :,</span><span class="ch">])?</span><span class="kw">/</span><span class="ch">\e</span><span class="st">[34m</span><span class="dt">$&amp;</span><span class="ch">\e</span><span class="st">[0m</span><span class="kw">/g</span>;

    <span class="co"># Numeric IPV4 address and port</span>
    <span class="kw">s/</span><span class="ot"> </span><span class="dt">$ipv4_addr</span><span class="ot">\.\K</span><span class="dt">$port</span><span class="ch">(?=[</span><span class="bn"> :,</span><span class="ch">])?</span><span class="kw">/</span><span class="ch">\e</span><span class="st">[36m</span><span class="dt">$&amp;</span><span class="ch">\e</span><span class="st">[0m</span><span class="kw">/g</span>;
    <span class="kw">s/</span><span class="ch">(?&lt;=</span><span class="ot"> </span><span class="ch">)</span><span class="dt">$ipv4_addr</span><span class="ch">(?=[</span><span class="bn"> :,</span><span class="ch">])?</span><span class="kw">/</span><span class="ch">\e</span><span class="st">[34m</span><span class="dt">$&amp;</span><span class="ch">\e</span><span class="st">[0m</span><span class="kw">/g</span>;

    <span class="co"># FQDN</span>
    <span class="kw">s/</span><span class="ot"> </span><span class="dt">$fqdn</span><span class="ot">\.\K</span><span class="dt">$port</span><span class="ch">(?=[</span><span class="bn"> :,</span><span class="ch">])?</span><span class="kw">/</span><span class="ch">\e</span><span class="st">[36m</span><span class="dt">$&amp;</span><span class="ch">\e</span><span class="st">[0m</span><span class="kw">/g</span>;
    <span class="kw">s/</span><span class="ch">(?&lt;=</span><span class="ot"> </span><span class="ch">)</span><span class="dt">$fqdn</span><span class="ch">(?=[</span><span class="bn"> :,</span><span class="ch">])?</span><span class="kw">/</span><span class="ch">\e</span><span class="st">[34m</span><span class="dt">$&amp;</span><span class="ch">\e</span><span class="st">[0m</span><span class="kw">/g</span>;

    <span class="co"># Bridge</span>
    <span class="kw">s/</span><span class="ch">(?&lt;=</span><span class="ot"> </span><span class="ch">)(</span><span class="dt">$port</span><span class="ch">)</span><span class="ot">\.</span><span class="ch">(</span><span class="dt">$ipv4_addr</span><span class="ch">|</span><span class="dt">$ipv6_addr</span><span class="ch">)</span><span class="ot">\.</span><span class="ch">(</span><span class="dt">$port</span><span class="ch">)(?=[</span><span class="bn"> :,</span><span class="ch">])</span><span class="kw">/</span><span class="ch">\e</span><span class="st">[36m</span><span class="dt">$1</span><span class="ch">\e</span><span class="st">[0m.</span><span class="ch">\e</span><span class="st">[34m</span><span class="dt">$2</span><span class="ch">\e</span><span class="st">[0m.</span><span class="ch">\e</span><span class="st">[36m</span><span class="dt">$3</span><span class="ch">\e</span><span class="st">[0m</span><span class="kw">/g</span>;
    <span class="kw">s/</span><span class="ch">(?&lt;=</span><span class="ot"> </span><span class="ch">)(</span><span class="dt">$port</span><span class="ch">)</span><span class="ot">\.</span><span class="ch">(</span><span class="dt">$ipv4_addr</span><span class="ch">|</span><span class="dt">$ipv6_addr</span><span class="ch">)(?=[</span><span class="bn"> :,</span><span class="ch">])</span><span class="kw">/</span><span class="ch">\e</span><span class="st">[36m</span><span class="dt">$1</span><span class="ch">\e</span><span class="st">[0m.</span><span class="ch">\e</span><span class="st">[34m</span><span class="dt">$2</span><span class="ch">\e</span><span class="st">[0m</span><span class="kw">/g</span>;

    <span class="co"># Packet data (tcpdump -x)</span>
    <span class="kw">s/</span><span class="bn">\s</span><span class="ch">+</span><span class="ot">0x</span><span class="dt">$hex</span><span class="ch">+(?=:)</span><span class="kw">/</span><span class="ch">\e</span><span class="st">[35m</span><span class="dt">$&amp;</span><span class="ch">\e</span><span class="st">[0m</span><span class="kw">/</span>;

    <span class="co"># Warnings</span>
    <span class="kw">s/</span><span class="ot">\[bad udp cksum</span><span class="ch">[^</span><span class="bn">\]</span><span class="ch">]*</span><span class="ot">\]</span><span class="kw">/</span><span class="ch">\e</span><span class="st">[31m</span><span class="dt">$&amp;</span><span class="ch">\e</span><span class="st">[0m</span><span class="kw">/</span>;

    <span class="fu">print</span>;
}</code></pre>]]></description>
  </item>
  <item>
    <title><![CDATA[mmap() files in Common Lisp]]></title>
    <guid>http://wandrian.net/2012-04-07-1352-mmap-files-in-lisp.html</guid>
    <link>http://wandrian.net/2012-04-07-1352-mmap-files-in-lisp.html</link>
    <pubDate>Sat, 07 Apr 2012 13:52:00 +0200</pubDate>
    <description><![CDATA[

<p><code>mmap()</code> is a POSIX function used to map files or memory into the address space of a process. While Common Lisp provides functions to manipulate files, a lower level access is sometimes needed. For example, if you have multiple processes accessing the same file, or if you need random access to large files, <code>mmap()</code> can be useful.</p>
<p><a href="http://common-lisp.net/project/osicat">Osicat</a> provides access to various POSIX functions, including <code>mmap()</code>. In the following example, we will use Osicat and <code>mmap()</code> to read the <a href="http://id3.org">ID3</a> version of an audio file.</p>
<p>Mapping a file is done by opening it with <code>open()</code>, reading its size with <code>fstat()</code>, then calling <code>mmap()</code>. Once the file has been mapped we can close the file descriptor, it’s not needed anymore.</p>
<pre class="sourceCode commonlisp"><code class="sourceCode commonlisp">(<span class="kw">defun</span><span class="fu"> mmap-file </span>(path)
  (<span class="kw">let</span> ((fd (osicat-posix:open path (<span class="kw">logior</span> osicat-posix:o-rdonly))))
    (<span class="kw">unwind-protect</span>
         (<span class="kw">let*</span> ((size (osicat-posix:stat-size (osicat-posix:fstat fd)))
                (addr (osicat-posix:mmap (cffi:null-pointer) size
                                         (<span class="kw">logior</span> osicat-posix:prot-read)
                                         (<span class="kw">logior</span> osicat-posix:map-private)
                                         fd <span class="dv">0</span>)))
           (<span class="kw">values</span> addr size))
      (osicat-posix:close fd))))</code></pre>
<p>The <code>mmap-file</code> function returns two values: the address of the memory mapping and its size.</p>
<p>Unmapping this chunk of memory is done with <code>munmap()</code>:</p>
<pre class="sourceCode commonlisp"><code class="sourceCode commonlisp">(<span class="kw">defun</span><span class="fu"> munmap-file </span>(addr size)
  (osicat-posix:munmap addr size))</code></pre>
<p>Let’s add a macro to safely map and unmap files:</p>
<pre class="sourceCode commonlisp"><code class="sourceCode commonlisp">(<span class="kw">defmacro</span><span class="fu"> with-mmapped-file </span>((file addr size) &amp;body body)
  (<span class="kw">let</span> ((original-addr (<span class="kw">gensym</span> <span class="st">&quot;ADDR-&quot;</span>))
        (original-size (<span class="kw">gensym</span> <span class="st">&quot;SIZE-&quot;</span>)))
    `(<span class="kw">multiple-value-bind</span> (,addr ,size)
         (mmap-file ,file)
       (<span class="kw">let</span> ((,original-addr ,addr)
             (,original-size ,size))
         (<span class="kw">unwind-protect</span>
              (<span class="kw">progn</span> ,@body)
           (munmap-file ,original-addr ,original-size))))))</code></pre>
<p>It’s now easy to read data in memory using <a href="http://common-lisp.net/project/cffi">CFFI</a> functions. An ID3 header starts with 3 bytes containing the ASCII characters <code>&quot;ID3&quot;</code>, followed by 2 bytes indicating the ID3 version used:</p>
<pre class="sourceCode commonlisp"><code class="sourceCode commonlisp">(<span class="kw">defun</span><span class="fu"> file-id3-version </span>(path)
  (with-mmapped-file (path addr size)
    (<span class="kw">when</span> (<span class="kw">&lt;</span> size <span class="dv">5</span>)
      (<span class="kw">error</span> <span class="st">&quot;~A doesn&#39;t contain an ID3 header.&quot;</span> path))
    (<span class="kw">let</span> ((id (cffi:foreign-string-to-lisp addr <span class="kw">:count</span> <span class="dv">3</span>)))
      (<span class="kw">unless</span> (<span class="kw">string=</span> id <span class="st">&quot;ID3&quot;</span>)
        (<span class="kw">error</span> <span class="st">&quot;~A doesn&#39;t contain an ID3 identifier.&quot;</span> path)))
    (cffi:incf-pointer addr <span class="dv">3</span>)
    (<span class="kw">let</span> ((version (cffi:mem-aref addr :ushort)))
      (<span class="kw">case</span> version
        (<span class="dv">2</span> :id3v2<span class="fl">-2.2.0</span>)
        (<span class="dv">3</span> :id3v2<span class="fl">-2.3.0</span>)
        (<span class="dv">4</span> :id3v2<span class="fl">-2.4.0</span>)
        (<span class="kw">t</span> :unknown)))))</code></pre>
<p>Thanks to Peder O. Klingenberg for pointing out safety issues in the <code>with-mmapped-file</code> macro.</p>]]></description>
  </item>
  <item>
    <title><![CDATA[Custom git hunk headers for lisp files]]></title>
    <guid>http://wandrian.net/2012-03-11-1727-custom-git-hunk-headers-for-lisp.html</guid>
    <link>http://wandrian.net/2012-03-11-1727-custom-git-hunk-headers-for-lisp.html</link>
    <pubDate>Sun, 11 Mar 2012 17:27:00 +0100</pubDate>
    <description><![CDATA[

<p>Patches generated by <a href="http://git-scm.com">git</a> are organized in hunks whose title contains useful information about the context of the modification. For example, in C files, the hunk title contains the name of the function where the modification occurs.</p>
<p>Git doesn’t have any specific rule to name hunks for Common Lisp files, but we can provide a method ourselves.</p>
<p>First add a <code>.gitattributes</code> files at the root of your repository with the following content:</p>
<pre><code>*.lisp diff=lisp</code></pre>
<p>This tells git to look at the <code>diff.lisp</code> section of the configuration file to know how to handle lisp files for diffs.</p>
<p>Then edit your Git configuration file (for example <code>~/.gitconfig</code>), and add the following section:</p>
<pre><code>[diff &quot;lisp&quot;]
    xfuncname=&quot;^(\\((def|test).*)$&quot;</code></pre>
<p>With this regexp, the title of each hunk will indicate the corresponding top-level form, which most of the time starts with the <code>def</code> prefix. I added <code>test</code> which is used to define <a href="http://common-lisp.net/project/bese/FiveAM.html">5am</a> tests, and is handy for diffs in test suites.</p>
<p>Max Mikhanosha pointed out that we can have a global attribute file since git 1.7.4, which is really nice to avoid modifying the attributes of each repository you work with. Just indicate the path to the attribute file in you git configuration file:</p>
<pre><code>[core]
     attributesfile = ~/.gitattributes</code></pre>]]></description>
  </item>
  <item>
    <title><![CDATA[Thread-safe sockets for lisp-zmq]]></title>
    <guid>http://wandrian.net/2012-03-01-1945-thread-safe-sockets-for-lisp-zmq.html</guid>
    <link>http://wandrian.net/2012-03-01-1945-thread-safe-sockets-for-lisp-zmq.html</link>
    <pubDate>Thu, 01 Mar 2012 19:45:00 +0100</pubDate>
    <description><![CDATA[

<p>My Common Lisp binding of the <a href="http://zeromq.org">zeromq</a> messaging library, <a href="/lisp-zmq.html">lisp-zmq</a>, now supports thread-safe sockets.</p>
<p>In the zeromq C library, each socket is supposed to be used in a single thread. While this is reasonable given the message-oriented paradigm of zeromq, it is an issue in a language such as Common Lisp where we have a REPL to interact with the application. In <a href="http://common-lisp.net/project/slime">Slime</a>, the Common Lisp backend can evaluate each expression is a separate thread. Therefore calling zmq functions from the REPL is definitely not a good idea.</p>
<p>With the new version of lisp-zmq (1.3.0), you can use the <code>:thread-safe</code> key argument when creating a socket:</p>
<pre class="sourceCode commonlisp"><code class="sourceCode commonlisp">(zmq:socket context :pub :thread-safe <span class="kw">t</span>)</code></pre>
<p>In that case, operations on this socket will be protected by a mutex.</p>
<p>While this mutex makes socket functions safe, you may need to manually lock sequences of operations, for example if you want to receive a whole multipart message in a thread. For this reason, the macro <code>with-socket-locked</code> has been added.</p>
<p>The <a href="http://common-lisp.net/project/bordeaux-threads">bordeaux-threads</a> library is used for portable mutexes, it is a new dependency of lisp-zmq.</p>
<p>Note that sockets are now objects, and not foreign pointers to the underlying zeromq sockets. <code>socket-%socket</code> and <code>socket-lock</code> return respectively the foreign pointer to the zeromq socket and the mutex of a socket.</p>]]></description>
  </item>
  <item>
    <title><![CDATA[prctl() support in Osicat]]></title>
    <guid>http://wandrian.net/2012-02-22-0759-osicat-prctl-support.html</guid>
    <link>http://wandrian.net/2012-02-22-0759-osicat-prctl-support.html</link>
    <pubDate>Wed, 22 Feb 2012 07:59:00 +0100</pubDate>
    <description><![CDATA[

<p>I added support for the <code>prctl()</code> Linux syscall, which allows to control process execution, to <a href="http://common-lisp.net/project/osicat">Osicat</a>.</p>
<p>I also added a new function, <code>process-name</code>, which returns the task name of the current process. Oh, and it’s <code>setf</code>-able, which is helpful when you have several threads and want to easily tell them apart.</p>
<p>The patch is available in my Osicat fork on <a href="https://github.com/galdor/osicat">Github</a>.</p>]]></description>
  </item>
  <item>
    <title><![CDATA[Lisp daemons with SBCL]]></title>
    <guid>http://wandrian.net/2012-02-20-1958-lisp-daemons-with-sbcl.html</guid>
    <link>http://wandrian.net/2012-02-20-1958-lisp-daemons-with-sbcl.html</link>
    <pubDate>Mon, 20 Feb 2012 19:58:00 +0100</pubDate>
    <description><![CDATA[

<p>While opening a REPL — from a terminal or using <a href="http://common-lisp.net/project/slime">SLIME</a> in Emacs — is really simple, running a daemon wasn’t obvious to me when I started programming in Common Lisp. A common setup is based on <a href="http://www.gnu.org/s/screen">screen</a> or <a href="http://www.cliki.net/detachtty">detachtty</a>, so I started with them.</p>
<p>Some months ago, <a href="http://random-state.net">Nikodemus Siivola</a> wrote <a href="https://github.com/nikodemus/sb-daemon">sb-daemon</a>, which can be used to daemonize an SBCL process. I find this solution cleaner and simpler, and now use it for all my Common Lisp daemons.</p>
<p>Since I regularly need to create background processes to run various pieces of code, I wrote a Common Lisp script that makes a daemon from the current process, start a swank server, and makes sure to redirect output to files.</p>
<p>Pid files are stored in <code>/var/run/sbcl-daemon/$name</code> where <code>$name</code> is the name of the daemon, and log files are saved in <code>/var/log/sbcl-daemon/$name</code>.</p>
<pre class="sourceCode commonlisp"><code class="sourceCode commonlisp">(<span class="kw">require</span> :asdf)

(asdf:load-system :sb-daemon)
(asdf:load-system :swank)

(<span class="kw">defvar</span><span class="fu"> *swank-server*</span>)

(<span class="kw">defun</span><span class="fu"> signal-handler </span>(<span class="kw">signal</span>)
  (<span class="kw">format</span> <span class="kw">t</span> <span class="st">&quot;~A received~%&quot;</span> <span class="kw">signal</span>)
  (sb-ext:quit))

(<span class="kw">when</span> (<span class="kw">&lt;</span> (<span class="kw">length</span> sb-ext:*posix-argv*) <span class="dv">3</span>)
  (<span class="kw">error</span> <span class="st">&quot;Missing command line arguments.&quot;</span>))

(<span class="kw">destructuring-bind</span> (argv0 name port) sb-ext:*posix-argv*
  (<span class="kw">let*</span> ((name-directory (<span class="kw">concatenate</span> &#39;string name <span class="st">&quot;/&quot;</span>))
         (log-path (<span class="kw">merge-pathnames</span> name-directory #p<span class="st">&quot;/var/log/sbcl-daemon/&quot;</span>))
         (run-path (<span class="kw">merge-pathnames</span> name-directory #p<span class="st">&quot;/var/run/sbcl-daemon/&quot;</span>))
         (pid-file (<span class="kw">concatenate</span> &#39;string name <span class="st">&quot;.pid&quot;</span>)))
    (sb-daemon:daemonize :exit-parent <span class="kw">t</span>
                         <span class="kw">:output</span> (<span class="kw">merge-pathnames</span> <span class="st">&quot;stdout.log&quot;</span> log-path)
                         <span class="kw">:error</span> (<span class="kw">merge-pathnames</span> <span class="st">&quot;stderr.log&quot;</span> log-path)
                         :pidfile (<span class="kw">merge-pathnames</span> pid-file run-path)
                         :sigterm &#39;signal-handler
                         :sigabrt &#39;signal-handler
                         :sigint &#39;signal-handler))
  (<span class="kw">setf</span> *swank-server*
        (swank:create-server :port (<span class="kw">parse-integer</span> port)
                             :coding-system <span class="st">&quot;utf-8-unix&quot;</span>
                             :dont-close <span class="kw">t</span>))
  (<span class="kw">loop</span>
    (<span class="kw">sleep</span> <span class="dv">10</span>)))</code></pre>
<p>I then use the following shell script to easily create new daemons:</p>
<pre class="sourceCode bash"><code class="sourceCode bash"><span class="co">#!/bin/sh -e</span>

<span class="kw">if </span>[ <span class="ot">$#</span> -lt 2 ]; <span class="kw">then</span>
    <span class="kw">echo</span> <span class="st">&quot;Usage: </span><span class="ot">$0</span><span class="st"> &lt;name&gt; &lt;port&gt;&quot;</span>
    <span class="kw">exit</span> 1
<span class="kw">fi</span>

<span class="ot">name=$1</span>
<span class="ot">port=$2</span>

<span class="ot">logpath=</span><span class="st">&quot;/var/log/sbcl-daemon&quot;</span>
<span class="kw">if </span>[ ! -d <span class="ot">$logpath</span> ]; <span class="kw">then</span>
    <span class="kw">echo</span> <span class="st">&quot;</span><span class="ot">$logpath</span><span class="st"> not found&quot;</span>
    <span class="kw">exit</span> 1
<span class="kw">fi</span>
<span class="ot">runpath=</span><span class="st">&quot;/var/run/sbcl-daemon&quot;</span>
<span class="kw">if </span>[ ! -d <span class="ot">$runpath</span> ]; <span class="kw">then</span>
    <span class="kw">echo</span> <span class="st">&quot;</span><span class="ot">$runpath</span><span class="st"> not found&quot;</span>
    <span class="kw">exit</span> 1
<span class="kw">fi</span>

<span class="ot">logpath=$logpath</span>/<span class="ot">$name</span>
<span class="kw">if </span>[ ! -d <span class="ot">$logpath</span> ]; <span class="kw">then</span>
    <span class="kw">echo</span> <span class="st">&quot;creating </span><span class="ot">$logpath</span><span class="st">&quot;</span>
    <span class="kw">mkdir</span> <span class="ot">$logpath</span>
<span class="kw">fi</span>
<span class="ot">runpath=$runpath</span>/<span class="ot">$name</span>
<span class="kw">if </span>[ ! -d <span class="ot">$runpath</span> ]; <span class="kw">then</span>
    <span class="kw">echo</span> <span class="st">&quot;creating </span><span class="ot">$runpath</span><span class="st">&quot;</span>
    <span class="kw">mkdir</span> <span class="ot">$runpath</span>
<span class="kw">fi</span>

sbcl --script <span class="ot">$HOME</span>/bin/sbcl-daemon.lisp <span class="ot">$name</span> <span class="ot">$port</span></code></pre>
<p>With this code, creating a new background process is as simple as running <code>sbcl-daemon &lt;name&gt; &lt;port&gt;</code>.</p>]]></description>
  </item>
  <item>
    <title><![CDATA[Displaying the remote hostname in slime]]></title>
    <guid>http://wandrian.net/2012-02-15-2118-hostname-display-in-slime.html</guid>
    <link>http://wandrian.net/2012-02-15-2118-hostname-display-in-slime.html</link>
    <pubDate>Wed, 15 Feb 2012 21:18:00 +0100</pubDate>
    <description><![CDATA[

<p><a href="http://common-lisp.net/project/slime">Slime</a> is an Emacs mode for Common Lisp development. One of its features is to connect to a remote Lisp process, which is very useful for debugging. I often had the problem to mistake one REPL for another, running some code on the wrong Lisp process.</p>
<p>I finally configured the <code>slime-banner</code> package, which displays a line at the top of the REPL buffer, and made it shows the hostname of the machine the Lisp process is running on.</p>
<pre class="sourceCode commonlisp"><code class="sourceCode commonlisp">(eval-after-load &#39;slime
  &#39;(<span class="kw">progn</span>
     (slime-setup &#39;(slime-repl &#39;slime-banner))
     (slime-banner-init)

     (<span class="kw">setq</span> slime-repl-banner-function
           (<span class="kw">lambda</span> ()
             (<span class="kw">setq</span> header-line-format
                   (<span class="kw">format</span> <span class="st">&quot;%s@%s:%d&quot;</span>
                           (slime-lisp-implementation-type)
                           (slime-eval &#39;(cl:machine-instance))
                           (process-contact (slime-connection) :service))))))</code></pre>
<p>We add <code>'slime-banner</code> to the list of packages to load with slime, then initialize it with <code>slime-banner-init</code>. <code>slime-banner</code> calls a function which sets the <code>header-line-format</code> variable. We then use <code>slime-lisp-implementation-type</code> to get the name of the Common Lisp implementation (such as <code>SBCL</code>), and <del><code>slime-port</code> to get the port number of the swank server we are connected to</del> read the port used by the process associated to the current slime connection. Getting the hostname of the remote machine is a bit more tricky, since we need to evaluate some code on this remote machine. We use <code>slime-eval</code> to execute a Common Lisp form on the remote machine. The standard function <code>cl:machine-instance</code> returns the hostname of the machine.</p>
<p><strong>2012-03-24</strong>: the code has been modified to correctly display the port. <code>slime-port</code> is the default value used by <code>slime-connect</code>, not the port used by the current connection. The correct way is to get the emacs process associated with the connection, and read the port (<code>:service</code>) it uses.</p>]]></description>
  </item>
  <item>
    <title><![CDATA[Keeping windows in the org-mode agenda]]></title>
    <guid>http://wandrian.net/2012-02-12-2320-org-agenda-fix.html</guid>
    <link>http://wandrian.net/2012-02-12-2320-org-agenda-fix.html</link>
    <pubDate>Sun, 12 Feb 2012 23:20:00 +0100</pubDate>
    <description><![CDATA[

<p>I’m using <a href="http://orgmode.org">org-mode</a> and its agenda in emacs, but was annoyed by the behaviour of <code>org-agenda</code> which deletes all windows while displaying the command list.</p>
<p>Reading <code>org-agenda.el</code> tells us than <code>org-agenda-get-restriction-and-command</code> displays the list of agenda commands, and calls <code>delete-other-windows</code>.</p>
<p>A simple hack to avoid this behaviour is to <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Advising-Functions.html">advise</a> this function:</p>
<pre class="sourceCode commonlisp"><code class="sourceCode commonlisp">(defadvice org-agenda-get-restriction-and-command
  (around nm-org-agenda-get-restriction-and-command activate)
  (<span class="kw">flet</span> ((delete-other-windows () <span class="kw">nil</span>))
    ad-do-it))</code></pre>
<p>A proper fix would be to add an option to org-mode indicating whether other windows has to be deleted or not, but this will do for the moment.</p>]]></description>
  </item>
  </channel>
</rss>
