<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
	<title>mvidell.se</title>
	<link>https://mvidell.se/</link>
	<description>Recent content in Home on mvidell.se</description>
	<generator>Hugo -- gohugo.io</generator>
	<language>en</language>
	<lastBuildDate>Mon, 18 May 2026 00:21:58 +0200</lastBuildDate>
    
        <atom:link href="https://mvidell.se/index.xml" rel="self" type="application/rss+xml" />
	
	
	<item>
		<title>Offsetof</title>
		<link>https://mvidell.se/posts/offsetof/</link>
		<pubDate>Mon, 18 May 2026 00:21:58 +0200</pubDate>
		
		<guid>https://mvidell.se/posts/offsetof/</guid>
		<description>&lt;p&gt;A common problem in programming is parsing different key-value pairs. These keys and values could easily be read into a map of some sort and each value lookup-ed when needed. But often these key-value pairs follow a schema. They have a known structure to them.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;instrument_id&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;10&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;ACME&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;&amp;#34;long_name&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;ACME Corporation&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;C has a way to represent structured data. Its the common &lt;code&gt;struct&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;InstrumentInfo&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// (1)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000&#34;&gt;i64&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;instrument_id&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000&#34;&gt;String&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000&#34;&gt;String&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;long_name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The problem however is how to write the structured JSON data into the structured C data. Without any meaningful type introspection in C it becomes quite hard to map the keys to the fields in the struct. You could have a bunch of if-statements to check but that gets old quite quickly especially when you consider that you probably have multiple different structures to parse.&lt;/p&gt;
&lt;p&gt;Enter &lt;code&gt;offsetof(3)&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-man&#34; data-lang=&#34;man&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NAME
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     offsetof - offset of a structure member
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;LIBRARY
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     Standard C library (libc, -lc)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SYNOPSIS
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     #include &amp;lt;stddef.h&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     size_t offsetof(type, member);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;DESCRIPTION
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     The macro offsetof() returns the offset of the field member from the start
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     of the structure type.
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	 ...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;offsetof&lt;/code&gt; is great. &lt;code&gt;offsetof(InstrumentInfo, name)&lt;/code&gt; can be used to find the the byte offset of the field &lt;code&gt;name&lt;/code&gt; in the struct &lt;code&gt;InstrumentInfo&lt;/code&gt;. But it does not get us all the way there. &lt;code&gt;offsetof&lt;/code&gt; cannot be used on an arbitrary string at runtime. It only calculates the offsets for compile-time constants.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s declare some structs.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Schema&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Key&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// The name of the key and field.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000&#34;&gt;String&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;key&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Offset of the field in the struct given by offsetof.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000&#34;&gt;i64&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;offset&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// A schema for the corresponding value.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000&#34;&gt;Schema&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;schema&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;enum&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Type&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000&#34;&gt;INTEGER&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;OBJECT&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;STRING&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// ...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Schema&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000&#34;&gt;Type&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// An array of keys.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000&#34;&gt;Key&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;keys&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000&#34;&gt;i64&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;num_keys&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// The size of the struct representing the object.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000&#34;&gt;i64&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;size&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Each &lt;code&gt;Schema&lt;/code&gt; has a list of keys and a size of the struct it represents. Each &lt;code&gt;Key&lt;/code&gt; has the name of the key, its offset into the struct, and a separate schema describing its paired value.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s define some schemas.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Schemas for &amp;#34;primitive&amp;#34; types
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000&#34;&gt;Schema&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;i64_schema&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;INTEGER&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000&#34;&gt;Schema&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;String_schema&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;type&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;STRING&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Schema for InstrumentInfo
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000&#34;&gt;Key&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;InstrumentInfo_keys&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[]&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000&#34;&gt;make_key3&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;InstrumentInfo&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;instrument_id&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;i64_schema&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000&#34;&gt;make_key3&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;InstrumentInfo&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;String_schema&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000&#34;&gt;make_key3&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;InstrumentInfo&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;long_name&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;String_schema&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000&#34;&gt;make_schema&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;InstrumentInfo&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the section above some primitive schemas are defined and a schema &lt;code&gt;InstrumentInfo_schema&lt;/code&gt; is defined from the &lt;code&gt;InstrumentInfo&lt;/code&gt; struct. An array of keys is defined using the macro &lt;code&gt;make_key3&lt;/code&gt; which uses the stringizing operator &lt;code&gt;#&lt;/code&gt; to convert the field name to a string constant and calls &lt;code&gt;offsetof&lt;/code&gt; on the given field. The &lt;code&gt;make_schema&lt;/code&gt; macro defines &lt;code&gt;InstrumentInfo_schema&lt;/code&gt; with the defined keys &lt;code&gt;IntrumentInfo_keys&lt;/code&gt; using the token-pasting operator &lt;code&gt;##&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;#define make_key3(Struct, property, json_schema)    \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;    {                                               \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;        .key = S(#property),                        \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;        .offset = offsetof(Struct, property),       \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;        .schema = json_schema,                      \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;#define make_schema(Struct)                         \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;    Schema Struct ## _schema = {                    \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;        .type = OBJECT,                             \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;        .keys = Struct ## _keys,                    \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;        .num_keys = countof(Struct ## _keys),       \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;        .size = sizeof(Struct),                     \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But this is quite silly. Why are we defining a &lt;code&gt;Schema&lt;/code&gt; for &lt;code&gt;InstrumentInfo&lt;/code&gt; when the schema already exist? We wrote the schema when we declared the struct in (1)! We should use that.&lt;/p&gt;
&lt;p&gt;A key insight is that &lt;code&gt;InstrumentInfo_keys&lt;/code&gt; and &lt;code&gt;InstrumentInfo_schema&lt;/code&gt; can and should be automatically generated at compile-time. If the schemas are written into a header file &lt;code&gt;schemas.h&lt;/code&gt; then a simple parser (emphasis on &lt;em&gt;simple&lt;/em&gt;) can be executed using the header file as input at build time. This parser would extract all of the structs and their fields in the header and output a separate file containing the definitions for &lt;code&gt;_keys&lt;/code&gt; and &lt;code&gt;_schema&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;parsing-values&#34;&gt;Parsing Values&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s consider parsing values.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Read into (compile-time) known struct.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000&#34;&gt;InstrumentInfo&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;info&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000&#34;&gt;parse_value&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;stream&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;InstrumentInfo_schema&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;char&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;info&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Read into arbitrary struct given by schema.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;buffer&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;char&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;malloc&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;schema&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;size&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000&#34;&gt;parse_value&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;stream&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;schema&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;buffer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;parse_value&lt;/code&gt; takes an input stream of tokens, a schema, and a buffer as parameters. An underlying assumption is that the data is structured and it is known what is expected, therefore the parse function is given a schema as a parameter. The &lt;code&gt;buffer&lt;/code&gt; is a pointer to a location that is at least &lt;code&gt;schema-&amp;gt;size&lt;/code&gt; large and the parsed values are written to it.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;parse_value&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Stream&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;stream&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Schema&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;schema&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;buffer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;switch&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;schema&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;type&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;case&lt;/span&gt; &lt;span style=&#34;color:#f57900&#34;&gt;INTEGER&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;parse_integer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;stream&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;schema&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;buffer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;case&lt;/span&gt;  &lt;span style=&#34;color:#f57900&#34;&gt;OBJECT&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;parse_object&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;stream&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;schema&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;buffer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;case&lt;/span&gt;  &lt;span style=&#34;color:#f57900&#34;&gt;STRING&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;parse_string&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;stream&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;schema&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;buffer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;default&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;:&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;error&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;parse_value&lt;/code&gt; simply switches on schema type.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;parse_integer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Stream&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;stream&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Schema&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;schema&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;buffer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Expect integer value from the input stream.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000&#34;&gt;i64&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;integer&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;expect_integer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;stream&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000&#34;&gt;i64&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;field&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;i64&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;buffer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;field&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;integer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the case of integers, strings, and other primitives the value is just read from the input stream and written directly into the given buffer. It checks that the read value actually is an integer and that the read data conforms to the expected schema.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;parse_object&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;Stream&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;stream&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Schema&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;schema&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;buffer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Loop over the input stream for as long as the object is open
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;while&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;!&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;object_ended&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;stream&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;))&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Read key from stream and lookup in schema-&amp;gt;keys
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#000&#34;&gt;Key&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;key&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;lookup&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;expect_key&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;stream&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;),&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;schema&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;!&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;key&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;error&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// This is where the parsed value should be stored.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;char&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;field&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;buffer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;key&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;offset&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Call parse_value with the key&amp;#39;s schema and field.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#000&#34;&gt;parse_value&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;stream&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;key&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;schema&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;field&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When parsing objects it reads the key and parses the next value according to the key&amp;rsquo;s schema. The storage for the value is inside the given buffer. Then continue with the next key-value pair.&lt;/p&gt;
&lt;p&gt;The example can easily be extended to cover nested objects.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Price&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000&#34;&gt;String&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;price&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000&#34;&gt;i64&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;decimals&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;PriceInfo&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000&#34;&gt;Price&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;last&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000&#34;&gt;Price&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;open&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000&#34;&gt;Price&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;close&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000&#34;&gt;i64&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;tick_timestamp&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;UnderlyingDetails&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000&#34;&gt;InstrumentInfo&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;info&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#000&#34;&gt;PriceInfo&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;price_info&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Define the _keys and _schema variables...
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;demo&#34;&gt;Demo&lt;/h2&gt;
&lt;p&gt;Check out demo with &lt;code&gt;git clone https://mvidell.se/offsetof.git
&lt;/code&gt;. Build it with &lt;code&gt;make&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The demo features&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;two large JSON files parsed using different schemas.&lt;/li&gt;
&lt;li&gt;more types including arrays.&lt;/li&gt;
&lt;li&gt;both input and output types for on-the-fly conversions, e.g. a floating point number in JSON can be stored as a String in the struct.&lt;/li&gt;
&lt;li&gt;a flag for each key whether the value should be stored directly or as a pointer.&lt;/li&gt;
&lt;li&gt;a simple &lt;a href=&#34;https://en.wikipedia.org/wiki/Recursive_descent_parser&#34;&gt;recursive descent parser&lt;/a&gt; for header files that generates the schemas at build time.&lt;/li&gt;
&lt;li&gt;an object equality function according to schema in a function similar to &lt;code&gt;parse_value&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/skeeto/pdjson&#34;&gt;pdjson&lt;/a&gt;, a streaming JSON parser (more of a lexer), by &lt;a href=&#34;https://nullprogram.com&#34;&gt;Chris Wellons&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;memory arenas inspired by &lt;a href=&#34;https://www.youtube.com/watch?v=xt1KNDmOYqA&#34;&gt;Casey Muratori&amp;rsquo;s N+2 programmer&lt;/a&gt; and &lt;a href=&#34;https://nullprogram.com/index/&#34;&gt;Chris Wellons&amp;rsquo;s blog&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;possible-extensions&#34;&gt;Possible Extensions&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Use macro magic to define &lt;code&gt;_keys&lt;/code&gt; and &lt;code&gt;_schemas&lt;/code&gt; instead of the parser.&lt;/li&gt;
&lt;li&gt;Expected keys, i.e. keys that must be in the read object or its an error.&lt;/li&gt;
&lt;li&gt;Default values for keys and a flag to check whether the key was found in the object.&lt;/li&gt;
&lt;li&gt;Arrays that support more than one type of values.&lt;/li&gt;
&lt;li&gt;Infer the schema automatically from JSON examples.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;offsetof&lt;/code&gt; can clearly be used for the purpose of parsing structured data into structured data.&lt;/p&gt;
&lt;p&gt;Are there any downsides? The structs in the demo can be quite large, some nearing 1 KiB in size. The sizes can be somewhat reduced by storing the data indirectly using pointers but on the other hand, should you? The data has to be stored somewhere and storing it as a map probably uses an even larger memory footprint, with worse locality, and with more expensive lookups compared to structs. Using and chasing too many pointers will convert the struct to a linked list with linked list performance (serial cache misses).&lt;/p&gt;
&lt;p&gt;One worry is that there is some hidden footgun or undefined behaviour somewhere but it seems fine. UBSan complained initially about misaligned pointers but that was solved by tweaking the arena memory allocations.&lt;/p&gt;
&lt;p&gt;On the other hand we should wonder why it is so hard to read structured data into structured data. We should expect programming languages for the 21st century to be able to solve this much easier using type introspection, reflective programming, and/or metaprogramming.&lt;/p&gt;
</description>
	</item>
	
	<item>
		<title>Livestream - README</title>
		<link>https://mvidell.se/posts/livestream---readme/</link>
		<pubDate>Wed, 13 May 2026 12:33:04 +0200</pubDate>
		
		<guid>https://mvidell.se/posts/livestream---readme/</guid>
		<description>
