<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title></title>
      <link>https://fau.re</link>
      <description></description>
      <generator>Zola</generator>
      <language>en</language>
      <atom:link href="https://fau.re/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Mon, 02 Feb 2026 00:00:00 +0000</lastBuildDate>
      <item>
          <title>Making a coat rack inspired by Pablo Picasso</title>
          <pubDate>Mon, 02 Feb 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20260202_bulls_head/</link>
          <guid>https://fau.re/20260202_bulls_head/</guid>
          <description xml:base="https://fau.re/20260202_bulls_head/">&lt;p&gt;I ride my bicycle to go to work a few times a week.  Paris’ weather can be quite
rainy at times, but I still enjoy the ride.&lt;&#x2F;p&gt;
&lt;p&gt;When getting back home after getting soaked, I want to hang my rain coat and
my rain pants.&lt;&#x2F;p&gt;
&lt;p&gt;I could have bought some random Chinese-made hanger, but I got inspired by a sculpture
by Pablo Picasso, called &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Bull&amp;#x27;s_Head&quot;&gt;Tête de
taureau &#x2F; Bull’s Head&lt;&#x2F;a&gt;, as shown
below.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20260202_bulls_head&#x2F;tete_taureau_picasso.jpg&quot; alt=&quot;Tête de taureau&quot; title=&quot;Pablo Picasso, 1942, Tête de taureau (Bull&amp;#39;s Head), bicycle seat and handlebars, 33.5 x 43.5 x 19 cm, Musée Picasso, Paris&quot; &#x2F;&gt;
&lt;em&gt;Pablo Picasso, 1942, Tête de taureau (Bull’s Head), bicycle seat and handlebars, 33.5 x 43.5 x 19 cm, &lt;a href=&quot;https:&#x2F;&#x2F;www.museepicassoparis.fr&#x2F;&quot;&gt;Musée Picasso&lt;&#x2F;a&gt;, Paris&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The sculpture is made of a bicycle seat and handlebars.&lt;&#x2F;p&gt;
&lt;p&gt;I wanted to create something similar to hang my wet clothes.&lt;&#x2F;p&gt;
&lt;p&gt;I was not going to weld the metal parts together like Picasso did since I do
not have the skills nor the tools for that.  So I decided to create a wooden frame to hold
the saddle and the handlebars.&lt;&#x2F;p&gt;
&lt;p&gt;I started by designing the frame as &lt;a href=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20260202_bulls_head&#x2F;taureau_blueprint.svg&quot;&gt;a SVG file&lt;&#x2F;a&gt; and
asked a local woodworker to cut some oak wood according to the blueprint.  I
applied some wood stain to protect the wood from humidity.&lt;&#x2F;p&gt;
&lt;p&gt;My plan was to screw the stem to the back of the frame. Those screws would
hold the stem in place and the stem would hold the handlebars.&lt;&#x2F;p&gt;
&lt;p&gt;To hold the saddle, I simply use some clips that are used to hold cables but
this time to hold the saddle’s rails.&lt;&#x2F;p&gt;
&lt;p&gt;Then, just like Pablo Picasso, I decided to use second-hand goods.  The bar
tape was new but I had it already and it was unused.  For the end plugs, I
chose some used whisky corks (not to confuse with the great parts from
&lt;a href=&quot;https:&#x2F;&#x2F;whiskyparts.co&#x2F;&quot;&gt;Whisky Parts&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;At first I wanted to install it in my apartment, but finally I installed it
in my bike garage to avoid bringing my soaked clothes inside my apartment.&lt;&#x2F;p&gt;
&lt;p&gt;I’m quite happy with the result since it is both functional and artistic.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20260202_bulls_head&#x2F;tete_taureau_boris_1.jpg&quot; alt=&quot;Coat rack installed in my bike garage&quot; title=&quot;Coat
rack installed in my bike garage, from the front&quot; &#x2F;&gt;
&lt;em&gt;Coat rack installed in my bike garage&lt;&#x2F;em&gt;
&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20260202_bulls_head&#x2F;tete_taureau_boris_2.jpg&quot; alt=&quot;Coat rack installed in my bike garage&quot; title=&quot;Coat
rack installed in my bike garage, from the side&quot; &#x2F;&gt;
&lt;em&gt;From the side&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Detect-Changed-Files in Rust with a proper GitHub Actions</title>
          <pubDate>Sun, 18 Jan 2026 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20260118_detect_changed_files_action/</link>
          <guid>https://fau.re/20260118_detect_changed_files_action/</guid>
          <description xml:base="https://fau.re/20260118_detect_changed_files_action/">&lt;p&gt;I wrote a small tool in Zig to detect changed files in a GitHub. I wrote about
&lt;a href=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20260118_detect_changed_files_action&#x2F;20250810_detect_changed_files&#x2F;&quot;&gt;this last August&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It was using Zig 0.14 and I wanted to port it to Zig 0.15.  It was not a
straightforward as I expected and I was not feeling efficient at this task.&lt;&#x2F;p&gt;
&lt;p&gt;Since I wrote a lot of Rust code recently, I decided to rewrite the tool in
Rust.&lt;&#x2F;p&gt;
&lt;p&gt;I changed the configuration file format from YAML to something simpler,
similar to INI files.  This means that the tool has no dependencies, making it
very easy to generate a static binary.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;docker-container&quot;&gt;Docker container&lt;&#x2F;h2&gt;
&lt;p&gt;To make the tool easy to share, I decided to package
the tool as &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;detect-changed-files&#x2F;pkgs&#x2F;container&#x2F;detect-changed-files&#x2F;&quot;&gt;a docker container hosted on GitHub Container
Registry&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It is built in 2 stages:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;First, a builder stage based on &lt;a href=&quot;https:&#x2F;&#x2F;www.alpinelinux.org&#x2F;&quot;&gt;alpine&lt;&#x2F;a&gt; that
compiles the Rust code into a static binary. Then I used
&lt;a href=&quot;https:&#x2F;&#x2F;upx.github.io&#x2F;&quot;&gt;upx&lt;&#x2F;a&gt; to compress the binary.&lt;&#x2F;li&gt;
&lt;li&gt;Second, a minimal stage based on &lt;a href=&quot;https:&#x2F;&#x2F;hub.docker.com&#x2F;_&#x2F;scratch&quot;&gt;scratch&lt;&#x2F;a&gt;
that just copies the static binary from the builder stage.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;github-action&quot;&gt;Github Action&lt;&#x2F;h2&gt;
&lt;p&gt;My ultimate goal was to create a proper GitHub Action around the tool.&lt;&#x2F;p&gt;
&lt;p&gt;I created a new repository
&lt;a href=&quot;hptps:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;detect-changed-files-action&quot;&gt;borisfaure&#x2F;detect-changed-files-action&lt;&#x2F;a&gt;
that uses the docker container.&lt;&#x2F;p&gt;
&lt;p&gt;The action take an input parameter &lt;code&gt;config-file&lt;&#x2F;code&gt; that is the path to the
configuration file.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-it-works&quot;&gt;How It Works&lt;&#x2F;h3&gt;
&lt;ol&gt;
&lt;li&gt;Determines the base git reference (PR base, push event, manual input, or &lt;code&gt;origin&#x2F;main&lt;&#x2F;code&gt; fallback)&lt;&#x2F;li&gt;
&lt;li&gt;Fetches the base reference from the remote repository to ensure it’s available locally&lt;&#x2F;li&gt;
&lt;li&gt;Runs &lt;code&gt;git diff --name-only&lt;&#x2F;code&gt; to get the list of changed files&lt;&#x2F;li&gt;
&lt;li&gt;Passes the file list to a Docker container running the &lt;code&gt;detect-changed-files&lt;&#x2F;code&gt; tool&lt;&#x2F;li&gt;
&lt;li&gt;The tool matches files against patterns defined in the configuration file&lt;&#x2F;li&gt;
&lt;li&gt;Returns a JSON object indicating which groups have changes&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;In term of security, I have added the option &lt;code&gt;--network=none&lt;&#x2F;code&gt; to docker to
ensure that the rust binary has no network access.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;example&quot;&gt;Example&lt;&#x2F;h3&gt;
&lt;p&gt;It is very simple to use.&lt;&#x2F;p&gt;
&lt;p&gt;Given a configuration file (&lt;code&gt;.github&#x2F;changed-files.conf&lt;&#x2F;code&gt;) like this one:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;ini&quot; class=&quot;language-ini z-code&quot;&gt;&lt;code class=&quot;language-ini&quot; data-lang=&quot;ini&quot;&gt;&lt;span class=&quot;z-source z-genconfig&quot;&gt;&lt;span class=&quot;z-storage z-type z-genconfig&quot;&gt;[linter]
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-genconfig&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-genconfig&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-genconfig&quot;&gt;.&lt;&#x2F;span&gt;py
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-genconfig&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-genconfig&quot;&gt;&lt;span class=&quot;z-storage z-type z-genconfig&quot;&gt;[tests]
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-genconfig&quot;&gt;&lt;span class=&quot;z-meta z-param z-genconfig&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-genconfig&quot;&gt;src&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-block z-genconfig&quot;&gt;&lt;span class=&quot;z-comment z-block z-genconfig&quot;&gt;&#x2F;**
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-genconfig&quot;&gt;&lt;span class=&quot;z-comment z-block z-genconfig&quot;&gt;tests&#x2F;**
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-genconfig&quot;&gt;&lt;span class=&quot;z-comment z-block z-genconfig&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-genconfig&quot;&gt;&lt;span class=&quot;z-comment z-block z-genconfig&quot;&gt;[docs]
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-genconfig&quot;&gt;&lt;span class=&quot;z-comment z-block z-genconfig&quot;&gt;docs&#x2F;**
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-genconfig&quot;&gt;&lt;span class=&quot;z-comment z-block z-genconfig&quot;&gt;README.md
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then the action can be used like this in a workflow
(&lt;code&gt;.github&#x2F;workflows&#x2F;ci.yml&lt;&#x2F;code&gt;):&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;yaml&quot; class=&quot;language-yaml z-code&quot;&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;&lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;jobs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;  &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;detect-changes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;    &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;runs-on&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;ubuntu-latest&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;    &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;outputs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;      &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;changes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;${{ steps.detect.outputs.changes }}&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;    &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;steps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;      &lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;-&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;Checkout code&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;        &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;uses&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;actions&#x2F;checkout@v4&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;        &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;with&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;          &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;fetch-depth&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-yaml&quot;&gt;0&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;      &lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;-&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;Detect changed files&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;        &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;detect&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;        &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;uses&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;borisfaure&#x2F;detect-changed-files-action@v0.1.3&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;        &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;with&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;          &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;config-file&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;.github&#x2F;changed-files.conf&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;  &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;run-linter&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;    &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;needs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;detect-changes&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;    &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;if&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;fromJson(needs.detect-changes.outputs.changes).linter&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;    &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;runs-on&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;ubuntu-latest&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;    &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;steps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;      &lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;-&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;run&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;echo &amp;quot;Running linter...&amp;quot;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;  &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;run-tests&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;    &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;needs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;detect-changes&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;    &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;if&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;fromJson(needs.detect-changes.outputs.changes).tests&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;    &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;runs-on&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;ubuntu-latest&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;    &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;steps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;      &lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;-&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;run&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;echo &amp;quot;Running tests...&amp;quot;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This way, jobs can be conditionally executed based on the changed files.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Detect-Changed-Files for GitHub Actions</title>
          <pubDate>Sun, 10 Aug 2025 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20250810_detect_changed_files/</link>
          <guid>https://fau.re/20250810_detect_changed_files/</guid>
          <description xml:base="https://fau.re/20250810_detect_changed_files/">&lt;p&gt;For my personal projects and at work, I use &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;features&#x2F;actions&quot;&gt;GitHub
Actions&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I have been using &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tj-actions&#x2F;changed-files&quot;&gt;tj-actions&#x2F;changed-files&lt;&#x2F;a&gt;
It is used to
run some jobs only specific files have changed.  This is particularly useful in large
repositories.  For example, one might want to compile the documentation only
when the documentation files are changed, or run a linter only when the source
code is changed.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;tj-actions&#x2F;changed-files&lt;&#x2F;code&gt; has some limitations when a large number of files are
changed.  It also has a lot of dependencies and experienced &lt;a href=&quot;https:&#x2F;&#x2F;www.stepsecurity.io&#x2F;blog&#x2F;harden-runner-detection-tj-actions-changed-files-action-is-compromised&quot;&gt;a major security
issue few months
ago&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Since my needs were pretty simple, I decided to write my own tool.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;requirements&quot;&gt;Requirements&lt;&#x2F;h2&gt;
&lt;p&gt;To minimize security risks, I want the tool to run simply, without requiring
network access.&lt;&#x2F;p&gt;
&lt;p&gt;The list of all changed files from a pull request is fetched directly using git, outside of the tool:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh z-code&quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; diff&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;name-only&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-expansion z-parameter z-begin z-shell&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;BASE_SHA&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-expansion z-parameter z-end z-shell&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The tool takes a configuration file that defines groups of patterns.  Those
patterns are similar to ones in &lt;code&gt;.gitignore&lt;&#x2F;code&gt; files.&lt;&#x2F;p&gt;
&lt;p&gt;Here is a simple example with three groups:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;github-workflows&lt;&#x2F;code&gt; for all the files in &lt;code&gt;.github&#x2F;workflows&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;c&lt;&#x2F;code&gt; for all the C files in the repository&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;doc&lt;&#x2F;code&gt; for all the documentation files in &lt;code&gt;README.md&lt;&#x2F;code&gt; and &lt;code&gt;docs&#x2F;&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The configuration, written in &lt;a href=&quot;https:&#x2F;&#x2F;yaml.org&#x2F;&quot;&gt;YAML&lt;&#x2F;a&gt;, is as follows:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;yaml&quot; class=&quot;language-yaml z-code&quot;&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;&lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;github-workflows&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;  &lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;-&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;.github&#x2F;workflows&#x2F;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;&lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;c&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;  &lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;-&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-single z-yaml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-yaml&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;*.c&lt;span class=&quot;z-punctuation z-definition z-string z-end z-yaml&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;  &lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;-&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-single z-yaml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-yaml&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;*.h&lt;span class=&quot;z-punctuation z-definition z-string z-end z-yaml&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;  &lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;-&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-single z-yaml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-yaml&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;meson.build&lt;span class=&quot;z-punctuation z-definition z-string z-end z-yaml&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;  &lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;-&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&#x2F;meson_options.txt&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;&lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;doc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;  &lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;-&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-single z-yaml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-yaml&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;docs&#x2F;**&lt;span class=&quot;z-punctuation z-definition z-string z-end z-yaml&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;  &lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;-&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-single z-yaml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-yaml&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;README.md&lt;span class=&quot;z-punctuation z-definition z-string z-end z-yaml&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Given a list of changed files, the tool identifies which groups
contain matching files. It then returns a JSON object with the groups as keys and a
boolean value indicating if there are matching files or not.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;json&quot; class=&quot;language-json z-code&quot;&gt;&lt;code class=&quot;language-json&quot; data-lang=&quot;json&quot;&gt;&lt;span class=&quot;z-source z-json&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-mapping z-begin z-json&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-json&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-json&quot;&gt;  &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-key z-json&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;c&lt;span class=&quot;z-punctuation z-definition z-string z-end z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-key-value z-json&quot;&gt;:&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-constant z-language z-json&quot;&gt;true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-pair z-json&quot;&gt;,&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-json&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;  &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-key z-json&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;github-workflows&lt;span class=&quot;z-punctuation z-definition z-string z-end z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-key-value z-json&quot;&gt;:&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-constant z-language z-json&quot;&gt;false&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-pair z-json&quot;&gt;,&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-json&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;  &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-key z-json&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;doc&lt;span class=&quot;z-punctuation z-definition z-string z-end z-json&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-key-value z-json&quot;&gt;:&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-constant z-language z-json&quot;&gt;true&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-json&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-value z-json&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-mapping z-end z-json&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I chose JSON to make the output easy to use in a GitHub Actions workflow.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;implementation&quot;&gt;Implementation&lt;&#x2F;h2&gt;
&lt;p&gt;I decided to write the tool in &lt;a href=&quot;https:&#x2F;&#x2F;ziglang.org&#x2F;&quot;&gt;Zig&lt;&#x2F;a&gt;.  I had wanted to try
Zig on a real-world use case for a while and this was a good opportunity to do so.&lt;&#x2F;p&gt;
&lt;p&gt;The implementation is very simple and straightforward.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;impressions-on-zig&quot;&gt;Impressions on Zig&lt;&#x2F;h2&gt;
&lt;p&gt;Zig is a very nice language. It is fast to learn as the &lt;a href=&quot;https:&#x2F;&#x2F;ziglang.org&#x2F;documentation&#x2F;&quot;&gt;entire documentation is on a
single webpage&lt;&#x2F;a&gt;.  I feel like Alex Kladov
that &lt;a href=&quot;https:&#x2F;&#x2F;matklad.github.io&#x2F;2025&#x2F;08&#x2F;09&#x2F;zigs-lovely-syntax.html&quot;&gt;Zig’s syntax is lovely&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;With over 20 years of experience in C, I
felt right at home with Zig.&lt;&#x2F;p&gt;
&lt;p&gt;The compiler is very fast and its error
messages are excellent.  It should be even faster with the upcoming
Zig 0.15 release where the compiler will be rewritten in Zig itself, without
depending on LLVM.&lt;&#x2F;p&gt;
&lt;p&gt;I experimented a bit with
&lt;a href=&quot;https:&#x2F;&#x2F;ziglang.org&#x2F;documentation&#x2F;master&#x2F;#comptime&quot;&gt;&lt;code&gt;comptime&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.  It’s a
powerful and unique feature that allows you to execute code at compile time.&lt;&#x2F;p&gt;
&lt;p&gt;The standard library is small but well designed.  The ecosystem is still
young and reminds me of Rust before the 1.0 release.  To write the tool, only
one dependency was needed:
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kubkon&#x2F;zig-yaml&quot;&gt;kubkon&#x2F;zig-yaml&lt;&#x2F;a&gt;.  JSON is supported
natively in Zig.&lt;&#x2F;p&gt;
&lt;p&gt;I was pleasantly surprised to to find native &lt;a href=&quot;https:&#x2F;&#x2F;ziglang.org&#x2F;documentation&#x2F;0.14.1&#x2F;std&#x2F;#std.os.linux.IoUring&quot;&gt;&lt;code&gt;io_uring&lt;&#x2F;code&gt; support in
zig&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;A few units tests are provided to test the tool.  This is an area where  I
feel Zig’s youth shows.
For example, using the default testing framework, I couldn’t run a singe,
specific test.  I also couldn’t find a way to list all available tests.
&lt;code&gt;zig build test --verbose --summary all&lt;&#x2F;code&gt; gives a summary like:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Build Summary: 8&#x2F;8 steps succeeded; 28&#x2F;28 tests passed
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;test success
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;├─ run test success 204us MaxRSS:1M
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;│  └─ zig test Debug native success 2s MaxRSS:235M
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;│     └─ options cached
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;├─ run test 15 passed 28ms MaxRSS:1M
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;│  └─ zig test Debug native cached 36ms MaxRSS:37M
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;└─ run test 13 passed 18ms MaxRSS:1M
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;   └─ zig test Debug native cached 34ms MaxRSS:37M
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Like Go, Zig can generate static binaries, which makes the tool very
portable.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;result&quot;&gt;Result&lt;&#x2F;h2&gt;
&lt;p&gt;My tool is called &lt;code&gt;detect-changed-files&lt;&#x2F;code&gt; and is released under the &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;MIT_license&quot;&gt;MIT license&lt;&#x2F;a&gt;
and &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;detect-changed-files&quot;&gt;hosted on
GitHub&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Using it is as simple as:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh z-code&quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;git&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; diff&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;name-only&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-expansion z-parameter z-begin z-shell&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;BASE_SHA&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-expansion z-parameter z-end z-shell&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;.&#x2F;detect-changed-files&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; changed-files.yaml&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Or within a GitHub Actions workflow, it can be used like this:
you can use it like this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;yaml&quot; class=&quot;language-yaml z-code&quot;&gt;&lt;code class=&quot;language-yaml&quot; data-lang=&quot;yaml&quot;&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;&lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;jobs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;  &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;detect-changes&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;    &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;outputs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;      &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;run&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;${{ steps.changed-groups.outputs.run }}&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;    &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;steps&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;    &lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;-&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;Checkout code&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;      &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;uses&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;actions&#x2F;checkout@v4&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;      &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;with&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;        &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;fetch-depth&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-yaml&quot;&gt;1&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;    &lt;span class=&quot;z-punctuation z-definition z-block z-sequence z-item z-yaml&quot;&gt;-&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;fetch branch&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;      &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;id&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;changed-groups&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;      &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;run&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-control z-flow z-block-scalar z-literal z-yaml&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;&lt;span class=&quot;z-string z-unquoted z-block z-yaml&quot;&gt;        git fetch --depth=1 origin ${{ github.base_ref }}
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;&lt;span class=&quot;z-string z-unquoted z-block z-yaml&quot;&gt;        gh -R borisfaure&#x2F;detect-changed-files release download -p detect_changed_files-ubuntu-latest -O detect_changed_files
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;&lt;span class=&quot;z-string z-unquoted z-block z-yaml&quot;&gt;        chmod +x detect_changed_files
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;&lt;span class=&quot;z-string z-unquoted z-block z-yaml&quot;&gt;        RUN=$(git diff --name-only ${BASE_SHA} | .&#x2F;detect_changed_files .groups.yaml)
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;&lt;span class=&quot;z-string z-unquoted z-block z-yaml&quot;&gt;        printf &amp;quot;run=%s&amp;quot; &amp;quot;$RUN&amp;quot; &amp;gt;&amp;gt; $GITHUB_OUTPUT
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;&lt;span class=&quot;z-string z-unquoted z-block z-yaml&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;&lt;span class=&quot;z-string z-unquoted z-block z-yaml&quot;&gt;&lt;&#x2F;span&gt;  &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;linter&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;    &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;needs&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;detect-changes&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;    &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-yaml&quot;&gt;if&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-mapping z-yaml&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-unquoted z-plain z-out z-yaml&quot;&gt;fromJson(needs.detect-changes.outputs.run).linter&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-yaml&quot;&gt;    &lt;span class=&quot;z-constant z-numeric z-float z-decimal z-yaml&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-decimal z-yaml&quot;&gt;.&lt;&#x2F;span&gt;..&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I plan on supporting &lt;code&gt;detect-changed-files&lt;&#x2F;code&gt; and will soon port it to zig-0.15 when it’s
released, to take a good look at &lt;a href=&quot;https:&#x2F;&#x2F;blog.ivnj.org&#x2F;post&#x2F;function-coloring-is-inevitable&quot;&gt;the new I&#x2F;O
model&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Ronde, a simple monitoring service</title>
          <pubDate>Sun, 26 May 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20240526_ronde/</link>
          <guid>https://fau.re/20240526_ronde/</guid>
          <description xml:base="https://fau.re/20240526_ronde/">&lt;p&gt;As seen in &lt;a href=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20240526_ronde&#x2F;@content&#x2F;20240420_gentoo_on_oci.md&quot;&gt;a previous post&lt;&#x2F;a&gt;, I’m running Gentoo on
various servers.  I wanted a simple way to monitor them and know when one of
the service I needed is down.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tools-i-considered&quot;&gt;Tools I considered&lt;&#x2F;h2&gt;
&lt;p&gt;I stumbled upon various tools:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;checkmk.com&#x2F;&quot;&gt;check_mk&lt;&#x2F;a&gt; It’s a very powerful tool but it’s a bit
overkill for my needs.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;uptime.kuma.pet&#x2F;&quot;&gt;uptime-kuma&lt;&#x2F;a&gt; It’s a very nice tool but it’s
limited to HTTP&#x2F;DNS&#x2F;PING checks.  I wanted to be able to run any command and
check that my mail server is up, that my backups are running, etc.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;successful-proof-of-concept&quot;&gt;Successful proof of concept&lt;&#x2F;h2&gt;
&lt;p&gt;I wrote a small proof of concept in Rust that would run some commands and
generate a status page based on their output.&lt;&#x2F;p&gt;
&lt;p&gt;It was very easy to write with &lt;a href=&quot;https:&#x2F;&#x2F;tokio.rs&#x2F;&quot;&gt;Tokio&lt;&#x2F;a&gt; and I was happy with
the result.  I decided to make it a bit more polished and released it as
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;ronde&quot;&gt;Ronde&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-does-it-work&quot;&gt;How does it work ?&lt;&#x2F;h2&gt;
&lt;p&gt;Ronde is run every X minutes by a cron job.  It reads a configuration file that
is written in TOML.  It looks like this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;toml&quot; class=&quot;language-toml z-code&quot;&gt;&lt;code class=&quot;language-toml&quot; data-lang=&quot;toml&quot;&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-toml&quot;&gt;#&lt;&#x2F;span&gt;# Ronde configuration file&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-toml&quot;&gt;#&lt;&#x2F;span&gt; Name of the Ronde instance, used in the HTML output&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-key z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-key-value z-toml&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-basic z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;Ronde&lt;span class=&quot;z-punctuation z-definition z-string z-end z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-toml&quot;&gt;#&lt;&#x2F;span&gt; Where to store the HTML output&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-key z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;output_dir&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-key-value z-toml&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-basic z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&#x2F;var&#x2F;lib&#x2F;ronde&#x2F;html&lt;span class=&quot;z-punctuation z-definition z-string z-end z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-toml&quot;&gt;#&lt;&#x2F;span&gt; Where to store the history file&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-key z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;history_file&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-key-value z-toml&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-basic z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&#x2F;var&#x2F;lib&#x2F;ronde&#x2F;history.json&lt;span class=&quot;z-punctuation z-definition z-string z-end z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-toml&quot;&gt;#&lt;&#x2F;span&gt;# Default environment variables for all commands&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-table z-begin z-toml&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-table z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-table z-toml&quot;&gt;default_env&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-table z-end z-toml&quot;&gt;]&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-toml&quot;&gt;#&lt;&#x2F;span&gt; If present, the command will be run as this user&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-key z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;uid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-key-value z-toml&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-toml&quot;&gt;65534&lt;&#x2F;span&gt; &lt;span class=&quot;z-comment z-line z-number-sign z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-toml&quot;&gt;#&lt;&#x2F;span&gt; nobody&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-toml&quot;&gt;#&lt;&#x2F;span&gt; If present, the command will be run as this group&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-key z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;gid&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-key-value z-toml&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-toml&quot;&gt;65534&lt;&#x2F;span&gt; &lt;span class=&quot;z-comment z-line z-number-sign z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-toml&quot;&gt;#&lt;&#x2F;span&gt; nogroup&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-toml&quot;&gt;#&lt;&#x2F;span&gt; If present, the command will be run from this directory&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-key z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;cwd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-key-value z-toml&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-basic z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&#x2F;tmp&lt;span class=&quot;z-punctuation z-definition z-string z-end z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-toml&quot;&gt;#&lt;&#x2F;span&gt; If set to true, clear the environment variables before running the command&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-key z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;clear_env&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-key-value z-toml&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-language z-toml&quot;&gt;true&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-toml&quot;&gt;#&lt;&#x2F;span&gt; If present, the command will be run with these environment variables set&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-key z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;env&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key z-toml&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;PATH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-key-value z-toml&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-basic z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&#x2F;usr&#x2F;local&#x2F;bin:&#x2F;usr&#x2F;bin:&#x2F;opt&#x2F;bin&lt;span class=&quot;z-punctuation z-definition z-string z-end z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-key z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;env&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key z-toml&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;USER&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-key-value z-toml&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-basic z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;nobody&lt;span class=&quot;z-punctuation z-definition z-string z-end z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-key z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;env&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key z-toml&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;HOME&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-key-value z-toml&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-basic z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&#x2F;home&#x2F;nobody&lt;span class=&quot;z-punctuation z-definition z-string z-end z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-key z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;env&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key z-toml&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;_&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-key-value z-toml&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-basic z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&#x2F;usr&#x2F;bin&#x2F;env&lt;span class=&quot;z-punctuation z-definition z-string z-end z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-toml&quot;&gt;#&lt;&#x2F;span&gt;# List of commands to run&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-table z-array z-begin z-toml&quot;&gt;[[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-table z-array z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-table z-toml&quot;&gt;commands&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-table z-array z-end z-toml&quot;&gt;]]&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-toml&quot;&gt;#&lt;&#x2F;span&gt; Name of the command, used in the HTML output&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-key z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-key-value z-toml&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-basic z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;ping localhost&lt;span class=&quot;z-punctuation z-definition z-string z-end z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-toml&quot;&gt;#&lt;&#x2F;span&gt; Command to run&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-key z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;run&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-key-value z-toml&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-basic z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;ping -c 4 localhost&lt;span class=&quot;z-punctuation z-definition z-string z-end z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-toml&quot;&gt;#&lt;&#x2F;span&gt; Consider the command a failure if it takes more than this many seconds&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-key z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;timeout&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-key-value z-toml&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-toml&quot;&gt;5&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-table z-array z-begin z-toml&quot;&gt;[[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-table z-array z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-table z-toml&quot;&gt;commands&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-table z-array z-end z-toml&quot;&gt;]]&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-key z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-key-value z-toml&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-basic z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;ping hits timeout&lt;span class=&quot;z-punctuation z-definition z-string z-end z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-key z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;run&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-key-value z-toml&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-basic z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;ping -c 10 localhost&lt;span class=&quot;z-punctuation z-definition z-string z-end z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-key z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;timeout&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-key-value z-toml&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-toml&quot;&gt;5&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-table z-array z-begin z-toml&quot;&gt;[[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-table z-array z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-table z-toml&quot;&gt;commands&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-table z-array z-end z-toml&quot;&gt;]]&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-key z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-key-value z-toml&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-basic z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;ping google.com&lt;span class=&quot;z-punctuation z-definition z-string z-end z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-key z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;run&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-key-value z-toml&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-basic z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;ping -c 4 google.com&lt;span class=&quot;z-punctuation z-definition z-string z-end z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-key z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;timeout&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-key-value z-toml&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-toml&quot;&gt;5&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-table z-array z-begin z-toml&quot;&gt;[[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-tag z-table z-array z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-table z-toml&quot;&gt;commands&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-table z-array z-end z-toml&quot;&gt;]]&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-key z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;name&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-key-value z-toml&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-basic z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;ping6 google.com&lt;span class=&quot;z-punctuation z-definition z-string z-end z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-key z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;run&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-key-value z-toml&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-basic z-toml&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;ping6 -c 4 google.com&lt;span class=&quot;z-punctuation z-definition z-string z-end z-toml&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-toml&quot;&gt;&lt;span class=&quot;z-meta z-tag z-key z-toml&quot;&gt;&lt;span class=&quot;z-entity z-name z-tag z-toml&quot;&gt;timeout&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-key-value z-toml&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-toml&quot;&gt;5&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Every command is run in a separate process and the output is stored in the
history file.&lt;&#x2F;p&gt;
&lt;p&gt;Based on the output of the commands, Ronde generates an HTML page that shows
the status of this run and the history of the previous runs.  It aggregates
the history of the commands over up to a week.&lt;&#x2F;p&gt;
&lt;p&gt;It also sends a notification if a command fails.
It uses the &lt;a href=&quot;https:&#x2F;&#x2F;pushover.net&#x2F;&quot;&gt;Pushover API&lt;&#x2F;a&gt; to send notifications.
It is cheap and works well.  I use it to send notifications to my phone.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-status-page&quot;&gt;The Status page&lt;&#x2F;h2&gt;
&lt;p&gt;At first, I wanted to a single page that would hold all the information.  I
used &lt;a href=&quot;https:&#x2F;&#x2F;maud.lambda.xyz&#x2F;&quot;&gt;Maud&lt;&#x2F;a&gt; in the proof of concept but given all
the output of the commands was held, the page was getting quite big and long
to open.  I decided to have a simple HTML page that would load JSON data as
needed.  It only using native JavaScript and CSS with no dependencies.&lt;&#x2F;p&gt;
&lt;p&gt;On the CSS part, I made it responsive and it looks good on a phone.  It also
has a dark mode based on the user’s preference.&lt;&#x2F;p&gt;
&lt;p&gt;The colorscheme is based on the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;morhetz&#x2F;gruvbox&quot;&gt;gruvbox&lt;&#x2F;a&gt; colorscheme.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security&quot;&gt;Security&lt;&#x2F;h2&gt;
&lt;p&gt;I tried to limit the attack surface of Ronde. It can run as an unprivileged
user and every command is run in a separate process with a limited environment.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-does-it-look-like&quot;&gt;What does it look like?&lt;&#x2F;h2&gt;
&lt;p&gt;I host a sample instance of Ronde at &lt;a href=&quot;https:&#x2F;&#x2F;fau.re&#x2F;ronde.sample&#x2F;&quot;&gt;fau.re&#x2F;ronde.sample&#x2F;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Installing Gentoo on a Virtual Private Server</title>
          <pubDate>Tue, 20 Feb 2024 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20240220_gentoo_on_oci/</link>
          <guid>https://fau.re/20240220_gentoo_on_oci/</guid>
          <description xml:base="https://fau.re/20240220_gentoo_on_oci/">&lt;p&gt;I’ve been running Gentoo on my servers for ages.  Recently I moved from a hosted
hardware server to a set of virtual ones, running at &lt;a href=&quot;https:&#x2F;&#x2F;www.ovhcloud.com&quot;&gt;OVH
Cloud&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;www.oracle.com&#x2F;cloud&#x2F;&quot;&gt;Oracle Cloud&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Below is an example of how I setup 2 servers with Gentoo on Oracle Cloud while gentoo is not offered.
This is done in 3 main steps:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Installing Gentoo on a local VM on our own environment&lt;&#x2F;li&gt;
&lt;li&gt;Pushing this VM image onto the VPS&lt;&#x2F;li&gt;
&lt;li&gt;Finishing the setup and enjoying Gentoo&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This is mostly written as a reminder on how to do it and it may voluntarily
skip many details.&lt;&#x2F;p&gt;
&lt;p&gt;On installing Gentoo itself, I suggest reading the
&lt;a href=&quot;https:&#x2F;&#x2F;wiki.gentoo.org&#x2F;wiki&#x2F;Handbook:Main_Page&quot;&gt;Gentoo Handbook&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;local-gentoo-install&quot;&gt;Local Gentoo Install&lt;&#x2F;h1&gt;
&lt;p&gt;On the home computer, I download the gentoo iso from links on &lt;a href=&quot;https:&#x2F;&#x2F;www.gentoo.org&#x2F;downloads&#x2F;&quot;&gt;gentoo.org&lt;&#x2F;a&gt; and verify it:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;wget https:&#x2F;&#x2F;distfiles.gentoo.org&#x2F;releases&#x2F;amd64&#x2F;autobuilds&#x2F;20240218T170410Z&#x2F;install-amd64-minimal-20240218T170410Z.iso{,.asc}
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;gpg --import &#x2F;usr&#x2F;share&#x2F;openpgp-keys&#x2F;gentoo-release.asc
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;gpg --verify install-amd64-minimal-*.iso.asc
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then, I spawn an instance on OCI with RockyLinux and
configure ssh by adding to the &lt;code&gt;.ssh&#x2F;config&lt;&#x2F;code&gt; on our local machine:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Host vpsoci
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    Hostname IP_ADDR_HERE
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    User opc
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;    IdentityFile ~&#x2F;.ssh&#x2F;id_ed25519
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Test it by downloading &lt;code&gt;dmesg&lt;&#x2F;code&gt; and &lt;code&gt;lsmod&lt;&#x2F;code&gt; to keep as reference for later:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;ssh vpsoci &amp;quot;dmesg&amp;quot; &amp;gt; dmesg
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;ssh vpsoci &amp;quot;lsmod&amp;quot; &amp;gt; lsmod
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Get the vps size:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;ssh vpsoci &amp;quot;sudo sgdisk -p &#x2F;dev&#x2F;sda | head -n 1&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;that outputs &lt;code&gt;Disk &#x2F;dev&#x2F;sda: 97677312 sectors, 46.6 GiB&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Next I create our own disk image and start our own local VM and connect to it:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;qemu-img create -f raw gentoo.raw $((97677312 * 512))
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;qemu-system-x86_64 -drive file=gentoo.raw,format=raw,cache=writeback -cdrom install-amd64-minimal-*.iso -boot d -machine type=q35,accel=kvm -cpu host -smp 2 -m 1024 -vnc :0 -device virtio-net,netdev=vmnic -netdev user,id=vmnic,hostfwd=tcp::10022-:22
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;vncviewer :0
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;On it, I add a password and start ssh:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;passwd
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;rc-service sshd start
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now I can &lt;code&gt;ssh root@localhost -p 10022&lt;&#x2F;code&gt; and partition the VM:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;sgdisk -n1:0:+2M -t1:EF02 &#x2F;dev&#x2F;sda
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;sgdisk -n2:0:+512M -t2:EF00 &#x2F;dev&#x2F;sda
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;sgdisk -n3:0:0 -t3:8300 &#x2F;dev&#x2F;sda
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;mkfs.fat -F 32 -n efi-boot &#x2F;dev&#x2F;sda2
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And I setup dm-crypt on the whole disk. I kept the default settings. To pick a
password, I suggesting following Randall Munroe’s advice at &lt;a href=&quot;https:&#x2F;&#x2F;xkcd.com&#x2F;936&#x2F;&quot;&gt;xkcd&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;cryptsetup luksFormat &#x2F;dev&#x2F;sda3
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;cryptsetup luksDump &#x2F;dev&#x2F;sda3
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;cryptsetup luksOpen --allow-discards &#x2F;dev&#x2F;sda3 root
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;mkfs.ext4 -m 1 &#x2F;dev&#x2F;mapper&#x2F;root
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;mount &#x2F;dev&#x2F;mapper&#x2F;root &#x2F;mnt&#x2F;gentoo
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then, I install the base system on it&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;cd &#x2F;mnt&#x2F;gentoo
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;wget https:&#x2F;&#x2F;distfiles.gentoo.org&#x2F;releases&#x2F;amd64&#x2F;autobuilds&#x2F;20240218T170410Z&#x2F;stage3-amd64-openrc-20240218T170410Z.tar.xz{,.asc}
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;gpg --import &#x2F;usr&#x2F;share&#x2F;openpgp-keys&#x2F;gentoo-release.asc
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;gpg --verify stage3-*.tar.xz.DIGESTS
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;tar xpvf stage3-*.tar.xz --xattrs-include=&amp;#39;*.*&amp;#39; --numeric-owner
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;rm stage3-*.tar.*
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And edit the portage configuration:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;vi &#x2F;mnt&#x2F;gentoo&#x2F;etc&#x2F;portage&#x2F;make.conf
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;mkdir --parents &#x2F;mnt&#x2F;gentoo&#x2F;etc&#x2F;portage&#x2F;repos.conf
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;cp &#x2F;mnt&#x2F;gentoo&#x2F;usr&#x2F;share&#x2F;portage&#x2F;config&#x2F;repos.conf &#x2F;mnt&#x2F;gentoo&#x2F;etc&#x2F;portage&#x2F;repos.conf&#x2F;gentoo.conf
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Prepare to chroot&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;cp --dereference &#x2F;etc&#x2F;resolv.conf &#x2F;mnt&#x2F;gentoo&#x2F;etc&#x2F;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;mount --types proc &#x2F;proc &#x2F;mnt&#x2F;gentoo&#x2F;proc
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;mount --rbind &#x2F;sys &#x2F;mnt&#x2F;gentoo&#x2F;sys &amp;amp;&amp;amp; mount --make-rslave &#x2F;mnt&#x2F;gentoo&#x2F;sys
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;mount --rbind &#x2F;dev &#x2F;mnt&#x2F;gentoo&#x2F;dev &amp;amp;&amp;amp; mount --make-rslave &#x2F;mnt&#x2F;gentoo&#x2F;dev
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;mount --bind &#x2F;run &#x2F;mnt&#x2F;gentoo&#x2F;run &amp;amp;&amp;amp; mount --make-slave &#x2F;mnt&#x2F;gentoo&#x2F;run
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;chroot &#x2F;mnt&#x2F;gentoo &#x2F;bin&#x2F;bash
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;source &#x2F;etc&#x2F;profile
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;export PS1=&amp;quot;(chroot) ${PS1}&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Once in the chroot, I update and start configuring the system:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;emerge-webrsync
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;eselect profile set 15
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;echo &amp;quot;Europe&#x2F;Paris&amp;quot; &amp;gt; &#x2F;etc&#x2F;timezone
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;rm &#x2F;etc&#x2F;localtime
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;emerge --config sys-libs&#x2F;timezone-data
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;cat &amp;lt;&amp;lt;EOF &amp;gt; &#x2F;etc&#x2F;locale.gen
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;en_DK.UTF-8 UTF-8
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;en_US.UTF-8 UTF-8
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;fr_FR.UTF-8 UTF-8
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;C.UTF8 UTF-8
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;EOF
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;locale-gen
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;eselect locale list
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;eselect locale set 4
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;env-update &amp;amp;&amp;amp; source &#x2F;etc&#x2F;profile &amp;amp;&amp;amp; export PS1=&amp;quot;(chroot) ${PS1}&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Install gentoo gpg keys:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;emerge -qaAv getuto &amp;amp;&amp;amp; getuto
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Add &lt;code&gt;-v3&lt;&#x2F;code&gt; to the &lt;code&gt;sync-uri&lt;&#x2F;code&gt; of
&lt;code&gt;&#x2F;etc&#x2F;portage&#x2F;binrepos.conf&#x2F;gentoobinhost.conf&lt;&#x2F;code&gt; to be able to install binary
packages more fit for our target system.&lt;&#x2F;p&gt;
&lt;p&gt;Install base components:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;emerge -qaAvg sys-apps&#x2F;fakeroot app-admin&#x2F;sysklogd sys-process&#x2F;cronie net-misc&#x2F;chrony app-editors&#x2F;neovim
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;rc-update add sysklogd default
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;rc-update add cronie default
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;rc-update add sshd default
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;rc-update add chronyd default
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;the-kernel&quot;&gt;The kernel&lt;&#x2F;h2&gt;
&lt;p&gt;I like configuring my kernels and use &lt;code&gt;genkernel&lt;&#x2F;code&gt; to build them.
Here it is setup to allow an ssh connection to the initramfs to be able to
decrypt the root volume.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;echo &amp;quot;sys-kernel&#x2F;genkernel -firmware&amp;quot; &amp;gt;&amp;gt; &#x2F;etc&#x2F;portage&#x2F;package.use&#x2F;main
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;echo &amp;quot;sys-kernel&#x2F;gentoo-sources experimental&amp;quot; &amp;gt;&amp;gt; &#x2F;etc&#x2F;portage&#x2F;package.use&#x2F;main
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;net-misc&#x2F;dropbear static -pam
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;sys-libs&#x2F;zlib static-libs
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;virtual&#x2F;libcrypt static-libs
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;sys-libs&#x2F;libxcrypt static-libs
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;sys-apps&#x2F;kmod zstd static-libs
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;emerge -qaAvg sys-kernel&#x2F;gentoo-sources sys-kernel&#x2F;genkernel net-misc&#x2F;dropbear
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I edit &lt;code&gt;&#x2F;etc&#x2F;dropbear&#x2F;authorized_keys&lt;&#x2F;code&gt; with the keys I want to use.&lt;&#x2F;p&gt;
&lt;p&gt;Set &lt;code&gt;GRUB_PLATFORMS=&quot;efi-64 emu pc&quot;&lt;&#x2F;code&gt; to &lt;code&gt;&#x2F;etc&#x2F;portage&#x2F;make.conf&lt;&#x2F;code&gt;.
Set &lt;code&gt;GRUB_CMDLINE_LINUX_DEFAULT=&quot;root_trim=yes crypt_root=&#x2F;dev&#x2F;sda3 ip=dhcp dosshd gk.sshd.port=2222&quot;&lt;&#x2F;code&gt; to &lt;code&gt;&#x2F;etc&#x2F;default&#x2F;grub&lt;&#x2F;code&gt;.
Using port 2222 helps make ssh not complain that the host is different from
the initramfs and the live system.&lt;&#x2F;p&gt;
&lt;p&gt;Finish grub setup:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;mount &#x2F;dev&#x2F;sda2 &#x2F;boot
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;echo &amp;quot;sys-boot&#x2F;grub device-mapper efiemu&amp;quot; &amp;gt;&amp;gt; &#x2F;etc&#x2F;portage&#x2F;package.use&#x2F;main
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;emerge -qaAvg sys-boot&#x2F;grub
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;grub-install --target=x86_64-efi --efi-directory=&#x2F;boot --removable
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;grub-mkconfig -o &#x2F;boot&#x2F;grub&#x2F;grub.cfg
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Generate the kernel configuration and then run:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;genkernel all --kernel-config=&#x2F;usr&#x2F;src&#x2F;kernel-config-6.1.67-v1
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;configuring-the-system&quot;&gt;Configuring the system&lt;&#x2F;h2&gt;
&lt;p&gt;Run &lt;code&gt;blkid&lt;&#x2F;code&gt; to get the UUID of &lt;code&gt;&#x2F;dev&#x2F;mapper&#x2F;root&lt;&#x2F;code&gt; and then write &lt;code&gt;&#x2F;etc&#x2F;fstab&lt;&#x2F;code&gt;
like so:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;# &amp;lt;fs&amp;gt;                  &amp;lt;mountpoint&amp;gt;    &amp;lt;type&amp;gt;          &amp;lt;opts&amp;gt;          &amp;lt;dump&amp;gt; &amp;lt;pass&amp;gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;LABEL=efi-boot          &#x2F;boot           vfat            noauto,noatime  0 2
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;#&#x2F;dev&#x2F;mapper&#x2F;root
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;UUID=&amp;quot;1ec95162-17a6-462c-b0ba-00878f74fe29&amp;quot;  &#x2F;  ext4    noatime         0 1
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Set the hostname. Please have more inspiration.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;echo vpsoci &amp;gt; &#x2F;etc&#x2F;hostname
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For the network, just use dhcpcd:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;emerge -qaAdg dhcpcd
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;rc-update add dhcpcd default
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;rc-service dhcpcd start
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Add a udev rule to rename &lt;code&gt;enp0s3&lt;&#x2F;code&gt; to &lt;code&gt;eth0&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;rc-config add udev
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;mkdir -p &#x2F;etc&#x2F;udev&#x2F;rules.d&#x2F;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;cat &amp;lt;&amp;lt;EOF &amp;gt; &#x2F;etc&#x2F;udev&#x2F;rules.d&#x2F;76-net-name-use-custom.rules
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;SUBSYSTEM==&amp;quot;net&amp;quot;, ACTION==&amp;quot;add&amp;quot;, ENV{ID_NET_NAME_PATH}==&amp;quot;enp0s3&amp;quot;, NAME=&amp;quot;eth0&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;EOF
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;copying-the-image-to-the-vps&quot;&gt;Copying the image to the VPS&lt;&#x2F;h1&gt;
&lt;p&gt;Here’s the trick given by Adyxax when he &lt;a href=&quot;https:&#x2F;&#x2F;www.adyxax.org&#x2F;blog&#x2F;2023&#x2F;10&#x2F;04&#x2F;installing-nixos-on-a-vps&#x2F;&quot;&gt;installed NixOS on a
VPS&lt;&#x2F;a&gt;: the
idea is to rewrite the disk image on the vps with the one from the local VM.&lt;&#x2F;p&gt;
&lt;p&gt;This can be done by writing directly to the block device, bypassing the
filesystem that has to be remounted read-only to avoid it writing over our
data.&lt;&#x2F;p&gt;
&lt;p&gt;On the VPS, as root, after ensuring root can connect directly (need to modify
&lt;code&gt;&#x2F;root&#x2F;.ssh&#x2F;authorized_keys&lt;&#x2F;code&gt;), this can be done like so:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;dnf install zstd
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;swapoff -a
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;mount -o remount,ro &#x2F;boot
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;mount -o remount,ro &#x2F;boot&#x2F;efi
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;systemctl stop systemd-journald.service systemd-journald-dev-log.socket systemd-journald.socket
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;systemctl stop rsyslog.service crond.service chronyd.service gssproxy.service
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;systemctl stop systemd-udevd.service systemd-udevd-control.socket systemd-udevd-kernel.socket
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;systemctl stop rpcbind.service rpcbind.socket
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;systemctl stop tuned.service polkit.service atd.service auditd.service libstoragemgmt.service
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;systemctl stop tuned.service polkit.service atd.service libstoragemgmt.service
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;systemctl stop oracle-cloud-agent-updater.service oracle-cloud-agent.service pmcd.service pmie.service pmie_farm.service
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;systemctl stop firewalld.service irqbalance.service pmlogger.service pmlogger_farm.service
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;systemctl stop dtprobed.service
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;systemctl stop getty@tty1.service serial-getty@ttyS0.service
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;service auditd stop
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;mount -o remount,ro &#x2F;var&#x2F;oled
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;systemctl stop dbus-broker.service systemd-logind.service dbus.socket
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;systemctl stop iscsid.service iscsid.socket
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;mount -o remount,ro &#x2F;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And the long command to run from your environment:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;zstd -k -3 gentoo.raw --stdout | ssh -4 root@vpsoci &amp;quot;zstdcat | dd of=&#x2F;dev&#x2F;sda&amp;quot;; echo -e \a
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;finishing-the-install&quot;&gt;Finishing the install&lt;&#x2F;h1&gt;
&lt;p&gt;Reboot the VPS, and hopefully enjoy Gentoo.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;note-on-rewriting-the-root-volume&quot;&gt;Note on rewriting the root volume&lt;&#x2F;h2&gt;
&lt;p&gt;This may no longer be possible directly in the future starting with kernel 6.8 when the option &lt;code&gt;BLK_DEV_WRITE_MOUNTED&lt;&#x2F;code&gt; will be set to no:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Allow writing to mounted block devices&lt;&#x2F;p&gt;
&lt;p&gt;When a block device is mounted, writing to its buffer cache is very
likely going to cause filesystem corruption. It is also rather easy to
crash the kernel in this way since the filesystem has no practical way
of detecting these writes to buffer cache and verifying its metadata
integrity. However there are some setups that need this capability
like running fsck on read-only mounted root device, modifying some
features on mounted ext4 filesystem, and similar. If you say N, the
kernel will prevent processes from writing to block devices that are
mounted by filesystems which provides some more protection from runaway
privileged processes and generally makes it much harder to crash
filesystem drivers. Note however that this does not prevent
underlying device(s) from being modified by other means, e.g. by
directly submitting SCSI commands or through access to lower layers of
storage stack. If in doubt, say Y. The configuration can be overridden
with the bdev_allow_write_mounted boot option.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;See also this great article from LWN: &lt;a href=&quot;https:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;941764&#x2F;&quot;&gt;Defending mounted filesystems from the root user&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>JUnit-Parser v1.0.0</title>
          <pubDate>Fri, 22 Sep 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20230922_junit_parser/</link>
          <guid>https://fau.re/20230922_junit_parser/</guid>
          <description xml:base="https://fau.re/20230922_junit_parser/">&lt;p&gt;Testing is a very important part of software engineering.  Tests results are
usually written as JUnit reports, sometimes also referred as &lt;code&gt;xUnit&lt;&#x2F;code&gt; since the
file format is an XML document.&lt;&#x2F;p&gt;
&lt;p&gt;I wanted to store and analyze such documents.  Working with hundreds of JUnit
reports can be cumbersome and I wanted to write a dedicated tool to process
a large set of JUnit reports.&lt;&#x2F;p&gt;
&lt;p&gt;As you know, I enjoy writing rust code but sadly there is no library to help
parse JUnit documents.  That’s why I wrote a small library to do just that.
It is simply called &lt;a href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;junit-parser&#x2F;&quot;&gt;JUnit-Parser&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It is based on &lt;a href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;quick-xml&#x2F;&quot;&gt;quick-xml&lt;&#x2F;a&gt; to parse
efficiently the XML files.&lt;&#x2F;p&gt;
&lt;p&gt;It parses all the different JUnit files I encountered and I have added support
for some optional attributes.&lt;&#x2F;p&gt;
&lt;p&gt;The API is very simple as can be seen in the example below:&lt;&#x2F;p&gt;
&lt;h2 id=&quot;example&quot;&gt;Example&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust z-code&quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-keyword z-other z-rust&quot;&gt;use&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-path z-rust&quot;&gt;std&lt;span class=&quot;z-punctuation z-accessor z-rust&quot;&gt;::&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-path z-rust&quot;&gt;io&lt;span class=&quot;z-punctuation z-accessor z-rust&quot;&gt;::&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;Cursor&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;let&lt;&#x2F;span&gt; xml &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-raw z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-string z-rust&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-rust&quot;&gt;#&amp;quot;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-raw z-rust&quot;&gt;&amp;lt;testsuite tests=&amp;quot;3&amp;quot; failures=&amp;quot;1&amp;quot;&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-raw z-rust&quot;&gt;  &amp;lt;testcase classname=&amp;quot;foo1&amp;quot; name=&amp;quot;ASuccessfulTest&amp;quot;&#x2F;&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-raw z-rust&quot;&gt;  &amp;lt;testcase classname=&amp;quot;foo2&amp;quot; name=&amp;quot;AnotherSuccessfulTest&amp;quot;&#x2F;&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-raw z-rust&quot;&gt;  &amp;lt;testcase classname=&amp;quot;foo3&amp;quot; name=&amp;quot;AFailingTest&amp;quot;&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-raw z-rust&quot;&gt;    &amp;lt;failure type=&amp;quot;NotEnoughFoo&amp;quot;&amp;gt; details about failure &amp;lt;&#x2F;failure&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-raw z-rust&quot;&gt;  &amp;lt;&#x2F;testcase&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-raw z-rust&quot;&gt;&amp;lt;&#x2F;testsuite&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-raw z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-rust&quot;&gt;&amp;quot;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;let&lt;&#x2F;span&gt; cursor &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-path z-rust&quot;&gt;Cursor&lt;span class=&quot;z-punctuation z-accessor z-rust&quot;&gt;::&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;new&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;xml&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;let&lt;&#x2F;span&gt; r &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-path z-rust&quot;&gt;junit_parser&lt;span class=&quot;z-punctuation z-accessor z-rust&quot;&gt;::&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;from_reader&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;cursor&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-support z-macro z-rust&quot;&gt;assert!&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;r&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-rust&quot;&gt;is_ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;let&lt;&#x2F;span&gt; t &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; r&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-rust&quot;&gt;unwrap&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-support z-macro z-rust&quot;&gt;assert_eq!&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;t&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;suites&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-rust&quot;&gt;len&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-rust&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-rust&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;let&lt;&#x2F;span&gt; ts &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-bitwise z-rust&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;t&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;suites&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-rust&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-support z-macro z-rust&quot;&gt;assert_eq!&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;ts&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;tests&lt;span class=&quot;z-punctuation z-separator z-rust&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-rust&quot;&gt;3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-support z-macro z-rust&quot;&gt;assert_eq!&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;ts&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;failures&lt;span class=&quot;z-punctuation z-separator z-rust&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-rust&quot;&gt;1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-support z-macro z-rust&quot;&gt;assert_eq!&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;ts&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;cases&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-rust&quot;&gt;len&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-rust&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-rust&quot;&gt;3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-support z-macro z-rust&quot;&gt;assert!&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;ts&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;cases&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-rust&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;status&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-rust&quot;&gt;is_success&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-support z-macro z-rust&quot;&gt;assert!&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;ts&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;cases&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-rust&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;status&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-rust&quot;&gt;is_failure&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;release-usage&quot;&gt;Release &amp;amp; Usage&lt;&#x2F;h2&gt;
&lt;p&gt;Junit-Parser is licensed under the &lt;a href=&quot;https:&#x2F;&#x2F;opensource.org&#x2F;license&#x2F;bsd-2-clause&#x2F;&quot;&gt;BSD 2-Clause
license&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;After few iterations over the years, I think it is time to release v1.0.0.&lt;&#x2F;p&gt;
&lt;p&gt;The 1.0.0 release brings a better support for JUnit files along with updated
dependencies.  I have also taken into account some commits from forks on
github, like the optional &lt;code&gt;serde&lt;&#x2F;code&gt; feature to help serialize &#x2F; deserialize the
public types used to represent a JUnit file.&lt;&#x2F;p&gt;
&lt;p&gt;You can find more about it on the following links:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;junit-parser&#x2F;blob&#x2F;main&#x2F;Changelog.md&quot;&gt;Changelog&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;junit-parser&#x2F;&quot;&gt;page on crates.io&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;junit-parser&#x2F;latest&#x2F;junit-parser&#x2F;&quot;&gt;documentation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;junit-parser&quot;&gt;repository on GitHub&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;future&quot;&gt;Future&lt;&#x2F;h2&gt;
&lt;p&gt;I’ve added &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;dependabot&quot;&gt;Dependabot&lt;&#x2F;a&gt; and a small CI to help
me keep it up-to-date.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>A CLI to control Spotify</title>
          <pubDate>Thu, 10 Aug 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20230810_spotifyctl/</link>
          <guid>https://fau.re/20230810_spotifyctl/</guid>
          <description xml:base="https://fau.re/20230810_spotifyctl/">&lt;p&gt;I listen to music a lot when I’m on the computer.  When I’m not playing
&lt;a href=&quot;https:&#x2F;&#x2F;www.radiofrance.fr&#x2F;fip&quot;&gt;the fip radio&lt;&#x2F;a&gt; with its incredible playlist,
I listen to music or some podcasts on &lt;a href=&quot;https:&#x2F;&#x2F;www.spotify.com&#x2F;&quot;&gt;Spotify&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-very-basic-usage&quot;&gt;A very basic usage&lt;&#x2F;h2&gt;
&lt;p&gt;Two years ago, I started a very small project to be able to display the
currently playing song in my window manager’s taskbar.  I wrote a tool in rust
using &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ramsayleung&#x2F;rspotify&quot;&gt;rspotify&lt;&#x2F;a&gt;, a Spotify Web API
SDK implemented in Rust.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;doing-a-bit-more&quot;&gt;Doing a bit more&lt;&#x2F;h2&gt;
&lt;p&gt;The tool was working just fine but from the start I wanted it to do a bit
more: Play or Pause the playback, or Skip to the previous or next song in the
queue.  I added such commands to have bound to the media keys of my keyboard.
That way, I don’t have to go the application and can stay focus on what I’m
doing.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;release-usage&quot;&gt;Release &amp;amp; Usage&lt;&#x2F;h2&gt;
&lt;p&gt;I wrote all this in a tool called &lt;code&gt;spotifyctl&lt;&#x2F;code&gt;.
You can find more about it on the following links:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;spotifyctl&quot;&gt;page on crates.io&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;spotifyctl&#x2F;latest&#x2F;spotifyctl&#x2F;&quot;&gt;documentation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;spotifyctl&quot;&gt;repository on GitHub&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The installation itself is a bit complex since one has to register an
application to spotify to get some application tokens, then add you own
spotify user to it, and then let your own spotify user agree for API access by
this application.&lt;&#x2F;p&gt;
&lt;p&gt;Once it’s done, the tokens are read by the application through environment
variables and a token is saved and refreshed in your configuration directory
(&lt;code&gt;~&#x2F;.config&#x2F;.spotifyctl.token&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;future&quot;&gt;Future&lt;&#x2F;h2&gt;
&lt;p&gt;I’ve added &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;dependabot&quot;&gt;Dependabot&lt;&#x2F;a&gt; and a small CI to help
me keep it up-to-date.&lt;&#x2F;p&gt;
&lt;p&gt;I do not plan any new feature at the moment, but who knows!&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>A lovely (env) logger for Rust</title>
          <pubDate>Wed, 08 Feb 2023 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20230208_lovely_env_logger/</link>
          <guid>https://fau.re/20230208_lovely_env_logger/</guid>
          <description xml:base="https://fau.re/20230208_lovely_env_logger/">&lt;p&gt;Last year, I was not fully satisfied with a library I used to display logs in
my Rust programs.  It’s
&lt;a href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;pretty_env_logger&quot;&gt;pretty-env-logger&lt;&#x2F;a&gt;.  I
started patching the code but then I realized I had to change a lot of stuff
and decided to make a fork of it.  Some of my changes made the library too
different from the original.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;goals&quot;&gt;Goals&lt;&#x2F;h2&gt;
&lt;p&gt;I had two main goals:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;have the log lines take less space,&lt;&#x2F;li&gt;
&lt;li&gt;introduce some relative timestamping between log lines.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;state-of-the-library&quot;&gt;State of the library&lt;&#x2F;h2&gt;
&lt;p&gt;I have released version 0.6.0 today and I consider it to be fully usable.&lt;&#x2F;p&gt;
&lt;p&gt;It relies on &lt;a href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;log&#x2F;&quot;&gt;log&lt;&#x2F;a&gt; to write traces in your code:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust z-code&quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;    &lt;span class=&quot;z-support z-macro z-rust&quot;&gt;debug!&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-rust&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;some nice message to help debugging&lt;span class=&quot;z-punctuation z-definition z-string z-end z-rust&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;    &lt;span class=&quot;z-support z-macro z-rust&quot;&gt;info!&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-rust&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;information&lt;span class=&quot;z-punctuation z-definition z-string z-end z-rust&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;    &lt;span class=&quot;z-support z-macro z-rust&quot;&gt;warn!&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-rust&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;o_O&lt;span class=&quot;z-punctuation z-definition z-string z-end z-rust&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;    &lt;span class=&quot;z-support z-macro z-rust&quot;&gt;error!&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-rust&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;boom&lt;span class=&quot;z-punctuation z-definition z-string z-end z-rust&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And &lt;a href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;env_logger&#x2F;&quot;&gt;env-logger&lt;&#x2F;a&gt; to be able to filter them.&lt;&#x2F;p&gt;
&lt;p&gt;Like the original, it can be customized at run time with environment
variables.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;screenshots&quot;&gt;Screenshots&lt;&#x2F;h2&gt;
&lt;p&gt;Let me show you some examples as screenshots&lt;&#x2F;p&gt;
&lt;h3 id=&quot;default-output&quot;&gt;Default output&lt;&#x2F;h3&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20230208_lovely_env_logger&#x2F;log_default.png&quot; alt=&quot;default output&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;output-with-relative-timestamps-short-levels-my-favorite&quot;&gt;Output with relative timestamps, short levels (my favorite)&lt;&#x2F;h3&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20230208_lovely_env_logger&#x2F;log_relative_timestamps.png&quot; alt=&quot;example output with relative timestamps, short levels&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h3 id=&quot;output-with-system-timestamps-file-names-and-line-numbers&quot;&gt;Output with system timestamps, file names and line numbers&lt;&#x2F;h3&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20230208_lovely_env_logger&#x2F;log_file_line_system_time.png&quot; alt=&quot;example output with system timestamps, file names and line numbers&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;useful-links&quot;&gt;Useful links&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;lovely_env_logger&quot;&gt;page on crates.io&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;lovely_env_logger&#x2F;latest&#x2F;lovely_env_logger&#x2F;&quot;&gt;documentation&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;lovely-env-logger&quot;&gt;repository on GitHub&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I hope it will be useful to some of you.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Coccinelle</title>
          <pubDate>Fri, 01 Jul 2022 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20220701_coccinelle/</link>
          <guid>https://fau.re/20220701_coccinelle/</guid>
          <description xml:base="https://fau.re/20220701_coccinelle/">&lt;p&gt;Coccinelle (meaning ladybug in French) can be a gardener’s good friend and
even though I enjoy taking care of my house plants, I am writing here a bit
about software development.&lt;&#x2F;p&gt;
&lt;p&gt;Being a C developer, I know how dangerous the language can be and how
important it is to be able to protect oneself when using it.&lt;&#x2F;p&gt;
&lt;p&gt;This is the reason why
&lt;a href=&quot;https:&#x2F;&#x2F;scan.coverity.com&#x2F;projects&#x2F;terminology&quot;&gt;Coverity&lt;&#x2F;a&gt; is used on
Terminology. It does provide some static analysis on Terminology’s code.&lt;&#x2F;p&gt;
&lt;p&gt;However, it may not be enough or not have all the rules I wish.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;what-is-coccinelle&quot;&gt;What is Coccinelle?&lt;&#x2F;h1&gt;
&lt;blockquote&gt;
&lt;p&gt;Coccinelle is a program matching and transformation engine which provides the
language SmPL (Semantic Patch Language) for specifying desired matches and
transformations in C code.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Coccinelle can read C code and allow to write semantic patches on it.  Such
patches can be used to use a new API (or macro) like in the following example:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;diff&quot; class=&quot;language-diff z-code&quot;&gt;&lt;code class=&quot;language-diff&quot; data-lang=&quot;diff&quot;&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;@@
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;expression n,d;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;@@
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;(
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-deleted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-deleted z-diff&quot;&gt;-&lt;&#x2F;span&gt; (((n + d) - 1) &#x2F; d)
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-inserted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-inserted z-diff&quot;&gt;+&lt;&#x2F;span&gt; DIV_ROUND_UP(n,d)
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;|
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-deleted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-deleted z-diff&quot;&gt;-&lt;&#x2F;span&gt; ((n + (d - 1)) &#x2F; d)
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-markup z-inserted z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-inserted z-diff&quot;&gt;+&lt;&#x2F;span&gt; DIV_ROUND_UP(n,d)
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This script will generate patches to use the macro &lt;code&gt;DIV_ROUND_UP()&lt;&#x2F;code&gt; to make
the code easier to read.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;longer-example&quot;&gt;Longer example&lt;&#x2F;h1&gt;
&lt;p&gt;Recently, I stumbled accross some code that was messing up with the type of
enum a function should return.  Below is an example of bad code:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;C&quot; class=&quot;language-C z-code&quot;&gt;&lt;code class=&quot;language-C&quot; data-lang=&quot;C&quot;&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-storage z-type z-c&quot;&gt;enum&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-entity z-name z-enum z-c&quot;&gt;foo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt; &lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-c&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;    FOO_1&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;    FOO_2&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-meta z-assumed-macro z-c&quot;&gt;    FOO_3
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-c&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-storage z-type z-c&quot;&gt;enum&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-entity z-name z-enum z-c&quot;&gt;bar&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt; &lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-c&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;    BAR_1&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-meta z-assumed-macro z-c&quot;&gt;    BAR_2
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-c&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-storage z-type z-c&quot;&gt;enum&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-entity z-name z-enum z-c&quot;&gt;bar&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;my_func(void)
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-c&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;    &lt;span class=&quot;z-storage z-type z-c&quot;&gt;enum&lt;&#x2F;span&gt; foo f &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; FOO_3&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;do_something&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;    &lt;span class=&quot;z-keyword z-control z-flow z-return z-c&quot;&gt;return&lt;&#x2F;span&gt; f&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-enum z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-c&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Clang and Coverity can find such implicit enum conversions but I wanted to see
if I could write some Coccinelle patch to find and fix such cases.&lt;&#x2F;p&gt;
&lt;p&gt;Here’s what I wrote:&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;diff&quot; class=&quot;language-diff z-code&quot;&gt;&lt;code class=&quot;language-diff&quot; data-lang=&quot;diff&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;    @@
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;    type T, B != T;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;    identifier func, i;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;    expression E;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;    @@
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;    T func (...) {
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;    ...
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;    (
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;    T i;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;    |
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;    T i = E;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;    |
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;14&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;    -B i;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;15&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;    +T i;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;16&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;    |
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;17&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;    -B i = E;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;18&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;    +T i = E;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;19&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;    )
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;20&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;    &amp;lt;+...
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;21&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;    return i;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;22&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;    ...+&amp;gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;23&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;    }
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;On line 7, the return type of the function is set to &lt;code&gt;T&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Between the parentheses on lines 9 and 19, different patterns are matched.&lt;&#x2F;p&gt;
&lt;p&gt;On line 21, the &lt;code&gt;return&lt;&#x2F;code&gt; statement is matched and tells coccinelle to tag
a variable matching &lt;code&gt;i&lt;&#x2F;code&gt;. The &lt;code&gt;&amp;lt;+...&lt;&#x2F;code&gt; and &lt;code&gt;+...&amp;gt;&lt;&#x2F;code&gt; snippets tell Coccinelle that
the &lt;code&gt;return&lt;&#x2F;code&gt; statement may not be at a deeper level in the code, like inside
an &lt;code&gt;if&lt;&#x2F;code&gt; block.&lt;&#x2F;p&gt;
&lt;p&gt;Back to those parentheses, the type &lt;code&gt;T&lt;&#x2F;code&gt; can be instantiated with the variable &lt;code&gt;i&lt;&#x2F;code&gt; on line 10, 12.
On line 14 and 16, if the variable &lt;code&gt;i&lt;&#x2F;code&gt; is not using the correct type, then let
Coccinelle do the change and use the type &lt;code&gt;T&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Coccinelle produces this patch:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;diff&quot; class=&quot;language-diff z-code&quot;&gt;&lt;code class=&quot;language-diff&quot; data-lang=&quot;diff&quot;&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-meta z-diff z-header z-from-file&quot;&gt;&lt;span class=&quot;z-meta z-header z-from-file z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-from-file z-diff&quot;&gt;---&lt;&#x2F;span&gt; main.c
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-meta z-diff z-header z-to-file&quot;&gt;&lt;span class=&quot;z-meta z-header z-to-file z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-to-file z-diff&quot;&gt;+++&lt;&#x2F;span&gt; &#x2F;tmp&#x2F;cocci-output-1131-72d04b-main.c
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;&lt;span class=&quot;z-meta z-diff z-range z-unified&quot;&gt;&lt;span class=&quot;z-meta z-range z-unified z-diff&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-range z-diff&quot;&gt;@@&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-toc-list z-line-number z-diff&quot;&gt;-12,7 +12,7&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-definition z-range z-diff&quot;&gt;@@&lt;&#x2F;span&gt; &lt;span class=&quot;z-entity z-name z-section z-diff&quot;&gt;enum bar {&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt; enum bar
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;  my_func(void)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;   {
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;   -    enum foo f = FOO_3;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;   +    enum bar f = FOO_3;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-diff&quot;&gt;        do_something();
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h1 id=&quot;checks-ci&quot;&gt;Checks &amp;amp; CI&lt;&#x2F;h1&gt;
&lt;p&gt;Such patches can run in a CI environment and ensure that some APIs are used
correctly.&lt;&#x2F;p&gt;
&lt;p&gt;The following patch ensures that when a function ending with &lt;code&gt;_lock&lt;&#x2F;code&gt;, that is
followed by a function ending with &lt;code&gt;_unlock&lt;&#x2F;code&gt;, then all the code paths have an
&lt;code&gt;_unlock&lt;&#x2F;code&gt; call.  This can find issues that arise typically in error-management
code when one would forget to add an &lt;code&gt;_unlock&lt;&#x2F;code&gt; call.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;C&quot; class=&quot;language-C z-code&quot;&gt;&lt;code class=&quot;language-C&quot; data-lang=&quot;C&quot;&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-comment z-line z-double-slash z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-c&quot;&gt;&#x2F;&#x2F;&lt;&#x2F;span&gt; A mutex_lock is not matched by a mutex_unlock before an error return&#x2F;goto.
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;@@
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;expression l&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;identifier LOCK &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-c&quot;&gt;~&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-c&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;^.*_lock$&lt;span class=&quot;z-punctuation z-definition z-string z-end z-c&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;identifier UN &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-c&quot;&gt;~&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-double z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-c&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;^.*_unlock$&lt;span class=&quot;z-punctuation z-definition z-string z-end z-c&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;@@
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;LOCK&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;l&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-variadic z-c&quot;&gt;...&lt;&#x2F;span&gt; when &lt;span class=&quot;z-keyword z-operator z-comparison z-c&quot;&gt;!=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;UN&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;l&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;    when &lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-entity z-name z-function z-c&quot;&gt;any&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;    &lt;&#x2F;span&gt;when strict
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-c&quot;&gt;{&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-variadic z-c&quot;&gt;...&lt;&#x2F;span&gt; when &lt;span class=&quot;z-keyword z-operator z-comparison z-c&quot;&gt;!=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;UN&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;l&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-c&quot;&gt;+&lt;&#x2F;span&gt;   &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;todo_add_unlock&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;l&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;    &lt;span class=&quot;z-keyword z-control z-flow z-return z-c&quot;&gt;return&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-variadic z-c&quot;&gt;...&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-c&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-c&quot;&gt;|&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;UN&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;l&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;It is possible to use regular expression on identifiers to enforce that the
patch only applies to some functions, variables, types.&lt;&#x2F;p&gt;
&lt;p&gt;I wrote a small script to test Terminology’s code against such semantic
patches.  If Coccinelle produces a patch, then the CI fails and one has to
fix the code.&lt;&#x2F;p&gt;
&lt;p&gt;I’ve added some scripts that check the following:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;two comparisons of the same expression to different constants&lt;&#x2F;li&gt;
&lt;li&gt;a pointer should not be compared to 0&lt;&#x2F;li&gt;
&lt;li&gt;continue at the end of a for loop has no purpose&lt;&#x2F;li&gt;
&lt;li&gt;calling free() on variables on the stack&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;!x&amp;amp;y&lt;&#x2F;code&gt;: missing bit-wise operator and negation&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;NULL&lt;&#x2F;code&gt; tests where the value is known not to be &lt;code&gt;NULL&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;pointer is dereferenced when known to be &lt;code&gt;NULL&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;a variable is only initialized and never used&lt;&#x2F;li&gt;
&lt;li&gt;a variable used an iterator is used outside the iterator loop, without
breaking the loop, and thus the variable has a bad value&lt;&#x2F;li&gt;
&lt;li&gt;missing unlock&lt;&#x2F;li&gt;
&lt;li&gt;missing usage of macros &lt;code&gt;DIV_ROUND_UP&lt;&#x2F;code&gt;, &lt;code&gt;ROUND_UP&lt;&#x2F;code&gt;, &lt;code&gt;MIN&lt;&#x2F;code&gt;, &lt;code&gt;MAX&lt;&#x2F;code&gt;, …&lt;&#x2F;li&gt;
&lt;li&gt;bad type used in return statement&lt;&#x2F;li&gt;
&lt;li&gt;…&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h1 id=&quot;sources-pointers&quot;&gt;Sources &amp;amp; Pointers&lt;&#x2F;h1&gt;
&lt;p&gt;Most of the scripts I used can be found on &lt;a href=&quot;https:&#x2F;&#x2F;coccinelle.gitlabpages.inria.fr&#x2F;website&#x2F;rules&#x2F;&quot;&gt;Coccinelle website&lt;&#x2F;a&gt;.
The following links also helped me write some semantic patches:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;coccinelle.gitlabpages.inria.fr&#x2F;website&#x2F;&quot;&gt;Official Website&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.slideshare.net&#x2F;ennael&#x2F;coccinelle&quot;&gt;Presentation: Coccinelle, a bug finding tool&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;coccinelle.gitlabpages.inria.fr&#x2F;website&#x2F;papers&#x2F;cocciwk4_talk1.pdf&quot;&gt;Introduction to Coccinelle&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;www.lrz.de&#x2F;services&#x2F;compute&#x2F;courses&#x2F;x_lecturenotes&#x2F;hspc1w19.pdf&quot;&gt;Introduction to Semantic Patching of C programs with
Coccinelle, by Michele MARTONE&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;coccinellery.org&#x2F;&quot;&gt;Coccinellery&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;315686&#x2F;&quot;&gt;LWN - Semantic patching with Coccinelle&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;lwn.net&#x2F;Articles&#x2F;380835&#x2F;&quot;&gt;LWN - Evolutionary development of a semantic patch using Coccinelle&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;git.kernel.org&#x2F;pub&#x2F;scm&#x2F;linux&#x2F;kernel&#x2F;git&#x2F;stable&#x2F;linux.git&#x2F;tree&#x2F;scripts&#x2F;coccinelle&quot;&gt;Scripts used in the Linux kernel&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Writing Coccinelle patches can be a bit tedious sometimes. Thus, I encourage
anyone who wants to write some semantic patches with Coccinelle, to first
write a test case to validate that the script does indeed what is expected of
it.&lt;&#x2F;p&gt;
&lt;p&gt;I only presented Coccinelle as a tool to find bugs but semantic patches are
also great to automatically refactor some code.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Offline CI</title>
          <pubDate>Mon, 18 Apr 2022 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20220418_offline_ci/</link>
          <guid>https://fau.re/20220418_offline_ci/</guid>
          <description xml:base="https://fau.re/20220418_offline_ci/">&lt;p&gt;In the article about &lt;a href=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20190108_tytest&#x2F;&quot;&gt;Testing Terminology&lt;&#x2F;a&gt;, I explained
how Terminology is tested and very little about the CI and the concepts I
applied.&lt;&#x2F;p&gt;
&lt;p&gt;The main goal of the CI is to validate the code that will be released at some
point.  By running tests as often as possible, it is possible to catch bugs
soon after they have been written. Using the CI as a gatekeeper, it helps not
introduce them into the final code that will be released. Thus, this should
improve the quality of the releases.&lt;&#x2F;p&gt;
&lt;p&gt;No test is perfect and complete enough to represent the full scale of how the
code will be stressed in the wild and we can not be fully confident that no
bug exist.  However, one major concern is when one can not even rely on the
test results.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;flakiness&quot;&gt;Flakiness&lt;&#x2F;h2&gt;
&lt;p&gt;Flakiness occurs when a test is not behaving in a consistent manner.
Usually, it is when a test fails while the tested code has not changed.
Sometimes, it is also when a test passes while it was usually failing and no
change was intentionally introduced to change this behavior.&lt;&#x2F;p&gt;
&lt;p&gt;This produces some important issues:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;lack of trust&lt;&#x2F;strong&gt; on the CI: if a test fails, developers tend to dismiss it
and just &lt;strong&gt;retry&lt;&#x2F;strong&gt; the test it until it passes.  There are plenty of plugins
for CI frameworks to do just that.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;cost in developer time&lt;&#x2F;strong&gt; to investigate the failures.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;sources-of-flakiness&quot;&gt;Sources of flakiness&lt;&#x2F;h2&gt;
&lt;p&gt;There are many reasons why a test can fail but let me try to give some common
ones I encountered:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Network issues&lt;&#x2F;em&gt; when interacting with something on the Internet: failing to
fetch a package or when a webservice is down.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Limitations on the test runner&lt;&#x2F;em&gt;: when the test runs on some machine (VMs,
containers, …) that is not behaving as usual. This is usually the case in
shared environments when timings can be very different from one run to
another.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Contract changes&lt;&#x2F;em&gt; with 3rd-parties or the environment: when an API has
changed, or when a package has been modified.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Concurrency&lt;&#x2F;em&gt; issues or timers in the code: this usually reflects a bug in
the code and is one good reason to keep on investigating flakiness issues.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Randomness&lt;&#x2F;em&gt; issues: once in a while, the test hits a bad value.&lt;&#x2F;li&gt;
&lt;li&gt;Badly written tests.&lt;&#x2F;li&gt;
&lt;li&gt;…&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;learning-on-retries&quot;&gt;Learning on retries&lt;&#x2F;h2&gt;
&lt;p&gt;Flakiness is a topic serious enough that Big Tech have teams working on
trying to fix it. Most of the literature is related to handling retries:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;This is done at scale &lt;a href=&quot;https:&#x2F;&#x2F;testing.googleblog.com&#x2F;2016&#x2F;05&#x2F;flaky-tests-at-google-and-how-we.html&quot;&gt;at Google&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;docs.microsoft.com&#x2F;en-us&#x2F;azure&#x2F;devops&#x2F;pipelines&#x2F;test&#x2F;flaky-test-management&quot;&gt;Azure Pipelines&lt;&#x2F;a&gt;
offers this as a service.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;tech.ebayinc.com&#x2F;engineering&#x2F;ebay-launches-targeted-auto-retry&#x2F;&quot;&gt;eBay introduced Targeted Auto-Retries&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;engineering.fb.com&#x2F;2020&#x2F;12&#x2F;10&#x2F;developer-tools&#x2F;probabilistic-flakiness&#x2F;&quot;&gt;Facebook wrote a probabilistic model on flakiness&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;…&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;All of those are probably great but look far too complex just to test
Terminology.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;flakiness-as-a-risk&quot;&gt;Flakiness as a risk&lt;&#x2F;h2&gt;
&lt;p&gt;In my personal life, while interacting with the cycling community, I
encountered the concept of the &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Hierarchy_of_hazard_controls&quot;&gt;Hierarchy of hazard
controls&lt;&#x2F;a&gt; where,
when wanting to protect cyclists, it is more efficient to separate cyclists
from motor vehicles (risk elimination) than asking them to wear a helmet.&lt;&#x2F;p&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20220418_offline_ci&#x2F;hierarchy_of_hazard_controls.svg&quot; alt=&quot;Hierarchy of hazard controls&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;I am trying to apply this hierarchy to how flakiness is dealt with in the
industry:&lt;&#x2F;p&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20220418_offline_ci&#x2F;flakiness.svg&quot; alt=&quot;Hierarchy of flakiness counter measures&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;To limit the impact of flakiness, the best would be to &lt;strong&gt;eliminate&lt;&#x2F;strong&gt; it!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;elimination-of-some-sources-of-flakiness&quot;&gt;Elimination of some sources of flakiness&lt;&#x2F;h2&gt;
&lt;p&gt;There are different sources of flakiness and some can be removed
systematically.&lt;&#x2F;p&gt;
&lt;p&gt;In Terminology’s CI, fetching dependencies is not a source of flakiness since
all the dependencies are already stored in the image used to compile and run
the tests.  Instead of fetching the dependencies remotely, they are installed
from the image itself.  This is what I call an &lt;strong&gt;offline CI&lt;&#x2F;strong&gt;.  It is very
powerful and can enable &lt;strong&gt;reproductible builds&lt;&#x2F;strong&gt;.  By constructing the images
outside of the path to test the code, issues found while building those image
do not impact the way the code is tested and clearly &lt;em&gt;decouples&lt;&#x2F;em&gt; testing the
code from creating the environment to test the code.&lt;&#x2F;p&gt;
&lt;p&gt;At some point, Terminology was tested against 4 different versions of the
Enlightenment Foundation Libraries using this system. Terminology is also tested with 2
different compilers (gcc and clang) and many different compilation options
(mostly through of the use of sanitizers).&lt;&#x2F;p&gt;
&lt;p&gt;Terminology’s dependencies are rather small and rely only on alpine packages
but one could imagine using this same concept with cargo, pip, npm, go
modules, …&lt;&#x2F;p&gt;
&lt;p&gt;However, just doing this is not enough.  If a dependency is updated upstream,
this offline CI would not be able to test code against it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;using-the-ci-to-test-the-ci&quot;&gt;Using the CI to test … the CI&lt;&#x2F;h2&gt;
&lt;p&gt;When the tests are passing and after a review, we tend to consider that the
code being tested is good enough.  These same tests can also be used to
validate a newer dependency: if the code has not changed but only a dependency
has changed, then having the tests green, means that this
newer dependency is working well.&lt;&#x2F;p&gt;
&lt;p&gt;This is represented by the following workflow:&lt;&#x2F;p&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20220418_offline_ci&#x2F;ciflow.svg&quot; alt=&quot;Introducing dependencies&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;When the CI gets complex due to multiple sets of dependencies, it is useful to
try to decouple those sets using image inheritance.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;image-inheritance&quot;&gt;Image inheritance&lt;&#x2F;h2&gt;
&lt;p&gt;Let’s consider the following examples with 3 simple images based on alpine
where fetching (and installing) a different dependency is done on each image:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;step1.Dockerfile&lt;&#x2F;code&gt;:&lt;pre data-lang=&quot;dockerfile&quot; class=&quot;language-dockerfile z-code&quot;&gt;&lt;code class=&quot;language-dockerfile&quot; data-lang=&quot;dockerfile&quot;&gt;&lt;span class=&quot;z-source z-dockerfile&quot;&gt;  FROM alpine:latest
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-dockerfile&quot;&gt;  RUN apk add --no-cache gcc meson ninja
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;step2.Dockerfile&lt;&#x2F;code&gt;:&lt;pre data-lang=&quot;dockerfile&quot; class=&quot;language-dockerfile z-code&quot;&gt;&lt;code class=&quot;language-dockerfile&quot; data-lang=&quot;dockerfile&quot;&gt;&lt;span class=&quot;z-source z-dockerfile&quot;&gt; FROM foo:step1-pre
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-dockerfile&quot;&gt; RUN apk add --no-cache netcat-openbsd
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;step3.Dockerfile&lt;&#x2F;code&gt;:&lt;pre data-lang=&quot;dockerfile&quot; class=&quot;language-dockerfile z-code&quot;&gt;&lt;code class=&quot;language-dockerfile&quot; data-lang=&quot;dockerfile&quot;&gt;&lt;span class=&quot;z-source z-dockerfile&quot;&gt; FROM foo:step2-pre
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-dockerfile&quot;&gt; RUN apk add --no-cache patch
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;The CI will use the image from &lt;code&gt;step3.Dockerfile&lt;&#x2F;code&gt; when it is validated.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;validating-the-steps&quot;&gt;Validating the steps&lt;&#x2F;h3&gt;
&lt;p&gt;There can still be flakiness while building those images, but it’s not
directly impacting the CI used to test changes in the code.&lt;&#x2F;p&gt;
&lt;p&gt;A simple script to build those images and automatically publish when they are
good can be the following one:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;sh&quot; class=&quot;language-sh z-code&quot;&gt;&lt;code class=&quot;language-sh&quot; data-lang=&quot;sh&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;!&#x2F;bin&#x2F;sh&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; suffix to add to the images. useful to coordinate with change in code&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-assignment z-shell&quot;&gt;SFX&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-shell&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-unquoted z-shell&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;42&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; branch used to test&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-assignment z-shell&quot;&gt;BRANCH&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-shell&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-unquoted z-shell&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;master&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; build Step 1.  Exit early on failure&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-keyword z-control z-conditional z-if z-shell&quot;&gt;if&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-shell&quot;&gt;!&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-other z-readwrite z-assignment z-shell&quot;&gt;LOG1&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-shell&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-unquoted z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-parens z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-shell&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;docker&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; build&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;pull&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;no-cache&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;f&lt;&#x2F;span&gt; step1.Dockerfile&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;t&lt;&#x2F;span&gt; foo:step1-pre .&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-end z-shell&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-continue z-shell&quot;&gt;;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-control z-conditional z-then z-shell&quot;&gt;then&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-echo z-shell&quot;&gt;echo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;LOG1&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-exit z-shell&quot;&gt;exit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 1&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-keyword z-control z-conditional z-end z-shell&quot;&gt;fi&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; build Step 2.  Exit early on failure&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-keyword z-control z-conditional z-if z-shell&quot;&gt;if&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-shell&quot;&gt;!&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-other z-readwrite z-assignment z-shell&quot;&gt;LOG2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-shell&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-unquoted z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-parens z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-shell&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;docker&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; build&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;no-cache&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;f&lt;&#x2F;span&gt; step2.Dockerfile&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;t&lt;&#x2F;span&gt; foo:step2-pre .&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-end z-shell&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-continue z-shell&quot;&gt;;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-control z-conditional z-then z-shell&quot;&gt;then&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-echo z-shell&quot;&gt;echo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;LOG2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-exit z-shell&quot;&gt;exit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 1&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-keyword z-control z-conditional z-end z-shell&quot;&gt;fi&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; build Step 3.  Exit early on failure&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-keyword z-control z-conditional z-if z-shell&quot;&gt;if&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-shell&quot;&gt;!&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-other z-readwrite z-assignment z-shell&quot;&gt;LOG3&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-shell&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-unquoted z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-parens z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-shell&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;docker&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; build&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;no-cache&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;q&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;f&lt;&#x2F;span&gt; step3.Dockerfile&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;t&lt;&#x2F;span&gt; foo:step3-pre .&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-end z-shell&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-continue z-shell&quot;&gt;;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-control z-conditional z-then z-shell&quot;&gt;then&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-echo z-shell&quot;&gt;echo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;LOG3&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-exit z-shell&quot;&gt;exit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 1&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-keyword z-control z-conditional z-end z-shell&quot;&gt;fi&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; Run CI on defined branch on image `foo:step3-pre`&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-keyword z-control z-conditional z-if z-shell&quot;&gt;if&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-shell&quot;&gt;!&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-other z-readwrite z-assignment z-shell&quot;&gt;CILOG&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-shell&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-unquoted z-shell&quot;&gt;&lt;span class=&quot;z-meta z-group z-expansion z-command z-parens z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-begin z-shell&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;run_tests.sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;BRANCH&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; foo:step3-pre&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parens z-end z-shell&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-logical z-continue z-shell&quot;&gt;;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-control z-conditional z-then z-shell&quot;&gt;then&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-echo z-shell&quot;&gt;echo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;failed to run tests on newer images: &lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;CILOG&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-exit z-shell&quot;&gt;exit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 2&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-keyword z-control z-conditional z-end z-shell&quot;&gt;fi&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;docker&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; tag foo:step1-pre &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;foo:step1-latest-&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;SFX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-and z-shell&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;docker&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; push &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;foo:step1-latest-&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;SFX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;docker&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; tag foo:step2-pre &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;foo:step2-latest-&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;SFX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-and z-shell&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;docker&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; push &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;foo:step2-latest-&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;SFX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;docker&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; tag foo:step3-pre &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;foo:step3-latest-&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;SFX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-and z-shell&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;docker&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; push &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;foo:step3-latest-&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;SFX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;One issue with this approach is that we have to disable the docker cache.  One
improvement could be to only disable it when a dependency is known to have
changed.&lt;&#x2F;p&gt;
&lt;p&gt;By changing the &lt;code&gt;FROM&lt;&#x2F;code&gt; clause on the intermediate images to the one ending
with &lt;code&gt;latest-*&lt;&#x2F;code&gt; and enabling the docker cache, it is possible to test that the
last step is the one failing, and if not, going upward in the steps.  This is
not very practical.&lt;&#x2F;p&gt;
&lt;p&gt;To counter this, one could try to add tests on each step. However, if the
script runs often enough, there should not be a lot of changes in the steps
and finding the root cause of the failure should be easy.  Also, if one step
is clearly broken upstream, using the &lt;code&gt;latest&lt;&#x2F;code&gt; tag for it and enabling the
cache should let test other steps.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;when-should-it-run&quot;&gt;When should it run?&lt;&#x2F;h2&gt;
&lt;p&gt;This workflow can run daily or weekly, or be triggered from an external tool
that would alert of an updated dependency, or simply by the need to add or
change a dependency.  In Terminology, this is done every 2 weeks since there
are not a lot of changes in the dependencies.&lt;&#x2F;p&gt;
&lt;p&gt;Sometimes, an incompatibility also needs to be fixed alongside the code.  The
solution is to have, in the code repository, a tag to know which image to use.
In the example, this would be set using the &lt;code&gt;SFX&lt;&#x2F;code&gt; variable. That way, the CI
will only use the newer image when the dependency is known to work well with
the code.&lt;&#x2F;p&gt;
&lt;p&gt;The lifecycle of those images is left as exercice to the reader.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bonus&quot;&gt;Bonus&lt;&#x2F;h2&gt;
&lt;p&gt;In Terminology, a copy of the repository is stored in the base image and
updated whenever the image has to change.  This can limit the amount of data to
transfer when testing new code.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>A dumb raytracer written in Rust</title>
          <pubDate>Mon, 15 Jul 2019 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20190715_rust_raytracer/</link>
          <guid>https://fau.re/20190715_rust_raytracer/</guid>
          <description xml:base="https://fau.re/20190715_rust_raytracer/">&lt;h2 id=&quot;genesis&quot;&gt;Genesis&lt;&#x2F;h2&gt;
&lt;p&gt;A long time ago, I found a &lt;a href=&quot;https:&#x2F;&#x2F;www.reddit.com&#x2F;r&#x2F;wallpapers&#x2F;comments&#x2F;3npdce&#x2F;1920x1080_october_forest_variant_in_comments&#x2F;&quot;&gt;computer-generated forest background on
reddit&lt;&#x2F;a&gt;.
I wanted to generate by myself this kind of image and decided few months ago
to write a ray tracer with that goal!&lt;&#x2F;p&gt;
&lt;p&gt;Going back to doing maths in 3d, solving complex systems, triangulate matrices
was hard!!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;rust&quot;&gt;Rust&lt;&#x2F;h2&gt;
&lt;p&gt;I wrote the raytracer in Rust and making run in parallel was amazingly easy
with &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rayon-rs&#x2F;rayon&quot;&gt;rayon-rs&lt;&#x2F;a&gt;.
Since rendering can be quite long, I’ve added a way to stop resume rendering.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;colors&quot;&gt;Colors&lt;&#x2F;h2&gt;
&lt;p&gt;I wanted to give my rendering an aspect of sunset, during the &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Golden_hour_(photography)&quot;&gt;golden
hour&lt;&#x2F;a&gt; but I couldn’t
find any interesting litterature on it.
I decided that rays from the sun would just mix the objects colors with a bit
of orange and in the end, I like the result.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20190715_rust_raytracer&#x2F;objects.png&quot; alt=&quot;Some objects&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-forest&quot;&gt;The Forest&lt;&#x2F;h2&gt;
&lt;p&gt;I used a &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Monte_Carlo_method&quot;&gt;Monte Carlo
method&lt;&#x2F;a&gt; to generat my
forest and here’s the result:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20190715_rust_raytracer&#x2F;forest_mini.png&quot; alt=&quot;The Forest&quot; &#x2F;&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20190715_rust_raytracer&#x2F;forest.png&quot;&gt;4k version&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;While browsing the internets, I went to &lt;a href=&quot;https:&#x2F;&#x2F;www.johnstewart.dev&#x2F;five-programming-patterns-i-like&#x2F;&quot;&gt;that
page&lt;&#x2F;a&gt; that
showed the image below (Credits: Photo by Desmond Simon on Unsplash, but
couldn’t find it there).&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20190715_rust_raytracer&#x2F;photo.jpg&quot; alt=&quot;Actual forest&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;My image is no too far from there, with its own style.&lt;&#x2F;p&gt;
&lt;p&gt;As usual, this is opensource and on &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;billiob&#x2F;rt&quot;&gt;github&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Testing Terminology</title>
          <pubDate>Tue, 08 Jan 2019 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20190108_tytest/</link>
          <guid>https://fau.re/20190108_tytest/</guid>
          <description xml:base="https://fau.re/20190108_tytest/">&lt;h2 id=&quot;regressions&quot;&gt;Regressions :’(&lt;&#x2F;h2&gt;
&lt;p&gt;A few weeks ago, Egmont Koblinger (a developer on
&lt;a href=&quot;https:&#x2F;&#x2F;gitlab.gnome.org&#x2F;GNOME&#x2F;vte&#x2F;&quot;&gt;VTE (a Virtual Terminal library)&lt;&#x2F;a&gt;)
opened &lt;a href=&quot;https:&#x2F;&#x2F;phab.enlightenment.org&#x2F;T7475&quot;&gt;a ticket&lt;&#x2F;a&gt; on Terminology about
incorrect parsing of escape codes.
The following day, I pushed a commit to master to fix that issue.&lt;&#x2F;p&gt;
&lt;p&gt;I introduced a regression: some other escape codes were no longer
parsed  correctly. In a few hours after my change, the ticket was reopened and
I got notified twice on IRC.&lt;&#x2F;p&gt;
&lt;p&gt;I felt bad about it, having only tested the specific change; the bug
described in the ticket was fixed and my shell was drawing correctly,
nothing fancier than that.&lt;&#x2F;p&gt;
&lt;p&gt;I quickly reverted my changes on the repository but I needed to act.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;testing-tools&quot;&gt;Testing tools&lt;&#x2F;h2&gt;
&lt;p&gt;Currently, there is already some testing. On each change to the master
branch, &lt;a href=&quot;https:&#x2F;&#x2F;scan.coverity.com&#x2F;projects&#x2F;terminology&quot;&gt;coverity&lt;&#x2F;a&gt; and
&lt;a href=&quot;https:&#x2F;&#x2F;app.codacy.com&#x2F;project&#x2F;borisfaure&#x2F;terminology&#x2F;dashboard&quot;&gt;codacy&lt;&#x2F;a&gt; do
static analysis. On Terminology itself, I wrote
&lt;a href=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20151111_terminology_afl_fuzz&#x2F;&quot;&gt;tyfuzz&lt;&#x2F;a&gt;, a tool to run with
&lt;a href=&quot;https:&#x2F;&#x2F;lcamtuf.coredump.cx&#x2F;afl&#x2F;&quot;&gt;American Fuzzy Lop&lt;&#x2F;a&gt;. I need to run it for a
long period of time (weeks) and it would not help in this case.&lt;&#x2F;p&gt;
&lt;p&gt;In the enlightenment&#x2F;EFL world, we have
&lt;a href=&quot;https:&#x2F;&#x2F;git.enlightenment.org&#x2F;tools&#x2F;exactness.git&#x2F;&quot;&gt;exactness&lt;&#x2F;a&gt;, a pixel
perfect regression tester, but that’s a bit too complex for my needs.
Then, there is &lt;a href=&quot;https:&#x2F;&#x2F;invisible-island.net&#x2F;vttest&#x2F;&quot;&gt;vttest&lt;&#x2F;a&gt;, an
VT100&#x2F;VT220&#x2F;XTerm test utility. The main issue is that is it interactive: you
press a key then there is a message telling you what you will see and you
need to figure whether what is displayed is right or not. This is would be too
complex to automate.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;introducing-tytest&quot;&gt;Introducing &lt;code&gt;tytest&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;I needed to write something new. I wanted something simple with as little
dependency as possible.&lt;&#x2F;p&gt;
&lt;p&gt;I already had &lt;code&gt;tyfuzz&lt;&#x2F;code&gt; which takes escape codes in input, parses and
interprets them, and just exits.  At first, I wanted to dump some kind of
representation of what is drawn but that would be quite some work.  I ended up
taking a checksum of the different parts of the terminal and output it.
I am using &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;MD5&quot;&gt;a MD5 checksum&lt;&#x2F;a&gt; as it was
already in use in Terminology.  I write the tests in POSIX shell script.&lt;&#x2F;p&gt;
&lt;p&gt;Here is a simple test that sets a
&lt;a href=&quot;https:&#x2F;&#x2F;terminalguide.netlify.com&#x2F;seq&#x2F;csi_sq_t_space&#x2F;&quot;&gt;cursor shape&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;!&#x2F;bin&#x2F;sh&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-printf z-shell&quot;&gt;printf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-single z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;\033[0 q&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And how to take a checksum:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;tests&#x2F;cursor-shape-0.sh | build&#x2F;src&#x2F;bin&#x2F;tytest
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;c91e01b0e859cc043f21d804a01bcd50
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I wrote a shell script on top of that simple concept and I am able to test any
new changes for regressions on the tests I already wrote.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;continuous-integration&quot;&gt;Continuous Integration&lt;&#x2F;h2&gt;
&lt;p&gt;I used &lt;a href=&quot;https:&#x2F;&#x2F;circleci.com&#x2F;gh&#x2F;borisfaure&#x2F;terminology&quot;&gt;CircleCI&lt;&#x2F;a&gt; to run the
tests on each change to the master branch of Terminology.
Based on an &lt;a href=&quot;https:&#x2F;&#x2F;cloud.docker.com&#x2F;repository&#x2F;docker&#x2F;borisfaure&#x2F;terminology-ci&quot;&gt;alpine image&lt;&#x2F;a&gt;,
it compiles Terminology on both &lt;code&gt;clang&lt;&#x2F;code&gt; and &lt;code&gt;gcc&lt;&#x2F;code&gt;, and run the tests.
Then it uploads the coverage of the tests to
&lt;a href=&quot;https:&#x2F;&#x2F;codecov.io&#x2F;gh&#x2F;borisfaure&#x2F;terminology&quot;&gt;codecov.io&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-do-i-know-what-to-test&quot;&gt;How do I know what to test?&lt;&#x2F;h2&gt;
&lt;p&gt;So far, I have been reading the &lt;a href=&quot;https:&#x2F;&#x2F;vt100.net&#x2F;docs&#x2F;vt510-rm&#x2F;contents.html&quot;&gt;VT510
documentation&lt;&#x2F;a&gt; and writing
tests based on each command. I write the shell script, run it in XTerm and in
Terminology, then compare visually. Then I fix Terminology ☺&lt;&#x2F;p&gt;
&lt;p&gt;I also rely on the &lt;a href=&quot;http:&#x2F;&#x2F;www.ecma-international.org&#x2F;publications&#x2F;files&#x2F;ECMA-ST&#x2F;Ecma-048.pdf&quot;&gt;ECMA-48
documentation&lt;&#x2F;a&gt;.
Something I discovered lately is the &lt;a href=&quot;https:&#x2F;&#x2F;terminalguide.netlify.com&#x2F;&quot;&gt;Terminal
Guide&lt;&#x2F;a&gt;, it is of great help since it
lists bugs in other implementations (&lt;code&gt;urxvt&lt;&#x2F;code&gt;, &lt;code&gt;xterm&lt;&#x2F;code&gt;, &lt;code&gt;vte&lt;&#x2F;code&gt;, &lt;code&gt;konsole&lt;&#x2F;code&gt; and
&lt;code&gt;linux-vc&lt;&#x2F;code&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;I also check the coverage reports from
&lt;a href=&quot;https:&#x2F;&#x2F;codecov.io&#x2F;gh&#x2F;borisfaure&#x2F;terminology&quot;&gt;codecov.io&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Then I try to do some abstract art!&lt;&#x2F;p&gt;
&lt;p&gt;Testing cursor movements:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20190108_tytest&#x2F;tytest1.png&quot; alt=&quot;tytest on cursor movements&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Testing IL - Insert Lines:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20190108_tytest&#x2F;tytest2.png&quot; alt=&quot;tytest on IL&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;At the moment, there are 65 tests which found lots of small bugs.  I will keep
on adding tests and make Terminology even better!&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>A wrapper to i3status in go</title>
          <pubDate>Sat, 08 Dec 2018 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20181208_myi3status/</link>
          <guid>https://fau.re/20181208_myi3status/</guid>
          <description xml:base="https://fau.re/20181208_myi3status/">&lt;p&gt;I ride my bicycle to go to work and one thing is important about it: should I
put on my rain clothes? There is a service in France given by MétéoFrance that
tells you for most places in France whether it will rain in the next hour.&lt;&#x2F;p&gt;
&lt;p&gt;For every 5 minutes in the next hour, a rectangle is colored whether it will
rain and how strong.&lt;&#x2F;p&gt;
&lt;p&gt;Late last week, I wrote a small script in python that uses the API (not
public, I just opened Firefox’network page and reverse-engineered it…) to
query such piece of information.
I made the simple script below where the information is cached in a temporary
file and use &lt;code&gt;flock()&lt;&#x2F;code&gt; on it to protect concurrent accesses.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; class=&quot;language-python z-code&quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-comment z-line z-number-sign z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-python&quot;&gt;#&lt;&#x2F;span&gt;!&#x2F;usr&#x2F;bin&#x2F;env python3
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-meta z-statement z-import z-python&quot;&gt;&lt;span class=&quot;z-keyword z-control z-import z-python&quot;&gt;import&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;fcntl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-meta z-statement z-import z-python&quot;&gt;&lt;span class=&quot;z-keyword z-control z-import z-python&quot;&gt;import&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-meta z-statement z-import z-python&quot;&gt;&lt;span class=&quot;z-keyword z-control z-import z-python&quot;&gt;import&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;os&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-meta z-statement z-import z-python&quot;&gt;&lt;span class=&quot;z-keyword z-control z-import z-python&quot;&gt;import&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;requests&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-meta z-statement z-import z-python&quot;&gt;&lt;span class=&quot;z-keyword z-control z-import z-python&quot;&gt;import&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;sys&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-meta z-statement z-import z-python&quot;&gt;&lt;span class=&quot;z-keyword z-control z-import z-python&quot;&gt;import&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;time&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant z-python&quot;&gt;TMP_FILE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&#x2F;tmp&#x2F;pluie_dans_lheure.data&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-language z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;sys&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;argv&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-arguments z-python&quot;&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-python&quot;&gt;0&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;fd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;open&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-language z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;r&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;fcntl&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;flock&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;fd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;fcntl&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-constant z-python&quot;&gt;LOCK_EX&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-meta z-function z-python&quot;&gt;    &lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;&lt;span class=&quot;z-keyword z-declaration z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-entity z-name z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;generate_new_file&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-function z-begin z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;        &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant z-python&quot;&gt;BASE_URL&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;[REDACTED]&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;        &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant z-python&quot;&gt;CODE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;[REDACTED]&lt;span class=&quot;z-invalid z-illegal z-unclosed-string z-python&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;        &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;r&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;requests&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;get&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant z-python&quot;&gt;BASE_URL&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-arithmetic z-python&quot;&gt;+&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant z-python&quot;&gt;CODE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;        &lt;span class=&quot;z-keyword z-control z-flow z-assert z-python&quot;&gt;assert&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;r&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;status_code&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt;is&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-python&quot;&gt;200&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;        &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;j&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;r&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;json&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-arguments z-python&quot;&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;dataCadran&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;        &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;esc&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;chr&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-python&quot;&gt;27&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;        &lt;span class=&quot;z-meta z-statement z-with z-python&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-with z-python&quot;&gt;with&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;open&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant z-python&quot;&gt;TMP_FILE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;w&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-statement z-with z-python&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-with z-as z-python&quot;&gt;as&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-statement z-with z-python&quot;&gt; &lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-block z-with z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;            &lt;span class=&quot;z-meta z-statement z-loop z-for z-python&quot;&gt;&lt;span class=&quot;z-keyword z-control z-loop z-for z-python&quot;&gt;for&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;p&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-control z-loop z-for z-in z-python&quot;&gt;in&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-statement z-loop z-for z-python&quot;&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;d&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-statement z-loop z-for z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-loop z-for z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;                &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;p&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-arguments z-python&quot;&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;niveauPluie&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-item-access z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;                &lt;span class=&quot;z-meta z-statement z-conditional z-if z-python&quot;&gt;&lt;span class=&quot;z-keyword z-control z-conditional z-if z-python&quot;&gt;if&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-comparison z-python&quot;&gt;==&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-python&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-block z-conditional z-if z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;                    &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;f&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;write&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-python&quot;&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;_&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;                &lt;span class=&quot;z-meta z-statement z-conditional z-elseif z-python&quot;&gt;&lt;span class=&quot;z-keyword z-control z-conditional z-elseif z-python&quot;&gt;elif&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-comparison z-python&quot;&gt;==&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-python&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-block z-conditional z-elseif z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;                    &lt;span class=&quot;z-comment z-line z-number-sign z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-python&quot;&gt;#&lt;&#x2F;span&gt; light
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;                    &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;f&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;write&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-python&quot;&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;░&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;                &lt;span class=&quot;z-meta z-statement z-conditional z-elseif z-python&quot;&gt;&lt;span class=&quot;z-keyword z-control z-conditional z-elseif z-python&quot;&gt;elif&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-comparison z-python&quot;&gt;==&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-python&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-block z-conditional z-elseif z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;                    &lt;span class=&quot;z-comment z-line z-number-sign z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-python&quot;&gt;#&lt;&#x2F;span&gt; medium
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;                    &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;f&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;write&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-python&quot;&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;▒&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;                &lt;span class=&quot;z-meta z-statement z-conditional z-elseif z-python&quot;&gt;&lt;span class=&quot;z-keyword z-control z-conditional z-elseif z-python&quot;&gt;elif&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-comparison z-python&quot;&gt;==&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-python&quot;&gt;4&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-block z-conditional z-elseif z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;                    &lt;span class=&quot;z-comment z-line z-number-sign z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-python&quot;&gt;#&lt;&#x2F;span&gt; dark
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;                    &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;f&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;write&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-python&quot;&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;▓&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;                &lt;span class=&quot;z-meta z-statement z-conditional z-elseif z-python&quot;&gt;&lt;span class=&quot;z-keyword z-control z-conditional z-elseif z-python&quot;&gt;elif&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;n&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-comparison z-python&quot;&gt;&amp;gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-python&quot;&gt;5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-block z-conditional z-elseif z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;                    &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;f&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;write&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-string z-python&quot;&gt;u&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;█&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-meta z-statement z-exception z-try z-python&quot;&gt;&lt;span class=&quot;z-keyword z-control z-exception z-try z-python&quot;&gt;try&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-block z-exception z-try z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;        &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;st&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;os&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;stat&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant z-python&quot;&gt;TMP_FILE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-meta z-statement z-exception z-catch z-python&quot;&gt;&lt;span class=&quot;z-keyword z-control z-exception z-catch z-python&quot;&gt;except&lt;&#x2F;span&gt; &lt;span class=&quot;z-support z-type z-exception z-python&quot;&gt;FileNotFoundError&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-block z-exception z-catch z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;        &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;generate_new_file&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-meta z-statement z-conditional z-else z-python&quot;&gt;&lt;span class=&quot;z-keyword z-control z-conditional z-else z-python&quot;&gt;else&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-block z-conditional z-else z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;        &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;t&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;time&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;localtime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;st&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;st_ctime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;        &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;now&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;time&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;localtime&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;        &lt;span class=&quot;z-meta z-statement z-conditional z-if z-python&quot;&gt;&lt;span class=&quot;z-keyword z-control z-conditional z-if z-python&quot;&gt;if&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;t&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;tm_hour&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-comparison z-python&quot;&gt;!=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;now&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;tm_hour&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-python&quot;&gt;or&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt;int&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;now&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;tm_min&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-python&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-python&quot;&gt;5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-comparison z-python&quot;&gt;!=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-support z-type z-python&quot;&gt;int&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;t&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;tm_min&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-arithmetic z-python&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-python&quot;&gt;5&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-block z-conditional z-if z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;            &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;generate_new_file&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-meta z-statement z-with z-python&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-with z-python&quot;&gt;with&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;open&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-other z-constant z-python&quot;&gt;TMP_FILE&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;r&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-statement z-with z-python&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-with z-as z-python&quot;&gt;as&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-statement z-with z-python&quot;&gt; &lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;f&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-block z-with z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;        &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-support z-function z-builtin z-python&quot;&gt;print&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;f&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;read&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The idea was to get a string of unicode characters representing the next hour
and put that in my status bar on &lt;a href=&quot;https:&#x2F;&#x2F;i3wm.org&#x2F;&quot;&gt;i3&lt;&#x2F;a&gt;.
That script, even when just reading the file in &lt;code&gt;&#x2F;tmp&lt;&#x2F;code&gt;, was taking 1.5s. It
was to be called it every 5s. That was way too much time for such a simple
task.&lt;&#x2F;p&gt;
&lt;p&gt;I wanted to write something in &lt;a href=&quot;https:&#x2F;&#x2F;golang.org&#x2F;&quot;&gt;Go&lt;&#x2F;a&gt; for quite some time
and decided it was the good opportunity to do it.&lt;&#x2F;p&gt;
&lt;p&gt;On &lt;code&gt;i3status&lt;&#x2F;code&gt;’s manpage, there is an example about prepending the &lt;code&gt;i3status&lt;&#x2F;code&gt;
output with a custom command:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;!&#x2F;bin&#x2F;sh&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-begin z-shell&quot;&gt;#&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt; shell script to prepend i3status with more stuff&lt;&#x2F;span&gt;&lt;span class=&quot;z-comment z-line z-number-sign z-shell&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;i3status&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-control z-loop z-while z-shell&quot;&gt;while&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-colon z-shell&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-keyword z-control z-loop z-do z-shell&quot;&gt;do&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;            &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-read z-shell&quot;&gt;read&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; line&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;            &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-echo z-shell&quot;&gt;echo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;mystuff | &lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;line&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-or z-shell&quot;&gt;||&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-exit z-shell&quot;&gt;exit&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; 1&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-keyword z-control z-loop z-end z-shell&quot;&gt;done&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I did that but I wanted &lt;code&gt;i3bar&lt;&#x2F;code&gt; to display some colors. To do that, it uses a
&lt;a href=&quot;https:&#x2F;&#x2F;i3wm.org&#x2F;docs&#x2F;i3bar-protocol.html&quot;&gt;JSON protocol&lt;&#x2F;a&gt; and thus this small
script is not working since it’s not outputting valid JSON.&lt;&#x2F;p&gt;
&lt;p&gt;I wrote the same thing in Go and pushed it on
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;myi3status&quot;&gt;myi3status GitHub’s repository&lt;&#x2F;a&gt;.
As expected, it takes about nothing to run but the code is 3 times larger.&lt;&#x2F;p&gt;
&lt;p&gt;Here are some screenshots of it in action, first when there is no incoming
rain, then with some:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20181208_myi3status&#x2F;no_rain.png&quot; alt=&quot;myi3status with no rain&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20181208_myi3status&#x2F;rain.png&quot; alt=&quot;myi3status with some incoming rain&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Terminology supports hyperlinks escape sequences</title>
          <pubDate>Sun, 14 Oct 2018 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20181014_terminology_hyperlinks/</link>
          <guid>https://fau.re/20181014_terminology_hyperlinks/</guid>
          <description xml:base="https://fau.re/20181014_terminology_hyperlinks/">&lt;p&gt;Some time ago, Egmont Koblinger wrote &lt;a href=&quot;https:&#x2F;&#x2F;gist.github.com&#x2F;egmontkob&#x2F;eb114294efbcd5adb1944c9f3cb5feda&quot;&gt;a proposal&lt;&#x2F;a&gt; to add support for Hyperlinks in Terminal Emulators.&lt;&#x2F;p&gt;
&lt;p&gt;Terminology already highlights links whenever the mouse hovers them but this
proposal is to act just like links in your web browser.&lt;&#x2F;p&gt;
&lt;p&gt;I’ve patched Terminology to support that. When an application emits the needed
escape codes, Terminology will display some fancy link highlight when you
hover such links. It will also add a tooltip with the actual link so that you
shouldn’t be phished.&lt;&#x2F;p&gt;
&lt;p&gt;Here’s a video of it in action:&lt;&#x2F;p&gt;
&lt;video width=&quot;641&quot; height=&quot;571&quot; controls&gt;
	&lt;source src=&quot;terminology_hyperlinks.mp4&quot; type=&quot;video&#x2F;mp4&quot; &#x2F;&gt;
	&lt;source src=&quot;terminology_hyperlinks.ogv&quot; type=&quot;video&#x2F;ogg&quot; &#x2F;&gt;
&lt;&#x2F;video&gt;
</description>
      </item>
      <item>
          <title>Terminology provides more choice for cursors!</title>
          <pubDate>Fri, 16 Mar 2018 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20180316_terminology_cursors/</link>
          <guid>https://fau.re/20180316_terminology_cursors/</guid>
          <description xml:base="https://fau.re/20180316_terminology_cursors/">&lt;p&gt;Few months ago, &lt;a href=&quot;https:&#x2F;&#x2F;phab.enlightenment.org&#x2F;T6338&quot;&gt;a ticket was opened on
phabricator&lt;&#x2F;a&gt; to add support for
&lt;code&gt;DECSCUSR&lt;&#x2F;code&gt;. This escape code allows to change the cursor style.&lt;&#x2F;p&gt;
&lt;p&gt;I thought it was a good idea since I sometimes feel like the block cursor is
taking too much screen space.&lt;&#x2F;p&gt;
&lt;p&gt;For my 999th commit on Terminology, I’ve added support for this escape code
and did a bit more. It is now possible to choose one of the 3 available
shapes, blinking or not:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Block, the original one,&lt;&#x2F;li&gt;
&lt;li&gt;Underline,&lt;&#x2F;li&gt;
&lt;li&gt;Bar.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If you follow the git version, you can try one of the 3 &lt;code&gt;printf&lt;&#x2F;code&gt; below to
change the cursor:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;     &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-printf z-shell&quot;&gt;printf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;\x1b[1 q\n Block&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;     &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-printf z-shell&quot;&gt;printf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;\x1b[3 q\n Underline&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;     &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-printf z-shell&quot;&gt;printf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-string z-quoted z-double z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;\x1b[5 q\n Bar&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you chose to have a blinking a cursor, it will keep on being blinking. The
same works if you didn’t want it to blink.&lt;&#x2F;p&gt;
&lt;p&gt;Here’s how it renders for me:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20180316_terminology_cursors&#x2F;terminology_cursors.gif&quot; alt=&quot;showing up blinking cursors in terminology&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Terminology supports the Encircled escape sequence!</title>
          <pubDate>Tue, 13 Mar 2018 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20180313_terminology_encircled/</link>
          <guid>https://fau.re/20180313_terminology_encircled/</guid>
          <description xml:base="https://fau.re/20180313_terminology_encircled/">&lt;h2 id=&quot;truecolor&quot;&gt;TrueColor&lt;&#x2F;h2&gt;
&lt;p&gt;I was looking into TrueColor support for Terminology. It won’t support it
fully but it does approximate those TrueColors to a palette of 256 colors. It
should do it better than XTerm since it is not using a dumb euclidean distance
to compute color distance but something a bit more complex: &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Color_difference#Euclidean&quot;&gt;the last formula
on the Euclidean chapter on Color Distance on
wikipedia&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I looked a bit more on those escape codes
&lt;a href=&quot;https:&#x2F;&#x2F;www.itu.int&#x2F;rec&#x2F;dologin_pub.asp?lang=e&amp;amp;id=T-REC-T.416-199303-I!!PDF-E&amp;amp;type=items&quot;&gt;defined in ITU T.416 or ISO 8613&lt;&#x2F;a&gt;
and those TrueColors can be defined as
&lt;code&gt;RGB&lt;&#x2F;code&gt;, &lt;code&gt;CMY&lt;&#x2F;code&gt; and &lt;code&gt;CMYK&lt;&#x2F;code&gt;. Terminology supports all of them (and might be the
only one) but still does color approximation though.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;encircled&quot;&gt;Encircled&lt;&#x2F;h2&gt;
&lt;p&gt;That’s when I stumbled on the Encircled escape sequence.&lt;&#x2F;p&gt;
&lt;p&gt;3 years ago, I added support for the &lt;a href=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20140406_terminology_fraktur&#x2F;&quot;&gt;Fraktur escape sequence to
terminology&lt;&#x2F;a&gt;. And I just did the same for Encircled characters.&lt;&#x2F;p&gt;
&lt;p&gt;Unicode provides characters that are encircled in the &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Enclosed_Alphanumerics&quot;&gt;Enclosed Alphanumerics&lt;&#x2F;a&gt; block.&lt;&#x2F;p&gt;
&lt;p&gt;I did &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;terminology&#x2F;commit&#x2F;9e0243d9f16f13b3bc2449b551aefd0d8a4da81e&quot;&gt;the same
trick&lt;&#x2F;a&gt;:
translate the characters &lt;code&gt;a-z&lt;&#x2F;code&gt;, &lt;code&gt;A-Z&lt;&#x2F;code&gt;, &lt;code&gt;0-9&lt;&#x2F;code&gt; to their relative enclosed
characters.&lt;&#x2F;p&gt;
&lt;p&gt;If you follow the git version, you can try it like that:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;echo &amp;quot;\033[52mabcdefghijklmnopqrstuvwxyz\n\033[0m&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;echo &amp;quot;\033[52mABCDEFGHIJKLMNOPQRSTUVWXYZ\n\033[0m&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I’m still using &lt;a href=&quot;https:&#x2F;&#x2F;fsd.it&#x2F;shop&#x2F;fonts&#x2F;pragmatapro&#x2F;&quot;&gt;PragmataPro&lt;&#x2F;a&gt;, but it
only supports &lt;code&gt;p&lt;&#x2F;code&gt; enclosed. The other characters are rendered using Symbola
(this is transparent to the user).&lt;&#x2F;p&gt;
&lt;p&gt;Here’s how it renders for me:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20180313_terminology_encircled&#x2F;terminology_encircled.png&quot; alt=&quot;terminology rendering some encircled characters&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;Edit on 2024-01-10&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I’ve checked with a newer version of &lt;a href=&quot;https:&#x2F;&#x2F;fsd.it&#x2F;shop&#x2F;fonts&#x2F;pragmatapro&#x2F;&quot;&gt;PragmataPro&lt;&#x2F;a&gt;, and it renders great:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20180313_terminology_encircled&#x2F;terminology_encircled_font_updated.png&quot; alt=&quot;terminology rendering some encircled characters&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>The Signin crate</title>
          <pubDate>Tue, 11 Apr 2017 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20170411_rust_signin/</link>
          <guid>https://fau.re/20170411_rust_signin/</guid>
          <description xml:base="https://fau.re/20170411_rust_signin/">&lt;p&gt;For an unreleased personal project, I wanted to support &lt;a href=&quot;https:&#x2F;&#x2F;developers.google.com&#x2F;identity&#x2F;sign-in&#x2F;web&#x2F;&quot;&gt;Google SignIn&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;With it, you can “Enable Google Sign-In with only a few lines of code”.&lt;&#x2F;p&gt;
&lt;p&gt;On the client side, a web frontend, whenever a user signs in, a token is generated.&lt;&#x2F;p&gt;
&lt;p&gt;Then, this token is passed on all requests to the backend as a way to
authenticate users.&lt;&#x2F;p&gt;
&lt;p&gt;However, I needed to verify the tokens. I couldn’t find anything that suited
my needs so I decided to write a small library for that and publish it as a
&lt;a href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;signin&quot;&gt;crate&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The code is on &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;signin&quot;&gt;Github&lt;&#x2F;a&gt;.
I’ve also written a small &lt;a href=&quot;https:&#x2F;&#x2F;docs.rs&#x2F;signin&#x2F;latest&#x2F;signin&#x2F;&quot;&gt;documentation&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>A textual clock on i3lock</title>
          <pubDate>Tue, 19 Jul 2016 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20160719_i3_klok/</link>
          <guid>https://fau.re/20160719_i3_klok/</guid>
          <description xml:base="https://fau.re/20160719_i3_klok/">&lt;p&gt;I decided to give &lt;code&gt;i3&lt;&#x2F;code&gt; a try and it’s a nice ride. One of the things I missed
is my textual clock that I wrote &lt;a href=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20110606_klok&#x2F;&quot;&gt;5 years ago&lt;&#x2F;a&gt;.
I was using it as a lockscreen background.&lt;&#x2F;p&gt;
&lt;p&gt;I looked at the code of &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;i3&#x2F;i3lock&quot;&gt;i3lock&lt;&#x2F;a&gt; and decided it
was simple to patch it for my needs.
I spent few hours coding and learning about &lt;code&gt;cairo&lt;&#x2F;code&gt; and I’m happy with the result.&lt;&#x2F;p&gt;
&lt;p&gt;This is how it looks:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20160719_i3_klok&#x2F;i3klok.png&quot; alt=&quot;Screenshot of i3lock with klok on&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It is launched using the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;i3lock -k -i ~&#x2F;.bg.png
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The font used is &lt;a href=&quot;https:&#x2F;&#x2F;www.fsd.it&#x2F;shop&#x2F;fonts&#x2F;pragmatapro&#x2F;&quot;&gt;Pragmata Pro&lt;&#x2F;a&gt; in
bold.&lt;&#x2F;p&gt;
&lt;p&gt;My patches are available &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;i3lock&quot;&gt;on github&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>On mazes with Rust</title>
          <pubDate>Sat, 06 Feb 2016 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20160206_rust_maze/</link>
          <guid>https://fau.re/20160206_rust_maze/</guid>
          <description xml:base="https://fau.re/20160206_rust_maze/">&lt;p&gt;While browsing the internets, I came across a maze as a wallpaper. I wanted to
learn &lt;a href=&quot;https:&#x2F;&#x2F;www.rust-lang.org&#x2F;&quot;&gt;Rust&lt;&#x2F;a&gt; and decided to experiment with Rust by generating mazes.&lt;&#x2F;p&gt;
&lt;p&gt;The result of those experiments is available &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;maze.rs&quot;&gt;on
github&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;3-algorithms&quot;&gt;3 Algorithms&lt;&#x2F;h2&gt;
&lt;p&gt;On &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Maze_generation_algorithm&quot;&gt;wikipedia&lt;&#x2F;a&gt;, there
are 3 algorithms.
I started implementing the Prim’s algorithm. It took 295 iterations to
generate this maze:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;maze -r plain -g100x100 --foreground #585858 --animation --algorithm prim prim.gif
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20160206_rust_maze&#x2F;prim.gif&quot; alt=&quot;Generating a maze with the Prim’s algorithm&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Then I worked on Kruskal’s algorithm. Here it needed 287 iterations to
generate this maze&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;maze -r plain -g100x100 --foreground #585858 --animation --algorithm kruskal kruskal.gif
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20160206_rust_maze&#x2F;kruskal.gif&quot; alt=&quot;Generating a maze with the Kruskal’s algorithm&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Finally I worked on a Backtracker algorithm. This example took 169 iterations.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;maze -r plain -g100x100 --foreground #585858 --animation --algorithm backtracker backtracker.gif
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20160206_rust_maze&#x2F;backtracker.gif&quot; alt=&quot;Generating a maze with a backtracker algorithm&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;different-rendering-modes&quot;&gt;Different rendering modes&lt;&#x2F;h2&gt;
&lt;p&gt;I started with 2-colors mazes:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;maze -g630x400 --foreground #ffffff --background #000000 plain.png
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20160206_rust_maze&#x2F;plain.png&quot; alt=&quot;Simple maze&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I added different rendering mode based on previous image generation work I
did.
One that look like the background of the blog but not quite good:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;maze -g 635x400 -r mosaic mosaic.png
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20160206_rust_maze&#x2F;mosaic.png&quot; alt=&quot;Mosaic maze&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;One about &lt;a href=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20110612_eenvarders&#x2F;&quot;&gt;invaders&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;maze -g 637x399 --foreground #585858 -r invaders invaders.png
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20160206_rust_maze&#x2F;invaders.png&quot; alt=&quot;Invaders maze&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;bias&quot;&gt;Bias&lt;&#x2F;h2&gt;
&lt;p&gt;Since the algorithm are based on random number, I wanted to introduce some
bias.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;maze -g 630x400 --foreground #585858 -b 0.65 vertical_bias.png
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20160206_rust_maze&#x2F;bias.png&quot; alt=&quot;vertical bias&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Here, we can see the impact of the algorithm. It gets more vertical as it goes
to the right starting from the top left corner.&lt;&#x2F;p&gt;
&lt;p&gt;I added an option to specify the starting point of the algorithm.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;maze -g 630x400 --foreground #585858 -b 0.65 -o 0.5x0.5 bias_centered.png
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20160206_rust_maze&#x2F;bias_centered.png&quot; alt=&quot;vertical bias centered&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;shading&quot;&gt;Shading&lt;&#x2F;h2&gt;
&lt;p&gt;These 2-colors images are nice but let’s bring some more colors!&lt;&#x2F;p&gt;
&lt;p&gt;The color goes from red to white based on the length of path from the center:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;maze -g630x400 -o 0.5x0.5 --gradient length maze.png
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20160206_rust_maze&#x2F;shading_centered.png&quot; alt=&quot;maze with shading from center&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;An other option is to have the solution of the maze drawn and then have a
shading based on how far the cells are from the solution. It generates what I
call the lava river:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;maze -g630x400 --foreground #d70000\ #585858 --gradient solution lava_river.png
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20160206_rust_maze&#x2F;lava_river.png&quot; alt=&quot;lava river&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Here, we see the impact of the Prim algorithm. It tends to produce mazes that
go from top left to bottom right in a direct way.&lt;&#x2F;p&gt;
&lt;p&gt;With the Kruskal algorithm:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;maze -g630x400 --foreground #d70000\ #585858 --gradient solution --algorithm kruskal kruskal.png
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20160206_rust_maze&#x2F;kruskal_shaded.png&quot; alt=&quot;maze shaded based on the solution with the Kruskal algorithm&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;With the backtracker algorithm:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;maze -g630x400 --foreground #d70000\ #585858 --gradient solution --algorithm backtracker backtracker.png
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20160206_rust_maze&#x2F;backtracker_shaded.png&quot; alt=&quot;maze shaded based on the solution with the backtracker algorithm&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;contributions&quot;&gt;Contributions&lt;&#x2F;h2&gt;
&lt;p&gt;During my development of &lt;code&gt;maze.rs&lt;&#x2F;code&gt;, I wrote 2 crates:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;debug_macros&#x2F;&quot;&gt;debug_macros&lt;&#x2F;a&gt; to add the macro &lt;code&gt;dbg!()&lt;&#x2F;code&gt; that prints a message (like
&lt;code&gt;println!()&lt;&#x2F;code&gt;) but have it prefixed by the file and line where the call is
written.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;crates.io&#x2F;crates&#x2F;color_scaling&#x2F;&quot;&gt;color_scaling&lt;&#x2F;a&gt;: function to have
some shading between 2 colors.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I also wrote some ebuilds in my &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;gentoo-overlay&#x2F;tree&#x2F;master&#x2F;dev-lang&#x2F;rust-bin&quot;&gt;gentoo
overlay&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I also found a bug in the rust library I used to generate a gif and &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;PistonDevelopers&#x2F;image-gif&#x2F;pull&#x2F;16&quot;&gt;patched
it&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Fuzzing Terminology with AFL</title>
          <pubDate>Wed, 11 Nov 2015 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20151111_terminology_afl_fuzz/</link>
          <guid>https://fau.re/20151111_terminology_afl_fuzz/</guid>
          <description xml:base="https://fau.re/20151111_terminology_afl_fuzz/">&lt;p&gt;I wanted to fuzz Terminology for quite a long time. In late August, I found
&lt;a href=&quot;https:&#x2F;&#x2F;spin.atomicobject.com&#x2F;2015&#x2F;08&#x2F;23&#x2F;fuzz-testing-american-fuzzy-lop&#x2F;&quot;&gt;this
article&lt;&#x2F;a&gt;
about &lt;a href=&quot;https:&#x2F;&#x2F;lcamtuf.coredump.cx&#x2F;afl&#x2F;&quot;&gt;American Fuzzy Lop&lt;&#x2F;a&gt;.  All I had to do
to have it work with Terminology is to have Terminology take its input &lt;code&gt;stdin&lt;&#x2F;code&gt;
(or a file but I chose to read from &lt;code&gt;stdin&lt;&#x2F;code&gt;) instead of a &lt;code&gt;tty&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;when-epoll-is-not-behaving-as-i-d-like&quot;&gt;When &lt;code&gt;epoll&lt;&#x2F;code&gt; is not behaving as I’d like&lt;&#x2F;h2&gt;
&lt;p&gt;I did those changes but &lt;code&gt;afl&lt;&#x2F;code&gt; was not happy because Terminology was crashing
right-away.
I ran my first test-case like that:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;    &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;cat&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; afl&#x2F;in&#x2F;colors_font&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-pipe z-shell&quot;&gt;|&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;src&#x2F;bin&#x2F;terminology&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and it worked like a charm. A window appeared and disappeared with no error
message in the logs. The return code was 0. Nothing misbehaving here, but only
when ran with &lt;code&gt;afl&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Terminology uses &lt;code&gt;epoll&lt;&#x2F;code&gt; to know when there is some new data to
read from &lt;code&gt;stdin&lt;&#x2F;code&gt;. Due to the way &lt;code&gt;afl&lt;&#x2F;code&gt; works, &lt;code&gt;stdin&lt;&#x2F;code&gt; is a file descriptor to a regular
file (set to &lt;code&gt;stdin&lt;&#x2F;code&gt; after &lt;code&gt;fork()&lt;&#x2F;code&gt; before &lt;code&gt;exec()&lt;&#x2F;code&gt; using &lt;code&gt;dup2()&lt;&#x2F;code&gt;). When adding &lt;code&gt;stdin&lt;&#x2F;code&gt; to &lt;code&gt;epoll_ctl()&lt;&#x2F;code&gt;, it replied &lt;code&gt;EBADF&lt;&#x2F;code&gt; saying that &lt;code&gt;stdin&lt;&#x2F;code&gt; is not a valid file descriptor (to &lt;code&gt;epoll&lt;&#x2F;code&gt;) since &lt;code&gt;epoll&lt;&#x2F;code&gt; can not be used to poll regular files.&lt;&#x2F;p&gt;
&lt;p&gt;I did patch &lt;code&gt;afl&lt;&#x2F;code&gt; to make &lt;code&gt;stdin&lt;&#x2F;code&gt; behave like a
&lt;code&gt;pipe&lt;&#x2F;code&gt; for the test application and then it worked (almost) great.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;afl-did-find-bugs&quot;&gt;&lt;code&gt;afl&lt;&#x2F;code&gt; did find bugs&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;afl&lt;&#x2F;code&gt; did find a bug in Terminology that resulted in &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;terminology&#x2F;commit&#x2F;28965e6601d24e1d1b114559b7752ed40b8459b1&quot;&gt;this
commit&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It also did find an other bug, but outside Terminology: in Enlightenment! &lt;code&gt;afl&lt;&#x2F;code&gt;
kept on spawning Terminology and thus kept on creating and closing windows. At
some point Enlightenment would crash. This led to
&lt;a href=&quot;https:&#x2F;&#x2F;phab.enlightenment.org&#x2F;T2803&quot;&gt;T2803&lt;&#x2F;a&gt; that is now fixed thanks to
&lt;code&gt;zmike&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;tyfuzz&quot;&gt;&lt;code&gt;tyfuzz&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Because Terminology had to create windows all the time and initialize a bunch
of stuff, it was slow to actually do the fuzzing. I wrote a small piece of
code called &lt;code&gt;tyfuzz&lt;&#x2F;code&gt; to only test the relevant parts: the parsing of the
escape codes.
I has been running in &lt;code&gt;afl&lt;&#x2F;code&gt; for 2 days but it did not yield any crash so far.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-to-run-it&quot;&gt;How to run it?&lt;&#x2F;h2&gt;
&lt;p&gt;Everything is currently &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;terminology&#x2F;&quot;&gt;on git&lt;&#x2F;a&gt;. One need to compile Terminology with the afl compiler companion tool and activate fuzzing.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-assignment z-shell&quot;&gt;CC&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-shell&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-unquoted z-shell&quot;&gt;afl-gcc&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;.&#x2F;autogen.sh&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; --&lt;&#x2F;span&gt;enable-fuzzing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-logical z-and z-shell&quot;&gt;&amp;amp;&amp;amp;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;make&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Terminology produced that way won’t be usable outside &lt;code&gt;afl&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;afl-fuzz&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;m&lt;&#x2F;span&gt; none&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;i&lt;&#x2F;span&gt; afl&#x2F;in&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;o&lt;&#x2F;span&gt; afl&#x2F;out&lt;span class=&quot;z-keyword z-operator z-end-of-options z-shell&quot;&gt; --&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; src&#x2F;bin&#x2F;terminology -s&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;or
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-variable z-function z-shell&quot;&gt;afl-fuzz&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;m&lt;&#x2F;span&gt; none&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;i&lt;&#x2F;span&gt; afl&#x2F;in&lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt; -&lt;&#x2F;span&gt;o&lt;&#x2F;span&gt; afl&#x2F;out&lt;span class=&quot;z-keyword z-operator z-end-of-options z-shell&quot;&gt; --&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; src&#x2F;bin&#x2F;tyfuzz -s&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</description>
      </item>
      <item>
          <title>Terminology: on selections</title>
          <pubDate>Sat, 07 Feb 2015 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20150125_terminology_selections/</link>
          <guid>https://fau.re/20150125_terminology_selections/</guid>
          <description xml:base="https://fau.re/20150125_terminology_selections/">&lt;p&gt;I wanted to fix some bugs around selections in Terminology. In order to keep
Terminology rock-solid, I need to test all the ways to make a selection after
my changes to be sure I didn’t break anything. It is time to make a list and
document them.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;usual-way-to-make-a-selection&quot;&gt;Usual way to make a selection&lt;&#x2F;h2&gt;
&lt;p&gt;Terminology supports selection by clicking somewhere in the window and
dragging the pointer to where you want the selection to end, while keeping
down the left button of your mouse.&lt;&#x2F;p&gt;
&lt;p&gt;Because Terminology is build with the EFL, a selection is more fancy than just
inversing the color like it is usually the case with other terminal emulators.&lt;&#x2F;p&gt;
&lt;p&gt;Here is what is looks like in action:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20150125_terminology_selections&#x2F;simple.jpg&quot; alt=&quot;simple selection&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;stretching-selections&quot;&gt;Stretching selections&lt;&#x2F;h2&gt;
&lt;p&gt;One nice feature of Terminology is to be able to adjust selections after they
have been set.&lt;&#x2F;p&gt;
&lt;p&gt;There are 2 anchors that can be moved. They are the red bars on the words
&lt;code&gt;portittor&lt;&#x2F;code&gt; and &lt;code&gt;Aliquam&lt;&#x2F;code&gt;. An animation is played when the mouse hovers the
anchors. Clicking and dragging the anchors allows for expanding or expanding
the selection.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20150125_terminology_selections&#x2F;anchor.jpg&quot; alt=&quot;stretching a selection&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;introducing-the-box-selection&quot;&gt;Introducing the box selection&lt;&#x2F;h2&gt;
&lt;p&gt;Sometimes, the usual way of selecting text is not practical and one would want
to crop the text. The &lt;code&gt;box&lt;&#x2F;code&gt; selection is here in that case.
Press &lt;code&gt;ctrl&lt;&#x2F;code&gt; when doing the selection and the selection will be a rectangle.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20150125_terminology_selections&#x2F;box.jpg&quot; alt=&quot;a box selection&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;It is possible to stretch&#x2F;shrink those selections too.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;word-and-line-selection&quot;&gt;Word and line selection&lt;&#x2F;h2&gt;
&lt;p&gt;Double-click on a word and it will select it.
Triple-click on some text and the whole line will be selected.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20150125_terminology_selections&#x2F;line.jpg&quot; alt=&quot;a line selection&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Resizing the selection will now go by word&#x2F;line.
If you keep the mouse button pressed on your double-click, the selection will
go by words as you drag the mouse, until you release the mouse button.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;other-ways-to-make-selections&quot;&gt;Other ways to make selections&lt;&#x2F;h2&gt;
&lt;p&gt;Moving the mouse while having the left button of the mouse may not be
practical in some situations. In that case, click somewhere where you would
like to start your selection then move the mouse to where you would like your
selection to end. There, press &lt;code&gt;shift&lt;&#x2F;code&gt; and click and you have your selection.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;ctrl-shift+click&lt;&#x2F;code&gt; makes a box selection.
&lt;code&gt;shift+double-click&lt;&#x2F;code&gt; selects text from the original click, up to the word
being double-clicked on. This also works with lines and triple-clicks.&lt;&#x2F;p&gt;
&lt;p&gt;Once there is already a selection, making a &lt;code&gt;shift&lt;&#x2F;code&gt; click will extend the
current selection up to where the mouse pointer is.&lt;&#x2F;p&gt;
&lt;p&gt;From the original selection, this is what happens after a &lt;code&gt;shift-click&lt;&#x2F;code&gt; above
the selection and below it:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20150125_terminology_selections&#x2F;extended.jpg&quot; alt=&quot;an extended selection&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;when-the-application-is-stealing-the-mouse&quot;&gt;When the application is stealing the mouse?&lt;&#x2F;h2&gt;
&lt;p&gt;Simply do the selection action with &lt;code&gt;shift&lt;&#x2F;code&gt; pressed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;when-is-all-that-available&quot;&gt;When is all that available?&lt;&#x2F;h2&gt;
&lt;p&gt;It is currently in the master branch of the Terminology repository.
The &lt;code&gt;0.8&lt;&#x2F;code&gt; version of Terminology will have all those features. It will be
released soon.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Gravatar integration in Terminology</title>
          <pubDate>Sun, 19 Oct 2014 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20141019_terminology_gravatar/</link>
          <guid>https://fau.re/20141019_terminology_gravatar/</guid>
          <description xml:base="https://fau.re/20141019_terminology_gravatar/">&lt;p&gt;A long time ago, I received an email from a friend on my phone through the K9
application. I didn’t have her in my contacts (yet) but it did show me her
picture next to the email. I wonder what was the black magic behind that!&lt;&#x2F;p&gt;
&lt;p&gt;It was just K9 using &lt;a href=&quot;https:&#x2F;&#x2F;gravatar.com&#x2F;&quot;&gt;gravatar&lt;&#x2F;a&gt; to try to fetch a picture
related to her email address.&lt;&#x2F;p&gt;
&lt;p&gt;Since that event, I want to display gravatars as tooltip over email addresses in Terminology.
It can be nice in your email client if you use a console-based one or to see an
avatar after git-blaming someone :)&lt;&#x2F;p&gt;
&lt;p&gt;I finally wrote the code to do that for the EFL dev day 2014.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-does-it-work&quot;&gt;How does it work?&lt;&#x2F;h2&gt;
&lt;p&gt;It’s simple!
Take an email, let’s say &lt;code&gt;MyEmailAddress@example.com&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Trim the leading and trailing spaces.&lt;&#x2F;li&gt;
&lt;li&gt;Lower-case the address. &lt;code&gt;myemailaddress@example.com&lt;&#x2F;code&gt; in our example.&lt;&#x2F;li&gt;
&lt;li&gt;Take the md5 hash of that string: &lt;code&gt;0bc83cb571cd1c50ba6f3e8a78ef1346&lt;&#x2F;code&gt; in that
case.&lt;&#x2F;li&gt;
&lt;li&gt;Fetch &lt;code&gt;http:&#x2F;&#x2F;www.gravatar.com&#x2F;avatar&#x2F;&lt;&#x2F;code&gt; + the md5sum.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;how-does-it-look&quot;&gt;How does it look?&lt;&#x2F;h2&gt;
&lt;p&gt;A small capture of live action:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20141019_terminology_gravatar&#x2F;terminology_gravatar.gif&quot; alt=&quot;gravatar tooltip in terminology&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Of course it is possible to disable that feature in the Behavior panel in the
Settings.&lt;&#x2F;p&gt;
&lt;p&gt;If you have any cool ideas you want to see in Terminology, tell me about them!&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Terminology at the EFL Dev Day 2014</title>
          <pubDate>Tue, 14 Oct 2014 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20141014_terminology_efl_dev_day/</link>
          <guid>https://fau.re/20141014_terminology_efl_dev_day/</guid>
          <description xml:base="https://fau.re/20141014_terminology_efl_dev_day/">&lt;p&gt;The 2014 edition of the EFL Dev Day was held in Düsseldorf yesterday.
I gave a quick talk about Terminology.&lt;&#x2F;p&gt;
&lt;p&gt;Just like last year, I used Terminology itself to render my talk.&lt;&#x2F;p&gt;
&lt;p&gt;The code is on &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;typres&quot;&gt;github&lt;&#x2F;a&gt;. I refactored it a
bit and it should be more usable than the single script I had last year.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;terminology-0-7&quot;&gt;Terminology 0.7&lt;&#x2F;h2&gt;
&lt;p&gt;During the talk I said that the version 0.7 of Terminology would go out soon
and within few hours, it was released.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;distro-involvement&quot;&gt;Distro involvement&lt;&#x2F;h2&gt;
&lt;p&gt;I complained about the state of Terminology in the various Linux distributions.
It is still hard on many distributions to get Terminology.
If Terminology is not available in your distribution, please ask the
distribution maintainers to package it!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-future&quot;&gt;The future&lt;&#x2F;h2&gt;
&lt;p&gt;We have some great features planned but I don’t know what features people
would like to see soon in Terminology.&lt;&#x2F;p&gt;
&lt;p&gt;Here is a quick list of possibilities:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Make miniview an awesome scrollbar,&lt;&#x2F;li&gt;
&lt;li&gt;Improvements on CPU usage when on battery,&lt;&#x2F;li&gt;
&lt;li&gt;Searchable buffer,&lt;&#x2F;li&gt;
&lt;li&gt;Zooming on images,&lt;&#x2F;li&gt;
&lt;li&gt;Instant Replay to be able to render the terminal from few seconds ago,&lt;&#x2F;li&gt;
&lt;li&gt;Splits in tabs (Currently tabs can be in splits but not the other way
around),&lt;&#x2F;li&gt;
&lt;li&gt;Have more common “tabs”,&lt;&#x2F;li&gt;
&lt;li&gt;Bold&#x2F;Italic,&lt;&#x2F;li&gt;
&lt;li&gt;Tmux integration,&lt;&#x2F;li&gt;
&lt;li&gt;…&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;If you have some nice ideas, I would like to hear about them!
Feel free to contact me or open a “Wishlist” task on
&lt;a href=&quot;https:&#x2F;&#x2F;phab.enlightenment.org&#x2F;maniphest&#x2F;task&#x2F;create&#x2F;&quot;&gt;phab&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I will probably make a poll about those ideas to know what people think is
important to add to Terminology.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-slides&quot;&gt;The slides&lt;&#x2F;h2&gt;
&lt;p&gt;Here are the slides:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20141014_terminology_efl_dev_day&#x2F;01.jpg&quot; alt=&quot;Terminology - Oct 2014 - Beyond words&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20141014_terminology_efl_dev_day&#x2F;02.jpg&quot; alt=&quot;$ whoami&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20141014_terminology_efl_dev_day&#x2F;03.jpg&quot; alt=&quot;What is Terminology (in case you’re really new here)?&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20141014_terminology_efl_dev_day&#x2F;04.jpg&quot; alt=&quot;What have we done during the past year?&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20141014_terminology_efl_dev_day&#x2F;05.jpg&quot; alt=&quot;Releases!!&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20141014_terminology_efl_dev_day&#x2F;06.jpg&quot; alt=&quot;Terminology 0.4 (Dec 2013)&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20141014_terminology_efl_dev_day&#x2F;07.jpg&quot; alt=&quot;Terminology 0.5 (Mar 2014)&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20141014_terminology_efl_dev_day&#x2F;08.jpg&quot; alt=&quot;Terminology 0.6 (July 2014)&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20141014_terminology_efl_dev_day&#x2F;09.jpg&quot; alt=&quot;Terminology 0.7 (now!!!)&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20141014_terminology_efl_dev_day&#x2F;10.jpg&quot; alt=&quot;Great, but we haven’t conquered the world yet&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20141014_terminology_efl_dev_day&#x2F;11.jpg&quot; alt=&quot;State of Terminology in distros&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20141014_terminology_efl_dev_day&#x2F;12.jpg&quot; alt=&quot;What’s next?&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20141014_terminology_efl_dev_day&#x2F;13.jpg&quot; alt=&quot;What’s next?&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20141014_terminology_efl_dev_day&#x2F;14.jpg&quot; alt=&quot;Crazy ideas like…&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20141014_terminology_efl_dev_day&#x2F;15.jpg&quot; alt=&quot;Questions ?&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Miniview of the history in Terminology</title>
          <pubDate>Thu, 15 May 2014 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20140515_terminology_miniview/</link>
          <guid>https://fau.re/20140515_terminology_miniview/</guid>
          <description xml:base="https://fau.re/20140515_terminology_miniview/">&lt;p&gt;Lately I have been working on a new feature for &lt;code&gt;terminology&lt;&#x2F;code&gt;: render the
history in a small widget that I call the miniview. This feature can be found
in trendy code editors.&lt;&#x2F;p&gt;
&lt;p&gt;It started as an old patch from Galatsanos Panagiotis back in June 2013!
I made it work with the current code base and iterated over it.&lt;&#x2F;p&gt;
&lt;p&gt;A picture is worth a thousand words:
&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20140515_terminology_miniview&#x2F;terminology_miniview.png&quot; alt=&quot;terminology showing the miniview&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The miniview is shown on the right. It can be shown with hitting Ctrl-Shift-h.
(I plan to make keyboard shortcuts configurable soon, but it will probably not
hit &lt;code&gt;terminology&lt;&#x2F;code&gt; 0.6)&lt;&#x2F;p&gt;
&lt;p&gt;Each character is converted to a single pixel. It is possible to click on it
to scroll the terminal to that position in the history.&lt;&#x2F;p&gt;
&lt;p&gt;The widget can be scrolled up or down with the mouse wheel cause it may not
show the whole history on one screen.  &lt;code&gt;PgUp&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;PgDown&lt;&#x2F;code&gt; scrolls by steps of 25
lines while &lt;code&gt;Shift-PgUp&#x2F;PgDown&lt;&#x2F;code&gt; scrolls by a whole screen. &lt;code&gt;Alt-PgUp&#x2F;PgDown&lt;&#x2F;code&gt;,
&lt;code&gt;Ctrl-PgUp&#x2F;PgDown&lt;&#x2F;code&gt; do the same.&lt;&#x2F;p&gt;
&lt;p&gt;Hitting &lt;code&gt;Ctrl-Shift-h&lt;&#x2F;code&gt; or the blue cross on the top left corner will close the
miniview.&lt;&#x2F;p&gt;
&lt;p&gt;Now it’s time to fix some bugs to be able to release &lt;code&gt;terminology&lt;&#x2F;code&gt; 0.6 next
month!&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Terminology supports the Fraktur escape sequence!</title>
          <pubDate>Sun, 06 Apr 2014 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20140406_terminology_fraktur/</link>
          <guid>https://fau.re/20140406_terminology_fraktur/</guid>
          <description xml:base="https://fau.re/20140406_terminology_fraktur/">&lt;p&gt;Thanks to a tweet from
&lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;resiak&#x2F;status&#x2F;452110266898337792&quot;&gt;@resiak&lt;&#x2F;a&gt;, I’ve learnt
that &lt;a href=&quot;http:&#x2F;&#x2F;www.ecma-international.org&#x2F;publications&#x2F;files&#x2F;ECMA-ST&#x2F;Ecma-048.pdf&quot;&gt;ECMA-48 - Control Functions for Coded Character Sets&lt;&#x2F;a&gt; provides some escape codes to diplay Fraktur!&lt;&#x2F;p&gt;
&lt;p&gt;According to
&lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Fraktur_%28typeface%29&quot;&gt;wikipedia&lt;&#x2F;a&gt;,&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Fraktur [fʁakˈtuːɐ] is a calligraphic hand of the Latin alphabet
and any of several blackletter typefaces derived from this hand. The
blackletter lines are broken up – that is, their forms contain many angles
when compared to the smooth curves of the Antiqua (common) typefaces
modeled after antique Roman square capitals and Carolingian minuscule.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Not long ago, &lt;a href=&quot;https:&#x2F;&#x2F;fsd.it&#x2F;shop&#x2F;fonts&#x2F;pragmatapro&#x2F;&quot;&gt;PragmataPro&lt;&#x2F;a&gt;, the
great monospace typeface I use every day got support for such characters.&lt;&#x2F;p&gt;
&lt;p&gt;I’ve spent few minutes to let &lt;code&gt;terminology&lt;&#x2F;code&gt;
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;terminology&#x2F;commit&#x2F;02856cbdec511e08cf579b08e906499d9583f018&quot;&gt;handle&lt;&#x2F;a&gt; those escape codes.&lt;&#x2F;p&gt;
&lt;p&gt;If you follow the git version, you can try it like that:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;echo &amp;quot;\033[20mabcdefghijklmnopqrstuvwxyz\n\033[0m&amp;quot;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;echo &amp;quot;\033[20mABCDEFGHIJKLMNOPQRSTUVWXYZ\n\033[0m&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Mandatory screenshot of the feature:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20140406_terminology_fraktur&#x2F;terminology_fraktur.png&quot; alt=&quot;terminology rendering some Fraktur characters&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>gdb + valgrind</title>
          <pubDate>Sun, 30 Mar 2014 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20140330_vgdb/</link>
          <guid>https://fau.re/20140330_vgdb/</guid>
          <description xml:base="https://fau.re/20140330_vgdb/">&lt;p&gt;During Fosdem 2014, I attended a great talk by Philippe Waroquiers about
&lt;a href=&quot;https:&#x2F;&#x2F;fosdem.org&#x2F;2014&#x2F;schedule&#x2F;event&#x2F;valgrind_gdb&#x2F;&quot;&gt;Combining the power of Valgrind and
GDB&lt;&#x2F;a&gt;. Since the video of
the talk is not available, I wanted to share the power of combining gdb and
valgrind.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;down-the-rabbit-hole&quot;&gt;Down the rabbit hole&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;code&gt;valgrind&lt;&#x2F;code&gt; can run a &lt;code&gt;gdb server&lt;&#x2F;code&gt; so that a &lt;code&gt;gdb&lt;&#x2F;code&gt; can interact with it.
&lt;code&gt;valgrind&lt;&#x2F;code&gt; has 2 options to trigger that:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--vgdb=yes&lt;&#x2F;code&gt;,&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;--vgdb-error=0&lt;&#x2F;code&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This second option tells &lt;code&gt;valgrind&lt;&#x2F;code&gt; it needs to wait for that many errors
before freezing and wait for a &lt;code&gt;gdb&lt;&#x2F;code&gt; to connect. Setting it to &lt;code&gt;0&lt;&#x2F;code&gt; will make
&lt;code&gt;valgrind&lt;&#x2F;code&gt; to wait for &lt;code&gt;gdb&lt;&#x2F;code&gt; to connect before executing the program.&lt;&#x2F;p&gt;
&lt;p&gt;So you start&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ valgrind --vgdb=yes --vgdb-error=0 .&#x2F;foo
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;valgrind&lt;&#x2F;code&gt; will tell you to run&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$ gdb .&#x2F;foo
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;and then enter at the &lt;code&gt;gdb&lt;&#x2F;code&gt; prompt the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(gdb) target remote | vgdb
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let’s show some examples.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;leak-search&quot;&gt;Leak search&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;C&quot; class=&quot;language-C z-code&quot;&gt;&lt;code class=&quot;language-C&quot; data-lang=&quot;C&quot;&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-preprocessor z-include z-c&quot;&gt;    &lt;span class=&quot;z-keyword z-control z-import z-include z-c&quot;&gt;#include&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-other z-lt-gt z-include z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-c&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;stdlib.h&lt;span class=&quot;z-punctuation z-definition z-string z-end z-c&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-preprocessor z-include z-c&quot;&gt;    &lt;span class=&quot;z-keyword z-control z-import z-include z-c&quot;&gt;#include&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-other z-lt-gt z-include z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-c&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;string.h&lt;span class=&quot;z-punctuation z-definition z-string z-end z-c&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;    
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;    &lt;span class=&quot;z-storage z-type z-c&quot;&gt;int&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-entity z-name z-function z-c&quot;&gt;main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-storage z-type z-c&quot;&gt;int&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-c&quot;&gt;argc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-storage z-type z-c&quot;&gt;char&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-c&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-c&quot;&gt;argv&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brackets z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-begin z-c&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-end z-c&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-c&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-storage z-type z-c&quot;&gt;char&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-c&quot;&gt;*&lt;&#x2F;span&gt;lost &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;strdup&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-c&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;catch me if you can!&lt;span class=&quot;z-punctuation z-definition z-string z-end z-c&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        lost &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-language z-c&quot;&gt;NULL&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;strdup&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-c&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;foobar&lt;span class=&quot;z-punctuation z-definition z-string z-end z-c&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-keyword z-control z-flow z-return z-c&quot;&gt;return&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-c&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Passing commands from &lt;code&gt;gdb&lt;&#x2F;code&gt; to &lt;code&gt;valgrind&lt;&#x2F;code&gt; is done with the &lt;code&gt;monitor&lt;&#x2F;code&gt; keyword.
Showing the help message is as follows:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(gdb) monitor help
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let’s put breakpoints at lines 6, 7 and 8 and continue the execution of the
program.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(gdb) target remote | vgdb
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(gdb) breakpoint 6
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(gdb) breakpoint 7
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(gdb) breakpoint 8
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(gdb) continue
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Is there a leak?&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Breakpoint 1, main (argc=1, argv=0xffeffbe68) at leak_check.c:6
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;6           lost = NULL;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(gdb) monitor leak_check
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756== LEAK SUMMARY:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==    definitely lost: 0 (+0) bytes in 0 (+0) blocks
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==    indirectly lost: 0 (+0) bytes in 0 (+0) blocks
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==      possibly lost: 0 (+0) bytes in 0 (+0) blocks
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==    still reachable: 21 (+21) bytes in 1 (+1) blocks
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==         suppressed: 0 (+0) bytes in 0 (+0) blocks
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756== Reachable blocks (those to which a pointer was found) are not
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;shown.
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756== To see them, add &amp;#39;reachable any&amp;#39; args to leak_check
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Not yet :) Let’s go to line 7 and &lt;code&gt;lost&lt;&#x2F;code&gt; no longer points to &lt;code&gt;catch me if you can!&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(gdb) continue
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Breakpoint 2, main (argc=1, argv=0xffeffbe68) at leak_check.c:7
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;7           strdup(&amp;quot;foobar&amp;quot;);
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(gdb) monitor leak_check
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756== LEAK SUMMARY:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==    definitely lost: 0 (+0) bytes in 0 (+0) blocks
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==    indirectly lost: 0 (+0) bytes in 0 (+0) blocks
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==      possibly lost: 0 (+0) bytes in 0 (+0) blocks
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==    still reachable: 21 (+0) bytes in 1 (+0) blocks
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==         suppressed: 0 (+0) bytes in 0 (+0) blocks
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756== Reachable blocks (those to which a pointer was found) are not
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;shown.
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756== To see them, add &amp;#39;reachable any&amp;#39; args to leak_check
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Strange! &lt;code&gt;valgrind&lt;&#x2F;code&gt; says the memory is still reachable! Let’s see why!&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(gdb) monitor block_list 1
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756== 21 (+0) bytes in 1 (+0) blocks are still reachable in loss record 1
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;of 1
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==    at 0x4C2C430: malloc (vg_replace_malloc.c:291)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==    by 0x4EB7EF9: strdup (in &#x2F;lib64&#x2F;libc-2.17.so)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==    by 0x4005A8: main (leak_search.c:5)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756== 0x51E1040[21]
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So who is pointing at this part of the memory?&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(gdb) monitor who_points_at 0x51E1040 21
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756== Searching for pointers pointing in 21 bytes from 0x51e1040
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756== tid 1 register RAX pointing at 0x51e1040
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So there is still a register pointing to &lt;code&gt;0x51e1040&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Go to line 8 and let’s see what changed from line 7:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(gdb) continue
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Breakpoint 3, main (argc=1, argv=0xffeffbe68) at leak_check.c:8
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;8           return 0;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(gdb) monitor leak_check full changed
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(gdb) monitor l f c
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756== 21 (+21) bytes in 1 (+1) blocks are definitely lost in loss
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;record 3 of 3
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==    at 0x4C2C430: malloc (vg_replace_malloc.c:291)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==    by 0x4EB7EF9: strdup (in &#x2F;lib64&#x2F;libc-2.17.so)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==    by 0x4005A8: main (leak_search.c:5)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756== LEAK SUMMARY:
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==    definitely lost: 21 (+21) bytes in 1 (+1) blocks
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==    indirectly lost: 0 (+0) bytes in 0 (+0) blocks
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==      possibly lost: 0 (+0) bytes in 0 (+0) blocks
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==    still reachable: 7 (-14) bytes in 1 (+0) blocks
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==         suppressed: 0 (+0) bytes in 0 (+0) blocks
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756== Reachable blocks (those to which a pointer was found) are not
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;shown.
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756== To see them, add &amp;#39;reachable any&amp;#39; args to leak_check
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==7756==
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The register no longer contains a pointer to &lt;code&gt;0x51e1040&lt;&#x2F;code&gt;.
There is still a pointer (a register in this case) that points to &lt;code&gt;&quot;foobar&quot;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;which-parts-of-memory-is-un-initialized&quot;&gt;Which parts of memory is (un)initialized?&lt;&#x2F;h2&gt;
&lt;pre data-lang=&quot;C&quot; class=&quot;language-C z-code&quot;&gt;&lt;code class=&quot;language-C&quot; data-lang=&quot;C&quot;&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-preprocessor z-include z-c&quot;&gt;    &lt;span class=&quot;z-keyword z-control z-import z-include z-c&quot;&gt;#include&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-other z-lt-gt z-include z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-c&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;stdlib.h&lt;span class=&quot;z-punctuation z-definition z-string z-end z-c&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-preprocessor z-include z-c&quot;&gt;    &lt;span class=&quot;z-keyword z-control z-import z-include z-c&quot;&gt;#include&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-other z-lt-gt z-include z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-c&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;stdio.h&lt;span class=&quot;z-punctuation z-definition z-string z-end z-c&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-preprocessor z-include z-c&quot;&gt;    &lt;span class=&quot;z-keyword z-control z-import z-include z-c&quot;&gt;#include&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-other z-lt-gt z-include z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-c&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;unistd.h&lt;span class=&quot;z-punctuation z-definition z-string z-end z-c&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-preprocessor z-include z-c&quot;&gt;    &lt;span class=&quot;z-keyword z-control z-import z-include z-c&quot;&gt;#include&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-other z-lt-gt z-include z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-c&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;sys&#x2F;types.h&lt;span class=&quot;z-punctuation z-definition z-string z-end z-c&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-preprocessor z-include z-c&quot;&gt;    &lt;span class=&quot;z-keyword z-control z-import z-include z-c&quot;&gt;#include&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-other z-lt-gt z-include z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-c&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;sys&#x2F;stat.h&lt;span class=&quot;z-punctuation z-definition z-string z-end z-c&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-preprocessor z-include z-c&quot;&gt;    &lt;span class=&quot;z-keyword z-control z-import z-include z-c&quot;&gt;#include&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-other z-lt-gt z-include z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-c&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;fcntl.h&lt;span class=&quot;z-punctuation z-definition z-string z-end z-c&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;    
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;    &lt;span class=&quot;z-meta z-struct z-c&quot;&gt;&lt;span class=&quot;z-storage z-type z-c&quot;&gt;struct&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-struct z-c&quot;&gt;&lt;span class=&quot;z-entity z-name z-struct z-c&quot;&gt;s_a&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-struct z-c&quot;&gt; &lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-c&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-struct z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-struct z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-storage z-type z-c&quot;&gt;char&lt;&#x2F;span&gt; c&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-struct z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-storage z-type z-c&quot;&gt;int&lt;&#x2F;span&gt;  i&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-struct z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-struct z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-c&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;    &lt;span class=&quot;z-storage z-type z-c&quot;&gt;int&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-entity z-name z-function z-c&quot;&gt;main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-storage z-type z-c&quot;&gt;int&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-c&quot;&gt;argc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-storage z-type z-c&quot;&gt;char&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-c&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-c&quot;&gt;argv&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brackets z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-begin z-c&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-end z-c&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-c&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-storage z-type z-c&quot;&gt;struct&lt;&#x2F;span&gt; s_a &lt;span class=&quot;z-keyword z-operator z-c&quot;&gt;*&lt;&#x2F;span&gt;a &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-support z-function z-C99 z-c&quot;&gt;malloc&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-word z-c&quot;&gt;sizeof&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-storage z-type z-c&quot;&gt;struct&lt;&#x2F;span&gt; s_a&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-storage z-type z-c&quot;&gt;int&lt;&#x2F;span&gt; fd &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;open&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-c&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&#x2F;dev&#x2F;null&lt;span class=&quot;z-punctuation z-definition z-string z-end z-c&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt; O_APPEND&lt;span class=&quot;z-keyword z-operator z-arithmetic z-c&quot;&gt;|&lt;&#x2F;span&gt;O_WRONLY&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        a&lt;span class=&quot;z-punctuation z-accessor z-c&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;c &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-single z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-c&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;c&lt;span class=&quot;z-punctuation z-definition z-string z-end z-c&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        a&lt;span class=&quot;z-punctuation z-accessor z-c&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;i &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;42&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;write&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;fd&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt; a&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-word z-c&quot;&gt;sizeof&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-c&quot;&gt;*&lt;&#x2F;span&gt;a&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;close&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;fd&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-keyword z-control z-flow z-return z-c&quot;&gt;return&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-c&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;When running such code in &lt;code&gt;valgrind&lt;&#x2F;code&gt;, we would have the following:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==8592== Syscall param write(buf) points to uninitialised byte(s)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==8592==    at 0x4F103B0: __write_nocancel (in &#x2F;lib64&#x2F;libc-2.17.so)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==8592==    by 0x4006CB: main (init.c:18)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==8592==  Address 0x51e1041 is 1 bytes inside a block of size 8 alloc&amp;#39;d
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==8592==    at 0x4C2C430: malloc (vg_replace_malloc.c:291)
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;==8592==    by 0x400688: main (init.c:14)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We can inspect the validity of the memory at &lt;code&gt;get_vbits 0x51e1040&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(gdb) monitor get_vbits 0x51e1040 8
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;00ffffff 00000000
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;0&lt;&#x2F;code&gt; means that the bit is valid, &lt;code&gt;1&lt;&#x2F;code&gt; that it’s invalid.
Here, the padding between &lt;code&gt;c&lt;&#x2F;code&gt; and &lt;code&gt;i&lt;&#x2F;code&gt; is indeed not initialized.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;watch-on-a-memory-range&quot;&gt;&lt;code&gt;watch&lt;&#x2F;code&gt; on a memory range&lt;&#x2F;h2&gt;
&lt;p&gt;One other great feature of using &lt;code&gt;valgrind&lt;&#x2F;code&gt; with &lt;code&gt;gdb&lt;&#x2F;code&gt; is to be able to have
lots of watchpoints.&lt;&#x2F;p&gt;
&lt;p&gt;Let’s consider this piece of code:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;C&quot; class=&quot;language-C z-code&quot;&gt;&lt;code class=&quot;language-C&quot; data-lang=&quot;C&quot;&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-preprocessor z-include z-c&quot;&gt;    &lt;span class=&quot;z-keyword z-control z-import z-include z-c&quot;&gt;#include&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-other z-lt-gt z-include z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-c&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;stdlib.h&lt;span class=&quot;z-punctuation z-definition z-string z-end z-c&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;    &lt;span class=&quot;z-storage z-type z-c&quot;&gt;int&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-entity z-name z-function z-c&quot;&gt;main&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-storage z-type z-c&quot;&gt;int&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-c&quot;&gt;argc&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-storage z-type z-c&quot;&gt;char&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-c&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-c&quot;&gt;argv&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brackets z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-begin z-c&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-end z-c&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-c&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-storage z-type z-c&quot;&gt;int&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-c&quot;&gt;*&lt;&#x2F;span&gt;array &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-support z-function z-C99 z-c&quot;&gt;calloc&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;4096&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-word z-c&quot;&gt;sizeof&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-storage z-type z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        array&lt;span class=&quot;z-meta z-brackets z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-begin z-c&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-support z-function z-C99 z-c&quot;&gt;rand&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-arithmetic z-c&quot;&gt;%&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;4096&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-end z-c&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;42&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-keyword z-control z-flow z-return z-c&quot;&gt;return&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-c&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Let’s break on line 5. We would like to know when array is modified. We
couldn’t use the &lt;code&gt;watch&lt;&#x2F;code&gt; command in &lt;code&gt;gdb&lt;&#x2F;code&gt; because the number of hardware
breakpoints is very limited (usually 4) and thus it can not cover the size of
the array. &lt;code&gt;valgrind&lt;&#x2F;code&gt; can handle that just fine:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Breakpoint 1, main (argc=1, argv=0xffeffbe68) at watch.c:5
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;5           array[rand() % 4096] = 42;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(gdb) p array
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;$1 = (int *) 0x51e1040
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(gdb) watch (int[4096]) *0x51e1040
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Hardware watchpoint 2: (int[4096]) *0x51e1040
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(gdb) continue
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Continuing.
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Hardware watchpoint 2: (int[4096]) *0x51e1040
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Old value = {0 &amp;lt;repeats 4096 times&amp;gt;}
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;New value = {0 &amp;lt;repeats 1383 times&amp;gt;, 42, 0 &amp;lt;repeats 2712 times&amp;gt;}
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;(gdb)
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;If you write C code, you must look into &lt;code&gt;valgrind&lt;&#x2F;code&gt; and &lt;code&gt;gdb&lt;&#x2F;code&gt;.
They are really awesome tools for C developers.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>View images attachments in mutt within terminology</title>
          <pubDate>Tue, 03 Dec 2013 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20131203_mutt_typop/</link>
          <guid>https://fau.re/20131203_mutt_typop/</guid>
          <description xml:base="https://fau.re/20131203_mutt_typop/">&lt;p&gt;This afternoon some brazilian guys from &lt;code&gt;#develop&lt;&#x2F;code&gt; wanted to render images
attachements in &lt;code&gt;mutt&lt;&#x2F;code&gt; within &lt;code&gt;terminology&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I wanted to do that for quite some time but never took the time to do that.
It is actually quite easy to do that. The only thing needed is the following
line in your mailcap file:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;image&#x2F;*; typop %s &amp;amp;&amp;amp; sleep 1; test=test -n &amp;quot;$TERMINOLOGY&amp;quot;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;typop&lt;&#x2F;code&gt; only writes some escape codes to let &lt;code&gt;terminology&lt;&#x2F;code&gt; know that it needs to
show a file on popup. The &lt;code&gt;sleep 1&lt;&#x2F;code&gt; is here to make sure &lt;code&gt;terminology&lt;&#x2F;code&gt; has the
time to load the image before &lt;code&gt;mutt&lt;&#x2F;code&gt; removes the file as &lt;code&gt;typop&lt;&#x2F;code&gt; exits as soon
as it has sent the escape codes.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;test&lt;&#x2F;code&gt; part is here to ensure the command is only ran within &lt;code&gt;terminology&lt;&#x2F;code&gt;.
You could then have an other viewer when using &lt;code&gt;mutt&lt;&#x2F;code&gt; from a different terminal
emulator, but who would do that?&lt;&#x2F;p&gt;
&lt;p&gt;This operation only works locally since &lt;code&gt;typop&lt;&#x2F;code&gt; only sends the path to the
file, not the content of the file. This feature could be done in future
versions.&lt;&#x2F;p&gt;
&lt;p&gt;This can also be done for videos since &lt;code&gt;terminology&lt;&#x2F;code&gt; can also render them.&lt;&#x2F;p&gt;
&lt;p&gt;Mandatory screenshot of the feature:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20131203_mutt_typop&#x2F;cake_mutt_terminology.jpg&quot; alt=&quot;the cake is a lie&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Terminology at the EFL Dev Day 2013</title>
          <pubDate>Sat, 26 Oct 2013 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20131026_terminology_efl_dev_day/</link>
          <guid>https://fau.re/20131026_terminology_efl_dev_day/</guid>
          <description xml:base="https://fau.re/20131026_terminology_efl_dev_day/">&lt;p&gt;The 2013 edition of the EFL Dev Day was held in Edinburgh last Sunday.
I gave a quick talk about Terminology.&lt;&#x2F;p&gt;
&lt;p&gt;I wanted to make a different talk from the one &lt;a href=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20130224_terminology_fosdem&#x2F;&quot;&gt;I gave at
fosdem&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I decided to use Terminology to talk about Terminology and show some of its
awesome features! I wrote a bash script to render my presentation.
With Terminology escape codes, I was able to use real images as bullet points
and inlined animated gifs to entertain my audience.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;escape-codes&quot;&gt;Escape codes&lt;&#x2F;h2&gt;
&lt;p&gt;This code is now on &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;typres&quot;&gt;github&lt;&#x2F;a&gt;. You can run
it yourself in Terminology.&lt;&#x2F;p&gt;
&lt;p&gt;To use images as bullet points, the following code is used:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash z-code&quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-echo z-shell&quot;&gt;echo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;-&lt;&#x2F;span&gt;ne&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-single z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;\033}it#2;1;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-expansion z-parameter z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-variable z-shell&quot;&gt;$&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-other z-readwrite z-shell&quot;&gt;PWD&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-single z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&#x2F;item_00.png\0&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-shell z-bash&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-shell&quot;&gt;&lt;span class=&quot;z-support z-function z-echo z-shell&quot;&gt;echo&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-shell&quot;&gt; &lt;span class=&quot;z-variable z-parameter z-option z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-parameter z-shell&quot;&gt;-&lt;&#x2F;span&gt;ne&lt;&#x2F;span&gt; &lt;span class=&quot;z-string z-quoted z-single z-shell&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-shell&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;\033}ib\0##\033}ie\0&lt;span class=&quot;z-punctuation z-definition z-string z-end z-shell&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Every terminology escape command starts with &lt;code&gt;\033}&lt;&#x2F;code&gt; and ends with &lt;code&gt;\0&lt;&#x2F;code&gt;.
We use &lt;code&gt;it&lt;&#x2F;code&gt; to Insert a Thumbnail on a cell area of &lt;code&gt;W&lt;&#x2F;code&gt; cells wide and &lt;code&gt;H&lt;&#x2F;code&gt;
cells hight. The format is &lt;code&gt;CW;H;FULL-PATH&lt;&#x2F;code&gt; with the following meaning:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;C&lt;&#x2F;code&gt; is the replace character to be identified in later text and will be
replaced by the image.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;W&lt;&#x2F;code&gt; is the width in character cells (up to 511).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;H&lt;&#x2F;code&gt; is the height in character cells (up to 511).&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;FULL-PATH&lt;&#x2F;code&gt; is the full path of the image to inline.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;This escape code has no effect by itself. It indicates a future
intention of inserting media into the terminal. Terminology will expect a grid
of &lt;code&gt;WxH&lt;&#x2F;code&gt; “replace characters” to follow. Each sequence of such replace
characters starts with a &lt;code&gt;ib&lt;&#x2F;code&gt; escape command and ends with an &lt;code&gt;ie&lt;&#x2F;code&gt; escape
command.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;other-bits&quot;&gt;Other bits&lt;&#x2F;h2&gt;
&lt;p&gt;I used the &lt;a href=&quot;https:&#x2F;&#x2F;ethanschoonover.com&#x2F;solarized&quot;&gt;solarized theme&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The font is &lt;a href=&quot;https:&#x2F;&#x2F;fsd.it&#x2F;shop&#x2F;fonts&#x2F;pragmatapro&#x2F;&quot;&gt;PragmataPro&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-slides&quot;&gt;The slides&lt;&#x2F;h2&gt;
&lt;p&gt;Here are the slides:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20131026_terminology_efl_dev_day&#x2F;01.jpg&quot; alt=&quot;Terminology - Oct 2013 - Where are we?&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20131026_terminology_efl_dev_day&#x2F;02.jpg&quot; alt=&quot;$ whoami&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20131026_terminology_efl_dev_day&#x2F;03.jpg&quot; alt=&quot;What is Terminology (in case you’re really new here)?&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;![Beware, the list is long04.jpg)&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20131026_terminology_efl_dev_day&#x2F;05.jpg&quot; alt=&quot;Features…&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20131026_terminology_efl_dev_day&#x2F;06.jpg&quot; alt=&quot;Interlude 1&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20131026_terminology_efl_dev_day&#x2F;07.jpg&quot; alt=&quot;More Features…&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20131026_terminology_efl_dev_day&#x2F;08.jpg&quot; alt=&quot;Interlude 2&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20131026_terminology_efl_dev_day&#x2F;09.jpg&quot; alt=&quot;More and More Features…&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20131026_terminology_efl_dev_day&#x2F;10.jpg&quot; alt=&quot;Figures&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20131026_terminology_efl_dev_day&#x2F;11.jpg&quot; alt=&quot;TODO&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20131026_terminology_efl_dev_day&#x2F;12.jpg&quot; alt=&quot;You can do it!&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20131026_terminology_efl_dev_day&#x2F;13.jpg&quot; alt=&quot;Next release at the end of the year, after efl 1.8&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20131026_terminology_efl_dev_day&#x2F;14.jpg&quot; alt=&quot;Terminology is an OS, like emacs, except better&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20131026_terminology_efl_dev_day&#x2F;15.jpg&quot; alt=&quot;Questions ?&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>PhotoAlbum.js</title>
          <pubDate>Sun, 18 Aug 2013 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20130817_photoalbum/</link>
          <guid>https://fau.re/20130817_photoalbum/</guid>
          <description xml:base="https://fau.re/20130817_photoalbum/">&lt;h2 id=&quot;what-is-photoalbum-js&quot;&gt;What is PhotoAlbum.js ?&lt;&#x2F;h2&gt;
&lt;p&gt;It is a small side-project I have started a month ago to show pictures taken
during my holidays.  I could have used one of the many web sites that exist
just for that purpose but I prefer to host my own content.&lt;&#x2F;p&gt;
&lt;p&gt;I had 2 main goals:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;generate a static website: I use a very small server and I do not want it
to be overloaded by php&#x2F;node.js&#x2F;ruby&#x2F;… generating web pages.  This is the
same concept I use for this blog.&lt;&#x2F;li&gt;
&lt;li&gt;be able to write a legend about each picture.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I decided to go with node.js to build that project.  I know javascript for
quite a long time but never achieved anything with node.js.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;features&quot;&gt;Features&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;infinite scrolling of the pictures: load more thumbnails as you scroll the
page,&lt;&#x2F;li&gt;
&lt;li&gt;the legend can be written using markdown,&lt;&#x2F;li&gt;
&lt;li&gt;have a timer in the diaporama or change images as you like,&lt;&#x2F;li&gt;
&lt;li&gt;use the html5 history API in the diaporama to make the experience more
natural,&lt;&#x2F;li&gt;
&lt;li&gt;an editor to write those legends and sort or remove images,&lt;&#x2F;li&gt;
&lt;li&gt;…&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;demo&quot;&gt;Demo&lt;&#x2F;h2&gt;
&lt;p&gt;I wrote a small demo using pictures from &lt;a href=&quot;https:&#x2F;&#x2F;www.photos-public-domain.com&quot;&gt;photos-public-domain.com&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;fau.re&#x2F;photoalbum_demo&#x2F;&quot;&gt;the album itself&lt;&#x2F;a&gt;,&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;fau.re&#x2F;photoalbum_demo&#x2F;editor.html&quot;&gt;the editor&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;You can find the code on &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;photoalbum.git&quot;&gt;github&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;acknowledgements&quot;&gt;Acknowledgements&lt;&#x2F;h2&gt;
&lt;p&gt;The code uses the following Node.js modules:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;rsms&#x2F;node-imagemagick&quot;&gt;imagemagick&lt;&#x2F;a&gt;,&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;broofa&#x2F;node-mime&quot;&gt;mime&lt;&#x2F;a&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It also uses:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;jquery.com&#x2F;&quot;&gt;jquery&lt;&#x2F;a&gt;,&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;evilstreak&#x2F;markdown-js&quot;&gt;markdown.js&lt;&#x2F;a&gt;,&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;http:&#x2F;&#x2F;onehackoranother.com&#x2F;projects&#x2F;jquery&#x2F;tipsy&#x2F;&quot;&gt;tipsy.js&lt;&#x2F;a&gt;,&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;jqueryui.com&#x2F;&quot;&gt;jquery-ui&lt;&#x2F;a&gt;, only for the editor.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The background can be found at &lt;a href=&quot;http:&#x2F;&#x2F;subtlepatterns.com&#x2F;black-paper&#x2F;&quot;&gt;sublepatterns.com&lt;&#x2F;a&gt;.
The icons were modified from the ones at &lt;a href=&quot;http:&#x2F;&#x2F;raphaeljs.com&#x2F;icons&#x2F;&quot;&gt;raphaeljs.com&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;todo&quot;&gt;TODO&lt;&#x2F;h2&gt;
&lt;p&gt;I am currently happy with the state of my photo album generator.
There are still few things that can be improved&#x2F;added:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;use some web-font to improve the look,&lt;&#x2F;li&gt;
&lt;li&gt;play a bit more with exif data: I wanted to put a location mark in
diaporama mode for pictures having some GPS data.&lt;&#x2F;li&gt;
&lt;li&gt;use the EFL instead of imagemagick to speed things up,&lt;&#x2F;li&gt;
&lt;li&gt;have some kind of animation when changing images,&lt;&#x2F;li&gt;
&lt;li&gt;make the diaporama timer more readable,&lt;&#x2F;li&gt;
&lt;li&gt;preload next image in diaporama mode,&lt;&#x2F;li&gt;
&lt;li&gt;have a better support for mobile phones: the diaporama UI should be
changed.&lt;&#x2F;li&gt;
&lt;li&gt;IE support :D&lt;&#x2F;li&gt;
&lt;li&gt;add comments support with disqus and we’ll have a flickr clone :)&lt;&#x2F;li&gt;
&lt;li&gt;…&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>Terminology at FOSDEM 2013</title>
          <pubDate>Sun, 24 Feb 2013 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20130224_terminology_fosdem/</link>
          <guid>https://fau.re/20130224_terminology_fosdem/</guid>
          <description xml:base="https://fau.re/20130224_terminology_fosdem/">&lt;p&gt;I gave a talk at FOSDEM 2013 about Terminology - the great terminal emulator
written with the EFL.&lt;&#x2F;p&gt;
&lt;p&gt;It was not recorded but here are the slides I used:
&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20130224_terminology_fosdem&#x2F;01.jpg&quot; alt=&quot;terminology - why should terminals be boring?&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20130224_terminology_fosdem&#x2F;02.jpg&quot; alt=&quot;what is terminology?&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20130224_terminology_fosdem&#x2F;03.jpg&quot; alt=&quot;what are the EFL?&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20130224_terminology_fosdem&#x2F;04.jpg&quot; alt=&quot;more details about the EFL?&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20130224_terminology_fosdem&#x2F;05.jpg&quot; alt=&quot;videos???&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20130224_terminology_fosdem&#x2F;06.jpg&quot; alt=&quot;backgrounds&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20130224_terminology_fosdem&#x2F;07.jpg&quot; alt=&quot;rendering&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20130224_terminology_fosdem&#x2F;08.jpg&quot; alt=&quot;fonts&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20130224_terminology_fosdem&#x2F;09.jpg&quot; alt=&quot;colors&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20130224_terminology_fosdem&#x2F;10.jpg&quot; alt=&quot;themes&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20130224_terminology_fosdem&#x2F;11.jpg&quot; alt=&quot;splits&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20130224_terminology_fosdem&#x2F;12.jpg&quot; alt=&quot;link detection&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20130224_terminology_fosdem&#x2F;13.jpg&quot; alt=&quot;escape codes&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20130224_terminology_fosdem&#x2F;14.jpg&quot; alt=&quot;what’s next?&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20130224_terminology_fosdem&#x2F;15.jpg&quot; alt=&quot;questions&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;I used &lt;code&gt;eyelight&lt;&#x2F;code&gt; to make that presentation. You can find the script and the
theme files on &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;2013_fosdem_terminology&quot;&gt;github&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Ptyproxy</title>
          <pubDate>Tue, 22 Jan 2013 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20130122_ptyproxy/</link>
          <guid>https://fau.re/20130122_ptyproxy/</guid>
          <description xml:base="https://fau.re/20130122_ptyproxy/">&lt;p&gt;Since few weeks, I have been working on
&lt;a href=&quot;https:&#x2F;&#x2F;www.enlightenment.org&#x2F;about-terminology&quot;&gt;terminology&lt;&#x2F;a&gt;, a
terminal emulator written with the Enlightenment Foundation Libraries.&lt;&#x2F;p&gt;
&lt;p&gt;I’ve specialized myself on tracking compatibility bugs: since we wrote our own
pty escape codes parser&#x2F;handler, some bugs slipped into the code and some
applications are not working like on that good old xterm.&lt;&#x2F;p&gt;
&lt;p&gt;Terminology tries to mimic xterm as best as it can, hence &lt;code&gt;$TERM&lt;&#x2F;code&gt; is defined
to &lt;code&gt;xterm&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I was told that emacs (Disclaimer: I’m a proud vim user) wasn’t working
correctly in terminology.
When I launched it, the menu and the status bar were underlined.
I couldn’t figure an issue with the underline code.
Emacs was querying the &lt;code&gt;device id&lt;&#x2F;code&gt; but I thought already fixed that issue some
time ago when I made vim work well in terminology.&lt;&#x2F;p&gt;
&lt;p&gt;On Sunday evening, I decided to write a pty proxy to know what was going on
between emacs and xterm and try to understand why emacs wasn’t giving his love
to terminology. (No, I won’t talk about emacs virgins.)&lt;&#x2F;p&gt;
&lt;p&gt;The code itself is simple: use &lt;code&gt;forkpty()&lt;&#x2F;code&gt; and when the child (emacs in our
case) outputs something through the &lt;code&gt;master&lt;&#x2F;code&gt; file descriptor, write it back to
the parent &lt;code&gt;stdout&lt;&#x2F;code&gt;. When there is something to read from the parent &lt;code&gt;stdin&lt;&#x2F;code&gt;,
write it back to the child &lt;code&gt;stdin&lt;&#x2F;code&gt; through the master file descriptor. I used
poll to do that since it was easy enough for my needs.&lt;&#x2F;p&gt;
&lt;p&gt;On Monday evening the code was working fine and I got 2 files: &lt;code&gt;in.log&lt;&#x2F;code&gt; and
&lt;code&gt;out.log&lt;&#x2F;code&gt;.
Just ran &lt;code&gt;ptyproxy emacs -nw&lt;&#x2F;code&gt; and enter &lt;code&gt;^X^C&lt;&#x2F;code&gt; in xterm. Backup the 2 files.
Repeat the action in terminology.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;in.log&lt;&#x2F;code&gt; files were different:&lt;&#x2F;p&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;xxd terminology.in.log
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;0000000: 1b5b 3e30 3b32 3731 3b30 6318 03         .[&amp;gt;0;271;0c..
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;xxd xterm.in.log
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;0000000: 1b5b 3e34 313b 3238 353b 3063 1803       .[&amp;gt;41;285;0c..
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The &lt;code&gt;device id&lt;&#x2F;code&gt; is different. The second number (271 or 285) is xterm’s
version.
The first number denotes the terminal type as expressed below:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;0 → VT100&lt;&#x2F;li&gt;
&lt;li&gt;1 → VT220&lt;&#x2F;li&gt;
&lt;li&gt;2 → VT240&lt;&#x2F;li&gt;
&lt;li&gt;18 → VT330&lt;&#x2F;li&gt;
&lt;li&gt;19 → VT340&lt;&#x2F;li&gt;
&lt;li&gt;24 → VT320&lt;&#x2F;li&gt;
&lt;li&gt;41 → VT420&lt;&#x2F;li&gt;
&lt;li&gt;61 → VT510&lt;&#x2F;li&gt;
&lt;li&gt;64 → VT520&lt;&#x2F;li&gt;
&lt;li&gt;65 → VT525&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Terminology was telling the world it was a VT100 while xterm acts as VT420.&lt;&#x2F;p&gt;
&lt;p&gt;I’ve committed a one-liner to act as xterm in
&lt;a href=&quot;http:&#x2F;&#x2F;trac.enlightenment.org&#x2F;e&#x2F;changeset&#x2F;83047&quot;&gt;revision 83047&lt;&#x2F;a&gt; and now emacs
users should enjoy running their favorite text editor in terminology as much
as the vim users already does.&lt;&#x2F;p&gt;
&lt;p&gt;I’ve pushed ptyproxy to &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;ptyproxy&quot;&gt;github&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If there are still some compatibility issues, please ping me on irc or open a
bug report on our &lt;a href=&quot;http:&#x2F;&#x2F;trac.enlightenment.org&#x2F;e&#x2F;newticket&quot;&gt;trac&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Why you shouldn&#x27;t concatenate strings in erlang</title>
          <pubDate>Tue, 10 Jul 2012 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20120710_erlang_string_concat/</link>
          <guid>https://fau.re/20120710_erlang_string_concat/</guid>
          <description xml:base="https://fau.re/20120710_erlang_string_concat/">&lt;p&gt;In the &lt;a href=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20120701_twf&#x2F;&quot;&gt;previous article&lt;&#x2F;a&gt;, I said that concatenating
strings was an &lt;code&gt;O(n)&lt;&#x2F;code&gt; operation on the length of the first string.&lt;&#x2F;p&gt;
&lt;p&gt;I feel the need to explain that.&lt;&#x2F;p&gt;
&lt;p&gt;In erlang, strings are lists of integer. Since they are integers, they can
store any unicode characters such as the snowman ☃ which has a value of 9731.&lt;&#x2F;p&gt;
&lt;p&gt;When one wants to concatenate 2 strings, one can use &lt;code&gt;string:concat&#x2F;2&lt;&#x2F;code&gt;
implemented in
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;erlang&#x2F;otp&#x2F;tree&#x2F;cfea5eea406ba3af96588ff458e55de9a149d9c5&#x2F;lib&#x2F;stdlib&#x2F;src&#x2F;string.erl#L53&quot;&gt;&lt;code&gt;lib&#x2F;stdlib&#x2F;src&#x2F;string.erl&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;
as follows:&lt;&#x2F;p&gt;
&lt;p&gt;(All code extracts in this article are subject to the Erlang Public License.)&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;erlang&quot; class=&quot;language-erlang z-code&quot;&gt;&lt;code class=&quot;language-erlang&quot; data-lang=&quot;erlang&quot;&gt;&lt;span class=&quot;z-source z-erlang&quot;&gt;    &lt;span class=&quot;z-comment z-line z-percentage z-erlang&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-percentage z-erlang&quot;&gt;%&lt;&#x2F;span&gt;% concat(String1, String2)
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-erlang&quot;&gt;    &lt;span class=&quot;z-comment z-line z-percentage z-erlang&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-percentage z-erlang&quot;&gt;%&lt;&#x2F;span&gt;%  Concatenate 2 strings.
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-erlang&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-erlang&quot;&gt;    &lt;span class=&quot;z-meta z-preprocessor z-spec z-erlang&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-keyword z-erlang&quot;&gt;-&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-control z-directive z-spec z-erlang&quot;&gt;spec&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-preprocessor z-spec z-name z-erlang&quot;&gt;&lt;span class=&quot;z-meta z-atom z-erlang&quot;&gt;&lt;span class=&quot;z-entity z-name z-function z-erlang&quot;&gt;concat&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-preprocessor z-spec z-erlang&quot;&gt;&lt;span class=&quot;z-meta z-preprocessor z-spec z-parameters z-erlang&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-begin z-erlang&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-preprocessor z-spec z-parameters z-erlang&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-erlang&quot;&gt;String1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-parameters z-erlang&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-erlang&quot;&gt;String2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-end z-erlang&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-preprocessor z-spec z-erlang&quot;&gt; &lt;span class=&quot;z-punctuation z-separator z-parameters-return-type z-erlang&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-preprocessor z-spec z-return-type z-erlang&quot;&gt; &lt;span class=&quot;z-variable z-other z-erlang&quot;&gt;String3&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-preprocessor z-spec z-return-type z-erlang&quot;&gt;&lt;span class=&quot;z-meta z-preprocessor z-spec z-guards z-erlang&quot;&gt;&lt;span class=&quot;z-keyword z-control z-conditional z-when z-erlang&quot;&gt;when&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-preprocessor z-spec z-guards z-erlang&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-erlang&quot;&gt;&lt;span class=&quot;z-meta z-preprocessor z-spec z-guards z-erlang&quot;&gt;          &lt;span class=&quot;z-variable z-other z-erlang&quot;&gt;String1&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-separator z-variable-type z-erlang&quot;&gt;::&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-type-call z-name z-erlang&quot;&gt;&lt;span class=&quot;z-meta z-atom z-erlang&quot;&gt;&lt;span class=&quot;z-support z-type z-erlang&quot;&gt;string&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-type-call z-arguments z-erlang&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-erlang&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-erlang&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-expressions z-erlang&quot;&gt;,&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-erlang&quot;&gt;&lt;span class=&quot;z-meta z-preprocessor z-spec z-guards z-erlang&quot;&gt;          &lt;span class=&quot;z-variable z-other z-erlang&quot;&gt;String2&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-separator z-variable-type z-erlang&quot;&gt;::&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-type-call z-name z-erlang&quot;&gt;&lt;span class=&quot;z-meta z-atom z-erlang&quot;&gt;&lt;span class=&quot;z-support z-type z-erlang&quot;&gt;string&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-type-call z-arguments z-erlang&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-erlang&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-erlang&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-expressions z-erlang&quot;&gt;,&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-erlang&quot;&gt;&lt;span class=&quot;z-meta z-preprocessor z-spec z-guards z-erlang&quot;&gt;          &lt;span class=&quot;z-variable z-other z-erlang&quot;&gt;String3&lt;&#x2F;span&gt; &lt;span class=&quot;z-punctuation z-separator z-variable-type z-erlang&quot;&gt;::&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-type-call z-name z-erlang&quot;&gt;&lt;span class=&quot;z-meta z-atom z-erlang&quot;&gt;&lt;span class=&quot;z-support z-type z-erlang&quot;&gt;string&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-type-call z-arguments z-erlang&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-erlang&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-erlang&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-preprocessor z-spec z-return-type z-erlang&quot;&gt;&lt;span class=&quot;z-punctuation z-terminator z-clause z-erlang&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-erlang&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-erlang&quot;&gt;    &lt;span class=&quot;z-meta z-function z-name z-erlang&quot;&gt;&lt;span class=&quot;z-meta z-atom z-erlang&quot;&gt;&lt;span class=&quot;z-entity z-name z-function z-erlang&quot;&gt;concat&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-name z-erlang&quot;&gt;&lt;span class=&quot;z-meta z-function z-parameters z-erlang&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-begin z-erlang&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-erlang&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-erlang&quot;&gt;S1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-parameters z-erlang&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-erlang&quot;&gt;S2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-end z-erlang&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-name z-erlang&quot;&gt; &lt;span class=&quot;z-punctuation z-separator z-clause-head-body z-erlang&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-other z-erlang&quot;&gt;S1&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-lists z-erlang&quot;&gt;++&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-other z-erlang&quot;&gt;S2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-clause z-erlang&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Ok, strings are lists, just concatenate lists!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;down-the-rabbit-hole&quot;&gt;Down the rabbit hole&lt;&#x2F;h2&gt;
&lt;p&gt;The &lt;code&gt;++&lt;&#x2F;code&gt; operator is a BIF, a Built-In Function implemented in C in the Beam
VM.
It is implemented in &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;erlang&#x2F;otp&#x2F;tree&#x2F;cfea5eea406ba3af96588ff458e55de9a149d9c5&#x2F;erts&#x2F;emulator&#x2F;beam&#x2F;erl_bif_lists.c#L37&quot;&gt;&lt;code&gt;erts&#x2F;emulator&#x2F;beam&#x2F;erl_bif_lists.c&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;pre data-linenos data-lang=&quot;C&quot; class=&quot;language-C z-code&quot;&gt;&lt;code class=&quot;language-C&quot; data-lang=&quot;C&quot;&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;1&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;    &lt;span class=&quot;z-comment z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-c&quot;&gt;&#x2F;*&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;2&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-comment z-block z-c&quot;&gt;     &lt;span class=&quot;z-punctuation z-definition z-comment z-c&quot;&gt;*&lt;&#x2F;span&gt; erlang:&amp;#39;++&amp;#39;&#x2F;2
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;3&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-comment z-block z-c&quot;&gt;     &lt;span class=&quot;z-punctuation z-definition z-comment z-c&quot;&gt;*&#x2F;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;4&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;    
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;5&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;    Eterm
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;6&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;    &lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-entity z-name z-function z-c&quot;&gt;ebif_plusplus_2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-c&quot;&gt;BIF_ALIST_2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;7&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-c&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;8&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-keyword z-control z-flow z-return z-c&quot;&gt;return&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;append&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;BIF_P&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt; BIF_ARG_1&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt; BIF_ARG_2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;9&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-c&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;    
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;11&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;    &lt;span class=&quot;z-storage z-modifier z-c&quot;&gt;static&lt;&#x2F;span&gt; BIF_RETTYPE &lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-entity z-name z-function z-c&quot;&gt;append&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;Process&lt;span class=&quot;z-keyword z-operator z-c&quot;&gt;*&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-c&quot;&gt;p&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt; Eterm &lt;span class=&quot;z-variable z-parameter z-c&quot;&gt;A&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt; Eterm &lt;span class=&quot;z-variable z-parameter z-c&quot;&gt;B&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;12&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-c&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;13&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        Eterm list&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;14&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        Eterm copy&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;15&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        Eterm last&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;16&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-support z-type z-sys-types z-c&quot;&gt;size_t&lt;&#x2F;span&gt; need&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;17&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        Eterm&lt;span class=&quot;z-keyword z-operator z-c&quot;&gt;*&lt;&#x2F;span&gt; hp&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;18&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-storage z-type z-c&quot;&gt;int&lt;&#x2F;span&gt; i&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;19&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;    
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;20&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-keyword z-control z-c&quot;&gt;if&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;i &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;list_length&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;A&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-comparison z-c&quot;&gt;&amp;lt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-c&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;21&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;            &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;BIF_ERROR&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;p&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt; BADARG&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;22&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-punctuation z-section z-block z-end z-c&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;23&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-keyword z-control z-c&quot;&gt;if&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;i &lt;span class=&quot;z-keyword z-operator z-comparison z-c&quot;&gt;==&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-c&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;24&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;            &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;BIF_RET&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;B&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;25&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-punctuation z-section z-block z-end z-c&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-control z-c&quot;&gt;else&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-control z-c&quot;&gt;if&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;is_nil&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;B&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-c&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;26&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;            &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;BIF_RET&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;A&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;27&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-punctuation z-section z-block z-end z-c&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;28&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;    
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;29&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        need &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-c&quot;&gt;*&lt;&#x2F;span&gt;i&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;30&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        hp &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;HAlloc&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;p&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt; need&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;31&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        list &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; A&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;32&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        copy &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; last &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;CONS&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;hp&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;CAR&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;list_val&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;list&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;make_list&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;hp&lt;span class=&quot;z-keyword z-operator z-arithmetic z-c&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;33&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        list &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;CDR&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;list_val&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;list&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;34&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        hp &lt;span class=&quot;z-keyword z-operator z-assignment z-augmented z-c&quot;&gt;+=&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;35&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        i&lt;span class=&quot;z-keyword z-operator z-arithmetic z-c&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;36&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-keyword z-control z-c&quot;&gt;while&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;i&lt;span class=&quot;z-keyword z-operator z-arithmetic z-c&quot;&gt;--&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-c&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;37&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;            Eterm&lt;span class=&quot;z-keyword z-operator z-c&quot;&gt;*&lt;&#x2F;span&gt; listp &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;list_val&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;list&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;38&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;            last &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;CONS&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;hp&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;CAR&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;listp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;make_list&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;hp&lt;span class=&quot;z-keyword z-operator z-arithmetic z-c&quot;&gt;+&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;2&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;39&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;            list &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;CDR&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;listp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;40&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;            hp &lt;span class=&quot;z-keyword z-operator z-assignment z-augmented z-c&quot;&gt;+=&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;2&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;41&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-punctuation z-section z-block z-end z-c&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;42&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;CDR&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;list_val&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;last&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; B&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;43&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;BIF_RET&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;copy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;tr&gt;&lt;td&gt;44&lt;&#x2F;td&gt;&lt;td&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;    &lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-c&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;First, the length of &lt;code&gt;A&lt;&#x2F;code&gt; is computed. This operation is &lt;code&gt;O(n)&lt;&#x2F;code&gt; where &lt;code&gt;n&lt;&#x2F;code&gt; is the
length of the list. Trust me on this one, of just go look at
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;erlang&#x2F;otp&#x2F;tree&#x2F;cfea5eea406ba3af96588ff458e55de9a149d9c5&#x2F;erts&#x2F;emulator&#x2F;beam&#x2F;utils.c#L252&quot;&gt;&lt;code&gt;erts&#x2F;emulator&#x2F;beam&#x2F;utils.c&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If either lists are empty, return the other one.&lt;&#x2F;p&gt;
&lt;p&gt;On lines 29 - 30, space is allocated on the process heap for a new list. Each
list item has a size of 2 &lt;code&gt;Eterm&lt;&#x2F;code&gt;: one for the list itself, one for the
element.&lt;&#x2F;p&gt;
&lt;p&gt;The code on lines 31 to 42 just copies &lt;code&gt;A&lt;&#x2F;code&gt; to our newly allocated list and
adds B on its tail.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;last-cons-hp-car-list-val-list-make-list-hp-2&quot;&gt;&lt;code&gt;last = CONS(hp, CAR(list_val(list)), make_list(hp+2));&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;Ok, what is that?&lt;&#x2F;p&gt;
&lt;p&gt;From
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;erlang&#x2F;otp&#x2F;tree&#x2F;cfea5eea406ba3af96588ff458e55de9a149d9c5&#x2F;erts&#x2F;emulator&#x2F;beam&#x2F;erl_term.h#L234&quot;&gt;&lt;code&gt;erts&#x2F;emulator&#x2F;beam&#x2F;erl_term.h&lt;&#x2F;code&gt;&lt;&#x2F;a&gt;,
we need some more definitions:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;C&quot; class=&quot;language-C z-code&quot;&gt;&lt;code class=&quot;language-C&quot; data-lang=&quot;C&quot;&gt;&lt;span class=&quot;z-source z-c&quot;&gt;    &lt;span class=&quot;z-meta z-preprocessor z-macro z-c&quot;&gt;&lt;span class=&quot;z-keyword z-control z-import z-define z-c&quot;&gt;#define&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-preprocessor z-macro z-c&quot;&gt; &lt;span class=&quot;z-entity z-name z-function z-preprocessor z-c&quot;&gt;CONS&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-preprocessor z-macro z-parameters z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-c&quot;&gt;hp&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-c&quot;&gt;car&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-c&quot;&gt;cdr&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-preprocessor z-macro z-c&quot;&gt; &lt;span class=&quot;z-punctuation z-separator z-continuation z-c&quot;&gt;\&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-preprocessor z-macro z-c&quot;&gt;            &lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;CAR&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;hp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;car&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;CDR&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;hp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;cdr&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-variable z-function z-c&quot;&gt;make_list&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;hp&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;    
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;    &lt;span class=&quot;z-meta z-preprocessor z-macro z-c&quot;&gt;&lt;span class=&quot;z-keyword z-control z-import z-define z-c&quot;&gt;#define&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-preprocessor z-macro z-c&quot;&gt; &lt;span class=&quot;z-entity z-name z-function z-preprocessor z-c&quot;&gt;CAR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-preprocessor z-macro z-parameters z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-c&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-preprocessor z-macro z-c&quot;&gt;  &lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;x&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brackets z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-begin z-c&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-end z-c&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;    &lt;span class=&quot;z-meta z-preprocessor z-macro z-c&quot;&gt;&lt;span class=&quot;z-keyword z-control z-import z-define z-c&quot;&gt;#define&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-preprocessor z-macro z-c&quot;&gt; &lt;span class=&quot;z-entity z-name z-function z-preprocessor z-c&quot;&gt;CDR&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-preprocessor z-macro z-parameters z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-c&quot;&gt;x&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-preprocessor z-macro z-c&quot;&gt;  &lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;x&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-brackets z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-begin z-c&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-end z-c&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;make_list&lt;&#x2F;code&gt; is used to return an &lt;code&gt;Eterm&lt;&#x2F;code&gt; tagged as a list from a pointer on
the process heap.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;list_val&lt;&#x2F;code&gt; does the opposite and returns the address on the heap of the list.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;CONS&lt;&#x2F;code&gt; puts 2 elements in &lt;code&gt;hp[0]&lt;&#x2F;code&gt; (the element in the list) and &lt;code&gt;hp[1]&lt;&#x2F;code&gt; (the next list item) and returns the list at &lt;code&gt;hp&lt;&#x2F;code&gt; as an &lt;code&gt;Eterm&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;That complicated expression can now be read as:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;copy in &lt;code&gt;hp[0]&lt;&#x2F;code&gt; the element of the list we want to copy,&lt;&#x2F;li&gt;
&lt;li&gt;set the next list item as the &lt;code&gt;Eterm&lt;&#x2F;code&gt; following on the stack (&lt;code&gt;hp+2&lt;&#x2F;code&gt;) since
the new list is allocated as one block on the stack.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;When list &lt;code&gt;A&lt;&#x2F;code&gt; has been fully copied, the last element is set to &lt;code&gt;B&lt;&#x2F;code&gt; at the
line 42 with &lt;code&gt;CDR(list_val(last)) = B;&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;memory-allocation&quot;&gt;Memory allocation&lt;&#x2F;h2&gt;
&lt;p&gt;If you’re curious, &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;erlang&#x2F;otp&#x2F;tree&#x2F;cfea5eea406ba3af96588ff458e55de9a149d9c5&#x2F;erts&#x2F;emulator&#x2F;beam&#x2F;sys.h#L254&quot;&gt;&lt;code&gt;erts&#x2F;emulator&#x2F;beam&#x2F;sys.h&lt;&#x2F;code&gt;&lt;&#x2F;a&gt; can tell you
that an &lt;code&gt;Eterm&lt;&#x2F;code&gt; has usually a size of 4 bytes.&lt;&#x2F;p&gt;
&lt;p&gt;Small integers can be stored directly in those 4 bytes.
There are 26 bits usable to store a small integer so it can store up to 2²⁵
= 33554432 because of the sign bit. For reference, &lt;a href=&quot;https:&#x2F;&#x2F;www.fileformat.info&#x2F;info&#x2F;unicode&#x2F;char&#x2F;1f4a9&#x2F;index.htm&quot;&gt;pile of
poo&lt;&#x2F;a&gt; which was
added in october 2010 has a value of 128169.&lt;&#x2F;p&gt;
&lt;p&gt;We can consider that unicode characters can be stored directly in the list.&lt;&#x2F;p&gt;
&lt;p&gt;If a string has &lt;code&gt;n&lt;&#x2F;code&gt; characters, it will use &lt;code&gt;2 * n&lt;&#x2F;code&gt; words.&lt;&#x2F;p&gt;
&lt;p&gt;A &lt;code&gt;binary&lt;&#x2F;code&gt; on the opposite will use 3 to 6 words (depending on the data size)
plus the size of the data itself.&lt;&#x2F;p&gt;
&lt;p&gt;A string stored as a list takes about 8 times the space it would take stored
as a &lt;code&gt;binary&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-about-other-lists&quot;&gt;What about other lists?&lt;&#x2F;h2&gt;
&lt;p&gt;The pointed values are not copied, only the list items themsleves.&lt;&#x2F;p&gt;
&lt;p&gt;Appending a list of records of &lt;code&gt;n&lt;&#x2F;code&gt; tuples to a list of &lt;code&gt;m&lt;&#x2F;code&gt; tuples will take
the same time&#x2F;memory as concatenating a string of length &lt;code&gt;n&lt;&#x2F;code&gt; to one of length
&lt;code&gt;m&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;The only difference is that tuples are not boxed in an &lt;code&gt;Eterm&lt;&#x2F;code&gt;. The list only
contains an &lt;code&gt;Eterm&lt;&#x2F;code&gt; as a &lt;em&gt;pointer&lt;&#x2F;em&gt; to the tuple: where it’s stored in the
heap.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;solution&quot;&gt;Solution?&lt;&#x2F;h2&gt;
&lt;p&gt;Of course there is one!
You should use &lt;code&gt;binary&lt;&#x2F;code&gt; and &lt;code&gt;IoList&lt;&#x2F;code&gt; whenever possible.
An &lt;code&gt;IoList&lt;&#x2F;code&gt; is &lt;code&gt;iolist = [char() | binary() | iolist()]&lt;&#x2F;code&gt;.
They are “deep-list”.&lt;&#x2F;p&gt;
&lt;p&gt;Want to append an &lt;code&gt;IoList a&lt;&#x2F;code&gt; to an &lt;code&gt;IoList b&lt;&#x2F;code&gt;? Simple! Just create a new list
with 2 elements: &lt;code&gt;a&lt;&#x2F;code&gt; and &lt;code&gt;b&lt;&#x2F;code&gt;!  Concatenation has become an O(1) operation.
Most IO apis accept IoLists.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Tiny Web Framework - a simple web framework written in erlang</title>
          <pubDate>Mon, 02 Jul 2012 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20120701_twf/</link>
          <guid>https://fau.re/20120701_twf/</guid>
          <description xml:base="https://fau.re/20120701_twf/">&lt;h2 id=&quot;what-is-twf&quot;&gt;What is twf ?&lt;&#x2F;h2&gt;
&lt;p&gt;Tiny Web Framework is a very web framework written in Erlang I started working
on out of frustration with Nitrogen.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;why-not-nitrogen&quot;&gt;Why not Nitrogen?&lt;&#x2F;h2&gt;
&lt;p&gt;I enjoy Nitrogen but I don’t use most of its features and I am annoyed by some
of its internals.&lt;&#x2F;p&gt;
&lt;p&gt;For example, I don’t like to have every DOM object created with Nitrogen to be
given a random id or that they automatically have their names added as class
like:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;html&quot; class=&quot;language-html z-code&quot;&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&lt;span class=&quot;z-text z-html z-basic&quot;&gt;    &lt;span class=&quot;z-meta z-tag z-inline z-table z-html&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag z-begin z-html&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag z-inline z-table z-html&quot;&gt;table&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-attribute-with-value z-class z-html&quot;&gt;&lt;span class=&quot;z-entity z-other z-attribute-name z-class z-html&quot;&gt;class&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-key-value z-html&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-html&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-html&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-html&quot;&gt;&lt;span class=&quot;z-meta z-class-name z-html&quot;&gt;table&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-class-name z-html&quot;&gt;wfid_temp34325&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-class-name z-html&quot;&gt;wfid_temp34892&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-html&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag z-end z-html&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; … &lt;span class=&quot;z-meta z-tag z-inline z-table z-html&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-tag z-begin z-html&quot;&gt;&amp;lt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-tag z-inline z-table z-html&quot;&gt;table&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-tag z-end z-html&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I’ve started to patch Nitrogen on
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;nitrogen_core&quot;&gt;github&lt;&#x2F;a&gt; to fit my needs.&lt;&#x2F;p&gt;
&lt;p&gt;In erlang, strings are lists. That’s handy but it has a cost on memory and
concatenating strings means concatenating lists which is an O(n) operation
where n is the length of the first string, that gets longer each time a string
is appended.&lt;&#x2F;p&gt;
&lt;p&gt;There’s a solution to solve that issue: use lists of binaries aka IoList.
Binaries can be viewed as C-strings.  Want to append an IoList a to an IoList
b? Simple! Just create a new list with 2 elements: a and b!  Most IO apis
accept IoLists.&lt;&#x2F;p&gt;
&lt;p&gt;I was not confortable to change all that in Nitrogen and since I don’t use
a lot of Nitrogen’s features, I decided to created a Tiny Web Framework.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-s-done-yet&quot;&gt;What’s done yet?&lt;&#x2F;h2&gt;
&lt;p&gt;Not much! I only worked on it few hours on my free time.&lt;&#x2F;p&gt;
&lt;p&gt;The current features are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;create HTML using lists of records almost like in Nitrogen&lt;&#x2F;li&gt;
&lt;li&gt;simple templating system&lt;&#x2F;li&gt;
&lt;li&gt;api to get QueryStrings&lt;&#x2F;li&gt;
&lt;li&gt;based on &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;ninenines&#x2F;cowboy&quot;&gt;cowboy&lt;&#x2F;a&gt;: well-documented, fast,
handles IoLists…&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;my-todo-list&quot;&gt;My TODO-list&lt;&#x2F;h2&gt;
&lt;p&gt;Here are the features I need that I should implement for a 0.1 version:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;session handling&lt;&#x2F;li&gt;
&lt;li&gt;create more DOM elements&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There is already a TODO-list for v0.2 which aims at optimization and
documentation:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;have a template cache&lt;&#x2F;li&gt;
&lt;li&gt;add spec&lt;&#x2F;li&gt;
&lt;li&gt;add documentation&lt;&#x2F;li&gt;
&lt;li&gt;do not use the process registry to store the context&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>E-Tiling v0.9 is released</title>
          <pubDate>Sun, 11 Dec 2011 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20111211_etiling/</link>
          <guid>https://fau.re/20111211_etiling/</guid>
          <description xml:base="https://fau.re/20111211_etiling/">&lt;p&gt;After many months, I have decided to branch e-tiling v0.9. You can find it on
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;e-tiling&quot;&gt;github&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If you wonder what e-tiling is, I’ve done &lt;a href=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20110717_etiling&#x2F;&quot;&gt;a presentation in a previous
article&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;new-features&quot;&gt;New Features&lt;&#x2F;h2&gt;
&lt;p&gt;The major change in this release is to be able to tile vertically or
horizontally.&lt;&#x2F;p&gt;
&lt;p&gt;It is now possible to use figures or a different set of characters to identify
windows and transitions.
While talking about settings, the window title is hidden or not as configured.&lt;&#x2F;p&gt;
&lt;p&gt;In order to improve the user experience, the original border and maximized
state are restored when untiling a window.&lt;&#x2F;p&gt;
&lt;p&gt;I’ve also added animations when compositing is disabled.&lt;&#x2F;p&gt;
&lt;p&gt;It has been reported that the module was working with dual-screens
configuration.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Presentation of E-Tiling</title>
          <pubDate>Mon, 11 Jul 2011 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20110717_etiling/</link>
          <guid>https://fau.re/20110717_etiling/</guid>
          <description xml:base="https://fau.re/20110717_etiling/">&lt;p&gt;I’ve branched e-tiling v0.5 on &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;e-tiling&quot;&gt;github&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-is-it&quot;&gt;What is it?&lt;&#x2F;h2&gt;
&lt;p&gt;It’s a tiling module for enlightenment.&lt;&#x2F;p&gt;
&lt;p&gt;I’ve done a quick video to introduce it:&lt;&#x2F;p&gt;
&lt;div style=&quot;padding:56.25% 0 0 0;position:relative;&quot;&gt;&lt;iframe src=&quot;https:&#x2F;&#x2F;player.vimeo.com&#x2F;video&#x2F;26547998?badge=0&amp;amp;autopause=0&amp;amp;player_id=0&amp;amp;app_id=58479&quot; frameborder=&quot;0&quot; allow=&quot;autoplay; fullscreen; picture-in-picture&quot; style=&quot;position:absolute;top:0;left:0;width:100%;height:100%;&quot; title=&quot;Presentation of E-Tiling&quot;&gt;&lt;&#x2F;iframe&gt;&lt;&#x2F;div&gt;&lt;script src=&quot;https:&#x2F;&#x2F;player.vimeo.com&#x2F;api&#x2F;player.js&quot;&gt;&lt;&#x2F;script&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;vimeo.com&#x2F;billiob&#x2F;presentation-of-e-tiling&quot;&gt;Presentation of E-Tiling&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;On the video, you may have noticed that windows are added on the &lt;em&gt;right&lt;&#x2F;em&gt; (not on left as is wrongly written).&lt;&#x2F;p&gt;
&lt;h2 id=&quot;features&quot;&gt;Features&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;tiling :)&lt;&#x2F;li&gt;
&lt;li&gt;swap windows&lt;&#x2F;li&gt;
&lt;li&gt;“Go To” feature&lt;&#x2F;li&gt;
&lt;li&gt;moving windows around&lt;&#x2F;li&gt;
&lt;li&gt;moving transitions to resize windows&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;As you may have seen, it’s possible to add a column by moving a window on the right border of the screen.&lt;&#x2F;p&gt;
&lt;p&gt;Keybindings are currently set to use the home row of your keyboard as much as
possible, hence &lt;em&gt;a&lt;&#x2F;em&gt;, &lt;em&gt;s&lt;&#x2F;em&gt;, &lt;em&gt;d&lt;&#x2F;em&gt;, …&lt;&#x2F;p&gt;
&lt;h2 id=&quot;quick-technical-note&quot;&gt;Quick technical note&lt;&#x2F;h2&gt;
&lt;p&gt;I use compositing in order to have transparency support for the animations. I
also disabled shadows on popups.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;todo&quot;&gt;TODO&lt;&#x2F;h2&gt;
&lt;p&gt;It’s not finished yet.
Here’s what I plan on adding:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;choice whether to display window titles; currently it’s hidden.&lt;&#x2F;li&gt;
&lt;li&gt;stack on rows or on columns&lt;&#x2F;li&gt;
&lt;li&gt;make sure it works fine on many screens since I haven’t tested it&lt;&#x2F;li&gt;
&lt;li&gt;have different animations whether transparency is available&lt;&#x2F;li&gt;
&lt;li&gt;improve ICCCM support&lt;&#x2F;li&gt;
&lt;li&gt;choice on how to identify windows&lt;&#x2F;li&gt;
&lt;li&gt;remove bugs :)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;edit&quot;&gt;Edit&lt;&#x2F;h3&gt;
&lt;p&gt;There are still some bugs when reloading enligthenment or when changing
configuration.&lt;&#x2F;p&gt;
&lt;p&gt;I hope to fix them soon. I will update this post when done.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;edit-2&quot;&gt;Edit #2&lt;&#x2F;h3&gt;
&lt;p&gt;Those bugs are now hopefully fixed.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Eenvaders: an animated wallpaper for enlightenment</title>
          <pubDate>Sun, 12 Jun 2011 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20110612_eenvarders/</link>
          <guid>https://fau.re/20110612_eenvarders/</guid>
          <description xml:base="https://fau.re/20110612_eenvarders/">&lt;p&gt;While browsing &lt;a href=&quot;http:&#x2F;&#x2F;levitated.net&#x2F;&quot;&gt;levitated.net&lt;&#x2F;a&gt; which
is an interesting site with lots of original flash animations, I stumbled
across &lt;a href=&quot;http:&#x2F;&#x2F;levitated.net&#x2F;daily&#x2F;levInvaderFractal.html&quot;&gt;Invader.fractal&lt;&#x2F;a&gt;.
I wanted to make the same as a wallpaper for enlightenment.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-bit-of-code&quot;&gt;A bit of code&lt;&#x2F;h2&gt;
&lt;p&gt;I’ve put all the code on
&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;eenvader.fractal&quot;&gt;github&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;In order for the wallpaper to be fast and use low ressources, I decided to
have an &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;eenvader.fractal&#x2F;blob&#x2F;master&#x2F;src&#x2F;eenvaders_evas_smart.c&quot;&gt;evas smart object&lt;&#x2F;a&gt; used inside an &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;eenvader.fractal&#x2F;blob&#x2F;master&#x2F;src&#x2F;eenvaders_edje_external.c&quot;&gt;edje external module&lt;&#x2F;a&gt;.
That module is then used in a &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;eenvader.fractal&#x2F;blob&#x2F;master&#x2F;data&#x2F;eenvaders.edc&quot;&gt;very small edc&lt;&#x2F;a&gt; file making it a background
usable by enlightenment.&lt;&#x2F;p&gt;
&lt;p&gt;In order to draw a 7x7 random eenvader, here’s the code:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;C&quot; class=&quot;language-C z-code&quot;&gt;&lt;code class=&quot;language-C&quot; data-lang=&quot;C&quot;&gt;&lt;span class=&quot;z-source z-c&quot;&gt;    &lt;span class=&quot;z-meta z-preprocessor z-macro z-c&quot;&gt;&lt;span class=&quot;z-keyword z-control z-import z-define z-c&quot;&gt;#define&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-preprocessor z-macro z-c&quot;&gt; &lt;span class=&quot;z-entity z-name z-constant z-preprocessor z-c&quot;&gt;FG&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-preprocessor z-macro z-c&quot;&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-hexadecimal z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-numeric z-base z-c&quot;&gt;0x&lt;&#x2F;span&gt;ff839496&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;    &lt;span class=&quot;z-support z-type z-stdint z-c&quot;&gt;uint16_t&lt;&#x2F;span&gt; u &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-support z-function z-C99 z-c&quot;&gt;rand&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;    &lt;span class=&quot;z-storage z-type z-c&quot;&gt;int&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-c&quot;&gt;*&lt;&#x2F;span&gt;mem &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-support z-function z-C99 z-c&quot;&gt;calloc&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;7&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-c&quot;&gt;*&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;7&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-c&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-word z-c&quot;&gt;sizeof&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-storage z-type z-c&quot;&gt;int&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-c&quot;&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;    &lt;span class=&quot;z-keyword z-control z-c&quot;&gt;for&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-c&quot;&gt;int&lt;&#x2F;span&gt; i &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;0&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt; i &lt;span class=&quot;z-keyword z-operator z-comparison z-c&quot;&gt;&amp;lt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;15&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt; i&lt;span class=&quot;z-keyword z-operator z-arithmetic z-c&quot;&gt;++&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-c&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-keyword z-control z-c&quot;&gt;if&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;u &lt;span class=&quot;z-keyword z-operator z-c&quot;&gt;&amp;amp;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;1&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-arithmetic z-c&quot;&gt;&amp;lt;&amp;lt;&lt;&#x2F;span&gt; i&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-c&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;            mem&lt;span class=&quot;z-meta z-brackets z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-begin z-c&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;7&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-arithmetic z-c&quot;&gt;+&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;7&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-c&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;i&lt;span class=&quot;z-keyword z-operator z-arithmetic z-c&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-arithmetic z-c&quot;&gt;+&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;1&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-arithmetic z-c&quot;&gt;+&lt;&#x2F;span&gt; i&lt;span class=&quot;z-keyword z-operator z-arithmetic z-c&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-end z-c&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; FG&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;            mem&lt;span class=&quot;z-meta z-brackets z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-begin z-c&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;7&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-arithmetic z-c&quot;&gt;+&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;7&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-c&quot;&gt;*&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-c&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-c&quot;&gt;(&lt;&#x2F;span&gt;i&lt;span class=&quot;z-keyword z-operator z-arithmetic z-c&quot;&gt;&#x2F;&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-c&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-arithmetic z-c&quot;&gt;+&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;5&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-arithmetic z-c&quot;&gt;-&lt;&#x2F;span&gt; i&lt;span class=&quot;z-keyword z-operator z-arithmetic z-c&quot;&gt;%&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-c&quot;&gt;3&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-brackets z-end z-c&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-c&quot;&gt;=&lt;&#x2F;span&gt; FG&lt;span class=&quot;z-punctuation z-terminator z-c&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;        &lt;span class=&quot;z-punctuation z-section z-block z-end z-c&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-c&quot;&gt;&lt;span class=&quot;z-meta z-block z-c&quot;&gt;    &lt;span class=&quot;z-punctuation z-section z-block z-end z-c&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I let my C compiler unroll the loop and optimise the code for me.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-does-it-look-like&quot;&gt;What does it look like?&lt;&#x2F;h2&gt;
&lt;p&gt;I use colors from &lt;a href=&quot;https:&#x2F;&#x2F;ethanschoonover.com&#x2F;solarized&quot;&gt;solarized&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20110612_eenvarders&#x2F;eenvarders1.png&quot; alt=&quot;eenvarders screenshot&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;And if you click and kill the big one on the left, here’s what you get:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20110612_eenvarders&#x2F;eenvarders2.png&quot; alt=&quot;eenvarders screenshot with the big one on the left killed&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;The wallpaper is refreshed every 30 seconds.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>A textual clock as background for enlightenment</title>
          <pubDate>Mon, 06 Jun 2011 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20110606_klok/</link>
          <guid>https://fau.re/20110606_klok/</guid>
          <description xml:base="https://fau.re/20110606_klok/">&lt;p&gt;I’ve implemented the &lt;a href=&quot;https:&#x2F;&#x2F;www.qlocktwo.com&#x2F;&quot;&gt;qlocktwo&lt;&#x2F;a&gt; for use as an
enlightenment wallpaper.&lt;&#x2F;p&gt;
&lt;p&gt;I’ve committed it on &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;klok&quot;&gt;github&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;It looks like that:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;fau.re&#x2F;20110606_klok&#x2F;klok.png&quot; alt=&quot;klok screenshot&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;p&gt;As you can see in that screenshot, the letters do not have the same size. I
hope to fix that bug soon.&lt;&#x2F;p&gt;
&lt;p&gt;Ps: If you want to buy me a qlocktwo, feel free to contact me :)&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Pull from faster read-only repos with git&#x27;s pushInsteadOf</title>
          <pubDate>Sun, 10 Apr 2011 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20110410_git_pushinsteadof/</link>
          <guid>https://fau.re/20110410_git_pushinsteadof/</guid>
          <description xml:base="https://fau.re/20110410_git_pushinsteadof/">&lt;p&gt;I pull changes from my own repos on different places: my laptop, my home
computer, my work computer, my router…&lt;&#x2F;p&gt;
&lt;p&gt;On every place, when fetching changes I have to enter my passphrase. That
does not make much sense since most of the repositories can be fetched anonymously.&lt;&#x2F;p&gt;
&lt;p&gt;The issue can be analyzed from a different point of view. When do I need to
authenticate myself? → Only on push.&lt;&#x2F;p&gt;
&lt;p&gt;One solution for that is &lt;em&gt;pushInsteadOf&lt;&#x2F;em&gt;. Since git v1.6.4, this option
exists to specify what URL git should use when pushing changes.
Now I need to change the URLs in all my repos to use by default the read-only
URL: for example changing &lt;code&gt;git@github.com:borisfaure&#x2F;bfb.git&lt;&#x2F;code&gt; to
&lt;code&gt;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;bfb.git&lt;&#x2F;code&gt;. I use &lt;code&gt;https&lt;&#x2F;code&gt; since it should have a smaller impact on
the servers than the git protocol.&lt;&#x2F;p&gt;
&lt;p&gt;Then I’ve added the following to my &lt;code&gt;~&#x2F;.gitconfig&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;ini&quot; class=&quot;language-ini z-code&quot;&gt;&lt;code class=&quot;language-ini&quot; data-lang=&quot;ini&quot;&gt;&lt;span class=&quot;z-source z-genconfig&quot;&gt;&lt;span class=&quot;z-storage z-type z-genconfig&quot;&gt;[url &amp;quot;git@github.com:borisfaure&#x2F;&amp;quot;]
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-genconfig&quot;&gt;&lt;span class=&quot;z-meta z-param z-genconfig&quot;&gt;    &lt;span class=&quot;z-variable z-parameter z-genconfig&quot;&gt;pushInsteadOf&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-genconfig&quot;&gt;=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-url z-genconfig&quot;&gt;&lt;span class=&quot;z-constant z-other z-genconfig&quot;&gt;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-genconfig&quot;&gt;&#x2F;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-genconfig&quot;&gt;&lt;span class=&quot;z-meta z-param z-genconfig&quot;&gt;    &lt;span class=&quot;z-variable z-parameter z-genconfig&quot;&gt;pushInsteadOf&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-genconfig&quot;&gt;=&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-url z-genconfig&quot;&gt;&lt;span class=&quot;z-constant z-other z-genconfig&quot;&gt;git:&#x2F;&#x2F;github.com&#x2F;borisfaure&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-genconfig&quot;&gt;&#x2F;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Those 3 lines work for all my github repos. An URL like
&lt;code&gt;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;bfb.git&lt;&#x2F;code&gt; will be rewritten
to &lt;code&gt;git@github.com:borisfaure&#x2F;bfb.git&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;No need to enter my passphrase when fetching changes!&lt;&#x2F;p&gt;
&lt;p&gt;Edit:
You can also add an url for push using &lt;code&gt;git remote&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>aMSN2&#x27;s web frontend</title>
          <pubDate>Sat, 12 Jun 2010 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20100612_amsn2_web_frontend/</link>
          <guid>https://fau.re/20100612_amsn2_web_frontend/</guid>
          <description xml:base="https://fau.re/20100612_amsn2_web_frontend/">&lt;p&gt;aMSN2 is designed to offer multiple frontends so that it should be able to run on
whatever you like.
One such frontend is the web frontend.&lt;&#x2F;p&gt;
&lt;p&gt;The primary is not to provide you a website where you’d go and connect to MSN.
Instead we want to let you host aMSN2 and run it in your web browser.&lt;&#x2F;p&gt;
&lt;p&gt;It was first designed using a webserver with php. It was working but I thought we could
use directly python instead of php and embed directly a small webserver in amsn2-web.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;amsn2-s-design&quot;&gt;aMSN2’s design&lt;&#x2F;h2&gt;
&lt;p&gt;Here is how I want to implement it, just like every other frontend:&lt;&#x2F;p&gt;
&lt;p&gt;papyon ↔ amsn2 ↔ the frontend&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;papyon is used to connect to the msn network&lt;&#x2F;li&gt;
&lt;li&gt;amsn2 listens to papyon and the frontend making them understand
each other.&lt;&#x2F;li&gt;
&lt;li&gt;the frontend displays what aMSN2 tells it and tells aMSN2 when the user did something
(like clicking on a contact in the contact list)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;aMSN2 has an event loop to deal with events from papyon or the frontend. This works
nicely for most of the frontends.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;but-the-web-is-different&quot;&gt;But the web is different.&lt;&#x2F;h2&gt;
&lt;p&gt;Here is how it was working:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;If the user clicked on a webpage, your browser (using jQuery) sends directly the query
to the webserver. The webserver put the query in a file.&lt;&#x2F;li&gt;
&lt;li&gt;aMSN look at that file every 100ms or so. Oh, there’s something to process! aMSN2
deals with the event and may ask papyon to do some work.&lt;&#x2F;li&gt;
&lt;li&gt;Then an event occured in papyon. aMSN2 gets notified directly. A contact went online.
It needs to tell your browser about it. To do that, it writes it to the file.&lt;&#x2F;li&gt;
&lt;li&gt;Every now and then, the web frontend asks if there is something new and get that your
contact has just came online.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There are some issues here. Having to check every X ms to know if there is something to
do isn’t great. We have an event loop, let’s use it!!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;cherrypy&quot;&gt;Cherrypy&lt;&#x2F;h2&gt;
&lt;p&gt;First, aMSN2 should include directly the webserver and add it to it’s event loop so that
when the web frontend wants something, it can reply to it right away.
I’ve tried to do that with cherrypy.&lt;&#x2F;p&gt;
&lt;p&gt;I tell my browser to go to
&lt;code&gt;http:&#x2F;&#x2F;127.0.0.1:8080&#x2F;static&#x2F;amsn2.html&lt;&#x2F;code&gt;. After few seconds, I see in the logs that cherrypy got the query.&lt;&#x2F;p&gt;
&lt;p&gt;It’s a static file. It should handle it easily. But I wait and wait again and
nothing happens. When I send SIGINT (Ctrl+c) to aMSN2, then the page load correctly!!
Even in its own thread, cherrypy is blocking on something.&lt;&#x2F;p&gt;
&lt;p&gt;Here is the code I use to do that:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;python&quot; class=&quot;language-python z-code&quot;&gt;&lt;code class=&quot;language-python&quot; data-lang=&quot;python&quot;&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-meta z-class z-python&quot;&gt;&lt;span class=&quot;z-storage z-type z-class z-python&quot;&gt;&lt;span class=&quot;z-keyword z-declaration z-class z-python&quot;&gt;class&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-entity z-name z-class z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;Root&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-class z-inheritance z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-inheritance z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-class z-inheritance z-python&quot;&gt;&lt;span class=&quot;z-entity z-other z-inherited-class z-python&quot;&gt;object&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-inheritance z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-class z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-class z-begin z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-meta z-function z-python&quot;&gt;    &lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;&lt;span class=&quot;z-keyword z-declaration z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-entity z-name z-function z-python&quot;&gt;&lt;span class=&quot;z-support z-function z-magic z-python&quot;&gt;__init__&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-python&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-parameters z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-python&quot;&gt;inq&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-parameters z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-python&quot;&gt;outq&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-function z-begin z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;        &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-language z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;_inq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;  &lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;inq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;        &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-language z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;_outq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;outq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-meta z-annotation z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-annotation z-python&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;cherrypy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-annotation z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;expose&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-meta z-function z-python&quot;&gt;    &lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;&lt;span class=&quot;z-keyword z-declaration z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-entity z-name z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;index&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-python&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-function z-begin z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;        &lt;span class=&quot;z-meta z-statement z-raise z-python&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-raise z-python&quot;&gt;raise&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;cherrypy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;HTTPRedirect&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;static&#x2F;amsn2.html&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-meta z-annotation z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-annotation z-python&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;cherrypy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-annotation z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;expose&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-meta z-function z-python&quot;&gt;    &lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;&lt;span class=&quot;z-keyword z-declaration z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-entity z-name z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;signin&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-python&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-parameters z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-python&quot;&gt;u&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-default-value z-python&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-python&quot;&gt;None&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-parameters z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-python&quot;&gt;p&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-default-value z-python&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-language z-python&quot;&gt;None&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-function z-begin z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;        &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-language z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;_inq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;put_nowait&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-sequence z-list z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-sequence z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-double z-python&quot;&gt;signin&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;u&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-sequence z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;p&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-sequence z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;    &lt;span class=&quot;z-meta z-annotation z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-annotation z-python&quot;&gt;@&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;cherrypy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-annotation z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;expose&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-meta z-function z-python&quot;&gt;    &lt;span class=&quot;z-storage z-type z-function z-python&quot;&gt;&lt;span class=&quot;z-keyword z-declaration z-function z-python&quot;&gt;def&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-entity z-name z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;out&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-parameters z-python&quot;&gt;&lt;span class=&quot;z-variable z-parameter z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-function z-begin z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;        &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;l&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-sequence z-list z-empty z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-sequence z-begin z-python&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-sequence z-end z-python&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;        &lt;span class=&quot;z-meta z-statement z-loop z-while z-python&quot;&gt;&lt;span class=&quot;z-keyword z-control z-loop z-while z-python&quot;&gt;while&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-language z-python&quot;&gt;True&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-block z-loop z-while z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;            &lt;span class=&quot;z-meta z-statement z-exception z-try z-python&quot;&gt;&lt;span class=&quot;z-keyword z-control z-exception z-try z-python&quot;&gt;try&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-block z-exception z-try z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;                &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;l&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;append&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-language z-python&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;_outq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;get_nowait&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;            &lt;span class=&quot;z-meta z-statement z-exception z-catch z-python&quot;&gt;&lt;span class=&quot;z-keyword z-control z-exception z-catch z-python&quot;&gt;except&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;Queue&lt;&#x2F;span&gt;.&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;Empty&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-block z-exception z-catch z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;                &lt;span class=&quot;z-keyword z-control z-flow z-break z-python&quot;&gt;break&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-statement z-python&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;        &lt;span class=&quot;z-keyword z-control z-flow z-return z-python&quot;&gt;return&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;l&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;current_dir&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;os&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;path&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;dirname&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;os&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;path&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;abspath&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-support z-variable z-magic z-python&quot;&gt;__file__&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;cherrypy&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;config&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;update&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-mapping z-begin z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-key z-python&quot;&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;log.error_file&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-key-value z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-python&quot;&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;amsn2-web-error.log&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-python&quot;&gt;,&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt;                       &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-key z-python&quot;&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;log.access_file&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-key-value z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-python&quot;&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;amsn2-web-access.log&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-python&quot;&gt;,&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt;                       &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-key z-python&quot;&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;log.screen&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-key-value z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-python&quot;&gt;&lt;span class=&quot;z-constant z-language z-python&quot;&gt;False&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-mapping z-end z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;conf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-mapping z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-mapping z-begin z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-key z-python&quot;&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&#x2F;static&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-key-value z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-python&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-mapping z-begin z-python&quot;&gt;{&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-key z-python&quot;&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;tools.staticdir.on&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-key-value z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-python&quot;&gt;&lt;span class=&quot;z-constant z-language z-python&quot;&gt;True&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-python&quot;&gt;,&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-value z-python&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt;        &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-key z-python&quot;&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;tools.staticdir.dir&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-key-value z-python&quot;&gt;:&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-value z-python&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;os&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;path&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;join&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;current_dir&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;static&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-mapping z-end z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-mapping z-python&quot;&gt;,&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-meta z-mapping z-python&quot;&gt;       &lt;span class=&quot;z-punctuation z-section z-mapping z-end z-python&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-python&quot;&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;cherrypy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-python&quot;&gt;.&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;quickstart&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-variable z-function z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;Root&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-begin z-python&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;inq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;outq&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-string z-python&quot;&gt;&lt;span class=&quot;z-string z-quoted z-single z-python&quot;&gt;&#x2F;&lt;span class=&quot;z-punctuation z-definition z-string z-end z-python&quot;&gt;&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-arguments z-python&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-python&quot;&gt;config&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-assignment z-python&quot;&gt;=&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-qualified-name z-python&quot;&gt;&lt;span class=&quot;z-meta z-generic-name z-python&quot;&gt;conf&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-arguments z-end z-python&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;how-i-want-to-handle-that-issue&quot;&gt;How I want to handle that issue.&lt;&#x2F;h2&gt;
&lt;p&gt;aMSN2 should listen to &lt;code&gt;127.0.0.1:8080&lt;&#x2F;code&gt; (or whatever you want). When something happens, it should have a tiny HTTP
machine to process the query and act just like the web frontend was like every other
frontend.&lt;&#x2F;p&gt;
&lt;p&gt;Then we should use “long push”. jQuery sends a query to now what’s new. aMSN2’s doesn’t
answer yet but once there is something to tell the frontend, it replies. The browser
updates whatever needed based on the answer and send right away a new query to know
what’s new.&lt;&#x2F;p&gt;
&lt;p&gt;If you want to help me with that, feel free to contact me.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>My gentoo overlay</title>
          <pubDate>Fri, 11 Jun 2010 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20100611_gentoo_overlay/</link>
          <guid>https://fau.re/20100611_gentoo_overlay/</guid>
          <description xml:base="https://fau.re/20100611_gentoo_overlay/">&lt;p&gt;I’m finally back on gentoo!! Gentoo didn’t cope very well on my lonely netbook ☺.&lt;&#x2F;p&gt;
&lt;p&gt;I had to patch small bits of ebuilds here and there so I’ve created my own overlay.&lt;&#x2F;p&gt;
&lt;p&gt;It is available &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;borisfaure&#x2F;gentoo-overlay&quot;&gt;on github&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I’ll put ebuilds of different kinds:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;ebuilds for newer versions of packages not already on portage. This is the case for the
teamspeak3 client for example.&lt;&#x2F;li&gt;
&lt;li&gt;ebuilds with fixes like the oss-devel ebuild which was missing a USE flag.&lt;&#x2F;li&gt;
&lt;li&gt;…&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I hope the overlay will be as small as possible by having much of my patches included
directly in portage.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>aMSN2&#x27;s status</title>
          <pubDate>Sun, 18 Apr 2010 00:00:00 +0000</pubDate>
          <author>Unknown</author>
          <link>https://fau.re/20100418_amsn2_status/</link>
          <guid>https://fau.re/20100418_amsn2_status/</guid>
          <description xml:base="https://fau.re/20100418_amsn2_status/">&lt;h2 id=&quot;what-is-amsn2&quot;&gt;What is aMSN2 ?&lt;&#x2F;h2&gt;
&lt;p&gt;aMSN2 is a complete rewrite of aMSN in python. It uses the papyon framework to connect to
MSN servers. It is meant to be multi-frontend so that it has a native look on the
operating system you use. Available frontends include :&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Cocoa, for MacOSX,&lt;&#x2F;li&gt;
&lt;li&gt;GTK, should be ran mainly on Linux,&lt;&#x2F;li&gt;
&lt;li&gt;Qt4, being able to run on both Linux and Windows,&lt;&#x2F;li&gt;
&lt;li&gt;EFL, the Enlightenment Foundation Libraries, should only run on Linux but a Windows
port may come to light someday,&lt;&#x2F;li&gt;
&lt;li&gt;Curses, to enjoy aMSN2 on your terminals,&lt;&#x2F;li&gt;
&lt;li&gt;Web, so that you can use aMSN2 from your favorite browser!&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;is-it-daily-usable&quot;&gt;Is it daily usable?&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;short-answer&quot;&gt;Short answer&lt;&#x2F;h3&gt;
&lt;p&gt;No!&lt;&#x2F;p&gt;
&lt;h3 id=&quot;long-answer&quot;&gt;Long answer&lt;&#x2F;h3&gt;
&lt;p&gt;The most advanced frontend is the GTK one. It’s almost usable.
The cocoa frontend needs love.
The Qt4 frontend should be almost usable soon.
On the Curses frontend, you can only see your contact list, but you won’t be able to chat.
The web frontend is completely broken. I plan on writing a blog post on why it’s broken
and how we may fix it.
About the EFL frontend, I’m also an enlightenment developer so I will fix it when I’ll
have enough time.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;but-when-do-you-give-us-a-beta-version-to-try-it&quot;&gt;but when do you give us a beta version to try it?&lt;&#x2F;h3&gt;
&lt;p&gt;Each time we get asked, the release is postponed for 3 months, so now I can say it’s post
2020 ☺ .&lt;&#x2F;p&gt;
&lt;p&gt;But you can help us!!&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-to-contribute&quot;&gt;How to contribute?&lt;&#x2F;h2&gt;
&lt;p&gt;The development is hosted on &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;amsn&#x2F;amsn2&quot;&gt;github&lt;&#x2F;a&gt;. Fork us!!!&lt;&#x2F;p&gt;
&lt;p&gt;We also use &lt;a href=&quot;http:&#x2F;&#x2F;codaset.com&#x2F;amsn&#x2F;amsn2&#x2F;tickets&quot;&gt;codaset&lt;&#x2F;a&gt; to deal with bugs and
timelines.&lt;&#x2F;p&gt;
&lt;p&gt;Before coding on aMSN2, you may want to read &lt;a href=&quot;http:&#x2F;&#x2F;www.amsn-project.net&#x2F;forums&#x2F;index.php?topic=5994.msg35025#msg35025&quot;&gt;this forum
entry&lt;&#x2F;a&gt; that
should explain everything you need to know to contribute on aMSN2.&lt;&#x2F;p&gt;
&lt;p&gt;You can reach us on irc on the #amsn channel at freenode if you have questions about the
development. We’ll be happy to help you help us!&lt;&#x2F;p&gt;
</description>
      </item>
    </channel>
</rss>