&lt;blockquote class=&#34;callout callout-summary callout-cyan&#34;&gt;
    &lt;div class=&#34;callout-title&#34;&gt;
        &lt;div class=&#34;callout-icon&#34;&gt;📋&lt;/div&gt;
        &lt;div class=&#34;callout-title-inner&#34;&gt;Summary&lt;/div&gt;
    &lt;/div&gt;&lt;p&gt;In this post I go through some of the implementation
details of the orchestrator that I implemented as a
workaround. For full context on the problems that I try
to solve see the previous article &lt;a href=&#34;https://mvidell.se/posts/livestream---save-the-frames/&#34;&gt;Livestream - Save the
Frames&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;my-workaround&#34;&gt;My Workaround&lt;/h2&gt;
&lt;p&gt;I have implemented a simple orchestrator that starts and maintains multiple processes of yt-dlp that redundantly download the stream. These processes are started using &lt;code&gt;--abort-on-unavailable&lt;/code&gt; and, if a yt-dlp process exits, the orchestrator will &lt;em&gt;waitpid(2)&lt;/em&gt; on it and start a new worker. As it automatically restart workers the user is no longer required to babysit the download. Through careful selection of flags it can even start download a new video (with different id) should the streamer stop the stream and restart it on their end.&lt;/p&gt;
&lt;p&gt;This is obviously not a great solution. The underlying assumption is that if one process encounters a problem downloading a fragment the other processes &lt;em&gt;might&lt;/em&gt; be spared. The solution requires a lot of extra storage and a lot of extra network bandwidth. It might not even work that well if the stream encounters a problem though at least it will restart the download should it encounter a problem.&lt;/p&gt;
&lt;h2 id=&#34;implementation-details&#34;&gt;Implementation Details&lt;/h2&gt;
&lt;h3 id=&#34;maintaining-workers&#34;&gt;Maintaining workers&lt;/h3&gt;
&lt;p&gt;The main loop of the orchestrator maintains two sets of (up to) &lt;em&gt;N&lt;/em&gt; workers; the main workers and the outgoing workers. The main workers are the workers that are currently downloading the stream. After the main workers have been running for &lt;em&gt;T&lt;/em&gt; seconds they are marked as &lt;em&gt;outgoing&lt;/em&gt; and a new set of main workers are spawned to take over. This is, in part, to keep the sizes of the video files manageable. After the outgoing workers have been running for &lt;em&gt;D&lt;/em&gt; seconds (overlapping with the newly spawned main workers) they are signalled to terminate. First with &lt;em&gt;SIGINT&lt;/em&gt; to allow them to cleanly exit and, after an additional delay, a &lt;em&gt;SIGKILL&lt;/em&gt; is sent to make sure that they are terminated.&lt;/p&gt;
&lt;p&gt;For each iteration of the main loop the main workers are checked to see that they are still running. If any workers have exited unexpectedly a new worker is spawned to take its place. If too many workers unexpectedly exits within the duration &lt;em&gt;T&lt;/em&gt; the orchestrator will exit and terminate all workers. The streamer probably ended the stream.&lt;/p&gt;
&lt;h3 id=&#34;starting-workers&#34;&gt;Starting Workers&lt;/h3&gt;
&lt;p&gt;The orchestrator creates a new directory for each worker. It then forks and the worker &lt;em&gt;cd:s&lt;/em&gt; into the directory and executes &lt;em&gt;yt-dlp&lt;/em&gt; using &lt;em&gt;exec(3)&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The workers need to know what to download and instead of giving the URL to the stream it is better to give the URL to the streamer. Using some selected options to yt-dlp it is possible to tell it to only download the current active livestream. This also solves the problem if the streamer restarts the stream. The most important flags are &lt;code&gt;--lazy-playlist&lt;/code&gt; which prevents yt-dlp to first generate (a potentially long) playlist and &lt;code&gt;--break-match-filter is_live&lt;/code&gt;  which tells yt-dlp to exit if the next video in the playlist is not live.&lt;/p&gt;
&lt;h3 id=&#34;blocking-unblocking-and-polling-for-signals&#34;&gt;Blocking, unblocking, and polling for signals&lt;/h3&gt;
&lt;p&gt;It is important that the user is able to cleanly shutdown the orchestrator and workers. When the orchestrator receives a &lt;em&gt;SIGINT&lt;/em&gt; signal it will start the teardown process and signal its workers to terminate.  It is important for the orchestrator though that the &lt;em&gt;SIGINT&lt;/em&gt; is captured synchronously. It would be bad if the main loop could be interrupted at any point during its execution leading to an inconsistent state. E.g. a worker could have been spawned but a signal interrupted the orchestrator before the number of workers was increased.  Therefore the orchestrator must block &lt;em&gt;SIGINT&lt;/em&gt;  using &lt;em&gt;sigprocmask(2)&lt;/em&gt; and, in order to not block the main loop, poll for signals using &lt;em&gt;sigtimedwait(2)&lt;/em&gt; to guarantee the correct state of the program.&lt;/p&gt;
&lt;p&gt;It is important for the forked workers to unblock &lt;em&gt;SIGINT&lt;/em&gt; otherwise it will be blocked for yt-dlp after &lt;em&gt;exec(3)&lt;/em&gt;. Otherwise the orchestrator could not tell its workers to terminate.&lt;/p&gt;
&lt;h3 id=&#34;download&#34;&gt;Download&lt;/h3&gt;
&lt;p&gt;Download the orchestrator using &lt;code&gt;git clone https://mvidell.se/livestream.git
&lt;/code&gt; and compile it (on Linux) using &lt;code&gt;make&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;help&#34;&gt;Help&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Usage: livestream [OPTIONS] URL

Options
    -h, --help      Print this help and exit.
    --test          Run the test_worker instead of yt-dlp.
                    Make sure it is in $PATH.

    Any other options are passed to yt-dlp.

Examples
    livestream https://www.youtube.com/@USER/streams
    livestream -f &amp;lt;code&amp;gt; -r &amp;lt;rate&amp;gt; https://www.youtube.com/@USER/streams

Default Options
    yt-dlp --lazy-playlist --max-downloads 1
    --skip-playlist-after-errors 1
    --break-match-filter is_live
    --abort-on-unavailable-fragments
    --fixup never
&lt;/code&gt;&lt;/pre&gt;</description>
	</item>
	
	<item>
		<title>Livestream - Save the Frames</title>
		<link>https://mvidell.se/posts/livestream---save-the-frames/</link>
		<pubDate>Wed, 13 May 2026 12:32:58 +0200</pubDate>
		
		<guid>https://mvidell.se/posts/livestream---save-the-frames/</guid>
		<description>
&lt;blockquote class=&#34;callout callout-summary callout-cyan&#34;&gt;
    &lt;div class=&#34;callout-title&#34;&gt;
        &lt;div class=&#34;callout-icon&#34;&gt;📋&lt;/div&gt;
        &lt;div class=&#34;callout-title-inner&#34;&gt;Summary&lt;/div&gt;
    &lt;/div&gt;&lt;p&gt;In this post I go through the difficulties I have had
when downloading ongoing streams from YouTube using
yt-dlp. yt-dlp is a big project with a lot of switches
and features and, while I have not explored every single
feature and option it has to offer, it is quite bad that
something as simple as &lt;em&gt;downloading an ongoing stream&lt;/em&gt; is
such a hard problem using the go-to &lt;em&gt;download everything
from YouTube&lt;/em&gt; downloader. In the end I present my
workaround which is to have multiple processes of yt-dlp
in parallell downloading the stream for redundancy. I
wrote a simple orchestrator in C/C++ that automates this.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;some-working-assumptions&#34;&gt;Some working assumptions&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;The download has to be done &lt;em&gt;while the stream is live&lt;/em&gt; as the stream is expected to be removed after it has ended (more common than you think).&lt;/li&gt;
&lt;li&gt;The stream can experience hiccups, lost fragments, false positive end of stream detected, etc.&lt;/li&gt;
&lt;li&gt;Some frames are lost between the streamer and YouTube. These can probably never be saved and are irrevocably lost forever.&lt;/li&gt;
&lt;li&gt;Frames are more often lost between YouTube and me and these are the frames I want to save. These unavailable fragments are often frequently available for download on retry (but &lt;em&gt;after&lt;/em&gt; failing the default retries).&lt;/li&gt;
&lt;li&gt;The solution should be hands off. The user should not have to babysit the download.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;lets-look-at-some-scenarios&#34;&gt;Lets look at some scenarios&lt;/h2&gt;
&lt;h3 id=&#34;just-use-yt-dlp-url-to-download-the-stream&#34;&gt;&lt;em&gt;Just use yt-dlp $URL to download the stream&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;This is the no-brain starter method but it is not a great solution. The problem with this is that this only downloads the stream from the current position. How are you going to download the beginning of the stream if it started hours ago?&lt;/p&gt;
&lt;h3 id=&#34;download-the-stream-from-the-beginning-with-yt-dlp&#34;&gt;&lt;em&gt;Download the stream from the beginning with yt-dlp &amp;ndash;live-from-start $URL&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;This will download the stream from the beginning up to to the current fragment and will even continue until the end of stream. But what will you do when a fragment 4321 of 5000+ fails to download? Several times I have encountered fragments that failed to download the first time (failing all default retries) but was able to be downloaded after the download was restarted. The problem here is that the &lt;em&gt;entire&lt;/em&gt; video has to be re-downloaded in this case. What if it is fragment 4322 that has a problem in the re-download? Am I supposed to restart the download from the beginning &lt;em&gt;again&lt;/em&gt;?&lt;/p&gt;
&lt;h3 id=&#34;add&#34;&gt;&lt;em&gt;Add &amp;ndash;keep-fragments option&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;Using this option it will keep the fragments downloaded as separate files and it will skip downloading fragments that have been previously downloaded if the process is restarted. But there are several problems. If the download is interrupted before the end of the stream it will merge all fragments into an incomplete video. At this point the download should be restarted as soon as possible, it should not spend a long time (and a lot of storage space) building an incomplete video. Furthermore, the merged video will (if combined with &lt;em&gt;&amp;ndash;live-from-start&lt;/em&gt;) prevent yt-dlp from downloading the stream again because yt-dlp will think that it has already downloaded it. The user is still required to babysit the download and to interrupt it if any fragments fail to download.&lt;/p&gt;
&lt;h3 id=&#34;heading&#34;&gt;&lt;em&gt;&amp;ndash;abort-on-unavailable-fragments&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;This will abort (i.e. exit the download) instead of continuing if it fails to download a fragment. It is &lt;em&gt;sometimes&lt;/em&gt; possible to restart the download (why? when? how? I have no idea). While using this you still have to be actively monitoring the download because if a fragment fails then it obviously won&amp;rsquo;t download the rest of the stream and the download has to be restarted manually.&lt;/p&gt;
&lt;h3 id=&#34;heading-1&#34;&gt;&lt;em&gt;&amp;ndash;abort-on-unavailable-fragments and &amp;ndash;keep-fragments&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;Using &lt;em&gt;&amp;ndash;abort-on-unavailable-fragments&lt;/em&gt; it will stop the download when a fragment is unavailable. This, in combination with &lt;em&gt;&amp;ndash;keep-fragments&lt;/em&gt;, might be good for easier restarts (still manual restarts though). This combination I have not been able to test thoroughly. If a fragment is irrevocably lost will this actually manage to download the rest of the stream?&lt;/p&gt;
&lt;h3 id=&#34;use-yt-dlp&#34;&gt;&lt;em&gt;Use yt-dlp &amp;ndash;fragment-retries infinite $URL&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;I haven&amp;rsquo;t tested this either but I would assume that this will hammer on fragment 4321 infinity times. This is good if the fragment become available in the future but some fragments are irrevocably lost and will never become available. Will this option then prevent the download of the remainder of the stream?&lt;/p&gt;
&lt;h3 id=&#34;use-yt-dlp-1&#34;&gt;&lt;em&gt;Use yt-dlp &amp;ndash;fragment-retries $X $URL where $X &amp;lt; infinite&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;This is obviously also not sufficient. The unavailable fragments could be unavailable during all retries and only become available after all retries have been exhausted. And if yt-dlp spends too much time waiting for missing fragments it will miss the remainder of the stream.&lt;/p&gt;
&lt;h3 id=&#34;not-possible-yt-dlp&#34;&gt;&lt;em&gt;Not possible: yt-dlp &amp;ndash;download-sections &amp;ldquo;*-5:00-inf&amp;rdquo; $URL&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;This does not currently supported for streams on YouTube. Why is this not possible? Who knows&amp;hellip; This would be helpful if a fragment failed and it is known approximately where, in time, that fragment is.&lt;/p&gt;
&lt;h3 id=&#34;heading-2&#34;&gt;&lt;em&gt;&amp;ndash;fixup never&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;This option has to be mentioned because of its usefulness though it does not help downloading fragments directly. When a download has ended yt-dlp spends a lot of time (and space) to &lt;em&gt;fix&lt;/em&gt; the stream. I do not know what this actually does but it certainly takes a lot of time and space. The entire stream is written to disk &lt;em&gt;again&lt;/em&gt; meaning yt-dlp requires double the stream&amp;rsquo;s size for the stream. &lt;em&gt;&amp;ndash;fixup never&lt;/em&gt; can be used to quickly stop after the download and to quickly restart it. Since it is a post-processing of the video it is fine to skip it for the moment. I wish the documentation was more clear of what it does and how it can be replicated after the download has finished.&lt;/p&gt;
&lt;h2 id=&#34;what-i-want&#34;&gt;What I Want&lt;/h2&gt;
&lt;p&gt;I want to tell yt-dlp to just download the stream! Why is it so hard!? When downloading a stream could you please try repeatedly to download the fragments that have failed but without preventing the download of the remainder of the stream? Stop creating incomplete and corrupt files by default!&lt;/p&gt;
&lt;p&gt;There is no good solution to this problem where fragments are downloaded sequentially. The solution must be able to fetch fragments non-sequentially and these fragments are retried infinitely without stopping to download the new fragments. This has a simple solution though. Just put the failed fragments in an array and retry them every now and then.&lt;/p&gt;
&lt;p&gt;yt-dlp would need to change their insane default behaviour and policy that it is better to have an corrupt final file than no file at all. This is a false dichotomy. Once the file has been finalized it is much harder to fix it. This is made even worse when yt-dlp corrupts the file by default often without the knowledge of the user.&lt;/p&gt;
&lt;p&gt;Some features that would help.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Non-sequential fragment downloader that keeps trying to download missing fragments in the background while it still downloads the ongoing stream.&lt;/li&gt;
&lt;li&gt;An option to not combine fragments when using &amp;ndash;keep-fragments. I can combine them myself afterwords.&lt;/li&gt;
&lt;li&gt;An option for downloading specific fragments either by number, by range, by list, etc. E.g. download fragment number 4321 or fragments 100-200.&lt;/li&gt;
&lt;li&gt;Downloading time ranges in streams as one would expect &lt;em&gt;&amp;ndash;download-sections&lt;/em&gt; to work.&lt;/li&gt;
&lt;li&gt;Not creating broken videos by default.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Other users have been complaining for years for similar reasons.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/yt-dlp/yt-dlp/issues/3445&#34;&gt;&amp;quot;[cbs] Damaged downloads&amp;quot;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/yt-dlp/yt-dlp/issues/6078&#34;&gt;&amp;ldquo;How to handle missing/incomplete fragments more elegantly&amp;rdquo;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/yt-dlp/yt-dlp/issues/6757&#34;&gt;&amp;ldquo;Do not skip fragments on filesystem errors&amp;rdquo;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/yt-dlp/yt-dlp/issues/6793&#34;&gt;&amp;ldquo;If parts are missing, don&amp;rsquo;t make it impossible to try to download them later (except for livestreams)&amp;rdquo;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/yt-dlp/yt-dlp/issues/6794&#34;&gt;&amp;ldquo;don&amp;rsquo;t create corrupt files by default without explicit user consent (except for live streams)&amp;rdquo;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/yt-dlp/yt-dlp/issues/15921&#34;&gt;&amp;ldquo;Live Stream Download Prematurely Terminating&amp;rdquo;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;my-workaround&#34;&gt;My Workaround&lt;/h2&gt;
&lt;p&gt;To workaround these problems I have implemented a simple orchestrator that starts and maintains multiple processes of yt-dlp that redundantly download the stream. These processes are started using &lt;em&gt;&amp;ndash;abort-on-unavailable&lt;/em&gt; and, if a yt-dlp process exits, the orchestrator will &lt;em&gt;waitpid(2)&lt;/em&gt; on it and start a new worker. As it automatically restart workers the user is no longer required to babysit the download. Through careful selection of flags it can even start download a new video (with different id) should the streamer stop the stream and restart it on their end.&lt;/p&gt;
&lt;p&gt;This is obviously not a great solution. The underlying assumption is that if one process encounters a problem downloading a fragment the other processes &lt;em&gt;might&lt;/em&gt; be spared. The solution requires a lot of extra storage and a lot of extra network bandwidth. It might not even work that well if the stream encounters a problem though at least it will restart the download should it encounter a problem.&lt;/p&gt;
&lt;p&gt;For more information about the orchestrator see its separate article: &lt;a href=&#34;https://mvidell.se/posts/livestream---readme&#34;&gt;Livestream - README&lt;/a&gt;.&lt;/p&gt;
</description>
	</item>
	
	<item>
		<title>Braider</title>
		<link>https://mvidell.se/posts/braider/</link>
		<pubDate>Wed, 31 Dec 2025 00:00:00 +0000</pubDate>
		
		<guid>https://mvidell.se/posts/braider/</guid>
		<description>&lt;figure class=&#34;gallery&#34;&gt;
    
    
    
    &lt;a href=&#34;braider2.png&#34;&gt;&lt;img src=&#34;braider2.png&#34; /&gt;&lt;/a&gt;
    

    
    
    &lt;a href=&#34;braider3.png&#34;&gt;&lt;img src=&#34;braider3.png&#34; /&gt;&lt;/a&gt;
    


    
    &lt;figcaption&gt;An old a new screenshot of &lt;a href=&#34;https://mvidell.se/braider/prototype&#34;&gt;the prototype&lt;/a&gt;.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Problem: I want to browse videos from several YouTube channels in chronological
order within a given date range. You would think that YouTube would make this
easy, but it is not. It is especially hard if the channels in question publish
a lot of videos and the time in question is several years ago.&lt;/p&gt;
&lt;p&gt;Using my prototype, Braider, you can browse thousands of videos from multiple
channels, including sorting videos on different values such as the number of
views or length. If you tried to browse YouTube in your browser like this you
would need multiple tabs each requiring 400+ MiB of memory.&lt;/p&gt;
&lt;p&gt;The prototype features&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a simple text search that matches titles and descriptions.&lt;/li&gt;
&lt;li&gt;the ability to filter channels using mute and solo-pattern &lt;a href=&#34;https://youtu.be/r9eQth4Q5jg?t=158&#34;&gt;adapted from
remedybg&lt;/a&gt; and DAWs.&lt;/li&gt;
&lt;li&gt;an interactive histogram that shows the number of videos released in
year-month buckets.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;centering&lt;/em&gt; on videos. Use the sidebar to filter the videos, highlight &lt;em&gt;one&lt;/em&gt;
of the shown videos and then reset the filter. The selected video is now
shown in the context of the full braid.&lt;/li&gt;
&lt;li&gt;a JavaScript test suite using my own implementation of the describe-it-should
test pattern.&lt;/li&gt;
&lt;li&gt;an incredibly fast interface compared to YouTube.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are some limitations in the prototype.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Braids are currently hardcoded and is currently not user friendly to
generate new ones.&lt;/li&gt;
&lt;li&gt;The web client does not support varying resolutions. It will not look or
function good on mobile.&lt;/li&gt;
&lt;li&gt;YouTube might not like websites that embed many videos and the iframes
sometimes produces errors.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Examples of what questions you could answer using Braider.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What is ThePrimeagen&amp;rsquo;s most popular video in the first quarter of 2025?&lt;/li&gt;
&lt;li&gt;Limited Life was a subseries that occurred during H9. How many videos were
published in that series? Which video is the most viewed?&lt;/li&gt;
&lt;li&gt;Simon biked the Marcher Castles Way on GCN in 2025. Find the GCN Tech
followup video that was published the day after.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is mostly a proof of concept/early prototype. I wanted the user to be able
to input a list of channels and it would then fetch all videos (with
client-side JavaScript) and then display them. But it seems like that is not
possible(?), or it is at least not straight forward due to security concerns.&lt;/p&gt;
&lt;p&gt;It is written in JavaScript (yuck) but I tried to make it better and more
pleasant using&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pure JavaScript without using any dependencies or npm-hell.&lt;/li&gt;
&lt;li&gt;ample use of &lt;a href=&#34;https://jsdoc.app/&#34;&gt;JSDoc&lt;/a&gt; for type hints.&lt;/li&gt;
&lt;li&gt;an LSP (ts_ls) which catches errors and type checks.&lt;/li&gt;
&lt;li&gt;the Chrome debugger.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Check out &lt;a href=&#34;https://mvidell.se/braider/prototype/&#34;&gt;YouTube Braider Prototype&lt;/a&gt; multiple hardcoded braids.&lt;/p&gt;
</description>
	</item>
	
	<item>
		<title>A Study in (Linux) Timers</title>
		<link>https://mvidell.se/posts/timers/</link>
		<pubDate>Tue, 18 Feb 2025 00:21:58 +0200</pubDate>
		
		<guid>https://mvidell.se/posts/timers/</guid>
		<description>&lt;p&gt;I watched &lt;a href=&#34;https://www.youtube.com/@ThePrimeTimeagen&#34;&gt;ThePrimeagen&lt;/a&gt; do a
LeetCode problem where he was asked to implement &lt;code&gt;debounce&lt;/code&gt;. I realised that I
have no idea on how to do this in C. Therefore I set out to figure it out
and this is what I came up with.&lt;/p&gt;
&lt;h2 id=&#34;the-problem&#34;&gt;The Problem&lt;/h2&gt;

&lt;blockquote class=&#34;callout callout-quote callout-gray&#34;&gt;
    &lt;div class=&#34;callout-title&#34;&gt;
        &lt;div class=&#34;callout-icon&#34;&gt;📜&lt;/div&gt;
        &lt;div class=&#34;callout-title-inner&#34;&gt;2627. Debounce&lt;/div&gt;
    &lt;/div&gt;&lt;p&gt;Given a function &lt;code&gt;fn&lt;/code&gt; and a time in milliseconds &lt;code&gt;t&lt;/code&gt;, return a &lt;strong&gt;debounced&lt;/strong&gt;
version of that function.&lt;/p&gt;
&lt;p&gt;A &lt;strong&gt;debounced&lt;/strong&gt; function is a function whose execution is delayed by &lt;code&gt;t&lt;/code&gt;
milliseconds and whose execution is cancelled if it is called again within
that window of time. The debounced function should also receive the passed
parameters.&lt;/p&gt;
&lt;p&gt;For example, lets say &lt;code&gt;t = 50ms&lt;/code&gt;, and the function was called at &lt;code&gt;30ms&lt;/code&gt;,
&lt;code&gt;60ms&lt;/code&gt;, and &lt;code&gt;100ms&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The first 2 function calls would be cancelled, and the 3rd function call
would be executed at &lt;code&gt;150ms&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If instead &lt;code&gt;t = 35ms&lt;/code&gt;. The 1st function call would be cancelled, the 2nd
would be executed at &lt;code&gt;95ms&lt;/code&gt;, and the 3rd would be executed at &lt;code&gt;135ms&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;From LeetCode: &lt;a href=&#34;https://leetcode.com/problems/debounce/description/&#34;&gt;https://leetcode.com/problems/debounce/description/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;via ThePrimeagen: &lt;a href=&#34;https://youtu.be/nO7J6pBEkJw?t=4793&#34;&gt;https://youtu.be/nO7J6pBEkJw?t=4793&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;attempt-one-debounce_itimerh&#34;&gt;Attempt One: &lt;code&gt;debounce_itimer.h&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;The first thing I investigated was &lt;code&gt;getitimer(2)&lt;/code&gt; and &lt;code&gt;setitimer(2)&lt;/code&gt; which
sets an interval timer. When the timer expires a signal is raised and the
debounced function can be executed from the signal handler. I managed to get
it to work in &lt;code&gt;debounce_itimer.c&lt;/code&gt; but it has several limitations.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;There is only one interval timer which means that only one function can be
debounced at a time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;My solution relies on a lot of global data and boilerplate that is
necessary for each function that you want to debounce. This global data
reinforces the problem with 1: only one function can be debounced at a time.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Higher order functions in C is a mess. The ideal interface that I wanted is
the one suggested in LeetCode code skeleton: a function &lt;code&gt;dx = debounce(x)&lt;/code&gt;
where &lt;code&gt;x&lt;/code&gt; is a function and &lt;code&gt;dx&lt;/code&gt; is a debounced version of &lt;code&gt;x&lt;/code&gt;, but this is
hard to accomplish in C.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;An example usage of &lt;code&gt;debounce_itimer&lt;/code&gt; is&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;dadd&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;int&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;int&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;debounce_add&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;50&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;millisleep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;30&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;dadd&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;millisleep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;30&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;dadd&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;3&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;millisleep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;40&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;dadd&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;4&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is the only solution where I managed to have a function return a callable
function, but as you will notice it is not called &lt;code&gt;debounce&lt;/code&gt;. &lt;code&gt;debounce_add&lt;/code&gt;
is a manually created boilerplate function that must be created for every
function that you want to debounce.&lt;/p&gt;
&lt;p&gt;You could argue that C is not meant to have inner functions or overloaded
functions and that wrestling with it is counterproductive and whatever
solution you end up with is not &lt;em&gt;pythonic&lt;/em&gt; (but for C).&lt;/p&gt;
&lt;p&gt;Here is the boilerplate required.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;global_a&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;global_b&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;global_add_t&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// This function is run when the timer expires
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;add_alarm_handler&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;signum&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000&#34;&gt;add&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;global_a&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;global_b&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// This is the function that gets executed when the user calls the
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// debounced add. It sets global data, sighandler, and (re)starts the
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// timer.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;debouncer_add&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;a&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000&#34;&gt;global_a&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;a&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000&#34;&gt;global_b&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000&#34;&gt;set_signalhandler_and_clock&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;global_add_t&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;add_alarm_handler&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;debounce_add&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;t&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;))(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;int&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;int&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;global_add_t&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;t&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;debouncer_add&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;attempt-two-timeouth&#34;&gt;Attempt Two: &lt;code&gt;timeout.h&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;After a careful reading of &lt;code&gt;setitimer(2)&lt;/code&gt; it notes that &lt;code&gt;setitimer&lt;/code&gt; has been
obsoleted in favour of &lt;code&gt;timer_settime(2)&lt;/code&gt; and related functions.&lt;/p&gt;
&lt;p&gt;When ThePrimeagen solved this problem he did it using &lt;code&gt;setTimeout&lt;/code&gt; in
Javascript. Therefore, instead of going directly to implement &lt;code&gt;debounce&lt;/code&gt;, I
set out to first implement &lt;code&gt;setTimeout&lt;/code&gt; using &lt;code&gt;timer_settime(2)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Here is how to use it.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;timer_t&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;id&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;AddArgs&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;args&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;args&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;args&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;b&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;id&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;setTimeout&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;timeout_add&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;50&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;args&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This interface requires a struct &lt;code&gt;AddArgs&lt;/code&gt; that stores the parameters for the
timeouted function. It also requires a function &lt;code&gt;timeout_add&lt;/code&gt; which is
executed after the timer has expired and unpacks the struct and calls the
function &lt;code&gt;add&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;AddArgs&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;a&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;timeout_add&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;p&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;AddArgs&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;AddArgs&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;p&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000&#34;&gt;add&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;a&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;a&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;a&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Different this time is that when the timer expires it is possible to have the
timer start a new thread and execute the timeouted function in parallel
instead of concurrently. Or it is possible to continue using signals. Threads
is probably the superior option.&lt;/p&gt;
&lt;p&gt;The following code creates the timer with either a thread handler or a signal
handler.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;/**
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;     * Sets up a timer according to `USE_THREAD`.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;     */&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;setup_timer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;data&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;thread_handler&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;union&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;sigval&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;signal_handler&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;int&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;siginfo_t&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;void&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;timer_t&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;timerid&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;sigevent&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;sev&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000&#34;&gt;sev&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;sigev_value&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;sival_ptr&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;data&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;  &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// The data to be passed
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;#if USE_THREADS
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000&#34;&gt;assert&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;thread_handler&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000&#34;&gt;sev&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;sigev_notify&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;SIGEV_THREAD&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000&#34;&gt;sev&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;sigev_notify_function&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;thread_handler&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;#else
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000&#34;&gt;assert&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;signal_handler&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Establish signal handler for timer signal
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;sigaction&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;sa&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000&#34;&gt;sa&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;sa_flags&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;SA_SIGINFO&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000&#34;&gt;sa&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;sa_sigaction&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;signal_handler&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000&#34;&gt;sigemptyset&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;sa&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;sa_mask&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;sigaction&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;SIGTIMER&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;sa&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87&#34;&gt;NULL&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#000&#34;&gt;perror&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;sigaction&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000&#34;&gt;sev&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;sigev_notify&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;SIGEV_SIGNAL&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000&#34;&gt;sev&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;sigev_signo&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;SIGTIMER&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;#endif
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Create the timer
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;if&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;timer_create&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;CLOCKID&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;sev&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;timerid&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;==&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#000&#34;&gt;perror&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;timer_create&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;attempt-three-debounceh&#34;&gt;Attempt Three: &lt;code&gt;debounce.h&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;I was now ready to implement &lt;code&gt;debounce&lt;/code&gt; using &lt;code&gt;timeout.h&lt;/code&gt;, but as I started
doing this I realised that I did not want to use it. The code I had written to
implement &lt;code&gt;timeout.h&lt;/code&gt; was easily reused though to set up a timer and handlers.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;Debounce&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;dadd&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;dadd&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ms&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ts&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;i&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;];&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;dadd&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;fn&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;add_h&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;debounce&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;dadd&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;AddArgs&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;aa&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;b&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;0&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;AddArgs&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;bb&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;b&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;AddArgs&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;cc&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;.&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;b&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;2&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;millisleep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;30&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;debounce_call&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;dadd&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;aa&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;millisleep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;30&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;debounce_call&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;dadd&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;bb&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;millisleep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;40&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;debounce_call&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;dadd&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;cc&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This solution requires the user to fill in a struct &lt;code&gt;Debounce&lt;/code&gt; with the
function that is to be executed when the timer expires and the time until
expiration. The function expects to be of the format &lt;code&gt;void (*)(void*)&lt;/code&gt; and a
struct per debounced is still necessary for the parameters.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;AddArgs&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;a&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;add_h&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;void&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;p&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;AddArgs&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;a&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;struct&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;AddArgs&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;*&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;)&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;p&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#000&#34;&gt;add&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;a&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;a&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;a&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;b&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Different this time is mutexes. The Debounce struct contains a mutex since it
would be bad if the timer expires and the main thread changes the parameters
while the debounced function is executing.&lt;/p&gt;
&lt;h1 id=&#34;attempt-four-debounce2h&#34;&gt;Attempt Four: &lt;code&gt;debounce2.h&lt;/code&gt;&lt;/h1&gt;
&lt;p&gt;This time I wanted to do the crazy macro. I don&amp;rsquo;t know how to feel about these
macros. They make the interface better for the caller but is it worth the
cost. In this case I think it might. The macros that I made are quite
readable.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;debounce&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;dadd&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;add&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;50&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;millisleep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;30&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;debounce_add&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;dadd&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;0&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;millisleep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;30&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;debounce_add&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;dadd&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;1&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;millisleep&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;40&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;debounce_add&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;dadd&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#0000cf;font-weight:bold&#34;&gt;2&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The boilerplate necessary for this is&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;DEBOUNCEABLE2&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;add&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;int&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;int&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Where &lt;code&gt;DEBOUNCABLE2&lt;/code&gt; is a big macro that defines 3 things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;the struct &lt;code&gt;add_args&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;the handler function &lt;code&gt;add_h&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;and the debounce function &lt;code&gt;debounce_add&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The &lt;code&gt;2&lt;/code&gt; in &lt;code&gt;DEBOUNCABLE2&lt;/code&gt; refers to the number of parameters the function
takes. This means that a new macro has to be made for every function that
requires a new number of parameters. This is not as bad as it might seem. The
macros copy paste pretty easily and there is only a few lines that need
editing. But it would be nice if C supported better macros, with say recursion
or nested definitions.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;debounce&lt;/code&gt; is also a macro and it looks like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;#define debounce(Debounced, Function, Milliseconds)                         \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;        struct Function ## _args Debounced ## _args = {};                       \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;        struct Debounce Debounced = {};                                         \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;        Debounced.ms = Milliseconds;                                            \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;        Debounced.fn = Function ## _h;                                          \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;        Debounced.args = &amp;amp; Debounced ## _args;                                  \
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;        debounce(&amp;amp;Debounced);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It declares and fills in automatically the struct &lt;code&gt;Debounce&lt;/code&gt; from &lt;code&gt;debounce.h&lt;/code&gt;.
It also creates a struct &lt;code&gt;add_args&lt;/code&gt; where the parameters are stored.&lt;/p&gt;
&lt;p&gt;Unfortunately I don&amp;rsquo;t think it is possible to get the Javascript syntax of &lt;code&gt;dx = debounce(fn, t)&lt;/code&gt; because you would need to return a function from &lt;code&gt;debounce&lt;/code&gt;
which depends on the given function &lt;code&gt;fn&lt;/code&gt;. Perhaps if &lt;code&gt;debounce&lt;/code&gt; returned a
variadic function but that might be problematic if the user then accidentally
calls it with the wrong number of parameters.&lt;/p&gt;
&lt;h2 id=&#34;testing&#34;&gt;Testing&lt;/h2&gt;
&lt;p&gt;When &lt;code&gt;print&lt;/code&gt; and &lt;code&gt;add&lt;/code&gt; are executed they write an output string into a simple
buffer which contains the time since the testcase began. This made it easy to
then afterwards just parse the lines of this buffer and extract the timing to
check if it was correct. This was also protected by a mutex.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// Print also writes the string into `buffer` and advances `bindex`.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// This is so that the test-functions can easily assert on the timing
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#8f5902;font-style:italic&#34;&gt;// and argument `s`.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#204a87;font-weight:bold&#34;&gt;int&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;length&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;snprintf&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;buffer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;bindex&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;],&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;BUFFER_SIZE&lt;/span&gt;&lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;-&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;bindex&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;[%lf ms] Hello &amp;#39;%s&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;ms&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;s&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;bindex&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;+=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;length&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The assert reads this buffer with &lt;code&gt;sscanf(3)&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;&#34;&gt;&lt;code class=&#34;language-c&#34; data-lang=&#34;c&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000&#34;&gt;matches&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;=&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;sscanf&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;buffer&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;[&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;index&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;],&lt;/span&gt; &lt;span style=&#34;color:#4e9a06&#34;&gt;&amp;#34;[%f ms] Hello &amp;#39;%60[^]&amp;#39;]&amp;#39;&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;\n&lt;/span&gt;&lt;span style=&#34;color:#4e9a06&#34;&gt;%n&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;ms&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#000&#34;&gt;string&lt;/span&gt;&lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;,&lt;/span&gt; &lt;span style=&#34;color:#ce5c00;font-weight:bold&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&#34;color:#000&#34;&gt;bytes&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#000;font-weight:bold&#34;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What has not been easy to test is the mutexes and other race conditions.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Should you use this? Probably not.&lt;/li&gt;
&lt;li&gt;If only I had Jai&amp;hellip; Would be interesting with better metaprogramming.&lt;/li&gt;
&lt;li&gt;Download code code with &lt;code&gt;git clone https://mvidell.se/timers.git&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
</description>
	</item>
	
	<item>
		<title>cmpfiles</title>
		<link>https://mvidell.se/posts/cmpfiles/</link>
		<pubDate>Wed, 15 Mar 2023 00:00:00 +0000</pubDate>
		
		<guid>https://mvidell.se/posts/cmpfiles/</guid>
		<description>&lt;p&gt;I have a lot of old files and weird old copies that sometimes have similar
files but in slightly different file tree structures. As I wanted to remove
the duplicate files I wanted to make sure that the files actually were
duplicates and were safe to delete.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ tree
.
├── dir1
│   ├── a.txt
│   ├── b.txt
│   └── c.txt
└── dir2
    ├── dir3
    │   └── c.txt
    └── dir4
        ├── a.txt
        └── b.txt

5 directories, 6 files
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The above examples shows that two different directories with different file
tree structures. Comparing manually whether it is safe to delete &lt;code&gt;dir2&lt;/code&gt; (&lt;em&gt;i.e&lt;/em&gt;
if all files in &lt;code&gt;dir1&lt;/code&gt; is in &lt;code&gt;dir2&lt;/code&gt; and vice versa) can be time consuming.
&lt;code&gt;cmpfiles&lt;/code&gt; recursively traverses the file tree, hashes all files, and then
compares whether the tree produced the same hashes by sorting the list of
hashes.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ cmpfiles dir1/ dir2/
&amp;#39;dir1/c.txt&amp;#39; does not exist in &amp;#39;dir2&amp;#39;

&amp;#39;dir2/dir3/c.txt&amp;#39; does not exist in &amp;#39;dir1&amp;#39;

&amp;#39;dir1/a.txt&amp;#39; &amp;lt;=&amp;gt; &amp;#39;dir2/dir4/a.txt&amp;#39;
&amp;#39;dir1/b.txt&amp;#39; &amp;lt;=&amp;gt; &amp;#39;dir2/dir4/b.txt&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In this example &lt;code&gt;cmpfiles&lt;/code&gt; tells us that &lt;code&gt;dir1/c.txt&lt;/code&gt; and &lt;code&gt;dir2/dir3/c.txt&lt;/code&gt; are
not found in the other directory (because they have different hashes) and we
know that we should not remove these files before investigating this
discrepancy. One file could be an older version of the other file.&lt;/p&gt;
&lt;h2 id=&#34;help&#34;&gt;Help&lt;/h2&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Usage: cmpfiles [OPTION]... DIR1 DIR2
Compares the files in DIR1 to the files in DIR2

Compares the files (but not the file structure) by hashing each file in DIR1
and in DIR2, and then comparing them. It does not dereference symbolic links.

With no options, it produces output in three sections. The first section contains
the files that are in DIR1 and not in DIR2. The second section contains the
files that are in DIR2 and not in DIR1. The third section contains the files
that are in both DIR1 and DIR2.

If the program encounters duplicate files inside DIR1 (or inside DIR2) it
ignores these and outputs warnings to stderr.

  -1     Suppress first section  (files in DIR1 but not in DIR2)
  -2     Suppress second section (files in DIR2 but not in DIR1)
  -3     Suppress third section  (files in both DIR1 and DIR2)

  --md5          Use MD5 as hash function instead of SHA256
  -h, --help     Display this help and exit

Examples:
  cmpfiles -12 dir1 dir2  Print only files in both dir1 and dir2.
  cmpfiles -3  dir1 dir2  Print files in dir1 and not in dir2, and vice versa.

Somewhat inspired by comm(1).
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The code for the project can be downloaded with
&lt;code&gt;git clone https://mvidell.se/cmpfiles.git
&lt;/code&gt;.&lt;/p&gt;
</description>
	</item>
	
	<item>
		<title>pdftoc</title>
		<link>https://mvidell.se/posts/pdftoc/</link>
		<pubDate>Sun, 25 Sep 2022 00:00:00 +0000</pubDate>
		
		<guid>https://mvidell.se/posts/pdftoc/</guid>
		<description>&lt;figure class=&#34;gallery&#34;&gt;
    &lt;video controls preload=&#34;auto&#34; width=&#34;600&#34;&gt;
        &lt;source src=&#34;pdftoc-demo.mp4&#34; type=&#34;video/mp4&#34;/&gt;
    &lt;/video&gt;
    &lt;figcaption&gt;Printing and editing the contents of K&amp;amp;R.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;A quick draft written about the project.&lt;/p&gt;
&lt;p&gt;Problem: I have a lot of PDFs that I read, many of them do not have a
proper Table of Contents (called Outline in the PDF specification). I
wrote a Recursive Descent Parser (in C/C++) that parses the PDF file
to find the outline.&lt;/p&gt;
&lt;p&gt;You still have to do the hard work of writing the Table of Contents to
a file. The goal was that you should be able to just copy over the
Table of Contents inside the book (if it exists). Some care is needed
to set the ranges correctly. Many books start off with a roman numeral
section before page 1, e.g. in K&amp;amp;R (see demo) &lt;em&gt;Contents&lt;/em&gt;
starts on page &lt;em&gt;v&lt;/em&gt; and &lt;em&gt;Introduction&lt;/em&gt; on page 1 (15th page
in the PDF).&lt;/p&gt;
&lt;p&gt;The code for the project can be downloaded with
&lt;code&gt;git clone https://mvidell.se/pdftoc.git
&lt;/code&gt;&lt;/p&gt;
</description>
	</item>
	
	<item>
		<title>Sigmar&#39;s Garden Solver</title>
		<link>https://mvidell.se/posts/sigmar/</link>
		<pubDate>Thu, 18 Feb 2021 00:21:58 +0200</pubDate>
		
		<guid>https://mvidell.se/posts/sigmar/</guid>
		<description>

&lt;figure id=&#34;fig1&#34; class=&#34;gallery&#34;&gt;
    &lt;div&gt;
        &lt;a href=&#34;dexbonus.png&#34;&gt;&lt;img alt=&#34;dexbonus.png&#34; src=&#34;small-dexbonus.png&#34; /&gt;&lt;/a&gt;&lt;a href=&#34;dexbonus-solution.png&#34;&gt;&lt;img alt=&#34;dexbonus-solution.png&#34; src=&#34;small-dexbonus-solution.png&#34; /&gt;&lt;/a&gt;&lt;a href=&#34;dexbonus-information.png&#34;&gt;&lt;img alt=&#34;dexbonus-information.png&#34; src=&#34;small-dexbonus-information.png&#34; /&gt;&lt;/a&gt;
    &lt;/div&gt;
    &lt;video preload=&#34;metadata&#34; controls width=&#34;640&#34; height=&#34;360&#34;&gt;
        &lt;source src=&#34;opus-demo.mp4&#34; type=&#34;video/mp4&#34; /&gt;
    &lt;/video&gt;
    &lt;figcaption&gt;
        &lt;p&gt;
        Figure 1:

        The first image shows a starting game board. The in-game conversation
        introduces the game.

        The second image shows a computed solution outputted by drawing lines
        and numbers on the input image.

        The third image shows an information panel containing the axes in the
        grid in green and blue, the coordinates for each hexagon, the
        extracted features, and the predicted type of each marble.

        The screenshots were taken from a Youtube video by Dexbonus.
        &lt;/p&gt;
        &lt;p&gt;
        Video 1: A recording of the program solving 3 puzzles.
        &lt;/p&gt;
    &lt;/figcaption&gt;
&lt;/figure&gt;


&lt;h2 id=&#34;introduction&#34;&gt;INTRODUCTION&lt;/h2&gt;
&lt;p&gt;Sigmar&amp;rsquo;s Garden is a minigame in &lt;a href=&#34;https://www.zachtronics.com/opus-magnum/&#34;&gt;Opus Magnum&lt;/a&gt;, the puzzle game
developed by &lt;a href=&#34;https://www.zachtronics.com/&#34;&gt;Zachtronics&lt;/a&gt;. Sigmar&amp;rsquo;s Garden presents a hexagonal
board with different types of marbles and the goal is to match two
marbles with each other to remove them and clear the board. Each
marble represents an alchemical element and there are rules on how you
can match them. Importantly, only free marbles, marbles that have 3 or
more connected empty neighbours, can be used when matching. The full
ruleset as explained in the game can be seen in Fig 1.&lt;/p&gt;
&lt;p&gt;The game constantly teases you to win more games. First it requests you to win
a single game, then win 10 games, then win 25 games and so on. This drove me
crazy and I got the idea to make a program that solves them. Using OpenCV and
X11 libraries, the solver screenshots the game, classifies the marbles, finds
a solution, and performs the solution using mouse movements and clicks.&lt;/p&gt;
&lt;h2 id=&#34;technical-details&#34;&gt;TECHNICAL DETAILS&lt;/h2&gt;
&lt;p&gt;The project consists of a single cpp-file that is divided into several
sections: a hashset, the solver, the OpenCV section, the X11 section, and a
main section. I started writing the solver in C but after OpenCV was added the
code turned more into C++ and is now a weird mix between them.&lt;/p&gt;
&lt;p&gt;The hashset and the solver work together. The solver is a simple recursive
exhaustive search that identifies possible moves and performs a depth first
search over them. Each board state that is explored is inserted into the
hashset as memoization to prevent exploring previously explored states. This
works really well because it is easy to reach the same state multiple times.&lt;/p&gt;
&lt;p&gt;OpenCV is used in two different ways. It is used for manipulation of images
and for its Support Vector Machine (SVM) that I used to classify the marble
types. At first I thought that perhaps it is enough to just use simple
template matching in order to classify the marbles but a closer look shows
that the marbles all have slightly different lighting effects depending on
their position in the board. Having used OpenCVs SVM previously I just chose
to use this again.&lt;/p&gt;
&lt;p&gt;The SVM is trained on screenshots of the game from &lt;a href=&#34;https://www.youtube.com/watch?v=8ofUjsMVE94&#34;&gt;Jonathan
Blow&lt;/a&gt; and &lt;a href=&#34;https://www.youtube.com/watch?v=elemHy_kv8k&#34;&gt;Dexbonus&lt;/a&gt;. One problem that I
encountered is that the marbles have different sprites when they are
free or closed. This forced me to add screenshots of games in progress
so that there are samples of metals that are in the free state when
training the classifier.&lt;/p&gt;
&lt;p&gt;The hexagonal grid is created by hardcoding the pixel values for the center
and hexagonal width at 720p for reference. Using the hardcoded values a
hexagonal coordinate system can be built using two axes. A limitation this
causes is that all image inputs are expected to be in 16:9 aspect ratio or the
grid might not be properly aligned. Red Blob Games has an excellent resource
on &lt;a href=&#34;https://www.redblobgames.com/grids/hexagons/&#34;&gt;hexagonal grids&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Features are extracted by cropping a 24x24 pixel square from each hexagon.
These are preprocessed by converting the images to black and white, adding a
bit of gaussian blur and then an adaptive threshold filter.&lt;/p&gt;
&lt;p&gt;After classifying and solving a game the solver can output the solution in
text, by drawing on the input image as shown in &lt;a href=&#34;#fig1&#34;&gt;Fig 1&lt;/a&gt;,
or in the form of mouse movements and clicks using X11, the common windowing
system for Unix-like operating systems. The idea is that you bind the solver
to a global hotkey that when pressed executes the solver. The solver will then
take control of the mouse and perform movements and clicks inside the focused
window (presumably the game itself, but for testing purposes YouTube or images
work too, assuming they are correctly sized). The solver will press New Game
before it exits.&lt;/p&gt;
&lt;h2 id=&#34;results&#34;&gt;RESULTS&lt;/h2&gt;
&lt;p&gt;The solver managed to solve 100 games of Sigmar&amp;rsquo;s Garden with only minor
issues. Most games where solved is less than a second after invoking the
solver. The time to perform the solution is not included in this. Performing
the solution takes several seconds.&lt;/p&gt;
&lt;p&gt;A few games took slightly longer than a second to solve, and only one game
took more than 10 seconds to solve. That game also broke the hardcoded memory
limit which was increased by 4x and never reached again.&lt;/p&gt;
&lt;p&gt;During the trial there were no errors with classifying the different marbles.
It should be pointed out that all solved games were solved from the beginning,
and I expect that the biggest problem with the classifier is classifying the
free metal marbles in the later game. Another limitation is in the resolution
of the game. The solver could not manage 900p resolution of game, but 1080p
worked. This is because the resolution option in the game is not a simple
scaling.&lt;/p&gt;
&lt;h2 id=&#34;future-work&#34;&gt;FUTURE WORK&lt;/h2&gt;
&lt;p&gt;In the source code there are several comments regarding future and possible
TODO such as some suggestions on improving the hashset, the solving algorithm,
and improving the structure around labelled data for the SVM.&lt;/p&gt;
&lt;p&gt;A large improvement would be to remove OpenCV. OpenCV is a huge 100+ MiB
dependency and a massive overkill for this project. The image loading and
manipulating can probably be replaced by stb_image, lodepng, or similar, and
it is possible to write a new classifier relatively simply.&lt;/p&gt;
&lt;h2 id=&#34;build-and-usage&#34;&gt;BUILD AND USAGE&lt;/h2&gt;
&lt;p&gt;Download code with &lt;code&gt;git clone https://mvidell.se/sigmar.git
&lt;/code&gt; and build
&lt;code&gt;sigmars_garden&lt;/code&gt; using the included &lt;code&gt;build.sh&lt;/code&gt; script. On first start it will
train the classifier and save it to &lt;code&gt;sigmars_garden.svm&lt;/code&gt;. Try it using
&lt;code&gt;--images&lt;/code&gt; on the included training/test data!&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$ ./sigmars_garden --help
Usage:
sigmars_garden [options]
Starts interactive mode, screenshots focused window and performs a solution
with mouse movements and clicks. Recommended to either bind sigmars_garden to
global hotkey or use sleep to be able to focus a window before it screenshots
and performs a solution.

sigmars_garden [options] --images image...
Transcribes the marbles and solves the garden, outputs a solution to stdout
and shows an image of a solution. Will run out of memory when run with a large
amount of images.

sigmars_garden [options] --text
Reads 91 marbles from stdin separated by whitespace in format &amp;#39;QUICKSILVER
VITAE EARTH SALT EMPTY&amp;#39; etc (case insensitive) starting in top left corner,
reading left to right. Just copy a transcribed image and pipe it in!

Options:
--new-svm      Force generation of a new SVM
--old-rules    Solves the game with old rules (salt cannot match salt)
--verbose      Prints extra info
-h, --help     Shows this help and exits
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;references&#34;&gt;REFERENCES&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.zachtronics.com/opus-magnum/&#34;&gt;Opus Magnum by Zachtronics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=8ofUjsMVE94&#34;&gt;Jonathan Blow playing Opus Magnum&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=elemHy_kv8k&#34;&gt;Dexbonus playing Opus Magnum&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.redblobgames.com/grids/hexagons/&#34;&gt;Red Blob Games on hexagonal grids&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
	</item>
	
	<item>
		<title>Ultimate Tic-Tac-Toe</title>
		<link>https://mvidell.se/posts/toe/</link>
		<pubDate>Sat, 25 Jul 2020 00:00:00 +0000</pubDate>
		
		<guid>https://mvidell.se/posts/toe/</guid>
		<description>&lt;figure class=&#34;gallery&#34;&gt;
    
    
    
    &lt;a href=&#34;https://mvidell.se/toe/angular/toe.png&#34;&gt;&lt;img src=&#34;https://mvidell.se/toe/angular/toe.png&#34; /&gt;&lt;/a&gt;
    

    
    
    &lt;a href=&#34;https://mvidell.se/toe/vue/toe.png&#34;&gt;&lt;img src=&#34;https://mvidell.se/toe/vue/toe.png&#34; /&gt;&lt;/a&gt;
    

    
    
    &lt;a href=&#34;https://mvidell.se/toe/svelte/toe.png&#34;&gt;&lt;img src=&#34;https://mvidell.se/toe/svelte/toe.png&#34; /&gt;&lt;/a&gt;
    


    
    &lt;figcaption&gt;Screenshots of the three different implementations. From left to right: AngularJS, Vue.js, Svelte.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Ultimate Tic Tac Toe is a more advanced variation on the
ordinary tic-tac-toe. The game is divided into 3-by-3 boxes
and each box contains an ordinary game of tic-tac-toe.&lt;/p&gt;
&lt;p&gt;The goal of the game is to win three small games of
tic-tac-toe so that the winning boards create three-in-a-row
in the larger game. But there is a catch.&lt;/p&gt;
&lt;p&gt;After a player has made their move by placing their piece in a
cell in a board, the following player can only make a move in
the board corresponding to the cell that the previous person
played in.&lt;/p&gt;
&lt;p&gt;Implementing Ultimate Tic-Tac-Toe has for me become a sort
intermediate test of web development frameworks and libraries.
I have made three different implementations of Ultimate Tic
Tac Toe. The first was made in AngularJS when it starting to
get popular (2013?). The second implementation was made
with Vue.js in 2017, and the third one was made with Svelte in
2020.&lt;/p&gt;
&lt;p&gt;Of the different framworks Svelte is definitely my favorite.&lt;/p&gt;
&lt;h2 id=&#34;links&#34;&gt;Links&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://mvidell.se/toe/angular/&#34;&gt;AngularJS implementation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://mvidell.se/toe/vue/&#34;&gt;Vue.js implementation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://mvidell.se/toe/svelte/&#34;&gt;Svelte implementation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
	</item>
	
	<item>
		<title>Kattis Submissions</title>
		<link>https://mvidell.se/posts/kattis/</link>
		<pubDate>Wed, 25 Jul 2018 00:00:00 +0000</pubDate>
		
		<guid>https://mvidell.se/posts/kattis/</guid>
		<description>&lt;p&gt;This is an incomplete list of problems that I have solved on
&lt;a href=&#34;https://kth.kattis.com/&#34;&gt;kth.kattis.com&lt;/a&gt;. Kattis is
a service used for evaluating solutions to programming
problems and was frequently used in my education. Most of the
problems listed here have been solved using Python or C++.&lt;/p&gt;
&lt;p&gt;Most problems were solved as part of the &amp;lsquo;Problem Solving and
Programming Under Pressure&amp;rsquo; course i took in 2015 (popup15). In the
course we implemented many algorithms and data structures such as
graph algorithms (e.g. shortest path, maximum flow), number theory
(e.g. Chinese remainder, prime sieve), and dynamic programming. The
problems marked with (*) were classified as harder problems in that
course.&lt;/p&gt;
&lt;p&gt;Since many problems are still used in education my solutions
are not publicly available. Kattis still lists me on the
high score lists on some of the problems (in Metadata &amp;gt; Statistics).&lt;/p&gt;
&lt;p&gt;PS: Some links have been changed and you are now (sometimes)
required to click on a course (e.g. popup15). The course you click on
does not seem to matter though, they seem to lead to the same problem
text and statistics.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/problems/kth.ai.checkers&#34;&gt;Checkers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/problems/chopwood&#34;&gt;(*) Chopping Wood&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/problems/classpicture&#34;&gt;Class Picture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/problems/councilling&#34;&gt;(*) Councilling&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/problems/deadfraction&#34;&gt;(*) Dead Fraction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/problems/kth.ai.duckhunt&#34;&gt;Duck Hunt&lt;/a&gt; (see also &lt;a href=&#34;https://mvidell.se/posts/duck-hunt&#34;&gt;Duck Hunt&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/problems/ecoins&#34;&gt;e-Coins&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/problems/escapeplan&#34;&gt;Escape Plan&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/problems/factovisors&#34;&gt;Factovisors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/problems/fulltank&#34;&gt;Full Tank?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/problems/gears&#34;&gt;(*) Gears in Action&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/problems/getshorty&#34;&gt;Get Shorty&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/problems/hidingplaces&#34;&gt;Hiding Places&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/problems/caching&#34;&gt;(*) Introspective Caching&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/problems/jednakost&#34;&gt;Jednakost&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/problems/moviecollection&#34;&gt;(*) Movie Collection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/problems/phonelist&#34;&gt;Phone List&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/problems/risk&#34;&gt;(*) Risk&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/problems/spiderman&#34;&gt;Spiderman&amp;rsquo;s Workout&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/problems/streamstats&#34;&gt;Streaming Statistics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/problems/threedigits&#34;&gt;Three Digits&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/problems/railway&#34;&gt;Toy Railway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/problems/xyzzy&#34;&gt;XYZZY&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/problems/satisfiability&#34;&gt;Yet Satisfiability Again!&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&#34;https://kth.kattis.com/courses/DD2458/popup15&#34;&gt;Full list of problems for popup15&lt;/a&gt;&lt;/p&gt;
</description>
	</item>
	
	<item>
		<title>Quadratic Sieve</title>
		<link>https://mvidell.se/posts/qs/</link>
		<pubDate>Sat, 14 Oct 2017 00:00:00 +0000</pubDate>
		
		<guid>https://mvidell.se/posts/qs/</guid>
		<description>&lt;p&gt;To be written&amp;hellip;&lt;/p&gt;
</description>
	</item>
	
	<item>
		<title>Duck Hunt</title>
		<link>https://mvidell.se/posts/duck-hunt/</link>
		<pubDate>Tue, 25 Jul 2017 00:00:00 +0000</pubDate>
		
		<guid>https://mvidell.se/posts/duck-hunt/</guid>
		<description>&lt;p&gt;This was an assignment in our Artificial Intelligence course.
The goal was to use hidden markov models to classify different
species of birds and predict their next movements in a
simulated version of the game Duck Hunt.&lt;/p&gt;
&lt;p&gt;Solutions were tested in several rounds in different
environments. Each round is 100 time slices long and during
each slice you could choose to fire at a bird by predicting
its next move. If you missed you lost a point, and if you
hit you gained a point. However, if you shoot the Black Stork
you lose all points in that environment.&lt;/p&gt;
&lt;p&gt;After each round you can guess the species of each bird.
Guessing correct gains you a point and incorrect loses a
point. After guessing you receive the correct answer allowing
you to learn each species behavior. Guessing the species is
where most points you earn come from.&lt;/p&gt;
&lt;p&gt;In this assignment we implemented Hidden Markov Models
including the forward, backwards, and viterbi-algorithms, and
correctly applied them to the problem. My highscore is 399.
Since this problem is still used in education I have not
released my solution.&lt;/p&gt;
&lt;h2 id=&#34;links&#34;&gt;Links&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://kth.kattis.com/courses/DD2380/ai13/assignments/qe8dko/problems/kth.ai.duckhunt&#34;&gt;Duck Hunt assignment on Kattis&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://mvidell.se/posts/kattis&#34;&gt;My other Kattis submissions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
	</item>
	
	<item>
		<title>C Command Shell</title>
		<link>https://mvidell.se/posts/shell/</link>
		<pubDate>Sun, 13 Dec 2015 00:00:00 +0000</pubDate>
		
		<guid>https://mvidell.se/posts/shell/</guid>
		<description>&lt;p&gt;To be written&amp;hellip;&lt;/p&gt;
</description>
	</item>
	
	<item>
		<title>Playhouse</title>
		<link>https://mvidell.se/posts/playhouse/</link>
		<pubDate>Mon, 27 Oct 2014 00:00:00 +0000</pubDate>
		
		<guid>https://mvidell.se/posts/playhouse/</guid>
		<description>&lt;figure class=&#34;gallery&#34;&gt;
    
    
    
    &lt;a href=&#34;Playthehouse_DN.jpg&#34;&gt;&lt;img src=&#34;Playthehouse_DN.jpg&#34; /&gt;&lt;/a&gt;
    

    
    
    &lt;a href=&#34;Playthehouse_Lockerdome.png&#34;&gt;&lt;img src=&#34;Playthehouse_Lockerdome.png&#34; /&gt;&lt;/a&gt;
    


    
    &lt;figcaption&gt;Press clippings from the project.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Playhouse was a large group project (9 people) to use Philips
Hue lightbulbs to play animations and interactive games in the
windows of buildings. The project was part of our education in
a software development course and was made in collaboration with
artist Håkan Lidbo.&lt;/p&gt;
&lt;p&gt;Philips Hue lightbulbs are capable changing colours in RGB
spectrum and can be controlled with an API by sending web
requests to the included wireless bridges. The goal was to
create animations and simple games such as mastermind and
tic-tac-toe that can be played by users in their mobile
browser.&lt;/p&gt;
&lt;p&gt;We created two web servers written in Python using Tornado.
The lamp server controls the lamps directly by sending web
requests to the bridges. The second server handles the
communication between users and the lamp server. It serves the
webpages, communicates actions using websockets, handles game
logic and sends commands to the lamp server.&lt;/p&gt;
&lt;p&gt;In the fall of 2014 the project continued and we installed it
in the newly built NOD building in Kista, as part of its
inauguration.&lt;/p&gt;
&lt;h2 id=&#34;links&#34;&gt;Links&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/smab/&#34;&gt;Github repositories&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
	</item>
	
	<item>
		<title>DCPU Game of Life</title>
		<link>https://mvidell.se/posts/dcpu/</link>
		<pubDate>Sun, 27 May 2012 00:00:00 +0000</pubDate>
		
		<guid>https://mvidell.se/posts/dcpu/</guid>
		<description>&lt;figure class=&#34;gallery&#34;&gt;
    &lt;video controls preload=&#34;auto&#34; width=&#34;600&#34;&gt;
        &lt;source src=&#34;acorn.mp4&#34; type=&#34;video/mp4&#34;/&gt;
    &lt;/video&gt;
    &lt;figcaption&gt;Runnning &lt;code&gt;acorn&lt;/code&gt; pattern in DCPU-IDE.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;After his success with Minecraft, Markus &amp;lsquo;Notch&amp;rsquo; Persson
announced a new game called 0x10c. It was designed to be a
science fiction sandbox that included a virtual computer and
virtual hardware peripherals that Notch himself had designed
the specifications for.&lt;/p&gt;
&lt;p&gt;I thought the concept was interesting and decided to implement
Conway&amp;rsquo;s Game of Life written in DCPU, the assembly-like
language created for the virtual computer and output the
result on the virtual monitor called LEM1802.&lt;/p&gt;
&lt;p&gt;The monitor is divided into 32x12 characters and each character is divided into
4x8 pixels. A program can print characters using a program-defined alphabet of
128 characters. The characters are all monochrome and each character is defined
by setting each pixel to be either foreground or background colour.&lt;/p&gt;
&lt;p&gt;One way to implement Game of Life would be to have one Game of
Life cell per character for a total of 32x12 = 384 cells, but
I wanted to divide each character into 2x4 cells (each cell
would be 2x2 pixels) for a total of 64x48 = 3072 cells.&lt;/p&gt;
&lt;p&gt;However, 8 cells per character means 2^8 = 256
different combinations, double the available alphabet. I
managed to solve this problem by utilising that each character
can be printed in normal or inverted colours, effectively
doubling the available alphabet if it is generated correctly.
I used the last cell as a sort of sign bit (inspired by Two&amp;rsquo;s
complement used to store signed integers) to determine whether
the character should be printed in normal or in inverted
colours.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;all-in-one.s&lt;/code&gt; source file is a
concatenation of all source files, to simplify copying and pasting
into the online emulator I used when creating this.&lt;/p&gt;
&lt;p&gt;Includes two premade patterns, a glider and acorn. To change
to acorn edit the line &lt;code&gt;JSR write_glider&lt;/code&gt; to &lt;code&gt;JSR write_acorn&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;links&#34;&gt;Links&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;all-in-one.s&#34;&gt;all-in-one.s&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://dcpu-ide.com/&#34;&gt;DCPU-IDE&lt;/a&gt; (&lt;a href=&#34;https://web.archive.org/web/20210125092343/http://www.dcpu-ide.com/&#34;&gt;archived&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/lucaspiller/dcpu-specifications&#34;&gt;DCPU Specification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://mvidell.se/posts/square-dino&#34;&gt;Square Dino (Game of Life in Java and Swing)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life&#34;&gt;Conway&amp;rsquo;s Game of Life on Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
	</item>
	
	<item>
		<title>Square Dino</title>
		<link>https://mvidell.se/posts/square-dino/</link>
		<pubDate>Fri, 27 Apr 2012 00:00:00 +0000</pubDate>
		
		<guid>https://mvidell.se/posts/square-dino/</guid>
		<description>&lt;figure class=&#34;gallery&#34;&gt;
    
    
    
    &lt;a href=&#34;sd.png&#34;&gt;&lt;img src=&#34;sd.png&#34; /&gt;&lt;/a&gt;
    


    
    &lt;figcaption&gt;Screenshot of Square Dino.&lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;Square Dino is a program that runs Conway&amp;rsquo;s Game of Life. It
was created with a friend of mine in the end of spring 2012 as
the last project in our introductory course in programming.
The course completely focused on Java and object oriented
programming.&lt;/p&gt;
&lt;p&gt;A reqirement in the project was using Swing, the GUI widget
toolkit. This was no problem for us as we had previous
experience in it and decided to go far beyond the
requirements.&lt;/p&gt;
&lt;p&gt;We added many features including import and exporting to file,
changing ruleset, and a backend using QuadTrees.&lt;/p&gt;
&lt;h2 id=&#34;features&#34;&gt;Features&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Modular interface using Swing Toolbox.&lt;/li&gt;
&lt;li&gt;Importing and exporting of patterns using a common format.&lt;/li&gt;
&lt;li&gt;Change the rules of when cells are born or die.&lt;/li&gt;
&lt;li&gt;Copy and paste selected areas.&lt;/li&gt;
&lt;li&gt;Infinite board.&lt;/li&gt;
&lt;li&gt;Zoom and pan.&lt;/li&gt;
&lt;li&gt;Graph of population.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;instructions&#34;&gt;Instructions&lt;/h2&gt;
&lt;p&gt;Build with &lt;code&gt;javac -d bin/ -cp src/ src/org/bitbucket/zetro/squaredino/SquareDino.java&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Execute with &lt;code&gt;java -cp bin/ org.bitbucket.zetro.squaredino.SquareDino&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;You should also be able to import it as a project in Eclipse and run it from there.&lt;/p&gt;
&lt;h2 id=&#34;links&#34;&gt;Links&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;square-dino.zip&#34;&gt;square-dino.zip&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://mvidell.se/posts/dcpu/&#34;&gt;Game of Life in DCPU&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life&#34;&gt;Conway&amp;rsquo;s Game of Life on Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
	</item>
	
	</channel>
</rss>
