<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>Artium Nihamkin's Blog</title><link href="http://www.nihamkin.com/" rel="alternate"></link><link href="http://www.nihamkin.com/feeds/all.atom.xml" rel="self"></link><id>http://www.nihamkin.com/</id><updated>2020-02-29T23:00:00+02:00</updated><subtitle>Software, Technology, Life</subtitle><entry><title>Boeing 787 Dreamliner and the Counter Overflow</title><link href="http://www.nihamkin.com/boeing-787-dreamliner-and-the-counter-overflow.html" rel="alternate"></link><published>2020-02-29T23:00:00+02:00</published><updated>2020-02-29T23:00:00+02:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2020-02-29:/boeing-787-dreamliner-and-the-counter-overflow.html</id><summary type="html">&lt;img alt="Photo of Boeing 787" class="align-center" src="files/dreamliner/The_Boeing_787_Dreamliner.jpg" style="width: 40%;" /&gt;
&lt;p&gt;This is another post in a series which covers famous software failures. Today's
failure is not very old nor it is very famous.&lt;/p&gt;
&lt;p&gt;In 2015, the &lt;em&gt;Federal Aviation Administration&lt;/em&gt; (FAA) issued and &lt;em&gt;Airworthiness
Derivative&lt;/em&gt; (AD) regarding Boeing's
flagship aircraft at that time, the 787 Dreamliner.&lt;/p&gt;
&lt;p&gt;In the AD, they &lt;a class="reference external" href="files/dreamliner/2015-10066.pdf"&gt;write …&lt;/a&gt;&lt;/p&gt;</summary><content type="html">&lt;img alt="Photo of Boeing 787" class="align-center" src="files/dreamliner/The_Boeing_787_Dreamliner.jpg" style="width: 40%;" /&gt;
&lt;p&gt;This is another post in a series which covers famous software failures. Today's
failure is not very old nor it is very famous.&lt;/p&gt;
&lt;p&gt;In 2015, the &lt;em&gt;Federal Aviation Administration&lt;/em&gt; (FAA) issued and &lt;em&gt;Airworthiness
Derivative&lt;/em&gt; (AD) regarding Boeing's
flagship aircraft at that time, the 787 Dreamliner.&lt;/p&gt;
&lt;p&gt;In the AD, they &lt;a class="reference external" href="files/dreamliner/2015-10066.pdf"&gt;write&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
We have been advised by Boeing of an issue identified during laboratory
testing.  The software counter internal to the generator control
units(GCUs) will overflow after 248 days of continuous power, causing that
GCU to go into failsafe mode. If the four main GCUs (associated with the
engine mounted generators) were powered up at the same time, after 248 days
of continuous power, all four GCUs will go into fail safe mode at the same
time, resulting in a loss of all AC electrical power regardless of flight
phase.&lt;/blockquote&gt;
&lt;p&gt;So what is going on here? Let's break down and analyze.&lt;/p&gt;
&lt;div class="section" id="discovery"&gt;
&lt;h2&gt;Discovery&lt;/h2&gt;
&lt;p&gt;First of all, this bug was discovered during lab testing. It was discovered
after the aircraft became operational. How is it possible? There are two
possible explanations that I can think of. First, it could have been discovered
during the testing of the next software version. Other explanation is that FAA
certifies aircraft even though the testing of the aircraft's components is not
complete at the time of the certification. Powering the aircraft's avionics
systems for such long period and checking that it still works properly can be
such test.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="ok-so-what-is-a-gcu"&gt;
&lt;h2&gt;Ok, so what is a &lt;em&gt;GCU&lt;/em&gt;?&lt;/h2&gt;
&lt;p&gt;It stands for &lt;em&gt;Generator Control Unit&lt;/em&gt;, this is an embedded device which
controls the generation of electric power produced by rotation of the engines.
Usually there is one generator for each engine but the Dreamliner has two.&lt;/p&gt;
&lt;p&gt;Loosing the GCUs can potentially lead to losing all power. On modern aircraft,
the pilot is not controlling the flight surfaces directly. Instead, stick and
throttle movements, along with a bunch of sensor data, are used as an input
into a flight computer. The computer calculates how the flight surfaces should
be moved and outputs commands to actuators. Without power, this process can not
work which means the pilot can not control the aircraft anymore.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="overflow"&gt;
&lt;h2&gt;Overflow&lt;/h2&gt;
&lt;p&gt;We also know that the GCUs went into a failsafe mode due to counter overflow
after 248 days. So what is so special about 248 days?&lt;/p&gt;
&lt;table border="1" class="colwidths-given docutils"&gt;
&lt;colgroup&gt;
&lt;col width="20%" /&gt;
&lt;col width="30%" /&gt;
&lt;col width="50%" /&gt;
&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;248 days&lt;/td&gt;
&lt;td&gt;248 X 24 X 3600 seconds&lt;/td&gt;
&lt;td&gt;2,142,720,000  ✕10 milliseconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class="formula"&gt;2&lt;sup&gt;31&lt;/sup&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;2,147,483,648&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;249 days&lt;/td&gt;
&lt;td&gt;249 X 24 X 3600 seconds&lt;/td&gt;
&lt;td&gt;2,151,360,000  ✕10 milliseconds&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Based on this, we can guess that this counter is 32 bit signed integer and it
is being incremented once every 10ms. Somewhere during the 248th day it
overflows. If all the GCUs on the aircraft start approximately at the same
time, they will go into failsafe mode at the same time and thus could leave the
aircraft without power. This is not fatal as there is a backup generator
powered by the flow of air which deploys in such situations. Nevertheless this
is a very dangerous situation.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="solution"&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;Until a software fix was ready, the AD requires aircraft operators to cycle
power to the GCUs every 120 days.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;AD Requirements&lt;/p&gt;
&lt;p&gt;This AD requires a repetitive maintenance task for electrical power deactivation.&lt;/p&gt;
&lt;p&gt;Interim Action&lt;/p&gt;
&lt;p&gt;We consider this AD interim action. The manufacturer is
currently developing a GCU software upgrade that will address the unsafe
condition identified in this AD. Once this software is developed, approved,
and available, we might consider additional rulemaking.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I don't know how common it is for an aircraft to operate for 120 days
continuously powering it's electrical systems. The 787 is not an aircraft that
you power off &amp;quot;at the end of the day&amp;quot;. There is no such concept at all as every
minute the aircraft is not in the air, the operator is losing money. It might
even go to maintenance while still being powered on.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="airbus-a350"&gt;
&lt;h2&gt;Airbus A350&lt;/h2&gt;
&lt;p&gt;In 2017, on the other side of the ocean, Airbus had a similar issue. This time
it was an overflow every 149 hours.&lt;/p&gt;
&lt;p&gt;For the sake of completeness hare is a &lt;a class="reference external" href="https://ad.easa.europa.eu/ad/2017-0129R1"&gt;link to the AD&lt;/a&gt; published by European Union
Aviation Safety Agency (EASA) and a similar table as for the 787 case:&lt;/p&gt;
&lt;table border="1" class="colwidths-given docutils"&gt;
&lt;colgroup&gt;
&lt;col width="20%" /&gt;
&lt;col width="30%" /&gt;
&lt;col width="50%" /&gt;
&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;149 hours&lt;/td&gt;
&lt;td&gt;149 X 3600 seconds&lt;/td&gt;
&lt;td&gt;536,400,000  ✕ milliseconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;span class="formula"&gt;2&lt;sup&gt;29&lt;/sup&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;td&gt;536,870,912&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;150 hours&lt;/td&gt;
&lt;td&gt;150 X 3600 seconds&lt;/td&gt;
&lt;td&gt;540,000,000  ✕ milliseconds&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;My guess is that the counter is a signed fixed point number with an LSB of
&lt;span class="formula"&gt;0.25&lt;/span&gt;, but this is of course just a speculation.&lt;/p&gt;
&lt;/div&gt;
</content><category term="Bugs"></category><category term="Embedded"></category><category term="Software Engineering"></category></entry><entry><title>Zune Leap Year Freeze</title><link href="http://www.nihamkin.com/zune-leap-year-freeze.html" rel="alternate"></link><published>2020-01-25T02:00:00+02:00</published><updated>2020-01-25T02:00:00+02:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2020-01-25:/zune-leap-year-freeze.html</id><summary type="html">&lt;p&gt;I am starting a new series of blog posts in which I will do analysis of famous
bugs and system design failures related to software. I will attempt to present
more technical analysis than what is available when reading about these
stories in the mainstream media.&lt;/p&gt;
&lt;p&gt;I love reading about …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I am starting a new series of blog posts in which I will do analysis of famous
bugs and system design failures related to software. I will attempt to present
more technical analysis than what is available when reading about these
stories in the mainstream media.&lt;/p&gt;
&lt;p&gt;I love reading about &amp;quot;failure&amp;quot; stories. It is a great entertainment but can
also be an educating experience which inspire me to think or do things
differently. Hope it will be relevant to you as well.&lt;/p&gt;
&lt;div class="section" id="zune"&gt;
&lt;h2&gt;Zune&lt;/h2&gt;
&lt;p&gt;&lt;a class="reference external" href="https://en.wikipedia.org/wiki/Zune_30"&gt;Zune 30&lt;/a&gt; was a 30GB media
players developed by Microsoft and released in 2006.  It was the era of the
iPod and Microsoft wanted a portable media player as well.&lt;/p&gt;
&lt;img alt="Photo of Zune30" class="align-center" src="files/zune/zune30.jpg" style="width: 40%;" /&gt;
&lt;p&gt;At midnight of December 31, 2008, all the millions of Zune 30 that Microsoft
sold started malfunctioning. When turned on, they would freeze on the loading
screen.&lt;/p&gt;
&lt;p&gt;Before looking at the code that caused the bug, lets understand how consumer
electronic products are usually developed.&lt;/p&gt;
&lt;p&gt;A hardware component manufacturer develops a component tailored for specific
product class. For example a DSP chip for surveillance cameras, a WIFI
communication chip for cell phones or a system on chip with all the necessary
peripherals for a portable media player.&lt;/p&gt;
&lt;p&gt;Along with this chip, the manufacturer develops a reference product. The design
of the reference product is released and includes design documents, schematics,
PCB layout and relevant code.&lt;/p&gt;
&lt;p&gt;A consumer product manufacturer will not do R&amp;amp;D from scratch, it will license
the reference design and &amp;quot;differentiate&amp;quot; it. Each manufacturer changes the
design slightly and thus we get a range of different product.&lt;/p&gt;
&lt;p&gt;In our case microsoft used the Freescale MC13783 chip. This chip handles
power management and audio and is designed specifically to be used in portable
media players.&lt;/p&gt;
&lt;img alt="Diagram of MC13783 chip" class="align-center" src="files/zune/MC13783_BD.jpg" style="width: 60%;" /&gt;
&lt;p&gt;Among other things, this chip handles the real time clock. This is a clock
powered by an auxiliary power source and is supposed to keep time when the
device is turned off.&lt;/p&gt;
&lt;p&gt;At startup, Zune's main processor would load the time from the real time clock
in days since 1980 and convert to a proper date (day, month, year).  Here is a
snippet of a driver code that does the conversion to the current year:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;BOOL&lt;/span&gt; &lt;span class="nf"&gt;ConvertDays&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UINT32&lt;/span&gt; &lt;span class="n"&gt;days&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SYSTEMTIME&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;lpTime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="n"&gt;year&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ORIGINYEAR&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="cm"&gt;/* = 1980 */&lt;/span&gt;

    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;days&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;365&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IsLeapYear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;year&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;days&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;366&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;days&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;366&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="n"&gt;year&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;days&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="mi"&gt;365&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="n"&gt;year&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Can you spot the bug?&lt;/p&gt;
&lt;p&gt;Before revealing the answer, let me help with some clues:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Zune froze, how can this snippet cause the device to freeze?&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;.&lt;/div&gt;
&lt;div class="line"&gt;.&lt;/div&gt;
&lt;div class="line"&gt;.&lt;/div&gt;
&lt;div class="line"&gt;.&lt;/div&gt;
&lt;div class="line"&gt;.&lt;/div&gt;
&lt;div class="line"&gt;.&lt;/div&gt;
&lt;div class="line"&gt;.&lt;/div&gt;
&lt;div class="line"&gt;.&lt;/div&gt;
&lt;/div&gt;
&lt;ol class="arabic simple" start="2"&gt;
&lt;li&gt;What is special about December 31?&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;.&lt;/div&gt;
&lt;div class="line"&gt;.&lt;/div&gt;
&lt;div class="line"&gt;.&lt;/div&gt;
&lt;div class="line"&gt;.&lt;/div&gt;
&lt;div class="line"&gt;.&lt;/div&gt;
&lt;div class="line"&gt;.&lt;/div&gt;
&lt;div class="line"&gt;.&lt;/div&gt;
&lt;div class="line"&gt;.&lt;/div&gt;
&lt;/div&gt;
&lt;ol class="arabic simple" start="3"&gt;
&lt;li&gt;What is special about 2008?&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="line-block"&gt;
&lt;div class="line"&gt;.&lt;/div&gt;
&lt;div class="line"&gt;.&lt;/div&gt;
&lt;div class="line"&gt;.&lt;/div&gt;
&lt;div class="line"&gt;.&lt;/div&gt;
&lt;div class="line"&gt;.&lt;/div&gt;
&lt;div class="line"&gt;.&lt;/div&gt;
&lt;div class="line"&gt;.&lt;/div&gt;
&lt;div class="line"&gt;.&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Let's address these three questions one by one. The freezing could have been
caused by an infinite loop. This happens if &lt;code&gt;days&lt;/code&gt; never gets smaller
than &lt;code&gt;366&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The date of this incident is December 31, which is the last day of the year. It
could be the 365th day of that year or if it is leap year it will be the 366th
day. Speaking of a leap year, 2008 was indeed a leap year.&lt;/p&gt;
&lt;p&gt;After several iterations of the while loop, we end up with &lt;code&gt;days&lt;/code&gt; equal
366. The code enters the first &lt;code&gt;if&lt;/code&gt; but does not enter the second. The
state during the execution of the next iteration is identical since nothing
has changed, and thus the loop will run infinitely.&lt;/p&gt;
&lt;!-- So why did not Zune reset itself? First we need to ask why should it have reset
itself. It is very common for embedded devices to have a *watchdog* components.
This is a special hardware component which needs to receive a signal from the
software running on the CPU that it is indeed running and not "stuck" in some
way. The operating system usually feeds the watchdog at context switches and it
can also be fed explicitly while executing specific time consuming operations. --&gt;
&lt;!--  --&gt;
&lt;p&gt;Full disclosure, &lt;a class="reference external" href="https://web.archive.org/web/20140105235759/http://www.zuneboards.com/forums/showthread.php?t=38143"&gt;here is a link&lt;/a&gt;
for reference I used for this blog post.&lt;/p&gt;
&lt;p&gt;Obviously this issue resolved itself on January the first. Until next leap year
at least, but I doubt there were many Zune users at that time.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="takeaway"&gt;
&lt;h2&gt;Takeaway&lt;/h2&gt;
&lt;p&gt;1. Non simple recalculation of the loop counter inside the body of the loop is
a smell. I have seen coding standards that forbid the use of &lt;code&gt;while&lt;/code&gt;
loops and force the &lt;code&gt;for&lt;/code&gt; loops to be &amp;quot;well formed&amp;quot;, partly because of
this reason.&lt;/p&gt;
&lt;p&gt;2. Time and date calculations are complicated and have a lot of edge cases. You
can watch &lt;a class="reference external" href="https://www.youtube.com/watch?v=-5wpm-gesOY"&gt;this video&lt;/a&gt; to get a
reinforcement of this view.&lt;/p&gt;
&lt;/div&gt;
</content><category term="Bugs"></category><category term="Embedded"></category><category term="Software Engineering"></category></entry><entry><title>Playing WAV Files on ESP8266</title><link href="http://www.nihamkin.com/playing-wav-files-on-esp8266.html" rel="alternate"></link><published>2019-09-15T03:00:00+03:00</published><updated>2019-09-15T03:00:00+03:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2019-09-15:/playing-wav-files-on-esp8266.html</id><summary type="html">&lt;p&gt;In the previous post, ESP8266 was playing music based on pitch sequences and a
recording of a sine wave. This is not sufficient for the speech sythesis
system. A method for playing WAV files is required.&lt;/p&gt;
&lt;p&gt;Fortunately, WAV format uses  PCM to represents the waveform. Thus the data can
be …&lt;/p&gt;</summary><content type="html">&lt;p&gt;In the previous post, ESP8266 was playing music based on pitch sequences and a
recording of a sine wave. This is not sufficient for the speech sythesis
system. A method for playing WAV files is required.&lt;/p&gt;
&lt;p&gt;Fortunately, WAV format uses  PCM to represents the waveform. Thus the data can
be directly fed into PCM5102.&lt;/p&gt;
&lt;p&gt;For a test, I synthesized a simple WAV file using desktop version of Festival.&lt;/p&gt;
&lt;audio controls="controls"&gt;
      &lt;source src="/files/esp8266/this_is_an_example_text.wav" type="audio/wav"&gt;
      Your browser does not support the &lt;code&gt;audio&lt;/code&gt; element.
&lt;/audio&gt;&lt;img alt="Graph of the generated data" class="align-center" src="files/esp8266/waveform.png" style="width: 50%;" /&gt;
&lt;p&gt;Next, I parsed this file using Python script. &lt;a class="reference external" href="http://soundfile.sapp.org/doc/WaveFormat/"&gt;This&lt;/a&gt; description of the WAV format was
very helpful.&lt;/p&gt;
&lt;p&gt;The script can be found at &lt;a class="reference external" href="https://gist.github.com/alkhimey/55eb4d4b03b680b1f5742ec513aeb071"&gt;this link&lt;/a&gt;. It's
input is a WAV file and it produces an H file looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#ifndef WAV_DATA&lt;/span&gt;
&lt;span class="cp"&gt;#define WAV_DATA&lt;/span&gt;

&lt;span class="cp"&gt;#define NUM_SAMPLES 33442&lt;/span&gt;
&lt;span class="cp"&gt;#define SAMPLE_RATE 16000&lt;/span&gt;

&lt;span class="kt"&gt;int16_t&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;NUM_SAMPLES&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;PROGMEM&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="p"&gt;....&lt;/span&gt; &lt;span class="c1"&gt;// samples&lt;/span&gt;

&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="cp"&gt;#endif&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Please keep in mind that I work with WAV files produced by Festival, and thus
the script assumes that the input WAV file has 1 channel and 16 bits per sample.
It can be extended to support any kind of WAV file. For me this was not worth
the effort since the script is used only for testing/experimenting.&lt;/p&gt;
&lt;p&gt;This H file is included into the most simple Arduino sketch:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;quot;ESP8266WiFi.h&amp;quot;&lt;/span&gt;&lt;span class="cp"&gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;quot;i2s.h&amp;quot;&lt;/span&gt;&lt;span class="cp"&gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;quot;i2s_reg.h&amp;quot;&lt;/span&gt;&lt;span class="cp"&gt;&lt;/span&gt;

&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;quot;wav_data.h&amp;quot;&lt;/span&gt;&lt;span class="cp"&gt;&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;system_update_cpu_freq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;160&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;i2s_begin&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;i2s_set_rate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SAMPLE_RATE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;size_t&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;NUM_SAMPLES&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;uint16_t&lt;/span&gt; &lt;span class="n"&gt;ua&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pgm_read_word_unaligned&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]));&lt;/span&gt;
        &lt;span class="kt"&gt;int16_t&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="n"&gt;memcpy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ua&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int16_t&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// reinterpret bits of unsigend into a signed value&lt;/span&gt;
        &lt;span class="n"&gt;i2s_write_lr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It looks straight forward except the use of &lt;code&gt;PROGMEM&lt;/code&gt; macro and the strange
memory access.&lt;/p&gt;
&lt;p&gt;The WAV file is too big to fit into ESP8266 RAM, therefore it has to be stored on
the FLASH and the samples have to be read from there. &lt;code&gt;PROGMEM&lt;/code&gt; macro
hides a compiler directive that tells it to put the &lt;code&gt;data&lt;/code&gt; array into the
&lt;code&gt;irom.text&lt;/code&gt; section.&lt;/p&gt;
&lt;p&gt;Although most of the ESP8266 FLASH is memory mapped, only 32 bit aligned access
is allowed. Since the samples in the array are 16 bit of length, it is not
possible to access individual array element even if the whole array is
correctly aligned.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;pgm_read_word_unaligned&lt;/code&gt; function is a built in way of accessing a
16 bit word from FLASH. Behind the scenes it calculate the aligned address,
retrieves a 32 bit value and returns only the relevant part of it in the form
of 16 bit unsigned value. The &lt;code&gt;memecpy&lt;/code&gt; call is just a portable way to
reinterpret the unsigned value into a signed value (that is what stored in the
data array in the first place).&lt;/p&gt;
&lt;p&gt;Since this is part of a project with a goal to run speech synthesis on the ESP
hardware, the next thing is to actually port &lt;a class="reference external" href="http://www.festvox.org/flite/"&gt;flite&lt;/a&gt; to ESP.&lt;/p&gt;
</content><category term="esp8266"></category><category term="arduino"></category><category term="embedded"></category><category term="wav"></category></entry><entry><title>PCM Audio on ESP8266 using the PCM5102 Chip</title><link href="http://www.nihamkin.com/pcm-audio-on-esp8266-using-the-pcm5102-chip.html" rel="alternate"></link><published>2019-08-22T23:00:00+03:00</published><updated>2019-08-22T23:00:00+03:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2019-08-22:/pcm-audio-on-esp8266-using-the-pcm5102-chip.html</id><summary type="html">&lt;p&gt;One of the projects I am currently working on is a text to speech system based
on ESP8266 (or more realistically - ESP32). It will utilize the CMU Flite
speech synthesis library. But a way to play back the synthesized waveform is
also required.&lt;/p&gt;
&lt;p&gt;For this propose, I will use a …&lt;/p&gt;</summary><content type="html">&lt;p&gt;One of the projects I am currently working on is a text to speech system based
on ESP8266 (or more realistically - ESP32). It will utilize the CMU Flite
speech synthesis library. But a way to play back the synthesized waveform is
also required.&lt;/p&gt;
&lt;p&gt;For this propose, I will use a &lt;a class="reference external" href="http://www.ti.com/lit/ds/slas764b/slas764b.pdf"&gt;PCM5102&lt;/a&gt; chip that will convert
digital data sent from the ESP8266 over I2S to analog signal that drive the
connected speaker.&lt;/p&gt;
&lt;img alt="Closeup of a PCM5102A breakout module." class="align-center" src="files/esp8266/pcm5102_closeup.jpg" style="width: 40%;" /&gt;
&lt;p&gt;ESP2866 has a hardware implemented I2S, so specific pins are required. Here is
the table showing the connections I have made.&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;colgroup&gt;
&lt;col width="36%" /&gt;
&lt;col width="31%" /&gt;
&lt;col width="33%" /&gt;
&lt;/colgroup&gt;
&lt;thead valign="bottom"&gt;
&lt;tr&gt;&lt;th class="head"&gt;ESP8266 Name&lt;/th&gt;
&lt;th class="head"&gt;ESP8266 IO&lt;/th&gt;
&lt;th class="head"&gt;PCM5102 Pin&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;MTDO&lt;/td&gt;
&lt;td&gt;IO 15&lt;/td&gt;
&lt;td&gt;BC(L)K&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;U0RXD&lt;/td&gt;
&lt;td&gt;IO  3&lt;/td&gt;
&lt;td&gt;DIN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;GPIO2&lt;/td&gt;
&lt;td&gt;IO  2&lt;/td&gt;
&lt;td&gt;L(R)CK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;Connect to 3.3V&lt;/td&gt;
&lt;td&gt;VIN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan="2"&gt;Connect to GND&lt;/td&gt;
&lt;td&gt;GND&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;If you want to use the other pins which control certain aspects of the chips
behavior, you can refer to the &lt;a class="reference external" href="http://www.ti.com/lit/ds/slas764b/slas764b.pdf"&gt;data-sheet&lt;/a&gt;. I did not connect any other
pin on the breakout board of the PCM5102.&lt;/p&gt;
&lt;p&gt;The full I2S protocol is explained on wikipedia better than anything I could
write. Here are few bullets to help you understand the code which appear later:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Data words are 16 bits two's complement.&lt;/li&gt;
&lt;li&gt;Each data word represents the magnitude of the wave front at specific point in time (this is called &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Pulse-code_modulation"&gt;PCM&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;There are two data words for each sample representing left and right channels.&lt;/li&gt;
&lt;li&gt;The sample rate is, as the name suggests, number of samples (and not words) per second.&lt;/li&gt;
&lt;li&gt;Here, I will not utilise stereo, so each sample's left and right channels will be identical.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ok, so first let's create 512 samples of a sine array using a python script:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;matplotlib.pylab&lt;/span&gt; &lt;span class="kn"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;plt&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;numpy&lt;/span&gt; &lt;span class="kn"&gt;as&lt;/span&gt; &lt;span class="nn"&gt;np&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;Yield successive n-sized chunks from l.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;SAMPLES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;512&lt;/span&gt;

&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;linspace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;pi&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SAMPLES&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;{0:#0{1}x}, &amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;

&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;plot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;plt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;show&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The above script prints the samples in a format suitable for embedding into a C
source file.&lt;/p&gt;
&lt;img alt="Graph of the generated data" class="align-center" src="files/esp8266/sine.png" style="width: 50%;" /&gt;
&lt;p&gt;Few things to notice:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;The graph does not look like a sinus. This is because we are looking at
unsigned values which represent signed data. So for example 0x8000 is actually
-32768.&lt;/li&gt;
&lt;li&gt;The start of the wave is at the value of 0, which represents the
diaphragm of the speaker at resting position. Other values would mean a
sudden jump to the requested position, which will add a little bit of noise.&lt;/li&gt;
&lt;li&gt;There is no no intention to use stereo. The same values will be sent to both
channels. Thus the &amp;quot;samples&amp;quot; are single data words and not pairs.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Using this data it will be possible to generate sine waves of
various frequencies (also known as &lt;em&gt;pitches&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;The ESP8266 implementation of Arduino environment has a built in library for
sending I2S data. All the function signatures can be found in &lt;a class="reference external" href="https://github.com/esp8266/Arduino/blob/master/cores/esp8266/i2s.h"&gt;i2s.h&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In the setup function, I set up the I2S to use 44100 Hz sample rate and the CPU
to run at 160 MHz:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;quot;ESP8266WiFi.h&amp;quot;&lt;/span&gt;&lt;span class="cp"&gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;quot;i2s.h&amp;quot;&lt;/span&gt;&lt;span class="cp"&gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;quot;i2s_reg.h&amp;quot;&lt;/span&gt;&lt;span class="cp"&gt;&lt;/span&gt;


&lt;span class="cp"&gt;#define RATE 44100&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="n"&gt;system_update_cpu_freq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;160&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;i2s_begin&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;i2s_set_rate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RATE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;On the ESP8266, I created a function that is similar to Arduino's &lt;a class="reference external" href="https://www.arduino.cc/reference/en/language/functions/advanced-io/tone/"&gt;tone&lt;/a&gt;
function. But this one is not a puny, square wave, piezzo buzzer driver:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#define SINE_SAMPLES 512&lt;/span&gt;

&lt;span class="kt"&gt;int16_t&lt;/span&gt; &lt;span class="n"&gt;sine&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;SINE_SAMPLES&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Paste here the generated samples from the python script&lt;/span&gt;

&lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;span class="cm"&gt;* Outputs a sine waveover I2S of the requested frequency for the&lt;/span&gt;
&lt;span class="cm"&gt;* requested duration of milliseconds.&lt;/span&gt;
&lt;span class="cm"&gt;*/&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;writeNote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uint32&lt;/span&gt; &lt;span class="n"&gt;freq&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;uint32&lt;/span&gt; &lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;freq&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;duration&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// Number of samples required for the requested duration&lt;/span&gt;
    &lt;span class="n"&gt;uint32&lt;/span&gt; &lt;span class="n"&gt;totalSamples&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;RATE&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Number of samples in full period of a sine wave for that particular frequency&lt;/span&gt;
    &lt;span class="n"&gt;uint32&lt;/span&gt; &lt;span class="n"&gt;samplesPerPeriod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;RATE&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;freq&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Round down total samples to an integer number of sine periods&lt;/span&gt;
    &lt;span class="n"&gt;totalSamples&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;totalSamples&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;samplesPerPeriod&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;samplesPerPeriod&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uint32&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;totalSamples&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;uint32&lt;/span&gt; &lt;span class="n"&gt;sampleIdx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;samplesPerPeriod&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;samplesPerPeriod&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SINE_SAMPLES&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;i2s_write_lr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;sine&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;sampleIdx&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;  &lt;span class="n"&gt;sine&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;sampleIdx&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You can hear in the following video, the tune of star wars played using
&lt;code&gt;writeNote&lt;/code&gt; function. The full source of the Arduino sketch can be found &lt;a class="reference external" href="https://gist.github.com/alkhimey/a705d563aaa9a470332e7ad5487d7d0e"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;div class="youtube youtube-16x9"&gt;&lt;iframe src="https://www.youtube.com/embed/bSYEUzV3nFE" allowfullscreen seamless frameBorder="0"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;p&gt;Next thing I will do is playing back WAV files. Stay &lt;em&gt;tuned&lt;/em&gt; ;)&lt;/p&gt;
</content><category term="esp8266"></category><category term="arduino"></category><category term="embedded"></category></entry><entry><title>Better TFT Library for ESP8266</title><link href="http://www.nihamkin.com/better-tft-library-for-esp8266.html" rel="alternate"></link><published>2019-08-20T03:00:00+03:00</published><updated>2019-08-20T03:00:00+03:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2019-08-20:/better-tft-library-for-esp8266.html</id><summary type="html">&lt;p&gt;In 2016 I wrote a &lt;a class="reference external" href="2016/03/04/connecting-esp8266-with-ili9341-tft-display/"&gt;tutorial&lt;/a&gt; about connecting
ESP8266 with an ili9341 TFT display. That tutorial suggested using Adafruit's
library modified to work with the ESP8266.&lt;/p&gt;
&lt;p&gt;Now I discovered that there is a much better library which is tailored for the
ESP8266. This library is called &lt;a class="reference external" href="https://github.com/Bodmer/TFT_eSPI"&gt;TFT_eSPI&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This library is …&lt;/p&gt;</summary><content type="html">&lt;p&gt;In 2016 I wrote a &lt;a class="reference external" href="2016/03/04/connecting-esp8266-with-ili9341-tft-display/"&gt;tutorial&lt;/a&gt; about connecting
ESP8266 with an ili9341 TFT display. That tutorial suggested using Adafruit's
library modified to work with the ESP8266.&lt;/p&gt;
&lt;p&gt;Now I discovered that there is a much better library which is tailored for the
ESP8266. This library is called &lt;a class="reference external" href="https://github.com/Bodmer/TFT_eSPI"&gt;TFT_eSPI&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This library is available from Arduino's library manager, thus the process of
installation is very easy.&lt;/p&gt;
&lt;img alt="TFT_eSPI in Arduino Library Manager." class="align-center" src="/files/esp8266/arduino_library_manager.png" /&gt;
&lt;p&gt;One thing to notice is that after installation, it is required to go to the file &lt;strong&gt;User_Setup.h&lt;/strong&gt; which is in the librarie's directory and edit it.
There are a lot of parameters there, the important are the definition of the ESP8266 pins that will be used for connecting the TFT display:&lt;/p&gt;
&lt;p&gt;For example, for my Lolin NodeMCU V3 I used the following configuration:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#define TFT_CS   PIN_D2  &lt;/span&gt;&lt;span class="c1"&gt;// Chip select control pin D8&lt;/span&gt;
&lt;span class="cp"&gt;#define TFT_DC   PIN_D1  &lt;/span&gt;&lt;span class="c1"&gt;// Data Command control pin&lt;/span&gt;
&lt;span class="c1"&gt;//#define TFT_RST  PIN_D4  // Reset pin (could connect to NodeMCU RST, see next line)&lt;/span&gt;
&lt;span class="cp"&gt;#define TFT_RST  -1&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Also check that ILI9341 driver is selected (TFT_eSPI supports several screen models):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;// Only define one driver, the other ones must be commented out&lt;/span&gt;
&lt;span class="cp"&gt;#define ILI9341_DRIVER&lt;/span&gt;
&lt;span class="c1"&gt;//#define ST7735_DRIVER      // Define additional parameters below for this display&lt;/span&gt;
&lt;span class="c1"&gt;//#define ILI9163_DRIVER     // Define additional parameters below for this display&lt;/span&gt;
&lt;span class="c1"&gt;//#define S6D02A1_DRIVER&lt;/span&gt;
&lt;span class="c1"&gt;//#define RPI_ILI9486_DRIVER // 20MHz maximum SPI&lt;/span&gt;
&lt;span class="c1"&gt;//#define HX8357D_DRIVER&lt;/span&gt;
&lt;span class="c1"&gt;//#define ILI9481_DRIVER&lt;/span&gt;
&lt;span class="c1"&gt;//#define ILI9486_DRIVER&lt;/span&gt;
&lt;span class="c1"&gt;//#define ILI9488_DRIVER     // WARNING: Do not connect ILI9488 display SDO to MISO if other devices share the SPI bus (TFT SDO does NOT tristate when CS is high)&lt;/span&gt;
&lt;span class="c1"&gt;//#define ST7789_DRIVER      // Full configuration option, define additional parameters below for this display&lt;/span&gt;
&lt;span class="c1"&gt;//#define ST7789_2_DRIVER    // Minimal configuration option, define additional parameters below for this display&lt;/span&gt;
&lt;span class="c1"&gt;//#define R61581_DRIVER&lt;/span&gt;
&lt;span class="c1"&gt;//#define RM68140_DRIVER&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The API is similar to Adafruit in most cases, but additionally TFT_eSPI has
more features like ability to draw Sprites.&lt;/p&gt;
&lt;p&gt;As a demonstration of how quicker it is, here are few comparisons of the
graphics test program. I tried several SPI frequencies, this can be controlled using the &lt;code&gt;#define SPI_FREQUENCY&lt;/code&gt; macro in &lt;em&gt;User_Setup.h&lt;/em&gt;.&lt;/p&gt;
&lt;div class="section" id="adafruit-ili9341-library"&gt;
&lt;h2&gt;Adafruit_ILI9341 Library&lt;/h2&gt;
&lt;blockquote&gt;
&lt;pre class="literal-block"&gt;
ILI9341 Test!
Display Power Mode: 0x94
MADCTL Mode: 0x48
Pixel Format: 0x5
Image Format: 0x80
Self Diagnostic: 0xC0
Benchmark                Time (microseconds)
Screen fill              1606040
Text                     92026
Lines                    809972
Horiz/Vert Lines         134436
Rectangles (outline)     85586
Rectangles (filled)      3329421
Circles (filled)         421733
Circles (outline)        356141
Triangles (outline)      184657
Triangles (filled)       1121997
Rounded rects (outline)  166946
Rounded rects (filled)   3330265
Done!
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class="section" id="tft-espi-with-spi-frequency-set-to-27000000"&gt;
&lt;h2&gt;TFT_eSPI with SPI_FREQUENCY set to 27000000&lt;/h2&gt;
&lt;blockquote&gt;
&lt;pre class="literal-block"&gt;
TFT_eSPI library test!
Benchmark                Time (microseconds)
Screen fill              237671
Text                     27003
Lines                    160091
Horiz/Vert Lines         20537
Rectangles (outline)     13842
Rectangles (filled)      487678
Circles (filled)         115760
Circles (outline)        101732
Triangles (outline)      37935
Triangles (filled)       194903
Rounded rects (outline)  48270
Rounded rects (filled)   554112
Done!
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class="section" id="tft-espi-with-spi-frequency-set-to-40000000"&gt;
&lt;h2&gt;TFT_eSPI with SPI_FREQUENCY set to 40000000&lt;/h2&gt;
&lt;blockquote&gt;
&lt;pre class="literal-block"&gt;
TFT_eSPI library test!
Benchmark                Time (microseconds)
Screen fill              161174
Text                     23332
Lines                    137703
Horiz/Vert Lines         14246
Rectangles (outline)     9835
Rectangles (filled)      330783
Circles (filled)         93076
Circles (outline)        87518
Triangles (outline)      32453
Triangles (filled)       142416
Rounded rects (outline)  39809
Rounded rects (filled)   380746
Done!
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class="section" id="tft-espi-with-spi-frequency-set-to-80000000"&gt;
&lt;h2&gt;TFT_eSPI with SPI_FREQUENCY set to 80000000&lt;/h2&gt;
&lt;blockquote&gt;
&lt;pre class="literal-block"&gt;
TFT_eSPI library test!
Benchmark                Time (microseconds)
Screen fill              84359
Text                     20697
Lines                    118085
Horiz/Vert Lines         7990
Rectangles (outline)     5913
Rectangles (filled)      173302
Circles (filled)         71464
Circles (outline)        78870
Triangles (outline)      27596
Triangles (filled)       91296
Rounded rects (outline)  33468
Rounded rects (filled)   207793
Done!
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
&lt;div class="section" id="tft-espi-with-spi-frequency-set-to-80000000-and-cpu-running-at-160-mhz"&gt;
&lt;h2&gt;TFT_eSPI with SPI_FREQUENCY set to 80000000 and CPU running at 160 MHz&lt;/h2&gt;
&lt;blockquote&gt;
&lt;pre class="literal-block"&gt;
TFT_eSPI library test!
Benchmark                Time (microseconds)
Screen fill              81344
Text                     13412
Lines                    79826
Horiz/Vert Lines         7326
Rectangles (outline)     5143
Rectangles (filled)      166979
Circles (filled)         51367
Circles (outline)        51259
Triangles (outline)      18983
Triangles (filled)       74893
Rounded rects (outline)  22796
Rounded rects (filled)   194053
Done!
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
</content><category term="esp8266"></category><category term="arduino"></category><category term="embedded"></category><category term="ili9341"></category></entry><entry><title>Building Text to Speech Service Based on Festival</title><link href="http://www.nihamkin.com/building-text-to-speech-service-based-on-festival.html" rel="alternate"></link><published>2019-06-14T13:00:00+03:00</published><updated>2019-06-14T13:00:00+03:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2019-06-14:/building-text-to-speech-service-based-on-festival.html</id><summary type="html">&lt;audio controls="controls"&gt;
      &lt;source src="/files/festival/intro.wav" type="audio/wav"&gt;
      Your browser does not support the &lt;code&gt;audio&lt;/code&gt; element.
&lt;/audio&gt;&lt;p&gt;Last week I participated in Hackathon where we built a demo of domain specific
personal assistant. One of the components of such system is the text to speech
component.&lt;/p&gt;
&lt;p&gt;In this post I will explain how I installed Festival speech synthesis system …&lt;/p&gt;</summary><content type="html">&lt;audio controls="controls"&gt;
      &lt;source src="/files/festival/intro.wav" type="audio/wav"&gt;
      Your browser does not support the &lt;code&gt;audio&lt;/code&gt; element.
&lt;/audio&gt;&lt;p&gt;Last week I participated in Hackathon where we built a demo of domain specific
personal assistant. One of the components of such system is the text to speech
component.&lt;/p&gt;
&lt;p&gt;In this post I will explain how I installed Festival speech synthesis system,
how I managed to alter the system to fit our specific domain requirements and
how I wrapped it with a Node.js server.&lt;/p&gt;
&lt;div class="section" id="festival"&gt;
&lt;h2&gt;Festival&lt;/h2&gt;
&lt;img alt="Festival logo" class="align-center" src="/files/festival/festival.jpg" /&gt;
&lt;p&gt;Festival is a speech synthesis system (also called speech to text, STT or S2T).
It has two maintainers and therefore two websites (which might be confusing a
bit):&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.cstr.ed.ac.uk/projects/festival/"&gt;The Center of Speech Technology Research - The University of Edinburgh&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference external" href="http://www.festvox.org/festival/index.html"&gt;Carnegie Mellon University Speech Group&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Another thing one should know about festival is the difference between Festival
and festvox. Festival is the speech synthesis system itself. On the other hand,
festvox is the name of a set of tools used to create voices for Festival.
Sometimes the whole project (Festival + festvox) are called by the festvox
name, so do not be confused.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="basic-installation-on-linux"&gt;
&lt;h2&gt;Basic Installation on Linux&lt;/h2&gt;
&lt;p&gt;Although Festival can be installed on some distributions from a package
manager like &lt;cite&gt;apt&lt;/cite&gt;, we will build it from source.&lt;/p&gt;
&lt;p&gt;I tested these instructions on Ubuntu 18.04 and 16.04.&lt;/p&gt;
&lt;p&gt;At the time of writing this blog post, the latest version of Festival is
&lt;strong&gt;2.5&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Got to &lt;a class="reference external" href="http://www.festvox.org/packed/festival/2.5/"&gt;http://www.festvox.org/packed/festival/2.5/&lt;/a&gt; and download &lt;strong&gt;all&lt;/strong&gt; five
&lt;cite&gt;tar.gz&lt;/cite&gt; archives that appear there.&lt;/p&gt;
&lt;p&gt;Additionally, got to the &lt;cite&gt;voices&lt;/cite&gt; subdirectory and
download:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;em&gt;festvox_kallpc16k.tar.gz&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;festvox_rablpc16k.tar.gz&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;festvox_cmu_us_awb_cg.tar.gz&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;festvox_cmu_us_awb_cg.tar.gz&lt;/em&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can download additional voices, but these are basic.&lt;/p&gt;
&lt;p&gt;Put all the files in a single directory.&lt;/p&gt;
&lt;p&gt;Now extract all the archive using the following command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;for&lt;/span&gt; a in &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="se"&gt;\l&lt;/span&gt;s -1 *.tar.gz&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; gzip -dc &lt;span class="nv"&gt;$a&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; tar xf -&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The directory structure will now look like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;~/Festival$ ls -l
total &lt;span class="m"&gt;126804&lt;/span&gt;
drwxr-xr-x  &lt;span class="m"&gt;9&lt;/span&gt; artium artium     &lt;span class="m"&gt;4096&lt;/span&gt; May &lt;span class="m"&gt;26&lt;/span&gt;  &lt;span class="m"&gt;2018&lt;/span&gt; festival
-rw-rw-r--  &lt;span class="m"&gt;1&lt;/span&gt; artium artium   &lt;span class="m"&gt;789013&lt;/span&gt; Jun  &lt;span class="m"&gt;8&lt;/span&gt; &lt;span class="m"&gt;13&lt;/span&gt;:49 festival-2.5.0-release.tar.gz
-rw-rw-r--  &lt;span class="m"&gt;1&lt;/span&gt; artium artium  &lt;span class="m"&gt;1925748&lt;/span&gt; Jun  &lt;span class="m"&gt;8&lt;/span&gt; &lt;span class="m"&gt;13&lt;/span&gt;:49 festlex_CMU.tar.gz
-rw-rw-r--  &lt;span class="m"&gt;1&lt;/span&gt; artium artium  &lt;span class="m"&gt;1474233&lt;/span&gt; Jun  &lt;span class="m"&gt;8&lt;/span&gt; &lt;span class="m"&gt;13&lt;/span&gt;:49 festlex_OALD.tar.gz
-rw-rw-r--  &lt;span class="m"&gt;1&lt;/span&gt; artium artium   &lt;span class="m"&gt;243656&lt;/span&gt; Jun  &lt;span class="m"&gt;8&lt;/span&gt; &lt;span class="m"&gt;13&lt;/span&gt;:49 festlex_POSLEX.tar.gz
-rw-rw-r--  &lt;span class="m"&gt;1&lt;/span&gt; artium artium &lt;span class="m"&gt;52653464&lt;/span&gt; Jun  &lt;span class="m"&gt;8&lt;/span&gt; &lt;span class="m"&gt;23&lt;/span&gt;:56 festvox_cmu_us_awb_cg.tar.gz
-rw-rw-r--  &lt;span class="m"&gt;1&lt;/span&gt; artium artium &lt;span class="m"&gt;61933982&lt;/span&gt; Jun  &lt;span class="m"&gt;8&lt;/span&gt; &lt;span class="m"&gt;23&lt;/span&gt;:56 festvox_cmu_us_rms_cg.tar.gz
-rw-rw-r--  &lt;span class="m"&gt;1&lt;/span&gt; artium artium  &lt;span class="m"&gt;4103663&lt;/span&gt; Jun  &lt;span class="m"&gt;8&lt;/span&gt; &lt;span class="m"&gt;13&lt;/span&gt;:49 festvox_kallpc16k.tar.gz
-rw-rw-r--  &lt;span class="m"&gt;1&lt;/span&gt; artium artium  &lt;span class="m"&gt;5369131&lt;/span&gt; Jun  &lt;span class="m"&gt;8&lt;/span&gt; &lt;span class="m"&gt;13&lt;/span&gt;:49 festvox_rablpc16k.tar.gz
drwxr-xr-x &lt;span class="m"&gt;23&lt;/span&gt; artium artium     &lt;span class="m"&gt;4096&lt;/span&gt; Jun  &lt;span class="m"&gt;8&lt;/span&gt; &lt;span class="m"&gt;23&lt;/span&gt;:50 speech_tools
-rw-rw-r--  &lt;span class="m"&gt;1&lt;/span&gt; artium artium  &lt;span class="m"&gt;1328624&lt;/span&gt; Jun  &lt;span class="m"&gt;8&lt;/span&gt; &lt;span class="m"&gt;13&lt;/span&gt;:49 speech_tools-2.5.0-release.tar.gz
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Notice that only two new directories were created. This is because all archives
share the same directory structure and thus when extracting files, they go into
the correct place inside &lt;em&gt;festival&lt;/em&gt; automatically.&lt;/p&gt;
&lt;p&gt;Now make sure &lt;em&gt;ncurses5&lt;/em&gt; is installed:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;sudo apt install libncurses5
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now go inside the &lt;code&gt;speech_tools&lt;/code&gt; directory and run:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;~/Festival/speech_tools$ ./configure
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Followed by:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;~/Festival/speech_tools$ make
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Just for reference, here is the compiler setup I used:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ gcc -v
Using built-in specs.
&lt;span class="nv"&gt;COLLECT_GCC&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gcc
&lt;span class="nv"&gt;COLLECT_LTO_WRAPPER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper
&lt;span class="nv"&gt;OFFLOAD_TARGET_NAMES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nvptx-none
&lt;span class="nv"&gt;OFFLOAD_TARGET_DEFAULT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Ubuntu 7.4.0-1ubuntu1~18.04&amp;#39;&lt;/span&gt; --with-bugurl&lt;span class="o"&gt;=&lt;/span&gt;file:///usr/share/doc/gcc-7/README.Bugs --enable-languages&lt;span class="o"&gt;=&lt;/span&gt;c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix&lt;span class="o"&gt;=&lt;/span&gt;/usr --with-gcc-major-version-only --program-suffix&lt;span class="o"&gt;=&lt;/span&gt;-7 --program-prefix&lt;span class="o"&gt;=&lt;/span&gt;x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir&lt;span class="o"&gt;=&lt;/span&gt;/usr/lib --without-included-gettext --enable-threads&lt;span class="o"&gt;=&lt;/span&gt;posix --libdir&lt;span class="o"&gt;=&lt;/span&gt;/usr/lib --enable-nls --with-sysroot&lt;span class="o"&gt;=&lt;/span&gt;/ --enable-clocale&lt;span class="o"&gt;=&lt;/span&gt;gnu --enable-libstdcxx-debug --enable-libstdcxx-time&lt;span class="o"&gt;=&lt;/span&gt;yes --with-default-libstdcxx-abi&lt;span class="o"&gt;=&lt;/span&gt;new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc&lt;span class="o"&gt;=&lt;/span&gt;auto --enable-multiarch --disable-werror --with-arch-32&lt;span class="o"&gt;=&lt;/span&gt;i686 --with-abi&lt;span class="o"&gt;=&lt;/span&gt;m64 --with-multilib-list&lt;span class="o"&gt;=&lt;/span&gt;m32,m64,mx32 --enable-multilib --with-tune&lt;span class="o"&gt;=&lt;/span&gt;generic --enable-offload-targets&lt;span class="o"&gt;=&lt;/span&gt;nvptx-none --without-cuda-driver --enable-checking&lt;span class="o"&gt;=&lt;/span&gt;release --build&lt;span class="o"&gt;=&lt;/span&gt;x86_64-linux-gnu --host&lt;span class="o"&gt;=&lt;/span&gt;x86_64-linux-gnu --target&lt;span class="o"&gt;=&lt;/span&gt;x86_64-linux-gnu
Thread model: posix
gcc version &lt;span class="m"&gt;7&lt;/span&gt;.4.0 &lt;span class="o"&gt;(&lt;/span&gt;Ubuntu &lt;span class="m"&gt;7&lt;/span&gt;.4.0-1ubuntu1~18.04&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After building &lt;code&gt;speech_tools&lt;/code&gt; it is possible to build &lt;em&gt;Festival&lt;/em&gt; itself.
There is no need to put &lt;code&gt;speech_tools/bin&lt;/code&gt; in the &lt;code&gt;PATH&lt;/code&gt; for this
purpose. Just make sure you follow the directory hierarchy I showed earlier.&lt;/p&gt;
&lt;p&gt;Run:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;~/Festival/festival$ ./configure
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Followed by:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;~/Festival/festival$ make
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;After building is finished, if you run &lt;code&gt;make test&lt;/code&gt; some tests will fail.
Some because the copyright message of the latests version was changed, some
because of missing voices and others because reasons I do not understand. For
reference, &lt;a class="reference external" href="/files/festival/test_results.txt"&gt;here&lt;/a&gt; is the output I got.&lt;/p&gt;
&lt;p&gt;These failing tests are not a no-go situation. We can use festival with no
problem. But first lets add it into &lt;code&gt;PATH&lt;/code&gt; (change the path of &lt;em&gt;bin&lt;/em&gt; to
reflect your location):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;:/home/artium/Festival/festival/bin
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now we can run &lt;code&gt;festival&lt;/code&gt; which will start the interpreter.&lt;/p&gt;
&lt;p&gt;Let's test it. Notice that to exit the interpreter you need to press
&lt;code&gt;Ctrl+ D&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nv"&gt;festival&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;SayText&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;hello&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;#&lt;/span&gt;&lt;span class="nv"&gt;&amp;lt;Utterance&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="nv"&gt;x7f25e1a58690&amp;gt;&lt;/span&gt;
&lt;span class="nv"&gt;festival&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;Linux:&lt;/span&gt; &lt;span class="nv"&gt;can&lt;/span&gt;&lt;span class="ss"&gt;&amp;#39;t&lt;/span&gt; &lt;span class="nv"&gt;open&lt;/span&gt; &lt;span class="nv"&gt;/dev/dsp&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;You probably does not hear anything and get this &lt;code&gt;can't open /dev/dsp&lt;/code&gt;
message. The reason is that Ubuntu does not have the &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Open_Sound_System"&gt;OSS&lt;/a&gt; modules by default. There
are two ways to solve this:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Install &lt;cite&gt;osspd&lt;/cite&gt; (&lt;code&gt;sudpo apt-get install osspd&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Tell festival to use &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Advanced_Linux_Sound_Architecture"&gt;ALSA&lt;/a&gt; for sound output.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The second solution is highly recommended. You need to open
&lt;code&gt;~/.festivalrc&lt;/code&gt; file and add these lines:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;Parameter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;set&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;Audio_Command&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;aplay -q -c 1 -t raw -f s16 -r $SR $FILE&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;Parameter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;set&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;Audio_Method&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;Audio_Command&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now running the &lt;code&gt;SayText&lt;/code&gt; command should output the speech through the
speakers or headphones. Make sure you have output device attached to the
computer.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="saving-to-file"&gt;
&lt;h2&gt;Saving to File&lt;/h2&gt;
&lt;p&gt;To save a &lt;em&gt;WAV&lt;/em&gt; file, many online tutorials recommend the &lt;cite&gt;text2wave&lt;/cite&gt; program
that was build along with festival. For me, running it gives a segfault, so
here is an alternative way using festival itself.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;utt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;save&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;wave&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;SayText&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;This is an example text&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;test.wav&amp;quot;&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;riff&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This method is ok for testing but the problem is that &lt;code&gt;SayText&lt;/code&gt; will
actually say the text and only then the file will be saved.&lt;/p&gt;
&lt;p&gt;Here is a  better way to accomplish the same task:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;set! &lt;/span&gt;&lt;span class="nv"&gt;utt1&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;Utterance&lt;/span&gt; &lt;span class="nv"&gt;Text&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;This is an example text&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;utt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;synth&lt;/span&gt; &lt;span class="nv"&gt;utt1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;utt&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;save&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;wave&lt;/span&gt; &lt;span class="nv"&gt;utt1&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;test2.wav&amp;quot;&lt;/span&gt; &lt;span class="ss"&gt;&amp;#39;riff&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="modifying-the-system"&gt;
&lt;h2&gt;Modifying the System&lt;/h2&gt;
&lt;p&gt;One of the requirements of our domain specific personal assistant is that
numbers should be pronounces digit by digit. For example the number &amp;quot;300.25&amp;quot;
should be pronounced &amp;quot;three zero zero two five&amp;quot; and not &amp;quot;three hundred dot
twenty five&amp;quot;&lt;/p&gt;
&lt;p&gt;Using &lt;a class="reference external" href="https://www.cs.cmu.edu/~awb/festival_demos/sable.html"&gt;SABLE&lt;/a&gt; markup it
is possible to use the &lt;code&gt;&amp;lt;SAYAS MODE=&amp;quot;literal&amp;quot;&amp;gt;&lt;/code&gt; tag. But I wanted this to
work with text mode not sable mode. I did not find a built-in way to tell
festival to use literal pronunciation when synthesizing an utterance. So I had
to implement it myself.&lt;/p&gt;
&lt;p&gt;I followed the &lt;a class="reference external" href="http://festvox.org/festtut/notes/festtut_toc.html"&gt;tutorial here&lt;/a&gt;
and used the &lt;a class="reference external" href="http://festvox.org/festtut/notes/festtut_5.html#SEC37"&gt;example on the bottom of chapter 5&lt;/a&gt;
to figure out what change should I make to festival.&lt;/p&gt;
&lt;p&gt;The result is the following code that should be executed after setting a voice.
I will not get into details of festival's architecture and Scheme syntax here.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;
&lt;span class="c1"&gt;;;                                                                 ;;&lt;/span&gt;
&lt;span class="c1"&gt;;; Custom definition required for our personal assistant project   ;;&lt;/span&gt;
&lt;span class="c1"&gt;;; Required because domain specific requirement.                   ;;&lt;/span&gt;
&lt;span class="c1"&gt;;;                                                                 ;;&lt;/span&gt;
&lt;span class="c1"&gt;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;set! &lt;/span&gt;&lt;span class="nv"&gt;previous_token_to_words&lt;/span&gt; &lt;span class="nv"&gt;token_to_words&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;token_to_words&lt;/span&gt; &lt;span class="nv"&gt;token&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="s"&gt;&amp;quot;In case of a real number, will pronounce the digits one by one excluding the decimal point&amp;quot;&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cond&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;string-matches&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;[0-9]+\\.[0-9]+&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;mapcar&lt;/span&gt; &lt;span class="nv"&gt;num-to-literal&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt; &lt;span class="nv"&gt;is_digit&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;symbolexplode&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="c1"&gt;; ;; (utf8explode utf8string) ?&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nv"&gt;t&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;previous_token_to_words&lt;/span&gt; &lt;span class="nv"&gt;token&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;num-to-literal&lt;/span&gt; &lt;span class="nv"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="s"&gt;&amp;quot;Returns the literal word of numeric characters&amp;quot;&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;car&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cdr&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;assoc&lt;/span&gt;
                &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;parse-number&lt;/span&gt; &lt;span class="nv"&gt;num&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nv"&gt;one&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="nv"&gt;two&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="nv"&gt;three&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="nv"&gt;four&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="nv"&gt;five&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="nv"&gt;six&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="nv"&gt;seven&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="nv"&gt;eight&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt; &lt;span class="nv"&gt;nine&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="nv"&gt;zero&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt; &lt;span class="nv"&gt;pred&lt;/span&gt; &lt;span class="nv"&gt;lst&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="s"&gt;&amp;quot;A new list is returned containing only the item matching the predicate&amp;quot;&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;reverse &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;filter-help&lt;/span&gt; &lt;span class="nv"&gt;pred&lt;/span&gt; &lt;span class="nv"&gt;lst&lt;/span&gt; &lt;span class="o"&gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;filter-help&lt;/span&gt; &lt;span class="nv"&gt;pred&lt;/span&gt; &lt;span class="nv"&gt;lst&lt;/span&gt; &lt;span class="nv"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;cond&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;null? &lt;/span&gt;&lt;span class="nv"&gt;lst&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;res&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;pred&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;car &lt;/span&gt;&lt;span class="nv"&gt;lst&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;filter-help&lt;/span&gt; &lt;span class="nv"&gt;pred&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cdr &lt;/span&gt;&lt;span class="nv"&gt;lst&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cons &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;car &lt;/span&gt;&lt;span class="nv"&gt;lst&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;res&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nv"&gt;t&lt;/span&gt;
            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;filter-help&lt;/span&gt; &lt;span class="nv"&gt;pred&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;cdr &lt;/span&gt;&lt;span class="nv"&gt;lst&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="nv"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;define &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;is_digit&lt;/span&gt; &lt;span class="nv"&gt;input&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="s"&gt;&amp;quot;Is input a single digit number?&amp;quot;&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;string-matches&lt;/span&gt; &lt;span class="nv"&gt;input&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;[0-9]&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here is an example of synthesis of the phrase &amp;quot;The radio frequency is 432.78&amp;quot;:&lt;/p&gt;
&lt;audio controls="controls"&gt;
      &lt;source src="/files/festival/numbers.wav" type="audio/wav"&gt;
      Your browser does not support the &lt;code&gt;audio&lt;/code&gt; element.
&lt;/audio&gt;&lt;/div&gt;
&lt;div class="section" id="web-service"&gt;
&lt;h2&gt;Web Service&lt;/h2&gt;
&lt;p&gt;For the web service I used Node.js with Express.&lt;/p&gt;
&lt;p&gt;My strategy was:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Receive the a text through a POST request.&lt;/li&gt;
&lt;li&gt;Generate a scheme code that would synthesize this text into speech and save
the speech into WAV file.&lt;/li&gt;
&lt;li&gt;Save the scheme code in a temporary script file.&lt;/li&gt;
&lt;li&gt;Invoke a festival process in batch mode and give it the scheme script as a
parameter.&lt;/li&gt;
&lt;li&gt;When finished synthesis, use Express's &lt;a class="reference external" href="https://expressjs.com/en/api.html#res.download"&gt;res.download&lt;/a&gt;
API call to send a response with the WAV file.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here is an example of &lt;code&gt;festival.js&lt;/code&gt; helper module:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;path&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;prod_dir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;/tmp/&amp;quot;&lt;/span&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get_sys_err_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prod_dir&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;static/error_in_tts.wav&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get_sound_file_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;fs&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;voice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;cmu_us_fem_cg&amp;quot;&lt;/span&gt;

    &lt;span class="c1"&gt;// Important: must call vocie BEFORE custom require&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sb"&gt;`(voice_&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;voice&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;)`&lt;/span&gt;
    &lt;span class="c1"&gt;// Notice: path delimiter might not be good for Windows&lt;/span&gt;
    &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="sb"&gt;`(require &amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;/custom&amp;quot;)`&lt;/span&gt;
    &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="sb"&gt;`(set! utt1 (Utterance Text &amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;&amp;quot;))`&lt;/span&gt;
    &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;(utt.synth utt1)&amp;#39;&lt;/span&gt;
    &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="sb"&gt;`(utt.save.wave utt1 &amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;timestamp&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;.wav&amp;quot; &amp;#39;riff)`&lt;/span&gt;

    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;scriptFullPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;prod_dir&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;.scm&amp;#39;&lt;/span&gt;
    &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;writeFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scriptFullPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;err&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Created file: &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;scriptFullPath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="c1"&gt;// Precondition: festival is in $PATH&lt;/span&gt;
    &lt;span class="kr"&gt;const&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;spawn&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;child_process&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="nx"&gt;ls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;festival&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;--batch&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;.scm&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;cwd&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;prod_dir&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;ls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;data&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`stdout: &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;ls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;data&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`stderr: &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="nx"&gt;ls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;close&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`child process exited with code &lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;Festival&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;get_sys_err_path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filepath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;cb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;prod_dir&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;.wav&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The complete code of the service can be found in &lt;a class="reference external" href="https://github.com/constrained-pa-hackathon/response-generation-component"&gt;this repository&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This process is not very efficient (and the implementation &lt;strong&gt;is not
secure&lt;/strong&gt;.  Can you spot why?)&lt;/p&gt;
&lt;p&gt;I measured the time to receive a response from the server for the most simplest
text: &lt;em&gt;I&lt;/em&gt;. it was 1.11 seconds.&lt;/p&gt;
&lt;p&gt;Here are some examples of the average response times of different phrases I
measured:&lt;/p&gt;
&lt;table border="1" class="docutils"&gt;
&lt;colgroup&gt;
&lt;col width="79%" /&gt;
&lt;col width="21%" /&gt;
&lt;/colgroup&gt;
&lt;tbody valign="top"&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Phrase&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Time&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;I&lt;/td&gt;
&lt;td&gt;1.1s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Test&lt;/td&gt;
&lt;td&gt;1.2s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;This is a test&lt;/td&gt;
&lt;td&gt;1.4s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;This is a longer test&lt;/td&gt;
&lt;td&gt;1.8s&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;The frequency was set to 30000&lt;/td&gt;
&lt;td&gt;2.4s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;And that is just the &amp;quot;text to speech&amp;quot; part. When integrated with all the other
steps of the personal assistant pipeline, we got a response latency that was
hardly acceptable. A user should &amp;quot;feel&amp;quot; the interaction with the assistant thus
the program can not &amp;quot;stop&amp;quot; and think about a reply every time a simple question
is asked. It was good enough for a Hackathon and a demonstration of a proof of
concept, so we did not attempt to optimize.&lt;/p&gt;
&lt;p&gt;Anyway, here are some ideas of why it takes that much time (no particular
order):&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;There are several reads and writes of files for each request.&lt;/li&gt;
&lt;li&gt;Each request causes a full Festival process to be forked. Initialization of
the process and Festival itself takes time.&lt;/li&gt;
&lt;li&gt;Network latency.&lt;/li&gt;
&lt;li&gt;Downloading the WAV file (~100KB) takes time (bandwidth).&lt;/li&gt;
&lt;li&gt;Festival itself is slow in synthesizing the WAV files.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We could use festival's &lt;a class="reference external" href="http://www.festvox.org/docs/manual-2.4.0/festival_28.html#Server_002fclient-API"&gt;built-in server capability&lt;/a&gt;
to overcome the disk writes and process forking issues.&lt;/p&gt;
&lt;p&gt;As for latency, bandwidth and general slowness of Festival, the best course of
action in my opinion is to use &lt;a class="reference external" href="http://www.festvox.org/flite/"&gt;Flite&lt;/a&gt; instead of Festival and do the synthesis
locally on the client itself.&lt;/p&gt;
&lt;/div&gt;
</content><category term="Javascript"></category><category term="TTS"></category><category term="T2S"></category><category term="Personal Assistant"></category><category term="Festival"></category><category term="Scheme"></category></entry><entry><title>Filtering Meetup Organizers with Greasemonkey Script</title><link href="http://www.nihamkin.com/filtering-meetup-organizers-with-greasemonkey-script.html" rel="alternate"></link><published>2018-12-08T18:00:00+02:00</published><updated>2018-12-08T18:00:00+02:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2018-12-08:/filtering-meetup-organizers-with-greasemonkey-script.html</id><summary type="html">&lt;img alt="Meetup and greasemonkey logo" class="align-center" src="files/greasemonkey/logos.png" style="width: 20%;" /&gt;
&lt;p&gt;I love meetups. It is a great opportunity to learn new things and expose myself
to new ideas. I manly interested in the technological stuff, but I am not
picky. Great concepts, ideas and life lessons has the quality of being
applicable across multiple fields.&lt;/p&gt;
&lt;p&gt;Every two weeks or so …&lt;/p&gt;</summary><content type="html">&lt;img alt="Meetup and greasemonkey logo" class="align-center" src="files/greasemonkey/logos.png" style="width: 20%;" /&gt;
&lt;p&gt;I love meetups. It is a great opportunity to learn new things and expose myself
to new ideas. I manly interested in the technological stuff, but I am not
picky. Great concepts, ideas and life lessons has the quality of being
applicable across multiple fields.&lt;/p&gt;
&lt;p&gt;Every two weeks or so, I go to &lt;a class="reference external" href="https://www.meetup.com/"&gt;meetup.com&lt;/a&gt;, choose
&amp;quot;All Meeteups&amp;quot; and browse for interesting meetings in the following two weeks.&lt;/p&gt;
&lt;p&gt;The problem is that there is a lot of clutter. Meetup allows to select which
organizers I am interested in, but I want to select which organizers I am not
interested in. I still want to see new stuff, but if I decided that something
is not relevant to me, then I want to filter it out in the future.&lt;/p&gt;
&lt;p&gt;Meetup does not allow filtering out specific organizers. So I decided to write
a &lt;a class="reference external" href="https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/"&gt;Greasemonkey&lt;/a&gt;
script to do this for me.&lt;/p&gt;
&lt;p&gt;Greasemonkey is plugin for firefox that allows running user defined scripts
written with Javascript. The scripts will run only when a page matching a
specific pattern is opened by the browser.&lt;/p&gt;
&lt;p&gt;Here is the script which does the filtering. It is pretty simple. You can also
install it from &lt;a class="reference external" href="https://greasyfork.org/en/scripts/375325-filter-out-meetup-search-results"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;// ==UserScript==&lt;/span&gt;
&lt;span class="c1"&gt;// @name     Filter Out Meetup Search Results&lt;/span&gt;
&lt;span class="c1"&gt;// @version  4&lt;/span&gt;
&lt;span class="c1"&gt;// @description Remove items from search results of meetup.com based on regular expression. Personally I use this to filter out organizers that are not relevant to me.&lt;/span&gt;
&lt;span class="c1"&gt;// @author      Artium Nihamkin artium@nihamkin.com&lt;/span&gt;
&lt;span class="c1"&gt;// @icon https://secure.meetupstatic.com/s/img/68780390453345256452178/favicon.ico&lt;/span&gt;
&lt;span class="c1"&gt;// @homepageURL    http://www.nihamkin.com&lt;/span&gt;
&lt;span class="c1"&gt;// @include https://www.meetup.com/*&lt;/span&gt;
&lt;span class="c1"&gt;// @require http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js&lt;/span&gt;
&lt;span class="c1"&gt;// ==/UserScript==&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="c1"&gt;// You need to edit this with your own filtering keywords. The regular expression&lt;/span&gt;
    &lt;span class="c1"&gt;// is run against href attributes of the search result links.&lt;/span&gt;
    &lt;span class="c1"&gt;// See http://www.nihamkin.com/filtering-meetup-organizers-with-greasemonkey-script.html&lt;/span&gt;
    &lt;span class="c1"&gt;//&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;blacklist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;All-the-best-Workshops-DIY-Israel&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;The-Best-Science-Bar-Talks-in-Tel-aviv&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;blRegex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;RegExp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blacklist&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;|&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;links&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;a&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;blRegex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;closest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;li.event-listing&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;DOMNodeInserted&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;First, some comparisons before and after:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Before running greasemonkey on my search results" src="files/greasemonkey/before.png" style="width: 45%;" /&gt; &lt;img alt="After running greasemonkey on my search results" src="files/greasemonkey/after.png" style="width: 45%;" /&gt;&lt;/p&gt;
&lt;p&gt;Now I will explain how function &lt;code&gt;f&lt;/code&gt; works. The &lt;code&gt;blacklist&lt;/code&gt; array
is an array of patterns.
These patterns should match the url of the meetup pages you want to
filter out. Since all meetup page urls contain the organizer name, I used it
as a filter criteria.&lt;/p&gt;
&lt;img alt="How to determine the href using the the built-in browser inspector" class="align-center" src="files/greasemonkey/link.png" style="width: 80%;" /&gt;
&lt;p&gt;After building the regular expression, the filtering will happen. This task is
assisted by jquery library which is imported in the &lt;code&gt;&amp;#64;require&lt;/code&gt; line.&lt;/p&gt;
&lt;p&gt;First it finds all &lt;code&gt;a&lt;/code&gt; tags whose &lt;code&gt;href&lt;/code&gt; match the regular
expression, jquery is asked to look up the DOM tree for the first occurrence of
&lt;code&gt;li&lt;/code&gt; tag with &lt;code&gt;event-listing&lt;/code&gt; class. This &lt;code&gt;li&lt;/code&gt; tag is the
container of the whole box, and thus it is removed to hide it.&lt;/p&gt;
&lt;img alt="How I determined which tag to remove using the the built-in browser inspector" class="align-center" src="files/greasemonkey/li.png" style="width: 80%;" /&gt;
&lt;p&gt;Finally it is important to tell when function &lt;code&gt;f&lt;/code&gt; should actually run.
I hooked the  &lt;code&gt;DOMNodeInserted&lt;/code&gt; event because the meetup search results
page is dynamic.
It use Ajax to load more items as the user scrolls down and presses the &amp;quot;More&amp;quot;
button. Therefore it is important to filter out any new search results as they
appear on the page.&lt;/p&gt;
&lt;p&gt;In conclusion, if you are familiar with Javascript then Greasemonkey can be a
simple but powerful tool for personalizing the experience you have with your
frequently visited websites.&lt;/p&gt;
</content><category term="Javascript"></category><category term="Greasemonkey"></category></entry><entry><title>How to Detect First Boot After Burning Program to Flash</title><link href="http://www.nihamkin.com/how-to-detect-first-boot-after-burning-program-to-flash.html" rel="alternate"></link><published>2018-10-12T22:00:00+03:00</published><updated>2018-10-12T22:00:00+03:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2018-10-12:/how-to-detect-first-boot-after-burning-program-to-flash.html</id><summary type="html">&lt;p&gt;I will write about Arduino, but this technique is relevant for any embedded
situation.&lt;/p&gt;
&lt;p&gt;Many applications require retaining data such settings or parameters
between resets.
On the Arduino, the already existing EEPROM of the Atmega chip is a common
solution for this problem.&lt;/p&gt;
&lt;p&gt;For the Arduino, the &lt;a class="reference external" href="https://www.arduino.cc/en/Reference/EEPROM"&gt;EEPROM&lt;/a&gt; library can …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I will write about Arduino, but this technique is relevant for any embedded
situation.&lt;/p&gt;
&lt;p&gt;Many applications require retaining data such settings or parameters
between resets.
On the Arduino, the already existing EEPROM of the Atmega chip is a common
solution for this problem.&lt;/p&gt;
&lt;p&gt;For the Arduino, the &lt;a class="reference external" href="https://www.arduino.cc/en/Reference/EEPROM"&gt;EEPROM&lt;/a&gt; library can be used to write or read values from the
EEPROM.&lt;/p&gt;
&lt;p&gt;It is important that the program does not read from the EEPROM on the first
time it is run after it was burned. The reason is that the version that was
burned, might have different representation of the data than the one stored in
the EEPROM. This will cause &amp;quot;not so nice&amp;quot; problems that might not go away even
after resetting.&lt;/p&gt;
&lt;p&gt;To solve this, one need to know when a program is run the first time after
it was burned, and use default values instead of reading from the EEPROM (and
of course store these to the EEPROM for next time)&lt;/p&gt;
&lt;p&gt;This is sometimes called IPL (&lt;em&gt;Initial Program Load&lt;/em&gt;) which means the first
time program is loaded into the RAM.&lt;/p&gt;
&lt;p&gt;To detect IPL one can use a constant that changes every time a new
version of your program is produced. This constant is compared with a value
stored in the EEPROM, and if they are different, it means that a new program
was burned and this is it's first boot after burning. After this, the value is
stored in the EEPROM and subsequent boots will not be detected as IPL.&lt;/p&gt;
&lt;p&gt;This constant can be managed manually, can be some preprocessor macro
representing git commit hash or date and time macro.&lt;/p&gt;
&lt;p&gt;For the Arduino example below, I used date and time macros which I find simple
and robust:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;span class="cm"&gt; * Address of the version data. This should never change between versions.&lt;/span&gt;
&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;span class="cp"&gt;#define EEPROM_ADDR_VERSION_DATE 0x0&lt;/span&gt;

&lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;span class="cm"&gt; * Your data should start after this location.&lt;/span&gt;
&lt;span class="cm"&gt; * On gcc, __DATE_ is 11 chars long, __TIME__ is 8&lt;/span&gt;
&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;span class="cp"&gt;#define EEPROM_ADD_START_OF_DATA 0x13&lt;/span&gt;

&lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;span class="cm"&gt;* Determine if this is the first power-up after&lt;/span&gt;
&lt;span class="cm"&gt;* fresh program was loaded into the flash.&lt;/span&gt;
&lt;span class="cm"&gt;*/&lt;/span&gt;
&lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;is_initial_program_load&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;version_date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;__DATE__&lt;/span&gt; &lt;span class="n"&gt;__TIME__&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;uint16_t&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;version_date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;is_ipl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;unsigned&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;EEPROM_ADDR_VERSION_DATE&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;EEPROM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;read&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;version_date&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;EEPROM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;version_date&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
            &lt;span class="n"&gt;is_ipl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;is_ipl&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
</content><category term="Arduino"></category><category term="Embedded"></category></entry><entry><title>Line Rasterisation</title><link href="http://www.nihamkin.com/line-rasterisation.html" rel="alternate"></link><published>2018-08-06T21:00:00+03:00</published><updated>2018-08-06T21:00:00+03:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2018-08-06:/line-rasterisation.html</id><summary type="html">&lt;p&gt;Sometimes even the simplest things are not as simple as they look.&lt;/p&gt;
&lt;img alt="Screenshot of the drawing results" class="align-center" src="files/bresenham_lines/bresenham_lines.png" /&gt;
&lt;p&gt;Recently, I had a task that required me to understand circle rasterisation.
So I went back to my computer graphics course notes which I took many years ago
to remind myself about how lines are drawn on a …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Sometimes even the simplest things are not as simple as they look.&lt;/p&gt;
&lt;img alt="Screenshot of the drawing results" class="align-center" src="files/bresenham_lines/bresenham_lines.png" /&gt;
&lt;p&gt;Recently, I had a task that required me to understand circle rasterisation.
So I went back to my computer graphics course notes which I took many years ago
to remind myself about how lines are drawn on a computer screen.&lt;/p&gt;
&lt;p&gt;Lines are mathematical objects, on the other hand a screen is built out of a
pixel grid of a finite resolution.&lt;/p&gt;
&lt;p&gt;Even if the endpoints of the line correspond exactly to specific pixels,
the line itself is not. It needs to be approximated by these pixels.&lt;/p&gt;
&lt;p&gt;The process of deciding which pixels should be turned on to approximate the
line is called &lt;strong&gt;rasterisation&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Reading the material again after that many years, I sharpened my understanding
a bit and now hope to share some of the insights.&lt;/p&gt;
&lt;div class="section" id="naive-algorithm"&gt;
&lt;h2&gt;Naive algorithm&lt;/h2&gt;
&lt;p&gt;The simplest way to implement this is to step over every integer value of
&lt;code&gt;x&lt;/code&gt; and use &lt;code&gt;y = mx + d&lt;/code&gt; function to calculate &lt;code&gt;y&lt;/code&gt;. The value
of &lt;code&gt;y&lt;/code&gt; is not an integer, it is a real number. And since pixel grid is an
integer grid, it needs to be rounded to the closest integer.&lt;/p&gt;
&lt;p&gt;I will use &lt;a class="reference external" href="https://processing.org/"&gt;processing&lt;/a&gt; tool for the demonstration:&lt;/p&gt;
&lt;p&gt;Please notice that 300 is the height of the drawing area and the horizontal
axis is inverses. Additionally, the &lt;code&gt;plot_y&lt;/code&gt; offset parameter has
nothing to do with the algorithm. It is just my way to control that each
implementation plots it's result on a different on the screen. These is the
reason for the &lt;code&gt;300 - (round(y) + plot_y_offset)&lt;/code&gt; calculation.&lt;/p&gt;
&lt;p&gt;For simplicity, through this article, I will consider only lines with
&lt;code&gt;0 &amp;lt; m &amp;lt; 1&lt;/code&gt; and &lt;code&gt;x0 &amp;lt; x1&lt;/code&gt; (lines which are vectors in the first
octant). Other cases (there are 8 of them) can be solved similarly by a
combination of reversing the order of the points, by iterating over &lt;code&gt;y&lt;/code&gt;
instead of &lt;code&gt;x&lt;/code&gt; and by reflecting around &lt;code&gt;x&lt;/code&gt; axis. Also vertical,
horizontal and diagonal lines have to be dealt with as edge cases.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cm"&gt;/*&lt;/span&gt;
&lt;span class="cm"&gt; * Draw a line pixel by pixel using the most naive algorithm&lt;/span&gt;
&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;line_naive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;plot_y_offset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;y0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;x0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y0&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;x0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;x0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="n"&gt;x1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;plot_y_offset&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;black&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are several inefficiencies in this implementation.&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;For every pixel, there is a floating point multiplication.&lt;/li&gt;
&lt;li&gt;For every pixel, there is a floating point rounding operation.&lt;/li&gt;
&lt;li&gt;For every line, there are several more floating point operations,
including multiplication and division.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Number 3 is relevant if you plan to draw large number of lines, which most of
the applications require.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="digital-differential-analyzer"&gt;
&lt;h2&gt;Digital Differential Analyzer&lt;/h2&gt;
&lt;p&gt;Digital Differential Analyzer (DDA) is just a fancy way of saying &lt;em&gt;lets do
increments instead of multiplication&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Naive implementation calculates &lt;code&gt;float(x) * m&lt;/code&gt; every iteration of the
loop. DDA on the other hand uses accumulator and increments by &lt;code&gt;m&lt;/code&gt; every
iteration. This replaces single floating point multiplication, with an
addition.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cm"&gt;/*&lt;/span&gt;
&lt;span class="cm"&gt; * Draw a line pixel by pixel using the DDA technique:&lt;/span&gt;
&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;line_dda&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;plot_y_offset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;y0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;x0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y0&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;x0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;curr_y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;x0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="n"&gt;x1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;curr_y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;plot_y_offset&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;black&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;curr_y&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="bresenham-s-midpoint"&gt;
&lt;h2&gt;Bresenham's Midpoint&lt;/h2&gt;
&lt;p&gt;This step actually does not make the algorithm more efficient. It is an
intermediate step before the final version of the algorithm.&lt;/p&gt;
&lt;p&gt;Rounding should be not slower than comparing two floating point numbers because
that is what actually rounding is about. More than that, depending on the
implementation, rounding can be implemented efficiently in hardware and it
could be faster.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cm"&gt;/*&lt;/span&gt;
&lt;span class="cm"&gt;* Draw a line pixel by pixel using the Bresenham&amp;#39;s midpoint algorithm&lt;/span&gt;
&lt;span class="cm"&gt;*/&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;line_midpoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;plot_y_offset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;y0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;x0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;midpoint_f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;y0&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;curr_y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;float&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;y0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;plot_y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y0&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;plot_y_offset&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;black&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x0&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;curr_y&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;midpoint_f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;plot_y&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="n"&gt;midpoint_f&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;curr_y&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plot_y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;plot_y_offset&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;black&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, since you know the motivation behind using comparison, let's dive into the
details.&lt;/p&gt;
&lt;p&gt;If we look at a pixel &lt;code&gt;(x,y)&lt;/code&gt; that was drawn at some iteration step of
the loop, there are only two possible locations for the next pixel. Either one
pixel to the right &lt;code&gt;(x+1,y)&lt;/code&gt; or one pixel to the right and one pixel up
&lt;code&gt;(x+1,y+1)&lt;/code&gt;. This behavior is due to constraints that were put on the
slope and the order of the points.&lt;/p&gt;
&lt;p&gt;So how to decide which pixel to take? One way already demonstrated was to
calculate the real &lt;code&gt;y&lt;/code&gt; and round it to the nearest integer value.&lt;/p&gt;
&lt;p&gt;Another way is to calculate the middle point between these two pixels and to
compare it to &lt;code&gt;y&lt;/code&gt;. If the midpoint (sometimes called a threshold) is
higher, then the algorithm draws the upper right pixel, otherwise it draws the
pixel to the right.&lt;/p&gt;
&lt;p&gt;The midpoint is updated incrementally every time pixel's &lt;code&gt;y&lt;/code&gt; is changed.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="bresenham-s-midpoint-with-integer"&gt;
&lt;h2&gt;Bresenham's Midpoint with Integer&lt;/h2&gt;
&lt;p&gt;Now comes the final trick. Can you implement the previous algorithm without
using a single floating operation? &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Jack_Elton_Bresenham"&gt;Jack Elton Bresenham&lt;/a&gt;
could do this.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cm"&gt;/*&lt;/span&gt;
&lt;span class="cm"&gt;* Draw a line pixel by pixel using integer only operations in the for loop.&lt;/span&gt;
&lt;span class="cm"&gt;*/&lt;/span&gt;
&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;line_midpoint_integer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;y1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;plot_y_offset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;dx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;x0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;dy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;y0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;midpoint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;y0&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;dx&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// (y0 + 0.5) * 2.0) * dx;&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;midpoint_inc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;dx&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;curr_y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;dx&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;curr_y_inc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;dy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;        &lt;span class="c1"&gt;// m * 2.0 * dx&lt;/span&gt;

  &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;plot_y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;y0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;y0&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;plot_y_offset&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;black&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x0&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;x1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;curr_y&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;midpoint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;plot_y&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="n"&gt;midpoint&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;midpoint_inc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;curr_y&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;curr_y_inc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plot_y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;plot_y_offset&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;black&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Since the algorithm draws on pixels )integer coordinates) the only reason for
floating point operations is the midpoint comparison part.
Since it is a comparison and not a calculation, it is ok to apply mathematical
operations on both sides of the equation.&lt;/p&gt;
&lt;p&gt;So to make &lt;code&gt;midpoint&lt;/code&gt; integer we multiply both side by &lt;code&gt;2&lt;/code&gt; and to
make &lt;code&gt;curr_y&lt;/code&gt; integer, we multiply both sides by &lt;code&gt;dx&lt;/code&gt; (because &lt;code&gt;curr_y = x*m = x * (dy/dx)&lt;/code&gt;)
Of course, the increments need to be updated as well.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="conclusion"&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The processing file that sums up this blog post can be found
&lt;a class="reference external" href="files/bresenham_lines/bresenham_lines.pde"&gt;here&lt;/a&gt;. I did not implement all
different cases the endpoints could be arranged.&lt;/p&gt;
&lt;img alt="Screenshot of the drawing results" class="align-center" src="files/bresenham_lines/bresenham_lines.png" /&gt;
&lt;p&gt;It runs each algorithm 10,000 times and outputs the frame rate.
It was a surprise to me that all the implementations had roughly the same fps
except for the &lt;em&gt;non&lt;/em&gt; integer midpoint which was a little faster (60 vs 65). No
comment on this right now.&lt;/p&gt;
&lt;/div&gt;
</content><category term="Computer Graphics"></category><category term="Processing"></category></entry><entry><title>Experimenting with Bats</title><link href="http://www.nihamkin.com/experimenting-with-bats.html" rel="alternate"></link><published>2018-07-08T23:00:00+03:00</published><updated>2018-07-08T23:00:00+03:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2018-07-08:/experimenting-with-bats.html</id><summary type="html">&lt;p&gt;I had some progress with my &lt;a class="reference external" href="https://github.com/alkhimey/Ada_Kernel_Module_Framework"&gt;Ada Kernel Module Framework&lt;/a&gt;.
Currently, what I have is a demo of a kernel module opening a character
device.&lt;/p&gt;
&lt;p&gt;While finishing that part, I realized that a good automatic testing strategy
needs to be developed.
At current stage, I do not even know which …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I had some progress with my &lt;a class="reference external" href="https://github.com/alkhimey/Ada_Kernel_Module_Framework"&gt;Ada Kernel Module Framework&lt;/a&gt;.
Currently, what I have is a demo of a kernel module opening a character
device.&lt;/p&gt;
&lt;p&gt;While finishing that part, I realized that a good automatic testing strategy
needs to be developed.
At current stage, I do not even know which Ada features are supported. The
framework is so fragile that any change can cause regression problems.&lt;/p&gt;
&lt;p&gt;Therefore I decided to explore testing with Bats - &lt;a class="reference external" href="https://github.com/bats-core/bats-core"&gt;Bash Automated Testing System&lt;/a&gt;.&lt;/p&gt;
&lt;div class="section" id="strategy"&gt;
&lt;h2&gt;Strategy&lt;/h2&gt;
&lt;p&gt;How does one test a &lt;strong&gt;framework&lt;/strong&gt;?&lt;/p&gt;
&lt;p&gt;My approach is to write a set of kernel modules that would demonstrate the
different Ada features and Linux kernel API bindings that are supported by the
framework.&lt;/p&gt;
&lt;p&gt;Each such module is written in a way that would allow executing the following
procedure:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Build the module.&lt;/li&gt;
&lt;li&gt;Insert it into the Kernel.&lt;/li&gt;
&lt;li&gt;Observe output through reading the message log.&lt;/li&gt;
&lt;li&gt;Operate on the module using a special user space program or a shell script.&lt;/li&gt;
&lt;li&gt;Cleanup&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Of course, everything have to be automated to allow efficient regression
testing.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="bats"&gt;
&lt;h2&gt;Bats&lt;/h2&gt;
&lt;p&gt;Bats is a &lt;a class="reference external" href="https://testanything.org/"&gt;TAP&lt;/a&gt;-compliant testing framework for Bash. It provides a simple way
to verify that the UNIX programs behave as expected.&lt;/p&gt;
&lt;p&gt;To install Bats on Ubuntu, it is required to add a &lt;code&gt;ppa&lt;/code&gt; repository
(as of 17.10):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ sudo add-apt-repository --yes ppa:duggan/bats
$ sudo apt-get update
$ sudo apt-get --yes install bats
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It seems that there is an active and helpful community surrounding this tool
and that is an important advantage for using it.&lt;/p&gt;
&lt;div class="section" id="basics"&gt;
&lt;h3&gt;Basics&lt;/h3&gt;
&lt;p&gt;Bats tests have the form form of shell scripts with &lt;code&gt;bats&lt;/code&gt; extension
and &lt;code&gt;#!/usr/bin/env bats&lt;/code&gt; shebag.&lt;/p&gt;
&lt;p&gt;Each bats file is broken down into several test steps that look like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;@test &lt;span class="s2"&gt;&amp;quot;Build module&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  run make
  &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$status&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; -eq &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="assertions"&gt;
&lt;h3&gt;Assertions&lt;/h3&gt;
&lt;p&gt;One of the drawbacks of Bats is the fact that there is no proper, convinient
way to make assertions. Fortunately, there is a third party script that makes
it possible.&lt;/p&gt;
&lt;p&gt;I found it in the &lt;a class="reference external" href="https://github.com/mbland/go-script-bash/tree/master/lib/bats"&gt;following repostiroy&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In case of failure, the assertion function will display the expected and actual
result.&lt;/p&gt;
&lt;p&gt;To load the function, one have to use bat's &lt;code&gt;load&lt;/code&gt; command. I decided to
organize stuff in a way that there is a single &lt;code&gt;environment&lt;/code&gt; script that
loads all the other dependencies (currently only one):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;load ../../testing-utils/environment
&lt;/pre&gt;&lt;/div&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="ch"&gt;#! /bin/bash&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;# Environment script for Bats tests&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;

&lt;span class="c1"&gt;# Assertion helpers were taken from&lt;/span&gt;
&lt;span class="c1"&gt;#    https://github.com/mbland/go-script-bash/tree/master/lib/bats&lt;/span&gt;
. &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;BASH_SOURCE&lt;/span&gt;&lt;span class="p"&gt;%/*&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/assertions&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;It is then possible to use &lt;code&gt;assert_success&lt;/code&gt;, &lt;code&gt;assert_equal&lt;/code&gt; and
similar commands:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;@test &lt;span class="s2"&gt;&amp;quot;Build module&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
   make
   assert_success
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;For other assert commands, &lt;a class="reference external" href="https://github.com/mbland/go-script-bash/blob/master/lib/bats/assertions"&gt;the source code of the script&lt;/a&gt;
is very clear and well documented. Worth opening it and reading.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="steps"&gt;
&lt;h3&gt;Steps&lt;/h3&gt;
&lt;p&gt;The first step would be to perform some precondition tests. These do not
provide more safety because if one of these fails, then some other consecutive
test is ought to fail as well. The reason to have these &amp;quot;sanity&amp;quot; tests is
to make it easier to debug the &lt;strong&gt;reason&lt;/strong&gt; of failure.&lt;/p&gt;
&lt;p&gt;Currently I only check if there is no loaded module with the same name as the
one about to be built.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nv"&gt;MODULE_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;hello&amp;#39;&lt;/span&gt;

lsmod_check&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
   lsmod &lt;span class="p"&gt;|&lt;/span&gt; grep &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

@test &lt;span class="s2"&gt;&amp;quot;verify there is no hello module already loaded&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
   run lsmod_check &lt;span class="nv"&gt;$MODULE_NAME&lt;/span&gt;
   assert_failure
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Next, the module is built and loaded:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;@test &lt;span class="s2"&gt;&amp;quot;build module&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    make
    assert_success
&lt;span class="o"&gt;}&lt;/span&gt;

@test &lt;span class="s2"&gt;&amp;quot;verify creation of loadable module with the correct name&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    run ls_check &lt;span class="nv"&gt;$MODULE_FILE&lt;/span&gt;
    assert_success
&lt;span class="o"&gt;}&lt;/span&gt;

@test &lt;span class="s2"&gt;&amp;quot;insert module&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    sudo insmod hello.ko
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now, we want to assert that the module operated correctly during it's
insertion.&lt;/p&gt;
&lt;p&gt;In the module's code, there are strategically placed &lt;code&gt;printk&lt;/code&gt; calls which
print into the kernel log:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;init_module&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;KERN_ERR&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Init module.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;printk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;KERN_ERR&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Hello Ada.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;adakernelmoduleinit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;ada_foo&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;printk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;KERN_ERR&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;%s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;After Ada&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;In Ada code, &lt;code&gt;Kernel_IO&lt;/code&gt; wrapper can be used:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;Linux&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Kernel_IO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Put_Line&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Creating device...&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Device&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Linux&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Device&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Device_Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;Class&lt;/span&gt;       &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Parent&lt;/span&gt;      &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Linux&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Device&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NONE_DEVICE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Devt&lt;/span&gt;        &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Linux&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Char_Device&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Make_Dev&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Major&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;Driver_Data&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;LT&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Lazy_Pointer_Type&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Null_Address&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;Name&lt;/span&gt;        &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;artiumdevice&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Linux&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Kernel_IO&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Put_Line&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Created device, check /dev&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The log can be read with the &lt;code&gt;dmesg&lt;/code&gt; command. It's output is parsed
and used for validation:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;@test &lt;span class="s2"&gt;&amp;quot;check module init and entry into the ada part&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;sudo dmesg -t &lt;span class="p"&gt;|&lt;/span&gt; tail -17 &lt;span class="p"&gt;|&lt;/span&gt; head -1&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
    assert_equal &lt;span class="s1"&gt;&amp;#39;Init module.&amp;#39;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;

    &lt;span class="nv"&gt;result&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;sudo dmesg -t &lt;span class="p"&gt;|&lt;/span&gt; tail -16 &lt;span class="p"&gt;|&lt;/span&gt; head -1&lt;span class="k"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
    assert_equal &lt;span class="s1"&gt;&amp;#39;Hello Ada.&amp;#39;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally, it is important to clean everything and bring it back to original
state. This is not 100% possible since the module itself could have made some
unpredictable changes to the Kernel.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;@test &lt;span class="s2"&gt;&amp;quot;remove module&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    sudo rmmod hello.ko
&lt;span class="o"&gt;}&lt;/span&gt;

@test &lt;span class="s2"&gt;&amp;quot;clean files&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
make clean
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="running"&gt;
&lt;h3&gt;Running&lt;/h3&gt;
&lt;p&gt;Here is some success example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ bats test.bats
✓ verify there is no hello module already loaded
✓ build module
✓ verify creation of loadable module with the correct name
✓ insert module
✓ check module init and entry into the ada part
✓ remove module
✓ clean files

&lt;span class="m"&gt;7&lt;/span&gt; tests, &lt;span class="m"&gt;0&lt;/span&gt; failures
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And here is an example where I messed the module a little bit:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ bats test.bats
✓ verify there is no hello module already loaded
✓ build module
✓ verify creation of loadable module with the correct name
✓ insert module
✗ check module init and entry into the ada part
&lt;span class="o"&gt;(&lt;/span&gt;in &lt;span class="nb"&gt;test&lt;/span&gt; file test.bats, line &lt;span class="m"&gt;47&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="sb"&gt;`&lt;/span&gt;assert_equal &lt;span class="s1"&gt;&amp;#39;Init module.&amp;#39;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39; failed&lt;/span&gt;
&lt;span class="s1"&gt;Actual value not equal to expected value:&lt;/span&gt;
&lt;span class="s1"&gt;    expected: &amp;#39;&lt;/span&gt;Init module.&lt;span class="s1"&gt;&amp;#39;&lt;/span&gt;
&lt;span class="s1"&gt;    actual:   &amp;#39;&lt;/span&gt;xyz&lt;span class="err"&gt;&amp;#39;&lt;/span&gt;
✓ remove module
✓ clean files

&lt;span class="m"&gt;7&lt;/span&gt; tests, &lt;span class="m"&gt;1&lt;/span&gt; failure
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="whats-next"&gt;
&lt;h3&gt;Whats Next&lt;/h3&gt;
&lt;p&gt;One thing I did not demonstrate yet is how to test module's &amp;quot;file&amp;quot; interface.&lt;/p&gt;
&lt;p&gt;My plan to do this is by implementing a helper user space program. This program
will call the file operations and output the results. A bats script will
drive this program.&lt;/p&gt;
&lt;p&gt;For simple operations like &lt;code&gt;read&lt;/code&gt; and &lt;code&gt;write&lt;/code&gt;, bash commands could
be used directly.&lt;/p&gt;
&lt;p&gt;I will probably write more about this in some future blog post.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="bats"></category><category term="linux"></category><category term="kernel"></category><category term="testing"></category><category term="bash"></category></entry><entry><title>Migrating Blogofile to Pelican</title><link href="http://www.nihamkin.com/migrating-blogofile-to-pelican.html" rel="alternate"></link><published>2017-05-13T23:00:00+03:00</published><updated>2017-05-13T23:00:00+03:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2017-05-13:/migrating-blogofile-to-pelican.html</id><summary type="html">&lt;p&gt;Since I started writing this blog in 2012, I used &lt;a class="reference external" href="https://github.com/EnigmaCurry/blogofile"&gt;Blogofile&lt;/a&gt; as the blogging platform.&lt;/p&gt;
&lt;p&gt;Blogofile is a static website generator, meaning that the content is written and stored in a structured format like &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Markdown"&gt;Markdown&lt;/a&gt;, then it is compiled offline into a set of HTML pages that can be hosted …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Since I started writing this blog in 2012, I used &lt;a class="reference external" href="https://github.com/EnigmaCurry/blogofile"&gt;Blogofile&lt;/a&gt; as the blogging platform.&lt;/p&gt;
&lt;p&gt;Blogofile is a static website generator, meaning that the content is written and stored in a structured format like &lt;a class="reference external" href="https://en.wikipedia.org/wiki/Markdown"&gt;Markdown&lt;/a&gt;, then it is compiled offline into a set of HTML pages that can be hosted on any web server, iregardless of it's technology. It can be even hosted cheaply on Amazon S3, which is what I am doing with this website.&lt;/p&gt;
&lt;p&gt;While Blogofile have served me well, It's development stalled for many years, and I felt that I wanted to try something new.&lt;/p&gt;
&lt;p&gt;After surveying modern website generators that are based on python, I decided to try &lt;a class="reference external" href="https://blog.getpelican.com/"&gt;Pelican&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In this blog post, I will explain how I managed to migrate from Blogofile to Pelican.&lt;/p&gt;
&lt;div class="section" id="migration"&gt;
&lt;h2&gt;Migration&lt;/h2&gt;
&lt;p&gt;First step was to follow the standard &lt;a class="reference external" href="http://docs.getpelican.com/en/3.6.3/install.html"&gt;instructions&lt;/a&gt; for installing Pelican and initializing a new blog.&lt;/p&gt;
&lt;p&gt;In pelican, blog posts are stored in the &lt;em&gt;content&lt;/em&gt; folder, so I copied all my Markdown files there.&lt;/p&gt;
&lt;p&gt;Unfortunately, this does not work &amp;quot;out of the box&amp;quot;. Some transformations on the files had to be made.&lt;/p&gt;
&lt;div class="section" id="removing"&gt;
&lt;h3&gt;Removing ---&lt;/h3&gt;
&lt;p&gt;Blogofile uses the triple dash (&lt;em&gt;---&lt;/em&gt;) sequences to mark the header part of the Markdown file. Pelican does not need it and in fact will renders it into the output html.&lt;/p&gt;
&lt;p&gt;The problem is that one needs to be careful not to remove legitimate sequences like those that are part of a table definition.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;artium@melon:~/Projects/nihamkin.com/content$ &lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt; grep -r &lt;span class="s1"&gt;&amp;#39;\-\-\-&amp;#39;&lt;/span&gt; .
./24-about-the-danger-of-merge-conflicts.markdown:---
./24-about-the-danger-of-merge-conflicts.markdown:---
...
./20-msp430-with-ili9341-display.markdown:---
./20-msp430-with-ili9341-display.markdown:---
./20-msp430-with-ili9341-display.markdown:&lt;span class="p"&gt;|&lt;/span&gt;:------------- &lt;span class="p"&gt;|&lt;/span&gt;:--------:&lt;span class="p"&gt;|&lt;/span&gt; -------:&lt;span class="p"&gt;|&lt;/span&gt;
./19-esp82266-with-ili9341-display.markdown:---
./19-esp82266-with-ili9341-display.markdown:---
./19-esp82266-with-ili9341-display.markdown:&lt;span class="p"&gt;|&lt;/span&gt;:------------- &lt;span class="p"&gt;|&lt;/span&gt;:--------:&lt;span class="p"&gt;|&lt;/span&gt; -------:&lt;span class="p"&gt;|&lt;/span&gt;
...
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here is a snippet I used to remove only the illegitimate sequences automatically:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;find . -type f -exec sed -i -r &lt;span class="s1"&gt;&amp;#39;/^---$/d&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt; &lt;span class="se"&gt;\;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Please be &lt;strong&gt;very careful&lt;/strong&gt; with this command. Run it only in the &lt;em&gt;content&lt;/em&gt; directory.&lt;/p&gt;
&lt;p&gt;If you run it from the wrong location, it might modify important files, so check and double check that you are running this correctly!&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="replacing-categories-with-tags"&gt;
&lt;h3&gt;Replacing Categories with Tags&lt;/h3&gt;
&lt;p&gt;Blogofile uses the &lt;em&gt;Categories&lt;/em&gt; keyword while Pelican uses &lt;em&gt;Tags&lt;/em&gt; to describe the same thing.&lt;/p&gt;
&lt;p&gt;This can be achieved easily with:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;find . -type f -exec sed -i &lt;span class="s1"&gt;&amp;#39;s/categories:/Tags:/g&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt; &lt;span class="se"&gt;\;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="code"&gt;
&lt;h3&gt;Code&lt;/h3&gt;
&lt;p&gt;Blogofile uses the &lt;code&gt;$$code(lang=Ada)&lt;/code&gt; syntax for syntax highlighted code blocks. Pelican's Markdown uses the &lt;code&gt;::Ada&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The following command will find all the places that use &lt;code&gt;$$code&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;grep -r &lt;span class="s1"&gt;&amp;#39;$$code&amp;#39;&lt;/span&gt; .
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I felt that doing the transformation by hand was quicker than writing a script. It all depends on the number of results of the command above.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="static-files"&gt;
&lt;h3&gt;Static Files&lt;/h3&gt;
&lt;p&gt;My blog is hosting some static files which are not blog posts, such as images that are used in the posts.&lt;/p&gt;
&lt;p&gt;Blogofile uses &lt;em&gt;files&lt;/em&gt; directory which was copied as-is to the output. In the blog posts, the following syntax was used to reference the image: &lt;code&gt;![ESP8288 connected to ILI9341](/files/esp1.jpg)&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;In Pelican, the static files are stored in &lt;em&gt;content/files&lt;/em&gt;. The links on the blog posts do not have to change but &lt;em&gt;pelicanconf.py&lt;/em&gt; needs to be aware that this folder contain static files:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;STATIC_PATHS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;&amp;#39;files&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;&amp;#39;extra&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="not-breaking-existing-links"&gt;
&lt;h3&gt;Not Breaking Existing Links&lt;/h3&gt;
&lt;p&gt;One of the most important point in the migration process is not to break inbound links to the old blog posts. Breaking links will affect SEO, make a mess in google analytics and might break Disqus comments.&lt;/p&gt;
&lt;p&gt;In pelican, it is possible to force a specific URL for a blog post.&lt;/p&gt;
&lt;p&gt;Here is an example of how it is done. Put the following code in the header section of the markdown file:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;url: 2016/11/25/writing-linux-modules-in-ada-part-3
save_as: 2016/11/25/writing-linux-modules-in-ada-part-3/index.html
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;I went over all my pages manually and gave each the appropriate link.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="adding-a-theme"&gt;
&lt;h3&gt;Adding a Theme&lt;/h3&gt;
&lt;p&gt;There are large number of user created &lt;a class="reference external" href="http://www.pelicanthemes.com/"&gt;themes&lt;/a&gt; that are available for Pelican.&lt;/p&gt;
&lt;p&gt;With Blogofile, I developed my own look and feel based on bootstrap. As I am not a designer, it was ugly and not mobile friendly.&lt;/p&gt;
&lt;p&gt;With Pelican, I chose to use &lt;a class="reference external" href="https://github.com/alexandrevicenzi/Flex"&gt;Flex&lt;/a&gt; theme. The installation is straight forward so I will not repeat what is already described in the &lt;a class="reference external" href="http://docs.getpelican.com/en/3.6.3/settings.html#themes"&gt;documentation&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="disqus-number-of-comments"&gt;
&lt;h3&gt;Disqus Number of Comments&lt;/h3&gt;
&lt;p&gt;One of the things I felt was missing in Flex is a direct link from the main page to the comments section of a post, along with the number of comments.&lt;/p&gt;
&lt;p&gt;I added this feature to Flex, as can be seen in the screenshot:&lt;/p&gt;
&lt;img alt="Screenshot of &amp;quot;discus number of comments&amp;quot; link" class="align-center" src="files/disqus_count.png" /&gt;
&lt;p&gt;Until my pull request is approved, the changes to the templates can be viewed &lt;a class="reference external" href="https://github.com/alexandrevicenzi/Flex/pull/111/files"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section" id="development-vs-production"&gt;
&lt;h3&gt;Development vs. Production&lt;/h3&gt;
&lt;p&gt;One neat feature of Pelican is the ability to separate production and development configurations.&lt;/p&gt;
&lt;p&gt;My use cases for this feature are:&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;I want to use different Disqus sitenames for production and for testing.&lt;/li&gt;
&lt;li&gt;I do not want to use Google analytics when testing.&lt;/li&gt;
&lt;li&gt;I want to use different site urls for testing (localhost) and production (my actual domain name). This is important because links in Pelican are generated with absolute paths based on &lt;code&gt;SITEURL&lt;/code&gt; parameter.&lt;/li&gt;
&lt;li&gt;I do not want to generate RSS/Atom when testing.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The production specific parameters are placed into &lt;em&gt;publishconfig.py&lt;/em&gt;. These parameters will override the parameters in &lt;em&gt;pelicanconf.py&lt;/em&gt; when publishing.&lt;/p&gt;
&lt;p&gt;Here is an example of &lt;em&gt;publishconfig.py&lt;/em&gt; from my blog:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="ch"&gt;#!/usr/bin/env python&lt;/span&gt;
&lt;span class="c1"&gt;# -*- coding: utf-8 -*- #&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;__future__&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;unicode_literals&lt;/span&gt;

&lt;span class="c1"&gt;# This file is only used if you use `make publish` or&lt;/span&gt;
&lt;span class="c1"&gt;# explicitly specify it as your config file.&lt;/span&gt;

&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;
&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;curdir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;pelicanconf&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;

&lt;span class="n"&gt;SITEURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;http://www.nihamkin.com&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;RELATIVE_URLS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

&lt;span class="n"&gt;FEED_ALL_ATOM&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;feeds/all.atom.xml&amp;#39;&lt;/span&gt;
&lt;span class="n"&gt;CATEGORY_FEED_ATOM&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;feeds/&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s1"&gt;.atom.xml&amp;#39;&lt;/span&gt;

&lt;span class="n"&gt;DELETE_OUTPUT_DIRECTORY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;

&lt;span class="c1"&gt;# Following items are often useful when publishing&lt;/span&gt;

&lt;span class="n"&gt;DISQUS_SITENAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;artiumsblog&amp;quot;&lt;/span&gt;
&lt;span class="n"&gt;GOOGLE_ANALYTICS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;UA-36977465-1&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div class="section" id="deploying-to-s3"&gt;
&lt;h3&gt;Deploying to S3&lt;/h3&gt;
&lt;p&gt;Deploying to S3 is build-in with Pelican. Simply run &lt;code&gt;make s3_upload&lt;/code&gt; and the script will guide you through the configuration.&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><category term="Blogofile"></category><category term="Pelican"></category></entry><entry><title>About the Pitfalls of Merge Conflicts</title><link href="http://www.nihamkin.com/2016/12/31/about-the-pitfalls-of-merge-conflicts" rel="alternate"></link><published>2016-12-31T14:00:00+02:00</published><updated>2016-12-31T14:00:00+02:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2016-12-31:/2016/12/31/about-the-pitfalls-of-merge-conflicts</id><summary type="html">&lt;p&gt;I do not consider myself a novice software developer. And yet I still have not exceeded the list of things I can learn "the hard way".&lt;/p&gt;
&lt;p&gt;Last month I had chance to learn about the dangers of resolving merge conflicts as well as how important is it to do a …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I do not consider myself a novice software developer. And yet I still have not exceeded the list of things I can learn "the hard way".&lt;/p&gt;
&lt;p&gt;Last month I had chance to learn about the dangers of resolving merge conflicts as well as how important is it to do a proper code review.&lt;/p&gt;
&lt;p&gt;We use a "classic" work-flow in my work place (ancient as Greece itself). At the beginning of a development cycle, we open a branch for each feature that will be developed in that cycle. All the branches are based on the same baseline. When all developers are done, we merge the branches one by one, test the final result and it becomes the new baseline of the next development cycle. We have one specific developer whose responsibility is to merge all the features. Sometimes, when the conflict appears to be difficult, the authors of the conflicting parts are also invited to be involved. &lt;/p&gt;
&lt;p&gt;The following code snippets are simplified representations of what happened in our code base.&lt;/p&gt;
&lt;p&gt;The base version of a certain file contained the following lines:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;if&lt;/span&gt;    &lt;span class="n"&gt;Msg_1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
   &lt;span class="c1"&gt;-- Do stuff 1&lt;/span&gt;
&lt;span class="kr"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;Msg_1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
   &lt;span class="c1"&gt;-- Do stuff 2&lt;/span&gt;
&lt;span class="kr"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;Msg_1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
   &lt;span class="c1"&gt;-- Do stuff 3&lt;/span&gt;
&lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;One of the developers added &lt;code&gt;Msg_2&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;procedure&lt;/span&gt; &lt;span class="nf"&gt;Proc_Msg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;Msg&lt;/span&gt; &lt;span class="p"&gt;: &lt;/span&gt;&lt;span class="nv"&gt;Msg_Type&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kr"&gt;is&lt;/span&gt;
&lt;span class="kr"&gt;begin&lt;/span&gt;
   &lt;span class="kr"&gt;if&lt;/span&gt;    &lt;span class="n"&gt;Msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
      &lt;span class="c1"&gt;-- Do stuff 1&lt;/span&gt;
   &lt;span class="kr"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;Msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
      &lt;span class="c1"&gt;-- Do stuff 2&lt;/span&gt;
   &lt;span class="kr"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;Msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
      &lt;span class="c1"&gt;-- Do stuff 3&lt;/span&gt;
   &lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kr"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- ...&lt;/span&gt;

&lt;span class="n"&gt;Proc_Msg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;Msg_1&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Proc_Msg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;Msg_2&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;In the meantime, another developer was busy implementing a new message ID number:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;if&lt;/span&gt;    &lt;span class="n"&gt;Msg_1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
   &lt;span class="c1"&gt;-- Do stuff 1&lt;/span&gt;
&lt;span class="kr"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;Msg_1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
   &lt;span class="c1"&gt;-- Do stuff 2&lt;/span&gt;
&lt;span class="kr"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;Msg_1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
   &lt;span class="c1"&gt;-- Do stuff 3&lt;/span&gt;
&lt;span class="kr"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;Msg_1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
   &lt;span class="n"&gt;Buffer&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Msg_1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="n"&gt;Buffer_Ready_Toggle&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;Buffer_Ready_Toggle&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Please believe me that under the constraints of our system, this way of using a toggle is a correct way to send a message to another process:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kr"&gt;if&lt;/span&gt; &lt;span class="n"&gt;Local_Toggle&lt;/span&gt; &lt;span class="o"&gt;/=&lt;/span&gt; &lt;span class="n"&gt;Buffer_Ready_Toggle&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
   &lt;span class="n"&gt;Local_Toggle&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Buffer_Ready_Toggle&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="c1"&gt;-- Now do stuff with buffer ...&lt;/span&gt;

&lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;I was present during the resolution of the conflict. It was late at night, and after some manual editing of the merge result we produced following result:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;procedure&lt;/span&gt; &lt;span class="nf"&gt;Proc_Msg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;Msg&lt;/span&gt; &lt;span class="p"&gt;: &lt;/span&gt;&lt;span class="nv"&gt;Msg_Type&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kr"&gt;is&lt;/span&gt;
&lt;span class="kr"&gt;begin&lt;/span&gt;
   &lt;span class="kr"&gt;if&lt;/span&gt;    &lt;span class="n"&gt;Msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
      &lt;span class="c1"&gt;-- Do stuff 1&lt;/span&gt;
   &lt;span class="kr"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;Msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
      &lt;span class="c1"&gt;-- Do stuff 2&lt;/span&gt;
   &lt;span class="kr"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;Msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
      &lt;span class="c1"&gt;-- Do stuff 3&lt;/span&gt;
   &lt;span class="kr"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;Msg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
      &lt;span class="n"&gt;Buffer&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Msg_1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="n"&gt;Buffer_Ready_Toggle&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;Buffer_Ready_Toggle&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kr"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- ...&lt;/span&gt;

&lt;span class="n"&gt;Proc_Msg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;Msg_1&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;Proc_Msg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;Msg_2&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Unfortunately, this code contains two problems. It was pure luck that we noticed them. Compilation error in another part of the file caused us to recheck the whole file.&lt;/p&gt;
&lt;p&gt;Can you find the problems yourself?&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;The first mistake is that the line &lt;code&gt;Buffer := Msg_1.Data&lt;/code&gt; should actually be &lt;code&gt;Buffer := Msg.Data&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The second problem is a bug that will happen if both messages have &lt;code&gt;Id&lt;/code&gt; of &lt;code&gt;4&lt;/code&gt;. In this case, the toggle changes will cancel each other.&lt;/p&gt;
&lt;p&gt;The disturbing part of this story is that these problems could not have been detected by tests. Each developer's tests, even when run on the merged version would have passed successfully. &lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;There are several lessons I learned from this incident.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Our work-flow has problems. We already in the process of adopting &lt;a href="http://nvie.com/posts/a-successful-git-branching-model/"&gt;another work flow&lt;/a&gt; that would reduce the number of conflicts and shift the responsibility of resolving them to the developers that actually participated in the relevant code.&lt;/li&gt;
&lt;li&gt;There should be more coordination between developers. Stand up meetings are good for this purpose, but additionally management should be involved for inter team/department coordination.&lt;/li&gt;
&lt;li&gt;Code reviews are important, especially after merge. There are bugs that are hard to catch using tests alone.&lt;/li&gt;
&lt;li&gt;Doing work late at night, when you are tired, is counterproductive. No matter how high the pressure is to deliver, the consequences will cost more that what you benefit. I have been bitten by this numerous times and still continue making this mistake.&lt;/li&gt;
&lt;/ul&gt;</content><category term="Ada"></category><category term="Software Engineering"></category><category term="Source Control"></category></entry><entry><title>Writing Linux Modules in Ada - Part 3</title><link href="http://www.nihamkin.com/2016/11/25/writing-linux-modules-in-ada-part-3" rel="alternate"></link><published>2016-11-25T20:00:00+02:00</published><updated>2016-11-25T20:00:00+02:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2016-11-25:/2016/11/25/writing-linux-modules-in-ada-part-3</id><summary type="html">&lt;p&gt;In this article I will continue to extend the runtime running in the kernel module. We have not touched the kernel module part itself yet, just laying the infrastructure. &lt;br&gt; The next step is to implement the &lt;code&gt;Image&lt;/code&gt; attribute. This requires some work as this attribute is implemented differently for each basic type it can be used on.&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a class="github-button" href="https://github.com/alkhimey/Ada_Kernel_Module_Toolkit/"  data-style="mega" aria-label="View alkhimey/Ada_Kernel_Module_Toolkit on GitHub"&gt;View on Github&lt;/a&gt;
&lt;a class="github-button" href="https://github.com/alkhimey/Ada_Kernel_Module_Toolkit" data-icon="octicon-star" data-style="mega" data-count-href="/alkhimey/Ada_Kernel_Module_Toolkit/stargazers" data-count-api="/repos/alkhimey/Ada_Kernel_Module_Toolkit#stargazers_count" data-count-aria-label="# stargazers on GitHub" aria-label="Star alkhimey/Ada_Kernel_Module_Toolkit on GitHub"&gt;Star on Github&lt;/a&gt;
&lt;a class="github-button" href="https://github.com/alkhimey/Ada_Kernel_Module_Toolkit/archive/blog-post-pt-3.zip" data-icon="octicon-cloud-download" data-style="mega" aria-label="Download alkhimey/Ada_Kernel_Module_Toolkit on GitHub"&gt;Download Pt-3&lt;/a&gt;&lt;/p&gt;
&lt;script async defer src="https://buttons.github.io/buttons.js"&gt;&lt;/script&gt;

&lt;!--
&lt;a href="https://github.com/alkhimey/Ada_Kernel_Module_Toolkit"&gt;&lt;img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/a6677b08c955af8400f44c6298f40e7d19cc5b2d/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677261795f3664366436642e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png"&gt;&lt;/a&gt;
--&gt;

&lt;p&gt;In this part, I will continue porting capabilities to the run-time&lt;/p&gt;
&lt;h2&gt;Image&lt;/h2&gt;
&lt;p&gt;The &lt;a href="http://www.adaic.org/resources/add_content/standards/05rm/html/RM-3-5.html#I1590"&gt;&lt;code&gt;'Image&lt;/code&gt;&lt;/a&gt; attribute is used to return the string representation of a value. This value can be integer, boolean, enumeration etc.&lt;/p&gt;
&lt;p&gt;The run-time have a separate implementation of the attribute for each supported type. Here is the list of files from my native run-time:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;/usr/gnat/lib/gcc/x86_64-pc-linux-gnu/4.9.4/rts-native/adainclude$  lsg img
s-imgbiu.adb
s-imgbiu.ads
s-imgboo.adb
s-imgboo.ads
s-imgcha.adb
s-imgcha.ads
s-imgdec.adb
s-imgdec.ads
s-imgenu.adb
s-imgenu.ads
s-imgint.adb
s-imgint.ads
s-imgllb.adb
s-imgllb.ads
s-imglld.adb
s-imglld.ads
s-imglli.adb
s-imglli.ads
s-imgllu.adb
s-imgllu.ads
s-imgllw.adb
s-imgllw.ads
s-imgrea.adb
s-imgrea.ads
s-imguns.adb
s-imguns.ads
s-imgwch.adb
s-imgwch.ads
s-imgwiu.adb
s-imgwiu.ads
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;These packages are not preset in our module's run-time, so when attempting to compile something like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;package&lt;/span&gt; &lt;span class="kd"&gt;body&lt;/span&gt; &lt;span class="nc"&gt;Ada_Foo_Pack&lt;/span&gt; &lt;span class="kr"&gt;is&lt;/span&gt;
   &lt;span class="kd"&gt;procedure&lt;/span&gt; &lt;span class="nf"&gt;Ada_Foo&lt;/span&gt; &lt;span class="kr"&gt;is&lt;/span&gt;
      &lt;span class="n"&gt;S&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="kt"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;&amp;#39;&lt;/span&gt;&lt;span class="na"&gt;Image&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="kt"&gt;Character&lt;/span&gt;&lt;span class="p"&gt;&amp;#39;&lt;/span&gt;&lt;span class="na"&gt;Val&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="kr"&gt;begin&lt;/span&gt;
      &lt;span class="n"&gt;Print_Kernel&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="nf"&gt;Ada_Foo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kr"&gt;begin&lt;/span&gt;
   &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="nf"&gt;Ada_Foo_Pack&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Will result in compiler error:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;ada_foo_pack.adb:3:22: construct not allowed in configurable run-time mode
ada_foo_pack.adb:3:22: file s-imgint.ads not found
ada_foo_pack.adb:3:22: entity &lt;span class="s2"&gt;&amp;quot;System.Img_Int.Image_Integer&amp;quot;&lt;/span&gt; not available
&lt;/pre&gt;&lt;/div&gt;


&lt;h3&gt;First Step&lt;/h3&gt;
&lt;p&gt;The first step would be to copy one of the native implementations as is.&lt;/p&gt;
&lt;p&gt;Unfortunately, the compilation results in the following errors:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;s-imgint.adb:75:10: violation of restriction &lt;span class="s2"&gt;&amp;quot;No_Recursion&amp;quot;&lt;/span&gt; at /home/artium/Projects/Ada_Kernel_Module_Toolkit/rts/gnat.adc:18
s-imgint.ads:42:07: violation of restriction &lt;span class="s2"&gt;&amp;quot;No_Default_Initialization&amp;quot;&lt;/span&gt; at /home/artium/Projects/Ada_Kernel_Module_Toolkit/rts/gnat.adc:74
&lt;/pre&gt;&lt;/div&gt;


&lt;h3&gt;No_Default_Initialization&lt;/h3&gt;
&lt;p&gt;The second violation points to the &lt;em&gt;out&lt;/em&gt; parameter &lt;code&gt;P&lt;/code&gt; of the following declaration&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;procedure&lt;/span&gt; &lt;span class="nf"&gt;Image_Integer&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;V&lt;/span&gt; &lt;span class="p"&gt;: &lt;/span&gt;&lt;span class="nv"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="nv"&gt;S&lt;/span&gt; &lt;span class="p"&gt;: &lt;/span&gt;&lt;span class="nv"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;out&lt;/span&gt; &lt;span class="nv"&gt;String&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="nv"&gt;P&lt;/span&gt; &lt;span class="p"&gt;: &lt;/span&gt;&lt;span class="nv"&gt;out&lt;/span&gt; &lt;span class="nv"&gt;Natural&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;After some reading documentation and asking for help at the #ada irc channel, I understood that this violation happens because &lt;em&gt;gnat.adc&lt;/em&gt; has both the &lt;a href="https://docs.adacore.com/gnat_rm-docs/html/gnat_rm/gnat_rm/standard_and_implementation_defined_restrictions.html#no-default-initialization"&gt;&lt;code&gt;No_Default_Initialization&lt;/code&gt;&lt;/a&gt; restriction and the &lt;a href="http://www.adaic.org/resources/add_content/standards/05rm/html/RM-H-1.html"&gt;&lt;code&gt;Normalize_Scalars&lt;/code&gt;&lt;/a&gt; pragma.&lt;/p&gt;
&lt;p&gt;As &lt;em&gt;sparre&lt;/em&gt; from the irc channel explains, "&lt;em&gt;Normalize_Scalars is a default initialization and you can't override the default initialization of an "out" parameter&lt;/em&gt;".&lt;/p&gt;
&lt;p&gt;As explained in &lt;a href="/2016/10/23/writing-linux-modules-in-ada-part-1/"&gt;part 1&lt;/a&gt;, the file &lt;em&gt;gnat.c&lt;/em&gt; was inherited from the bare bones tutorial. I do not know why the &lt;code&gt;No_Default_Initialization&lt;/code&gt; restriction was added, but &lt;code&gt;Normalize_Scalars&lt;/code&gt; looks pretty useful. Between these two I chose to remove the first one.&lt;/p&gt;
&lt;h3&gt;No_Recursion&lt;/h3&gt;
&lt;p&gt;This one is simple, the code have a recursion:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;procedure&lt;/span&gt; &lt;span class="nf"&gt;Set_Digits&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;T&lt;/span&gt; &lt;span class="p"&gt;: &lt;/span&gt;&lt;span class="nv"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="nv"&gt;S&lt;/span&gt; &lt;span class="p"&gt;: &lt;/span&gt;&lt;span class="nv"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;out&lt;/span&gt; &lt;span class="nv"&gt;String&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="nv"&gt;P&lt;/span&gt; &lt;span class="p"&gt;: &lt;/span&gt;&lt;span class="nv"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;out&lt;/span&gt; &lt;span class="nv"&gt;Natural&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;is&lt;/span&gt;
&lt;span class="kr"&gt;begin&lt;/span&gt;
   &lt;span class="kr"&gt;if&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
      &lt;span class="n"&gt;Set_Digits&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="n"&gt;P&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;P&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="n"&gt;S&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="kt"&gt;Character&lt;/span&gt;&lt;span class="p"&gt;&amp;#39;&lt;/span&gt;&lt;span class="na"&gt;Val&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="ow"&gt;rem&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
   &lt;span class="kr"&gt;else&lt;/span&gt;
      &lt;span class="n"&gt;P&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;P&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="n"&gt;S&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="kt"&gt;Character&lt;/span&gt;&lt;span class="p"&gt;&amp;#39;&lt;/span&gt;&lt;span class="na"&gt;Val&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="nf"&gt;Set_Digits&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The following version I wrote does not use recursion:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;procedure&lt;/span&gt; &lt;span class="nf"&gt;Set_Digits&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;T&lt;/span&gt; &lt;span class="p"&gt;: &lt;/span&gt;&lt;span class="nv"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="nv"&gt;S&lt;/span&gt; &lt;span class="p"&gt;: &lt;/span&gt;&lt;span class="nv"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;out&lt;/span&gt; &lt;span class="nv"&gt;String&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="nv"&gt;P&lt;/span&gt; &lt;span class="p"&gt;: &lt;/span&gt;&lt;span class="nv"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;out&lt;/span&gt; &lt;span class="nv"&gt;Natural&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kr"&gt;is&lt;/span&gt;
   &lt;span class="n"&gt;D&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Natural&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;-- will store number of digits&lt;/span&gt;
&lt;span class="kr"&gt;begin&lt;/span&gt;

   &lt;span class="kr"&gt;declare&lt;/span&gt;
      &lt;span class="n"&gt;T2&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Integer&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="kr"&gt;begin&lt;/span&gt;
      &lt;span class="kr"&gt;while&lt;/span&gt; &lt;span class="n"&gt;T2&lt;/span&gt; &lt;span class="o"&gt;/=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="kr"&gt;loop&lt;/span&gt;
         &lt;span class="n"&gt;D&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
         &lt;span class="n"&gt;T2&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;T2&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="kr"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="kr"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="kr"&gt;if&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="kr"&gt;then&lt;/span&gt;
      &lt;span class="n"&gt;P&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;P&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="n"&gt;S&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="p"&gt;&amp;#39;&lt;/span&gt;&lt;span class="na"&gt;0&lt;/span&gt;&lt;span class="p"&gt;&amp;#39;;&lt;/span&gt;
   &lt;span class="kr"&gt;else&lt;/span&gt;
      &lt;span class="kr"&gt;for&lt;/span&gt; &lt;span class="n"&gt;I&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="kr"&gt;reverse&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;..&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="kr"&gt;loop&lt;/span&gt;
         &lt;span class="n"&gt;P&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;P&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
         &lt;span class="n"&gt;S&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;P&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="kt"&gt;Character&lt;/span&gt;&lt;span class="p"&gt;&amp;#39;&lt;/span&gt;&lt;span class="na"&gt;Val&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;48&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="n"&gt;I&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;rem&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="kr"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="nf"&gt;Set_Digits&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The exponent operator I used in the code required copying additional files to the run-time:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;s-exnint.ads
s-exnint.adb
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;It was very tempting to rewrite this package completely, as it is not the most efficient implementation possible and does not use the Ada type system intelligently.&lt;/p&gt;
&lt;p&gt;But as I already explained, I am guided by the principle of doing as little changes as possible to the native run-time. &lt;/p&gt;
&lt;h3&gt;The Unknown Symbol&lt;/h3&gt;
&lt;p&gt;After the changes made, compiling the module resulted in a warning:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;WARNING: &lt;span class="s2"&gt;&amp;quot;system__img_int__image_integer&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;/home/artium/Projects/Ada_Kernel_Module_Toolkit/hello.ko&lt;span class="o"&gt;]&lt;/span&gt; undefined!
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Trying to insert the module resulted in an error:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nv"&gt;$sudo&lt;/span&gt; insmod hello.ko
insmod: ERROR: could not insert module hello.ko: Unknown symbol in module
&lt;span class="nv"&gt;$dmesg&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; tail -1
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;132897&lt;/span&gt;.268341&lt;span class="o"&gt;]&lt;/span&gt; hello: Unknown symbol system__img_int__image_integer &lt;span class="o"&gt;(&lt;/span&gt;err &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;It turns out that I forgot to add the run-time lib (&lt;em&gt;&lt;code&gt;libgnat.a&lt;/code&gt;&lt;/em&gt;) to the module's makefile. I am a little bit puzzled about why the previous stuff worked.&lt;/p&gt;
&lt;p&gt;After adding &lt;em&gt;"&lt;code&gt;rts/adalib/libgnat.a&lt;/code&gt;"&lt;/em&gt; to _&lt;code&gt;hello-y&lt;/code&gt; variable, the module loaded and produced the desired output:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ sudo insmod hello.ko 
$ dmesg &lt;span class="p"&gt;|&lt;/span&gt; tail -1
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;76863&lt;/span&gt;.379199&lt;span class="o"&gt;]&lt;/span&gt;  &lt;span class="m"&gt;42&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;h3&gt;Enumeration&lt;/h3&gt;
&lt;p&gt;To make the &lt;code&gt;Image&lt;/code&gt; attribute work with enumeration types I had to copy two additional files from the native run time:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;s-imenne.ads
s-imenne.adb
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;I also had to comment two additional restrictions in the &lt;code&gt;gnat.adc&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;-- pragma Discard_Names;&lt;/span&gt;
&lt;span class="c1"&gt;-- pragma Restrictions (No_Enumeration_Maps);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;What happens here is that the compiler will generate the strings and store them in the compiled binary.&lt;/p&gt;
&lt;p&gt;When compiling calls to &lt;code&gt;Some_Type'Image(Some_Value)&lt;/code&gt; the compiler will emit a call to an run-time function that will actually do the location of the correct string.&lt;/p&gt;
&lt;p&gt;Notice that &lt;code&gt;Some_Value&lt;/code&gt; can also be a variable, that is why the string must be resolved at run time.&lt;/p&gt;
&lt;h3&gt;Real Types&lt;/h3&gt;
&lt;p&gt;To add support for &lt;code&gt;Image&lt;/code&gt; of real types (fixed and floating point), a bunch of additional files should be copied:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;s-exnlli.adb
s-exnlli.ads
s-expllu.adb
s-expllu.ads
s-expuns.adb
s-expuns.ads
s-fatllf.ads
s-flocon.adb
s-flocon.ads
s-imglli.adb
s-imglli.ads
s-imgllu.adb
s-imgllu.ads
s-imgrea.adb
s-imgrea.ads
s-imguns.adb
s-imguns.ads
s-powtab.ads
s-unstyp.ads
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;I modified one of the file, &lt;code&gt;s-flocon.adb&lt;/code&gt; and removed the import of &lt;code&gt;__gnat_init_float&lt;/code&gt;. The Code that supposed to &lt;a href="http://wiki.osdev.org/FPU"&gt;initialize&lt;/a&gt; the FPU does nothing now. I have no problems with that, so far. After all, the Linux kernel should have already did the initialization before our module is being insert.&lt;/p&gt;
&lt;p&gt;Additionally a fixed point restriction should be lifted from &lt;code&gt;gnat.adc&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;--  pragma Restrictions (No_Fixed_Point);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;h3&gt;Final Words&lt;/h3&gt;
&lt;p&gt;That is all for now. Next I will do &lt;code&gt;Interfaces&lt;/code&gt; package and start binding functions from the Kernel itself.&lt;/p&gt;</content><category term="ada"></category><category term="linux"></category><category term="kernel"></category><category term="os"></category></entry><entry><title>Writing Linux Modules in Ada - Part 2</title><link href="http://www.nihamkin.com/2016/11/05/writing-linux-modules-in-ada-part-2" rel="alternate"></link><published>2016-11-05T17:30:00+02:00</published><updated>2016-11-05T17:30:00+02:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2016-11-05:/2016/11/05/writing-linux-modules-in-ada-part-2</id><summary type="html">&lt;p&gt;In this article I will focus on implementing the secondary stack of the runtime. &lt;br&gt; Secondary stack is required if we desire functions to return objects of unconstrained types. This in turn required for the &lt;code&gt;'Image&lt;/code&gt; attribute, which is used extensively in the &lt;code&gt;Interfaces.C&lt;/code&gt; package.&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a class="github-button" href="https://github.com/alkhimey/Ada_Kernel_Module_Toolkit/"  data-style="mega" aria-label="View alkhimey/Ada_Kernel_Module_Toolkit on GitHub"&gt;View on Github&lt;/a&gt;
&lt;a class="github-button" href="https://github.com/alkhimey/Ada_Kernel_Module_Toolkit" data-icon="octicon-star" data-style="mega" data-count-href="/alkhimey/Ada_Kernel_Module_Toolkit/stargazers" data-count-api="/repos/alkhimey/Ada_Kernel_Module_Toolkit#stargazers_count" data-count-aria-label="# stargazers on GitHub" aria-label="Star alkhimey/Ada_Kernel_Module_Toolkit on GitHub"&gt;Star on Github&lt;/a&gt;
&lt;a class="github-button" href="https://github.com/alkhimey/Ada_Kernel_Module_Toolkit/archive/blog-post-pt-2.zip" data-icon="octicon-cloud-download" data-style="mega" aria-label="Download alkhimey/Ada_Kernel_Module_Toolkit on GitHub"&gt;Download Pt-2&lt;/a&gt;&lt;/p&gt;
&lt;script async defer src="https://buttons.github.io/buttons.js"&gt;&lt;/script&gt;

&lt;!--
&lt;a href="https://github.com/alkhimey/Ada_Kernel_Module_Toolkit"&gt;&lt;img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/a6677b08c955af8400f44c6298f40e7d19cc5b2d/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677261795f3664366436642e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png"&gt;&lt;/a&gt;
--&gt;

&lt;p&gt;In the &lt;a href="/2016/10/23/writing-linux-modules-in-ada-part-1/"&gt;previous post&lt;/a&gt; I demonstrated that writing Linux kernel modules in Linux is not science fiction.&lt;/p&gt;
&lt;p&gt;Yet, the produced module was extremely simple. Before improving it, some foundation needs to be added. Today I want to introduce the secondary stack.&lt;/p&gt;
&lt;h2&gt;Secondary Stack&lt;/h2&gt;
&lt;p&gt;The existence of the secondary stack allows functions to return objects of unconstrained types.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Get_Answer&lt;/span&gt; &lt;span class="nf"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;String&lt;/span&gt; &lt;span class="kr"&gt;is&lt;/span&gt;
&lt;span class="kr"&gt;begin&lt;/span&gt;
   &lt;span class="kr"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Forty Two&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="nf"&gt;Get_Answer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The length of the returned &lt;code&gt;String&lt;/code&gt; is unknown during compilation, and therefore it is problematic to allocate space for it on the primary stack. In this particular example the compiler might deduce the maximum size statically but generally, the size of the returned string could also depend on user input.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://docs.adacore.com/gnat_ugx-docs/html/gnat_ugx/gnat_ugx/the_secondary_stack.html"&gt;This article&lt;/a&gt; has a good explanation about this stack.&lt;/p&gt;
&lt;p&gt;The secondary stack is required for &lt;code&gt;'Image&lt;/code&gt; attribute to work, which is in turn used in &lt;code&gt;Interfaces.C&lt;/code&gt; package. Therefore it is important for the purpose of writing bindings to Kernel functions.&lt;/p&gt;
&lt;p&gt;A &lt;a href="https://gcc.gnu.org/onlinedocs/gnat_ugn/Switches-for-gnatbind.html#index-g_t-D-_0028gnatbind_0029-683"&gt;compiler switch&lt;/a&gt;, as well as an attribute can control the size and type of the secondary stack.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;-D`nn'[k|m]&lt;/p&gt;
&lt;p&gt;This switch can be used to change the default secondary stack size value to a specified size nn, which is expressed in bytes by default, or in kilobytes when suffixed with k or in megabytes when suffixed with m.&lt;/p&gt;
&lt;p&gt;The secondary stack is used to deal with functions that return a variable sized result, for example a function returning an unconstrained String. There are two ways in which this secondary stack is allocated.&lt;/p&gt;
&lt;p&gt;For most targets, the secondary stack is growing on demand and is allocated as a chain of blocks in the heap. The -D option is not very relevant. It only give some control over the size of the allocated blocks (whose size is the minimum of the default secondary stack size value, and the actual size needed for the current allocation request).&lt;/p&gt;
&lt;p&gt;For certain targets, notably VxWorks 653, the secondary stack is allocated by carving off a fixed ratio chunk of the primary task stack. The -D option is used to define the size of the environment task's secondary stack.
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;task&lt;/span&gt; &lt;span class="n"&gt;A_Task&lt;/span&gt; &lt;span class="kn"&gt;with&lt;/span&gt;
  &lt;span class="nn"&gt;Storage_Size&lt;/span&gt;         &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;Secondary_Stack_Size&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;As can be understood from the example, each task has it's own secondary stack. We of course need only one secondary stack as there are no tasks in our run time.&lt;/p&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;The implementation of the secondary stack is located in &lt;strong&gt;s-secsta.ads&lt;/strong&gt; and &lt;strong&gt;s-secsta.ads&lt;/strong&gt; files.&lt;/p&gt;
&lt;p&gt;I copied these files from the native rts of the installed gnat (&lt;em&gt;/usr/gnat/lib/gcc/x86_64-pc-linux-gnu/4.9.4/rts-native/adainclude/s-secsta.adb&lt;/em&gt;) and started editing them.&lt;/p&gt;
&lt;p&gt;I uploaded the diff &lt;a href="https://gist.github.com/alkhimey/0e859655e32a5289e95ee193d76fabdf/revisions"&gt;here&lt;/a&gt;. Please Ignore the difference at the license header, I had some confusion between AdaCore and FSF versions.&lt;/p&gt;
&lt;p&gt;The interface is quite simple. A set of function like &lt;code&gt;Init&lt;/code&gt;, &lt;code&gt;Allocate&lt;/code&gt;, &lt;code&gt;Mark&lt;/code&gt; that receive an pointer to the stack in the form of an &lt;code&gt;System.Address&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The reason to receive the stack as a parameter is because there might be several stacks in the system, for example a stack for each task. In this Kernel run time there are no tasks, so only one stack is required. Nevertheless, the interface can not be changed as gnat tools are expecting these exact signatures.&lt;/p&gt;
&lt;p&gt;The implementation is even less Ada-iomatic. Untyped chunks of memory, unchecked conversions, unchecked deallocations and a lot of pointer work.&lt;/p&gt;
&lt;p&gt;I decided not to change the implementation very much. Only remove the unnecessary stuff.&lt;/p&gt;
&lt;p&gt;In the original code, dynamic stack is allocated on the heap as a linked list of memory chunks.&lt;/p&gt;
&lt;p&gt;For static stack, if a stack of less that 10K is required than a memory chunk that is defined as a global in the package is used. Otherwise a memory chunk of the appropriate size is dynamically allocated.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;   &lt;span class="n"&gt;Default_Secondary_Stack_Size&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Natural&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="c1"&gt;--  Default size of a secondary stack. May be modified by binder -D switch&lt;/span&gt;
   &lt;span class="c1"&gt;--  which causes the binder to generate an appropriate assignment in the&lt;/span&gt;
   &lt;span class="c1"&gt;--  binder generated file.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Throughout the code, static and dynamic cases are distinguished with &lt;code&gt;SS_Ratio_Dynamic&lt;/code&gt;. There is almost no shared code.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;   &lt;span class="no"&gt;SS_Ratio_Dynamic&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;constant&lt;/span&gt; &lt;span class="kt"&gt;Boolean&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt;
                        &lt;span class="n"&gt;Parameters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sec_Stack_Percentage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Parameters&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dynamic&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="c1"&gt;--  There are two entirely different implementations of the secondary&lt;/span&gt;
   &lt;span class="c1"&gt;--  stack mechanism in this unit, and this Boolean is used to select&lt;/span&gt;
   &lt;span class="c1"&gt;--  between them (at compile time, so the generated code will contain&lt;/span&gt;
   &lt;span class="c1"&gt;--  only the code for the desired variant). If SS_Ratio_Dynamic is&lt;/span&gt;
   &lt;span class="c1"&gt;--  True, then the secondary stack is dynamically allocated from the&lt;/span&gt;
   &lt;span class="c1"&gt;--  heap in a linked list of chunks. If SS_Ration_Dynamic is False,&lt;/span&gt;
   &lt;span class="c1"&gt;--  then the secondary stack is allocated statically by grabbing a&lt;/span&gt;
   &lt;span class="c1"&gt;--  section of the primary stack and using it for this purpose.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Since currently the run time does not support any kind of dynamic allocations, I removed all the dynamic stack branches, as well as the dynamic allocation of the static stack. This renders &lt;strong&gt;&lt;code&gt;-D&lt;/code&gt;&lt;/strong&gt; flag to have no effect on the code, a 10K stack is always allocated.&lt;/p&gt;
&lt;p&gt;It is true that dynamic allocation in the kernel can be done with &lt;code&gt;kmalloc&lt;/code&gt;, but it is a bit tricky for me at this stage.&lt;/p&gt;
&lt;p&gt;To allow the module code use the stack, I had to comment out a pragma restriction in the &lt;strong&gt;gnat.adc&lt;/strong&gt; file.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;--pragma Restrictions (No_Secondary_Stack);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This file contains a set of pragmas that are applied globally to the project. A gpr file configuration of the &lt;em&gt;adc&lt;/em&gt; file might look like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;package&lt;/span&gt; &lt;span class="nc"&gt;Builder&lt;/span&gt; &lt;span class="kr"&gt;is&lt;/span&gt;
   &lt;span class="kr"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Global_Configuration_Pragmas&lt;/span&gt; &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;gnat.adc&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="nf"&gt;Builder&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;There are many other restrictions in that file that prevent using run time features that are not implemented.&lt;/p&gt;
&lt;p&gt;After doing all this and adding a test module that demonstrates a function that return unconstrained string, I stumbled upon a strange error:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nv"&gt;$sudo&lt;/span&gt; insmod hello.ko 
insmod: ERROR: could not insert module hello.ko: Invalid module format
&lt;span class="nv"&gt;$dmesg&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; tail -2
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;36648&lt;/span&gt;.395725&lt;span class="o"&gt;]&lt;/span&gt; module: overflow in relocation &lt;span class="nb"&gt;type&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt; val ffffffffc04da000
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="m"&gt;36648&lt;/span&gt;.395731&lt;span class="o"&gt;]&lt;/span&gt; module: &lt;span class="sb"&gt;`&lt;/span&gt;hello&lt;span class="err"&gt;&amp;#39;&lt;/span&gt; likely not compiled with -mcmodel&lt;span class="o"&gt;=&lt;/span&gt;kernel
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;It turns out I had to add the "&lt;code&gt;-mcmodel=kernel&lt;/code&gt;" flag to the compilation section in the &lt;em&gt;gpr&lt;/em&gt; file.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;That is it. You can try it yourself using the "Download Pt-2" link at the top of the page. The "Download Pt-X" links are snapshots of the git repository that are compatible with the appropriate blog post. So even as I continue to improve the toolkit, readers will still be able to play with the original version.&lt;/p&gt;
&lt;p&gt;My next steps will be to add &lt;code&gt;'Image&lt;/code&gt; and &lt;code&gt;Interfaces.C&lt;/code&gt;. And after that I will be able to bind some kernel functions.&lt;/p&gt;
&lt;p&gt;Stay tuned :)&lt;/p&gt;</content><category term="ada"></category><category term="linux"></category><category term="kernel"></category><category term="os"></category></entry><entry><title>Writing Linux Modules in Ada - Part 1</title><link href="http://www.nihamkin.com/2016/10/23/writing-linux-modules-in-ada-part-1" rel="alternate"></link><published>2016-10-23T13:30:00+03:00</published><updated>2016-10-23T13:30:00+03:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2016-10-23:/2016/10/23/writing-linux-modules-in-ada-part-1</id><summary type="html">&lt;p&gt;In the following series of blog posts I will document my attempts to write Linux modules using the Ada language. &lt;br&gt; In part 1, I will demonstrate how to write in Ada and build a simple "hello world" Linux kernel module. &lt;br&gt; Additionally, I will introduce a basic customized Ada runtime to support our "hello world" module. This runtime will be extended in subsequent articles in the series.&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a class="github-button" href="https://github.com/alkhimey/Ada_Kernel_Module_Toolkit/"  data-style="mega" aria-label="View alkhimey/Ada_Kernel_Module_Toolkit on GitHub"&gt;View on Github&lt;/a&gt;
&lt;a class="github-button" href="https://github.com/alkhimey/Ada_Kernel_Module_Toolkit" data-icon="octicon-star" data-style="mega" data-count-href="/alkhimey/Ada_Kernel_Module_Toolkit/stargazers" data-count-api="/repos/alkhimey/Ada_Kernel_Module_Toolkit#stargazers_count" data-count-aria-label="# stargazers on GitHub" aria-label="Star alkhimey/Ada_Kernel_Module_Toolkit on GitHub"&gt;Star on Github&lt;/a&gt;&lt;/p&gt;
&lt;script async defer src="https://buttons.github.io/buttons.js"&gt;&lt;/script&gt;

&lt;!--
&lt;a href="https://github.com/alkhimey/Ada_Kernel_Module_Toolkit"&gt;&lt;img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/a6677b08c955af8400f44c6298f40e7d19cc5b2d/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677261795f3664366436642e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png"&gt;&lt;/a&gt;
--&gt;

&lt;p&gt;In the following series of blog posts I will document my attempts to write Linux modules using the Ada language.&lt;/p&gt;
&lt;p&gt;I am not a professional and my knowledge of the Linux kernel and gnat is not comprehensive. Please pardon me for any inaccuracies I make.&lt;/p&gt;
&lt;h2&gt;Introduction and Motivation&lt;/h2&gt;
&lt;p&gt;Linux module is a binary that can be dynamically loaded and linked into the Kernel. One major use case is device drivers. Traditionally Linux modules are written in C and built using &lt;em&gt;kbuild&lt;/em&gt;, an elaborate build system that is also used to build the kernel itself.&lt;/p&gt;
&lt;p&gt;Code written for a module runs in the kernel with the privileges of the kernel, meaning that a programming error can cause anomalies such a system reboot, memory corruption of applications, data corruption of the hard disk and more.&lt;/p&gt;
&lt;p&gt;Ada is a language that was designed specifically for embedded safety critical applications which makes it more suitable for writing device drivers.&lt;/p&gt;
&lt;h2&gt;Preparations&lt;/h2&gt;
&lt;p&gt;First, I investigated the current process of writing and building modules. An example tutorial can be found &lt;a href="http://www.tldp.org/LDP/lkmpg/2.6/html/lkmpg.html"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In an nutshell, it is required to create a file that looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cm"&gt;/*  &lt;/span&gt;
&lt;span class="cm"&gt; *  hello-1.c - The simplest kernel module.&lt;/span&gt;
&lt;span class="cm"&gt; */&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;linux/module.h&amp;gt;   /* Needed by all modules */&lt;/span&gt;&lt;span class="cp"&gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;linux/kernel.h&amp;gt;   /* Needed for KERN_INFO */&lt;/span&gt;&lt;span class="cp"&gt;&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;init_module&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;KERN_INFO&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Hello world 1.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="cm"&gt;/* &lt;/span&gt;
&lt;span class="cm"&gt;     * A non 0 return means init_module failed; module can&amp;#39;t be loaded. &lt;/span&gt;
&lt;span class="cm"&gt;     */&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;cleanup_module&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;KERN_INFO&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Goodbye world 1.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Additionally, a &lt;em&gt;mkefile&lt;/em&gt; that looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nv"&gt;obj-m&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; hello-1.o

&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    make  -C /lib/modules/&lt;span class="k"&gt;$(&lt;/span&gt;shell uname -r&lt;span class="k"&gt;)&lt;/span&gt;/build &lt;span class="nv"&gt;M&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;PWD&lt;span class="k"&gt;)&lt;/span&gt; modules
&lt;span class="nf"&gt;clean&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    make  -C /lib/modules/&lt;span class="k"&gt;$(&lt;/span&gt;shell uname -r&lt;span class="k"&gt;)&lt;/span&gt;/build &lt;span class="nv"&gt;M&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$(&lt;/span&gt;PWD&lt;span class="k"&gt;)&lt;/span&gt; clean
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Calling make will produce a &lt;em&gt;&lt;em&gt;.ko&lt;/em&gt;&lt;/em&gt; file which is the actual loadable module. It can be loaded and removed using the &lt;code&gt;insmodule&lt;/code&gt; and &lt;code&gt;rmodule&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The difference between a &lt;em&gt;.ko&lt;/em&gt; and &lt;em&gt;.o&lt;/em&gt; file is the additional memory sections added by the linker.&lt;/p&gt;
&lt;h2&gt;The Strategy&lt;/h2&gt;
&lt;p&gt;It is very tempting to abolish the cumbersome &lt;em&gt;kbuild&lt;/em&gt; system and use a &lt;em&gt;gpr&lt;/em&gt; file for the whole compilation and linkage. Unfortunately the makefiles that &lt;em&gt;kbuild&lt;/em&gt; is made of are too complex for me to understand, and I was able to imitate everything it does to produce the "&lt;em&gt;.ko&lt;/em&gt;" file. Additionally, it is not safe to work around the &lt;em&gt;kbuild&lt;/em&gt; system as the internal details might change it future versions of the kernel.&lt;/p&gt;
&lt;p&gt;So instead, I envision the following strategy. All the "logic" of the module will reside in Ada functions that will be compiled into a static library. The main file will be written in C and will consist of wrappers (eg &lt;code&gt;init_module&lt;/code&gt;, &lt;code&gt;cleanup_module&lt;/code&gt;) that will call the Ada functions. We will tell &lt;em&gt;kbuild&lt;/em&gt; about the existence of the Ada library, so it will link it into the module, and everyone will be happy.&lt;/p&gt;
&lt;h2&gt;Hello World with Ada&lt;/h2&gt;
&lt;h3&gt;The Code&lt;/h3&gt;
&lt;p&gt;The Ada files contain a function which always return a constant 42. &lt;code&gt;pragma Export&lt;/code&gt; is used to export the &lt;code&gt;ada_foo&lt;/code&gt; symbol.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;package&lt;/span&gt; &lt;span class="nc"&gt;Ada_Foo_Pack&lt;/span&gt; &lt;span class="kr"&gt;is&lt;/span&gt;

   &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Ada_Foo&lt;/span&gt; &lt;span class="nf"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;private&lt;/span&gt;
   &lt;span class="kr"&gt;pragma&lt;/span&gt; &lt;span class="cp"&gt;Export&lt;/span&gt;
      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Convention&lt;/span&gt;    &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;Entity&lt;/span&gt;        &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Ada_Foo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;External_Name&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;ada_foo&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="nf"&gt;Ada_Foo_Pack&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;:::&lt;/span&gt;&lt;span class="n"&gt;ada&lt;/span&gt;
&lt;span class="kd"&gt;package&lt;/span&gt; &lt;span class="kd"&gt;body&lt;/span&gt; &lt;span class="nc"&gt;Ada_Foo_Pack&lt;/span&gt; &lt;span class="kr"&gt;is&lt;/span&gt;

   &lt;span class="n"&gt;Ultimate_Unswer&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Integer&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Ada_Foo&lt;/span&gt; &lt;span class="nf"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Integer&lt;/span&gt; &lt;span class="kr"&gt;is&lt;/span&gt;
   &lt;span class="kr"&gt;begin&lt;/span&gt;

      &lt;span class="kr"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Ultimate_Unswer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="nf"&gt;Ada_Foo&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;begin&lt;/span&gt;

   &lt;span class="c1"&gt;--  This line of code will run during elaboration&lt;/span&gt;
   &lt;span class="c1"&gt;--&lt;/span&gt;
   &lt;span class="n"&gt;Ultimate_Unswer&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="nf"&gt;Ada_Foo_Pack&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The &lt;em&gt;C&lt;/em&gt; file performs the elaboration of Ada libraries by calling &lt;code&gt;adakernelmoduleinit&lt;/code&gt;, and then calls &lt;code&gt;prink&lt;/code&gt; with the value returned by the Ada function.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;linux/module.h&amp;gt; /* Needed by all modules */&lt;/span&gt;&lt;span class="cp"&gt;&lt;/span&gt;
&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;linux/kernel.h&amp;gt; /* Needed for KERN_INFO */&lt;/span&gt;&lt;span class="cp"&gt;&lt;/span&gt;

&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;adakernelmoduleinit&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;extern&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;ada_foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;init_module&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;adakernelmoduleinit&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;printk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;KERN_ERR&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Hello Ada %d.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ada_foo&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;cleanup_module&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printk&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;KERN_ERR&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Goodbye Ada.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;So far nothing too complicated. However when building the module, &lt;em&gt;kbuild&lt;/em&gt; complaints about many missing symbols. These missing symbols are part of the "Run Time". The calls to these methods are either produced by a compiler (for example &lt;code&gt;delay 0.1;&lt;/code&gt; will implicitly call functions from the calendar package) or produced by the binder (initialization of the run time).&lt;/p&gt;
&lt;p&gt;Normally, these functions can be found in &lt;em&gt;libgnat.so&lt;/em&gt;, but this dynamic library is not available in the kernel space.&lt;/p&gt;
&lt;p&gt;I also tried to tell &lt;em&gt;kbuild&lt;/em&gt; to statically link with &lt;em&gt;libgnat.a&lt;/em&gt;, but it turns out that &lt;em&gt;libgnat.a&lt;/em&gt; is referencing other symbols which are supposed to be located in further libraries which complicates everything.&lt;/p&gt;
&lt;p&gt;On top of this, linking the standard run time to the kernel does not make sense as it uses system calls (for example to open a file) which are available only in user space.&lt;/p&gt;
&lt;h3&gt;The Run Time&lt;/h3&gt;
&lt;p&gt;The solution is to build a custom, degraded run time. Such run times are also known as "&lt;em&gt;Zero Footprint&lt;/em&gt;".&lt;/p&gt;
&lt;p&gt;To achieve this I followed "&lt;em&gt;&lt;a href="http://wiki.osdev.org/Ada_Bare_bones"&gt;Ada Bare Bones&lt;/a&gt;&lt;/em&gt;" tutorial that was written by Luke A. Guest.&lt;/p&gt;
&lt;p&gt;To summarize, for building a run time, you will need &lt;em&gt;adainclude&lt;/em&gt; and &lt;em&gt;adalib&lt;/em&gt; directories. The first one will contain a copy of some of the files from the original run time, as well as &lt;em&gt;system.ads&lt;/em&gt;, &lt;em&gt;gnat.ads&lt;/em&gt; and additional custom packages. The second directory will contain the compiled library &lt;em&gt;libgnat.a&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;When building the kernel module library, every relevant tool needs to be called with the "&lt;code&gt;--RTS=&lt;/code&gt;" flag that specify the path to the directory that contains the above two.&lt;/p&gt;
&lt;p&gt;Deprating a little bit from Luke's tutorial, I did some modifications to the directory structure, the compiler flags, removed the console package and changed the &lt;em&gt;last chance handler&lt;/em&gt; into a &lt;em&gt;null&lt;/em&gt; function.&lt;/p&gt;
&lt;p&gt;The final directory structure would look like the following diagram. I have uploaded the complete project to githhub, and you can find this version of the project by looking for the &lt;a href="https://github.com/alkhimey/Ada_Kernel_Module_Toolkit/tree/blog-post-pt-1"&gt;&lt;em&gt;blog-post-pt-1&lt;/em&gt; git tag&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a class="github-button" href="https://github.com/alkhimey/Ada_Kernel_Module_Toolkit/archive/blog-post-pt-1.zip" data-icon="octicon-cloud-download" data-style="mega" aria-label="Download alkhimey/Ada_Kernel_Module_Toolkit on GitHub"&gt;Download Pt-1&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;.
├── gnat.adc
├── kernel_module_lib.gpr
├── lib
├── main.c
├── Makefile
├── obj
├── rts
│   ├── adainclude
│   │   ├── ada.ads
│   │   ├── a-unccon.ads
│   │   ├── a-uncdea.ads
│   │   ├── gnat.ads
│   │   ├── g-souinf.ads
│   │   ├── interfac.ads
│   │   ├── last_chance_handler.adb
│   │   ├── last_chance_handler.ads
│   │   ├── s-atacco.adb
│   │   ├── s-atacco.ads
│   │   ├── s-maccod.ads
│   │   ├── s-stoele.adb
│   │   ├── s-stoele.ads
│   │   └── system.ads
│   ├── adalib
│   ├── gnat.gpr
│   └── obj
└── src
    ├── ada_foo_pack.adb
    └── ada_foo_pack.ads
&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;The example module I have written is very simple proof of concept. The Ada part does not even use any of symbols exported by the kernel. In future articles I will make an attempt to write a usefull kernel module that actually does stuff.&lt;/p&gt;</content><category term="ada"></category><category term="linux"></category><category term="kernel"></category><category term="os"></category></entry><entry><title>Connecting MSP430 with ILI9341 TFT Display</title><link href="http://www.nihamkin.com/2016/04/30/connecting-msp430-with-ili9341-tft-display" rel="alternate"></link><published>2016-04-30T20:00:00+03:00</published><updated>2016-04-30T20:00:00+03:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2016-04-30:/2016/04/30/connecting-msp430-with-ili9341-tft-display</id><summary type="html">&lt;p&gt;&lt;center&gt;
&lt;img alt="msp430 launcpad connected to ili9341 display" src="/files/msp430photo.jpg"&gt;
&lt;/center&gt;&lt;/p&gt;
&lt;p&gt;In the previous post I described how to connect ESP8266 with an ILI9431 TFT display using the Adafruit library. Texas Instruments' MSP430 is another popular low cost 3.3v MCU used by the maker community. It has Energia which is an IDE forked from  and compatible to the Arduino IDE …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;center&gt;
&lt;img alt="msp430 launcpad connected to ili9341 display" src="/files/msp430photo.jpg"&gt;
&lt;/center&gt;&lt;/p&gt;
&lt;p&gt;In the previous post I described how to connect ESP8266 with an ILI9431 TFT display using the Adafruit library. Texas Instruments' MSP430 is another popular low cost 3.3v MCU used by the maker community. It has Energia which is an IDE forked from  and compatible to the Arduino IDE. Therefore porting the Adafruit library to work with it should be almost trivial.&lt;/p&gt;
&lt;p&gt;The first step is to obtain an MSP430 launchpad. You will need one that come with an MCU that has at least 16Kb of FLASH, I will explain this requirement later in this post. The currently sold 9.99$ &lt;a href="http://www.ti.com/ww/en/launchpad/launchpads-msp430-msp-exp430g2.html#tabs"&gt;value line&lt;/a&gt; version which comes with msp430g2553 MCU is sufficient. Older revisions of this launchpad might come with MCUs that does not have enough space.&lt;/p&gt;
&lt;p&gt;After obtaining the launchpad, download and install &lt;a href="http://energia.nu"&gt;Energia&lt;/a&gt;. You might want to try to upload and run some of the basic examples before advancing forward.&lt;/p&gt;
&lt;p&gt;Another requirement is to enable hardware UART by rotating jumpers on the launchpad as explained with &lt;a href="http://energia.nu/Serial.html"&gt;this tutorial&lt;/a&gt;. This will enable receiving debug messages from the graphicstest sketch.&lt;/p&gt;
&lt;p&gt;As Energia is an Arduino-like environment, therefore not many &lt;a href="https://github.com/alkhimey/Adafruit_ILI9341/commit/d232e057a852b474b509c42bb5a237d2f1905538"&gt;changes&lt;/a&gt; to the library were required. The graphicstest.ino example sketch had to be modified by excluding textTest function from the sketch when compiling for &lt;em&gt;msp430g2553&lt;/em&gt;. This is because this MCU has 16Kb of ROM memory, while the full sketch size is ~19Kb. There are MCUs with even lower ROM sizes (eg &lt;em&gt;&lt;a href="http://www.ti.com/product/MSP430G2452"&gt;msp430g2452&lt;/a&gt;&lt;/em&gt; which has 8Kb), if anyone would like to try this sketch, it will be required to remove more test function to reduce the size even further.&lt;/p&gt;
&lt;p&gt;Now &lt;a href="https://github.com/alkhimey/Adafruit_ILI9341/tree/msp430-support"&gt;download&lt;/a&gt; the modified library and place it in the &lt;a href="http://energia.nu/Guide_Environment.html#libraries"&gt;library&lt;/a&gt; folder of Energia. If you are cloning the repo, make sure to checkout "&lt;em&gt;msp430-support&lt;/em&gt;" branch. After restarting Energia, you will be able to see the &lt;em&gt;Adafruit_ILI9341&lt;/em&gt; examples in the &lt;em&gt;Examples&lt;/em&gt; list.&lt;/p&gt;
&lt;p&gt;You will also need to download and place the &lt;a href="https://github.com/adafruit/Adafruit-GFX-Library"&gt;Adafruit_GFX_Library&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Make the following connections. Those connections are specific to &lt;em&gt;msp430g2553&lt;/em&gt; launchpad. Other launchpads in this family have different pins for hardware SPI, so be careful and look it up in the reference.&lt;/p&gt;
&lt;p&gt;&lt;center&gt;
&lt;img alt="msp430g32553 pinout" src="/files/LaunchPadMSP430G2553-V1.5-700px.jpg"&gt;
&lt;/center&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align="left"&gt;ILI9341&lt;/th&gt;
&lt;th align="center"&gt;&lt;/th&gt;
&lt;th align="right"&gt;MSP430&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align="left"&gt;SDD/MISO&lt;/td&gt;
&lt;td align="center"&gt;&amp;#8660;&lt;/td&gt;
&lt;td align="right"&gt;P1.6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;LED&lt;/td&gt;
&lt;td align="center"&gt;&amp;#8660;&lt;/td&gt;
&lt;td align="right"&gt;3.3V&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;SCK&lt;/td&gt;
&lt;td align="center"&gt;&amp;#8660;&lt;/td&gt;
&lt;td align="right"&gt;P1.5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;SDI/MOSI&lt;/td&gt;
&lt;td align="center"&gt;&amp;#8660;&lt;/td&gt;
&lt;td align="right"&gt;P1.7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;DC/RS&lt;/td&gt;
&lt;td align="center"&gt;&amp;#8660;&lt;/td&gt;
&lt;td align="right"&gt;P2.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;RESET&lt;/td&gt;
&lt;td align="center"&gt;&amp;#8660;&lt;/td&gt;
&lt;td align="right"&gt;3.3V&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;CS&lt;/td&gt;
&lt;td align="center"&gt;&amp;#8660;&lt;/td&gt;
&lt;td align="right"&gt;P2.2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;GND&lt;/td&gt;
&lt;td align="center"&gt;&amp;#8660;&lt;/td&gt;
&lt;td align="right"&gt;GND&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;VCC&lt;/td&gt;
&lt;td align="center"&gt;&amp;#8660;&lt;/td&gt;
&lt;td align="right"&gt;3.3V&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;DC and CS can be any of the GPIO pins, yet they need to be consistent with the values passed to the library constructor.&lt;/p&gt;
&lt;p&gt;Here are the results of the benchmark, textTest did not run therefore its results are 0.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;ILI9341 Test!
Display Power Mode: 0x9C
MADCTL Mode: 0x48
Pixel Format: 0x5
Image Format: 0x0
Self Diagnostic: 0xC0
Benchmark                Time (microseconds)
Screen fill              3986432
Text                     0
Lines                    6518272
Horiz/Vert Lines         345088
Rectangles (outline)     235520
Rectangles (filled)      8283648
Circles (filled)         2135552
Circles (outline)        2848768
Triangles (outline)      2067456
Triangles (filled)       3433984
Rounded rects (outline)  1003008
Rounded rects (filled)   9315840
Done!
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;It is also possible to use software SPI the example sketch has a commented section that describes how to perform this. Being said, this option is extremely slow and I do not advice using it with MSP430.&lt;/p&gt;</content><category term="ili9341"></category><category term="msp430"></category><category term="embedded"></category></entry><entry><title>Connecting ESP8266 with ILI9341 TFT Display</title><link href="http://www.nihamkin.com/2016/03/04/connecting-esp8266-with-ili9341-tft-display" rel="alternate"></link><published>2016-03-04T15:00:00+02:00</published><updated>2016-03-04T15:00:00+02:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2016-03-04:/2016/03/04/connecting-esp8266-with-ili9341-tft-display</id><summary type="html">&lt;p&gt;ESP8266 was popular with hobbyists for a long time. Recently I decided to join the hype and bought this module along with a super cheap color TFT display (ILI9341). In this post I will describe the process of connecting those two, using already available code written for Arduino.&lt;/p&gt;
&lt;p&gt;&lt;center&gt;
&lt;img alt="ESP8288 connected to ILI9341" src="/files/esp1.jpg"&gt;
&lt;/center&gt;&lt;/p&gt;
&lt;p&gt;First step …&lt;/p&gt;</summary><content type="html">&lt;p&gt;ESP8266 was popular with hobbyists for a long time. Recently I decided to join the hype and bought this module along with a super cheap color TFT display (ILI9341). In this post I will describe the process of connecting those two, using already available code written for Arduino.&lt;/p&gt;
&lt;p&gt;&lt;center&gt;
&lt;img alt="ESP8288 connected to ILI9341" src="/files/esp1.jpg"&gt;
&lt;/center&gt;&lt;/p&gt;
&lt;p&gt;First step is to set up Arduino IDE to work with ESP8266.&lt;/p&gt;
&lt;p&gt;There is an excellent &lt;a href="https://learn.sparkfun.com/tutorials/esp8266-thing-hookup-guide/installing-the-esp8266-arduino-addon"&gt;tutorial&lt;/a&gt;  on Sparkfun's website that explains how to do this.&lt;/p&gt;
&lt;p&gt;Once Arduino IDE is setup, you need to get the Adafruit ILI9341 library. Currently version 1.0.1 is available through Arduino IDE's "&lt;em&gt;manage libraries&lt;/em&gt;" interface. Unfortunately this version is broken for ESP8266.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update 2019:&lt;/strong&gt; There is a faster library with more features called TFT_eSPI
and you can use it instead. See explanation in the
&lt;a href="better-tft-library-for-esp8266"&gt; follow up blog post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Until this is fixed, you have to get it directly from the &lt;a href="https://github.com/adafruit/Adafruit_ILI9341"&gt;Adafruit repository&lt;/a&gt;. One can &lt;code&gt;git clone&lt;/code&gt; it or download the zip. Put it into the arduino &lt;em&gt;library&lt;/em&gt; folder. The exact location is OS and IDE version depndent.&lt;/p&gt;
&lt;p&gt;After this, fire up the IDE. If previous step was performed correctly, Under the &lt;em&gt;file-&amp;gt;examples&lt;/em&gt; sub-menu you should be able to see &lt;em&gt;Adafruit ILI9341&lt;/em&gt; menu. Choose the &lt;em&gt;graphicstest&lt;/em&gt; example and try to compile it. If it compiles fine, you are ready for wiring.&lt;/p&gt;
&lt;p&gt;Wiring is a bit tricky. First look at the diagram of the nodemcu v3 board:&lt;/p&gt;
&lt;p&gt;&lt;center&gt;
&lt;img alt="nodemcu v3 lolin" src="/files/esp8266-nodemcu-dev-kit-v3-pins-700px.jpg"&gt;
&lt;/center&gt;&lt;/p&gt;
&lt;p&gt;Make the following connections:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align="left"&gt;ILI9341&lt;/th&gt;
&lt;th align="center"&gt;&lt;/th&gt;
&lt;th align="right"&gt;ESP8266&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align="left"&gt;SDD/MISO&lt;/td&gt;
&lt;td align="center"&gt;&amp;#8660;&lt;/td&gt;
&lt;td align="right"&gt;D6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;LED&lt;/td&gt;
&lt;td align="center"&gt;&amp;#8660;&lt;/td&gt;
&lt;td align="right"&gt;3.3V&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;SCK&lt;/td&gt;
&lt;td align="center"&gt;&amp;#8660;&lt;/td&gt;
&lt;td align="right"&gt;D5&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;SDI/MOSI&lt;/td&gt;
&lt;td align="center"&gt;&amp;#8660;&lt;/td&gt;
&lt;td align="right"&gt;D7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;DC/RS&lt;/td&gt;
&lt;td align="center"&gt;&amp;#8660;&lt;/td&gt;
&lt;td align="right"&gt;D1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;RESET&lt;/td&gt;
&lt;td align="center"&gt;&amp;#8660;&lt;/td&gt;
&lt;td align="right"&gt;3.3V&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;CS&lt;/td&gt;
&lt;td align="center"&gt;&amp;#8660;&lt;/td&gt;
&lt;td align="right"&gt;D2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;GND&lt;/td&gt;
&lt;td align="center"&gt;&amp;#8660;&lt;/td&gt;
&lt;td align="right"&gt;GND&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;VCC&lt;/td&gt;
&lt;td align="center"&gt;&amp;#8660;&lt;/td&gt;
&lt;td align="right"&gt;3.3V&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Make sure you connect all display's pins. Some tutorials do not mention RESET and LED pins and it took me some time to figure out that these can not be left floating.&lt;/p&gt;
&lt;p&gt;Now you need to alter the example sketch to reflect the fact that we chose D1 and D2 for CS and DC. Edit the configuration lines to be:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;// For the Adafruit shield, these are the default.&lt;/span&gt;
&lt;span class="cp"&gt;#define TFT_DC D1&lt;/span&gt;
&lt;span class="cp"&gt;#define TFT_CS D2&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Now connect the board to the computer, build and upload. You should be able to see a a test pattern start running on the TFT screen.&lt;/p&gt;
&lt;p&gt;Unfortunately, at some point the test pattern will freeze or even reset the device before the program completes the execution.&lt;/p&gt;
&lt;p&gt;If you open serial monitor, you will see something like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;���ԅu�D�ILI9341 Test!
Display Power Mode: 0x9C
MADCTL Mode: 0x48
Pixel Format: 0x5
Image Format: 0x0
Self Diagnostic: 0xC0
Benchmark                Time (microseconds)
Screen fill              2259125
Text                     161736
Lines                    
Soft WDT reset

ctx: cont 
sp: 3ffef8d0 end: 3ffefbd0 offset: 01b0

&amp;gt;&amp;gt;&amp;gt;stack&amp;gt;&amp;gt;&amp;gt;
3ffefa80:  016e3600 00000001 3ffeea58 000007e0  
3ffefa90:  00000080 00000008 3ffeea58 402032f8  
3ffefaa0:  3ffeea9c 00000001 3ffeea58 0000006c  
3ffefab0:  0000006d 0000002a 3ffeea58 40203378  
3ffefac0:  3ffeea9c 000000f6 3ffeea58 402037b2  
3ffefad0:  000000f7 000000f6 3ffeea9c 402027ab  
3ffefae0:  016e3600 00000001 3ffeea58 000007ff  
3ffefaf0:  0000006c 000000f6 3ffeea58 40203876  
3ffefb00:  016e3600 00000001 3ffeeb7c 00000000  
3ffefb10:  00000000 000000f0 3ffeea58 000000ef  
3ffefb20:  0000006c 000000ef 0000005f 402046e1  
3ffefb30:  00000000 00000001 000007ff 00000085  
3ffefb40:  3ffeea58 000000f6 402044b8 00000144  
3ffefb50:  000000f0 000007ff 3ffeea58 00cb82d4  
3ffefb60:  000000ba 000007ff 3ffeea58 40201c40  
3ffefb70:  0000013f 000000ef 00000140 000000ef  
3ffefb80:  000000ef 3ffeeba8 402044b8 3ffeebb0  
3ffefb90:  3ffeeb7c 00000018 4022d52d 3ffeeba8  
3ffefba0:  00000000 000000c0 3ffeeb7c 40202398  
3ffefbb0:  3fffdc20 00000000 3ffeeba0 402044f6  
3ffefbc0:  00000000 00000000 3ffeebb0 40100114  
&amp;lt;&amp;lt;&amp;lt;stack&amp;lt;&amp;lt;&amp;lt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The problem here is that ESP8266 has a watchdog set to one second. The &lt;em&gt;lines&lt;/em&gt; test pattern takes longer than one second to execute and therefore the watchdog resets the processor.&lt;/p&gt;
&lt;p&gt;The ILI9341 example is already "feeding" the watchdog using the &lt;code&gt;yield();&lt;/code&gt; call. Unfortunately, on the ESP8266, some code between the &lt;code&gt;yield();&lt;/code&gt; calls still takes more than one seconds (this code was written with Arduino in mind). To make this example run, you will have to add additional &lt;code&gt;yield();&lt;/code&gt; calls. Use trial and error method to figure out where to add those.&lt;/p&gt;
&lt;p&gt;Disabling the watchdog is also a viable options, but I was not able to figure out how to do it. If you find a way to do this, write me through the comments. &lt;/p&gt;
&lt;p&gt;&lt;center&gt;
&lt;img alt="ILI9341 example running" src="/files/esp2.jpg"&gt;
&lt;/center&gt;&lt;/p&gt;</content><category term="esp8266"></category><category term="arduino"></category><category term="embedded"></category><category term="ili9341"></category></entry><entry><title>Trying Ada Bindings for X11</title><link href="http://www.nihamkin.com/2015/09/01/trying-ada-bindings-for-x11" rel="alternate"></link><published>2015-09-01T17:00:00+03:00</published><updated>2015-09-01T17:00:00+03:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2015-09-01:/2015/09/01/trying-ada-bindings-for-x11</id><summary type="html">&lt;p&gt;Ada bindings for X11 were written Intermentics company and sponsored by Ada Joint Program Office (AJPO).&lt;/p&gt;
&lt;p&gt;While intemetics has long been gone (looks like the it's domain is owned by L3 now), and AJPO was closed in 1998, the bindings are still around.&lt;/p&gt;
&lt;p&gt;The "latest" version can be downloaded from …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Ada bindings for X11 were written Intermentics company and sponsored by Ada Joint Program Office (AJPO).&lt;/p&gt;
&lt;p&gt;While intemetics has long been gone (looks like the it's domain is owned by L3 now), and AJPO was closed in 1998, the bindings are still around.&lt;/p&gt;
&lt;p&gt;The "latest" version can be downloaded from &lt;a href="http://www.adapower.com/index.php?Command=Class&amp;amp;ClassID=AdaGUI"&gt;this page on adapower web site&lt;/a&gt; (the download link is at the bottom named &lt;em&gt;x11ada&lt;/em&gt;)&lt;/p&gt;
&lt;p&gt;I was surprised how smooth was the process of building and running a demo program. The following tutorial will walk through this process.&lt;/p&gt;
&lt;h2&gt;Setup&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The tools I used for this tutorial are &lt;em&gt;gnat 4.9.3&lt;/em&gt; and &lt;em&gt;gprbuild 2014&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Create a directory for your project. I called it "&lt;em&gt;ada11_testing&lt;/em&gt;".&lt;/li&gt;
&lt;li&gt;Download "&lt;em&gt;x11ada_v1.30.tar.gz&lt;/em&gt;" from the link provided above. Inside you will find "&lt;em&gt;ada&lt;/em&gt;" directory. Copy this whole directory to "&lt;em&gt;ada11_testing&lt;/em&gt;".&lt;/li&gt;
&lt;li&gt;Create a directory called "&lt;em&gt;obj&lt;/em&gt;" inside "&lt;em&gt;ada11_testing&lt;/em&gt;".&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Project File&lt;/h2&gt;
&lt;p&gt;Create "&lt;em&gt;test.gpr&lt;/em&gt;" file with the following contents:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt; &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="kr"&gt;is&lt;/span&gt;
  &lt;span class="kr"&gt;for&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;test&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kr"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Source_Dirs&lt;/span&gt; &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;./**&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kr"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Object_Dir&lt;/span&gt; &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;obj&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kr"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Exec_Dir&lt;/span&gt; &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;package&lt;/span&gt; &lt;span class="nc"&gt;Linker&lt;/span&gt; &lt;span class="kr"&gt;is&lt;/span&gt;
     &lt;span class="kr"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Default_Switches&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Ada&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;-lX11&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="nf"&gt;Linker&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;package&lt;/span&gt; &lt;span class="nc"&gt;Compiler&lt;/span&gt; &lt;span class="kr"&gt;is&lt;/span&gt;
     &lt;span class="kr"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Default_Switches&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Ada&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;-gnateE&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;-gnat2012&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
  &lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="nf"&gt;Compiler&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kr"&gt;for&lt;/span&gt; &lt;span class="n"&gt;Languages&lt;/span&gt; &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Ada&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;C&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;h2&gt;Code&lt;/h2&gt;
&lt;p&gt;Being thin bindings, every &lt;em&gt;C&lt;/em&gt; function of X11 library has an equivalent Ada function. Therefore example programs, documentation and tutorials that are aimed at C are suitable for Ada programmers as well.&lt;/p&gt;
&lt;p&gt;I used example program from the following &lt;a href="http://www.linuxjournal.com/article/4879"&gt;article&lt;/a&gt; of Linux Magazine.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;with&lt;/span&gt; &lt;span class="nn"&gt;Interfaces.C&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;with&lt;/span&gt; &lt;span class="nn"&gt;X&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;with&lt;/span&gt; &lt;span class="nn"&gt;X.Xlib&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;procedure&lt;/span&gt; &lt;span class="nf"&gt;Test&lt;/span&gt; &lt;span class="kr"&gt;is&lt;/span&gt;

   &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Interfaces&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Interfaces&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unsigned&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;type&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XDisplay_access&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="n"&gt;Cant_Open_Display_Error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;exception&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="n"&gt;Display&lt;/span&gt;          &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XDisplay_access&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="n"&gt;Screen_Num&lt;/span&gt;       &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Interfaces&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="n"&gt;Win&lt;/span&gt;              &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Window&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="n"&gt;Graphics_Context&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="n"&gt;Report&lt;/span&gt;           &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;aliased&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XEvent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kr"&gt;begin&lt;/span&gt;

   &lt;span class="n"&gt;Display&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XOpenDisplay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;

   &lt;span class="kr"&gt;if&lt;/span&gt; &lt;span class="n"&gt;Display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;  &lt;span class="kr"&gt;then&lt;/span&gt;
      &lt;span class="kr"&gt;raise&lt;/span&gt; &lt;span class="n"&gt;Cant_Open_Display_Error&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="kr"&gt;if&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="n"&gt;Screen_num&lt;/span&gt;     &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DefaultScreen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Display&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

   &lt;span class="n"&gt;Win&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XCreateSimpleWindow&lt;/span&gt;
     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Display&lt;/span&gt;      &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Display&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="n"&gt;Parent&lt;/span&gt;       &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RootWindow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Display&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Screen_Num&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
      &lt;span class="n"&gt;XX&lt;/span&gt;           &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="n"&gt;Y&lt;/span&gt;            &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="n"&gt;Width&lt;/span&gt;        &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="n"&gt;Height&lt;/span&gt;       &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="n"&gt;Border_Width&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="n"&gt;Border&lt;/span&gt;       &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BlackPixel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Display&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Screen_Num&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
      &lt;span class="n"&gt;Background&lt;/span&gt;   &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WhitePixel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Display&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Screen_Num&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

   &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XMapWindow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;display&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Win&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

   &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XSelectInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Display&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Win&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StructureNotifyMask&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

   &lt;span class="kr"&gt;loop&lt;/span&gt;
      &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XNextEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Display&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Report&lt;/span&gt;&lt;span class="p"&gt;&amp;#39;&lt;/span&gt;&lt;span class="na"&gt;access&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="kr"&gt;exit&lt;/span&gt; &lt;span class="kr"&gt;when&lt;/span&gt; &lt;span class="n"&gt;Report&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Event_Type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MapNotify&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="kr"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="n"&gt;Graphics_Context&lt;/span&gt; &lt;span class="p"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XDefaultGC&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Display&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Screen_Num&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

   &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XSetForeground&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Display&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Graphics_Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BlackPixel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Display&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Screen_Num&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

   &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XDrawLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Display&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Drawable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Win&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Graphics_Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;190&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;190&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XDrawLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Display&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Drawable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Win&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Graphics_Context&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;190&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;190&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

   &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XSelectInput&lt;/span&gt;
     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Display&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="n"&gt;Win&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
      &lt;span class="n"&gt;Interfaces&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Long&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;Interfaces&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Unsigned&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ButtonPressMask&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kr"&gt;or&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ButtonReleaseMask&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
     &lt;span class="p"&gt;);&lt;/span&gt;

   &lt;span class="kr"&gt;loop&lt;/span&gt;
      &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XNextEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Display&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Report&lt;/span&gt;&lt;span class="p"&gt;&amp;#39;&lt;/span&gt;&lt;span class="na"&gt;access&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

      &lt;span class="kr"&gt;exit&lt;/span&gt; &lt;span class="kr"&gt;when&lt;/span&gt; &lt;span class="n"&gt;Report&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Event_Type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ButtonRelease&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="kr"&gt;loop&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XDestroyWindow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Display&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Win&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Xlib&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;XCloseDisplay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Display&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kr"&gt;end&lt;/span&gt; &lt;span class="nf"&gt;Test&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Building with gprbuild:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;gprbuild -P test.gpr
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And that is all it takes to use 20 years old software package!&lt;/p&gt;</content><category term="Ada"></category><category term="X11"></category></entry><entry><title>Range Constrained Types in C++</title><link href="http://www.nihamkin.com/2014/09/05/range-constrained-types-in-c++" rel="alternate"></link><published>2014-09-05T22:00:00+03:00</published><updated>2014-09-05T22:00:00+03:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2014-09-05:/2014/09/05/range-constrained-types-in-c++</id><summary type="html">&lt;p&gt;One of the first things a new Ada programmer will learn is the ability to define constrained type. Which means that one can restrict the values that can be assigned to a variable of this specific type.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;subtype&lt;/span&gt; &lt;span class="kt"&gt;Positive&lt;/span&gt; &lt;span class="kr"&gt;is&lt;/span&gt; &lt;span class="kt"&gt;Integer&lt;/span&gt; &lt;span class="kr"&gt;range&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;..&lt;/span&gt; &lt;span class="kt"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;&amp;#39;&lt;/span&gt;&lt;span class="na"&gt;Last&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Being a subtype …&lt;/p&gt;</summary><content type="html">&lt;p&gt;One of the first things a new Ada programmer will learn is the ability to define constrained type. Which means that one can restrict the values that can be assigned to a variable of this specific type.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kd"&gt;subtype&lt;/span&gt; &lt;span class="kt"&gt;Positive&lt;/span&gt; &lt;span class="kr"&gt;is&lt;/span&gt; &lt;span class="kt"&gt;Integer&lt;/span&gt; &lt;span class="kr"&gt;range&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;..&lt;/span&gt; &lt;span class="kt"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;&amp;#39;&lt;/span&gt;&lt;span class="na"&gt;Last&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Being a subtype of &lt;em&gt;Integer&lt;/em&gt;, &lt;em&gt;Positive&lt;/em&gt; is fully compatible with it and can be used wherever &lt;em&gt;Integer&lt;/em&gt; is applicable. Ada's runtime system however, will guard against assignments of values lower than 1 and will dispatch a runtime error whenever this happens.&lt;/p&gt;
&lt;p&gt;This feature enhances type safety and reduces probability for bugs. For example, one can safely divide an &lt;em&gt;Integer&lt;/em&gt; by &lt;em&gt;Positive&lt;/em&gt; without fear of dividing by zero. &lt;/p&gt;
&lt;p&gt;C++ does not have this feature. There is an unofficial Boost library &lt;a href="http://www.boost.org/doc/libs/1_48_0/boost/date_time/constrained_value.hpp"&gt;claiming&lt;/a&gt; to implement it. However reading the implementation I found out that &lt;em&gt;constrained_value&lt;/em&gt; is not a proper subtype of &lt;em&gt;value_type&lt;/em&gt;. There are examples where instances of the first, can not substitute the other:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bounded_int&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;::&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="n"&gt;bounded_int&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;::&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Compilation error: operator not defined.&lt;/span&gt;
&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Compilation error: casting operator not defined.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;With these limitations, this feature becomes less useful.&lt;/p&gt;
&lt;p&gt;Therefore, as an exercise, I decided to implement this feature on my own. The goals of my implementation were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Proper subtyping of the base type. &lt;/li&gt;
&lt;li&gt;Smallest possible performance and memory penalty.&lt;/li&gt;
&lt;li&gt;Simple interface.&lt;/li&gt;
&lt;li&gt;Extensive automatic testing.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;How to Use&lt;/h3&gt;
&lt;p&gt;The code itself can be found on &lt;a href="https://github.com/alkhimey/ConstrainedTypes"&gt;github&lt;/a&gt;. Just grab the file named &lt;em&gt;subtype_range_constrained.h&lt;/em&gt; and add it to your project.&lt;/p&gt;
&lt;p&gt;Here is a simple usage example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;typedef&lt;/span&gt; &lt;span class="n"&gt;ct&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;RangeConstrained&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;short&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;positive&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;positive&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// Ok&lt;/span&gt;
    &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;      &lt;span class="c1"&gt;// Exception!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;</content><category term="C++"></category><category term="Ada"></category></entry><entry><title>Template Argument Deduction</title><link href="http://www.nihamkin.com/2014/05/04/template-argument-deduction" rel="alternate"></link><published>2014-05-04T23:00:00+03:00</published><updated>2014-05-04T23:00:00+03:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2014-05-04:/2014/05/04/template-argument-deduction</id><summary type="html">&lt;p&gt;With automatic template deduction, it is possible to omit the template argument when instantiating a template function. The compiler will deduce the type from the actual parameter sent to the function. This is of course assuming there are no ambiguities.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T …&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;</summary><content type="html">&lt;p&gt;With automatic template deduction, it is possible to omit the template argument when instantiating a template function. The compiler will deduce the type from the actual parameter sent to the function. This is of course assuming there are no ambiguities.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;       &lt;span class="c1"&gt;// equivalent to max&amp;lt;int&amp;gt;(0,1);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;As I have found recently, there is more to this feature than meets the eye.&lt;/p&gt;
&lt;p&gt;Assume that we want to write a function that would merge two std vectors. A usage example would look like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;&lt;span class="n"&gt;v3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;v3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;merge_vectors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Since &lt;em&gt;vector&lt;/em&gt; is a class template, the following signature would not compile:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt; &lt;span class="nf"&gt;merge_vectors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt; &lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt; &lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;blockquote&gt;
&lt;p&gt;error: invalid use of template-name ‘std::vector’ without an argument list&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We do not want to create a separate function for each vector instantiation we use in our program . The solution is to use a function template:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="k"&gt;template&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;merge_vectors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;v1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vector&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The deduction here is more complex than in the first example. &lt;em&gt;T&lt;/em&gt; is deduced not by the parameters sent to the function, but by the generic argument used to instantiate those parameters. This is important because we want to constraint the parameters to be vectors, we just do not care what kind of vectors they are.&lt;/p&gt;</content><category term="C++"></category><category term="generics"></category></entry><entry><title>How to Enable Logging of Chat Sessions in ERC</title><link href="http://www.nihamkin.com/2013/12/04/how-to-enable-logging-of-chat-sessions-in-erc" rel="alternate"></link><published>2013-12-04T14:00:00+02:00</published><updated>2013-12-04T14:00:00+02:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2013-12-04:/2013/12/04/how-to-enable-logging-of-chat-sessions-in-erc</id><summary type="html">&lt;p&gt;&lt;a href="http://www.emacswiki.org/emacs/ERC"&gt;ERC&lt;/a&gt; is an irc client that runs inside emacs. I sometimes use it to ask question or read interesting discussions. &lt;/p&gt;
&lt;p&gt;It is very nice to have the code I am working on and some interesting discussion side by side on the screen.&lt;/p&gt;
&lt;p&gt;Sometimes I read something interesting and later want …&lt;/p&gt;</summary><content type="html">&lt;p&gt;&lt;a href="http://www.emacswiki.org/emacs/ERC"&gt;ERC&lt;/a&gt; is an irc client that runs inside emacs. I sometimes use it to ask question or read interesting discussions. &lt;/p&gt;
&lt;p&gt;It is very nice to have the code I am working on and some interesting discussion side by side on the screen.&lt;/p&gt;
&lt;p&gt;Sometimes I read something interesting and later want to recall what exactly I read. &lt;/p&gt;
&lt;p&gt;For such cases ERC provide an ability to log chat sessions that the user is participating in. It is off by default, so it must be enabled in the configuration.&lt;/p&gt;
&lt;p&gt;I have the following configuration in my &lt;em&gt;.emacs&lt;/em&gt;, it took me some time to figure how to do it correctly, so I hope this information will help somebody else who is struggling as well:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;;; it is not possible to set erc-log-mode variable directly &lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;erc-log-mode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="c1"&gt;;; The directory should be created by user.&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;erc-log-channels-directory&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;~/.erc/logs/&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;erc-generate-log-file-name-function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;quote&lt;/span&gt; &lt;span class="nv"&gt;erc-generate-log-file-name-with-date&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;erc-save-buffer-on-part&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;erc-save-queries-on-quit&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;erc-log-write-after-insert&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;setq&lt;/span&gt; &lt;span class="nv"&gt;erc-log-write-after-send&lt;/span&gt; &lt;span class="no"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;There are few tricky thing to consider here. Firstly, the logs directory should exist, if ERC does not find the provided path, it will do nothing.&lt;/p&gt;
&lt;p&gt;Secondly, the call to &lt;em&gt;erc_log_mode&lt;/em&gt; enables logging. It can be confusing because unlike other configuration options, it is a call to a function. As the documentation says:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Erc Log Mode: &lt;br&gt;
  Non-nil if Erc-Log mode is enabled. &lt;br&gt;
 See the command &amp;#96;erc-log-mode' for a description of this minor mode. &lt;br&gt;
  Setting this variable directly does not take effect; &lt;br&gt;
  either customize it (see the info node &amp;#96;Easy Customization') &lt;br&gt;
  or call the function &amp;#96;erc-log-mode'. &lt;br&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There are more ERC related customization options available. It is possible to see them with the following emacs sequence:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nv"&gt;M-x&lt;/span&gt; &lt;span class="nv"&gt;customize-group&lt;/span&gt; &lt;span class="nv"&gt;RET&lt;/span&gt; &lt;span class="nv"&gt;erc&lt;/span&gt; &lt;span class="nv"&gt;RET&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This will display a nice GUI-like editor for those options and also will group them according to functionality. &lt;/p&gt;</content><category term="Emacs"></category></entry><entry><title>Making Legacy Software Work On Windows</title><link href="http://www.nihamkin.com/2013/11/09/making-legacy-software-work-on-windows" rel="alternate"></link><published>2013-11-09T14:00:00+02:00</published><updated>2013-11-09T14:00:00+02:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2013-11-09:/2013/11/09/making-legacy-software-work-on-windows</id><summary type="html">&lt;p&gt;It sometimes happens that programs written for old versions of Windows will not work on new versions even with compatibility mode enabled. It is not uncommon for such program to crash and show some cryptic message that even a person of technical background can not understand.  Sometimes only a simple …&lt;/p&gt;</summary><content type="html">&lt;p&gt;It sometimes happens that programs written for old versions of Windows will not work on new versions even with compatibility mode enabled. It is not uncommon for such program to crash and show some cryptic message that even a person of technical background can not understand.  Sometimes only a simple fix is required, like providing a missing DLL or creating a registry key, yet the program will not tell us what it actually expected to find. Recently I have discovered a technique that can help debug such situations. It might surprise the reader the the solution comes from the Linux world.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.winehq.org"&gt;Wine&lt;/a&gt; is a tool that allows running Windows programs on Linux. It does this by providing a Linux implementation of Window's API and system calls. One neat feature of Wine is the ability to output which system calls are being called during an execution of a program. &lt;/p&gt;
&lt;h3&gt;Example&lt;/h3&gt;
&lt;p&gt;I will demonstrate how to get advantage of this feature  with a game called "Janes F-15". This is a flight simulator released in 1998 for Windows 95.&lt;/p&gt;
&lt;p&gt;The problem I had, was not with the game itself but with it's installer. The installer would say "ERROR, Copying files" right after it began it's operation. Which files it was unable to copy it did not specify.&lt;/p&gt;
&lt;p&gt;&lt;img alt="setup error message" src="/files/f15-setup.png"&gt;&lt;/p&gt;
&lt;p&gt;Finding which file is missing can be done by reading the debug messages. The debug messages are enabled by setting the &lt;em&gt;WINEDEBUG&lt;/em&gt; environment variable before running the program:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ &lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;WINEDEBUG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;warn+all
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The number of messages produced by even a boilerplate program is very big, the console will spit text long after the application is closed, and it will be hard to determine cause and effect behavior.  Therefore different "debug" channels exist. In the example above I have used the "all" channel and limited it only to warnings. Other scenarios would require other channels. In the following &lt;a href="http://wiki.winehq.org/DebugChannels"&gt;link&lt;/a&gt; a complete documentation of all the channels can be found.&lt;/p&gt;
&lt;p&gt;So I set the environment variable and run the installer. Just before clicking the last "next" button of the wizard (which causes the installation process to actually start), I brought the the console to the front. Clicking on the final "next" button caused some more messages to be printed into the console, with the most relevant messages being printed last:&lt;/p&gt;
&lt;p&gt;&lt;img alt="screenshot of the console" src="/files/f15-setup-debug-small.png"&gt;&lt;/p&gt;
&lt;p&gt;It is now clear what the problem is. &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;warn:ntdll:NtQueryAttributesFile L&lt;span class="s2"&gt;&amp;quot;\\??\\C:\\windows\\system32\\EAREMOVE.EXE&amp;quot;&lt;/span&gt; not found &lt;span class="o"&gt;(&lt;/span&gt;c0000034&lt;span class="o"&gt;)&lt;/span&gt;
warn:file:OpenFile &lt;span class="o"&gt;(&lt;/span&gt;C:&lt;span class="se"&gt;\w&lt;/span&gt;indows&lt;span class="se"&gt;\s&lt;/span&gt;ystem32&lt;span class="se"&gt;\E&lt;/span&gt;AREMOVE.EXE&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; HFILE_ERROR &lt;span class="nv"&gt;error&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
warn:ntdll:NtQueryAttributesFile L&lt;span class="s2"&gt;&amp;quot;\\??\\C:\\Janes\\F15\\EAREMOVE.EXE&amp;quot;&lt;/span&gt; not found &lt;span class="o"&gt;(&lt;/span&gt;c0000034&lt;span class="o"&gt;)&lt;/span&gt;
warn:file:OpenFile &lt;span class="o"&gt;(&lt;/span&gt;C:&lt;span class="se"&gt;\J&lt;/span&gt;anes&lt;span class="se"&gt;\F&lt;/span&gt;&lt;span class="m"&gt;15&lt;/span&gt;&lt;span class="se"&gt;\E&lt;/span&gt;AREMOVE.EXE&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; HFILE_ERROR &lt;span class="nv"&gt;error&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
warn:ntdll:NtQueryAttributesFile L&lt;span class="s2"&gt;&amp;quot;\\??\\E:\\EAREMOVE.EXE&amp;quot;&lt;/span&gt; not found &lt;span class="o"&gt;(&lt;/span&gt;c0000034&lt;span class="o"&gt;)&lt;/span&gt;
warn:file:OpenFile &lt;span class="o"&gt;(&lt;/span&gt;.&lt;span class="se"&gt;\E&lt;/span&gt;AREMOVE.EXE&lt;span class="o"&gt;)&lt;/span&gt;: &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; HFILE_ERROR &lt;span class="nv"&gt;error&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The installer searches for a file called "EAREMOVE.EXE", first in system32 directory, then inside the directory where the game is about to be installed, and finally on the installation disk. I do not know what is the logic behind this behavior and why this file was missing. &lt;/p&gt;
&lt;p&gt;Creating an empty file named "EAREMOVE.EXE" in the system32 directory solved the problem and allowed the installer to continue. The game was installed correctly and I was able to run it.&lt;/p&gt;</content><category term="Linux"></category><category term="Windows"></category><category term="Wine"></category></entry><entry><title>Combining ls and cat Commands</title><link href="http://www.nihamkin.com/2013/08/17/combining-ls-and-cat-commands" rel="alternate"></link><published>2013-08-17T04:00:00+03:00</published><updated>2013-08-17T04:00:00+03:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2013-08-17:/2013/08/17/combining-ls-and-cat-commands</id><summary type="html">&lt;p&gt;Very often, when exploring contents of directory trees, I find myself confused between the the "ls" and "cat" commands and mistakenly type one instead of the other. Both these commands are used pretty often and conceptually they have similar meanings. One says "print out a content of directory". The other …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Very often, when exploring contents of directory trees, I find myself confused between the the "ls" and "cat" commands and mistakenly type one instead of the other. Both these commands are used pretty often and conceptually they have similar meanings. One says "print out a content of directory". The other says "print out the content of a file".&lt;/p&gt;
&lt;p&gt;Therfore, it is natural for these commands to be combined into a single one. So, I decided to write a shell script that would do exactly this.&lt;/p&gt;
&lt;p&gt;The following shell script will choose to run "ls" or "cat" depending on the type of the parameter (file or directory).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="ch"&gt;#!/bin/sh&lt;/span&gt;

&lt;span class="c1"&gt;## lc.sh&lt;/span&gt;
&lt;span class="c1"&gt;## Artium Nihamkin&lt;/span&gt;
&lt;span class="c1"&gt;## August 2013&lt;/span&gt;
&lt;span class="c1"&gt;## &lt;/span&gt;
&lt;span class="c1"&gt;## This script will to run &amp;quot;ls&amp;quot; or &amp;quot;cat&amp;quot; depending the type of the input.&lt;/span&gt;
&lt;span class="c1"&gt;##&lt;/span&gt;
&lt;span class="c1"&gt;## Examples where &amp;quot;ls&amp;quot; is invoked:&lt;/span&gt;
&lt;span class="c1"&gt;##    ./lc.sh file.txt&lt;/span&gt;
&lt;span class="c1"&gt;##    ./lc.sh&lt;/span&gt;
&lt;span class="c1"&gt;## Examples where &amp;quot;cat&amp;quot; is invoked&lt;/span&gt;
&lt;span class="c1"&gt;##    ./lc.sh ~/directory.name&lt;/span&gt;
&lt;span class="c1"&gt;##    ./lc.sh does.not.exist&lt;/span&gt;
&lt;span class="c1"&gt;##    echo &amp;quot;xxx&amp;quot; | ./lc.sh &lt;/span&gt;
&lt;span class="c1"&gt;##&lt;/span&gt;

&lt;span class="c1"&gt;# If stdin present, assume user meant cat&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; ! -t &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; 
&lt;span class="k"&gt;then&lt;/span&gt;
    cat &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c1"&gt;# Find the argument that is file/directory name and test it&lt;/span&gt;
&lt;span class="c1"&gt;# to find out if it is an existing directory. Other arguments are &lt;/span&gt;
&lt;span class="c1"&gt;# options and thus will begin with an &amp;quot;-&amp;quot;.&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; v in &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; 
&lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;-&amp;#39;&lt;/span&gt; !&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$v&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; cut -c1 &lt;span class="sb"&gt;`&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; 
    &lt;span class="k"&gt;then&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; -d &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$v&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;then&lt;/span&gt;
            &lt;span class="c1"&gt;# A directory, use &amp;quot;ls&amp;quot;.&lt;/span&gt;
            &lt;span class="c1"&gt;#&lt;/span&gt;
            ls &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;
         &lt;span class="k"&gt;else&lt;/span&gt;
            &lt;span class="c1"&gt;# Not a directory, use &amp;#39;cat&amp;#39;.&lt;/span&gt;
            &lt;span class="c1"&gt;# If this is not a file or a directory then cat will&lt;/span&gt;
            &lt;span class="c1"&gt;# print an error message:&lt;/span&gt;
            &lt;span class="c1"&gt;# cat: xxx: No such file or directory&lt;/span&gt;
            &lt;span class="c1"&gt;#&lt;/span&gt;
            cat &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;
        &lt;span class="k"&gt;fi&lt;/span&gt;
    &lt;span class="k"&gt;fi&lt;/span&gt;  
&lt;span class="k"&gt;done&lt;/span&gt;

&lt;span class="c1"&gt;# No file name provided, assume the user is trying to ls &lt;/span&gt;
&lt;span class="c1"&gt;# the working directory&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
ls &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$@&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Notice that running this script without a file/directory name parameter is equal to a plain "ls" which will list the working directory, but if you provide an stdin input it will assume the user is expecting the behavior of a "cat".&lt;/p&gt;
&lt;p&gt;Assuming that you have put this script in &lt;em&gt;/my/pah/to/lc.sh&lt;/em&gt; path, you can now add an alias to this command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;alias&lt;/span&gt; &lt;span class="nv"&gt;lc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/my/path/to/lc.sh&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Add this line into &lt;em&gt;~/.bashrc&lt;/em&gt; and it will run every time you start an interactive shell.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;$ ls
lc.sh
$ lc
lc.sh
$ mkdir &lt;span class="nb"&gt;test&lt;/span&gt;
$ &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;abc&amp;quot;&lt;/span&gt; &amp;gt; test/test.txt
$ lc -l &lt;span class="nb"&gt;test&lt;/span&gt;
total &lt;span class="m"&gt;4&lt;/span&gt;
-rw-rw-r-- &lt;span class="m"&gt;1&lt;/span&gt; artium artium &lt;span class="m"&gt;4&lt;/span&gt; Aug &lt;span class="m"&gt;17&lt;/span&gt; &lt;span class="m"&gt;03&lt;/span&gt;:47 test.txt
 lc test/test.txt
abc
$ &lt;span class="nb"&gt;echo&lt;/span&gt; xyz &lt;span class="p"&gt;|&lt;/span&gt; lc
xyz
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;You can even go as far as adding an alias for the "ls" and "cat" commands, thus overriding them. This will allow you to call "ls" on files and "cat" on directories and still get a desired effect.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nb"&gt;alias&lt;/span&gt; &lt;span class="nv"&gt;ls&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/my/path/to/lc.sh&amp;quot;&lt;/span&gt;
&lt;span class="nb"&gt;alias&lt;/span&gt; &lt;span class="nv"&gt;cat&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;/my/path/to/lc.sh&amp;quot;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;There two thing you need to know here :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;If for saome reason you will need to run the original command, you can type an "\" before it's name (for example &lt;em&gt;"\ls"&lt;/em&gt;) and this will disregard any aliases and run the original command.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Aliases are not expanded inside non-interactive shell scripts. So if you write "ls" inside a script, it will call the original "ls". This is good bacuase we don't want to break existing scripts that might be relaying on some esoteric behavior of "ls" or "cat" which is not imitated in my script. This is true as long as those scripts did not run &lt;em&gt;shopt -s expand_aliases&lt;/em&gt; which causes the expansion of aliases inside non-interactive scripts. Pretty rare and low risk, yet good to be aware.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</content><category term="shell"></category><category term="sh"></category><category term="linux"></category></entry><entry><title>OpenNI2 Samples and Dynamic Library Problems</title><link href="http://www.nihamkin.com/2013/08/02/openni2-samples-and-dynamic-library-problems" rel="alternate"></link><published>2013-08-02T17:00:00+03:00</published><updated>2013-08-02T17:00:00+03:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2013-08-02:/2013/08/02/openni2-samples-and-dynamic-library-problems</id><summary type="html">&lt;p&gt;While experimenting with the OpenNI2 samples, I sometimes would get the following error when trying to run one of the executables:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;~/OpenNI-Linux-x86-2.2$ Samples/Bin/SimpleViewer
Samples/Bin/SimpleViewer: error &lt;span class="k"&gt;while&lt;/span&gt; loading shared libraries: libOpenNI2.so: cannot open shared object file: No such file or directory
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The dynamic library file …&lt;/p&gt;</summary><content type="html">&lt;p&gt;While experimenting with the OpenNI2 samples, I sometimes would get the following error when trying to run one of the executables:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;~/OpenNI-Linux-x86-2.2$ Samples/Bin/SimpleViewer
Samples/Bin/SimpleViewer: error &lt;span class="k"&gt;while&lt;/span&gt; loading shared libraries: libOpenNI2.so: cannot open shared object file: No such file or directory
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The dynamic library file &lt;em&gt;libOpenNI2.so&lt;/em&gt; is located in the Bin folder alongside the executable. One would expect that like with DLLs on Windows, the dynamic linker have the executable's directory in it's search path.&lt;/p&gt;
&lt;p&gt;Well, it turns out that for Linux's linker it is not the case. It searches in the &lt;em&gt;working directory&lt;/em&gt; but not in the directory of the executable.&lt;/p&gt;
&lt;p&gt;This can be easily fixed by copying the library into a directory that is on the search path of the linker. According to &lt;a href="http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html"&gt;this guide&lt;/a&gt;, the convention is to put libraries in &lt;em&gt;/usr/local/lib&lt;/em&gt;. So all that needs to be done are the following actions:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;~&lt;span class="nv"&gt;$sudo&lt;/span&gt; cp &lt;span class="s2"&gt;&amp;quot;OpenNI-Linux-x86-2.2 Samples/Redist/libOpenNI2.so&amp;quot;&lt;/span&gt; /usr/local/lib
~&lt;span class="nv"&gt;$sudo&lt;/span&gt; ldconfig
&lt;/pre&gt;&lt;/div&gt;</content><category term="openni"></category><category term="linux"></category></entry><entry><title>How to Save Money in Israel</title><link href="http://www.nihamkin.com/2013/04/01/how-to-save-money-in-israel" rel="alternate"></link><published>2013-04-01T16:00:00+03:00</published><updated>2013-04-01T16:00:00+03:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2013-04-01:/2013/04/01/how-to-save-money-in-israel</id><summary type="html">&lt;p&gt;It is always good to cut on household expenses, especially at times when product prices are rising. In this post I have gathered several tips that will help you save money monthly with only small impact on your quality of life.&lt;/p&gt;
&lt;p&gt;Notice that this post is intended to help Israeli …&lt;/p&gt;</summary><content type="html">&lt;p&gt;It is always good to cut on household expenses, especially at times when product prices are rising. In this post I have gathered several tips that will help you save money monthly with only small impact on your quality of life.&lt;/p&gt;
&lt;p&gt;Notice that this post is intended to help Israeli residents and will not be as useful for visitors and tourists. &lt;/p&gt;
&lt;h4&gt;Cellphone Bills&lt;/h4&gt;
&lt;p&gt;Thanks to the cellphone market reform the prices today are quite fair. Yet many people are not aware of this and still pay for the older plans. New physical and virtual carriers offer "unlimited plans" for a price of 90-100 NIS per month. Some of the older carriers offer similar plans as well.&lt;/p&gt;
&lt;p&gt;If you do not use the phone very often you can reduce the bill even further by choosing a "pay per minute" plan. You need to look at your previous bills and see how many minutes you talk each month. Then calculate the price you will pay for these minutes in the "pay per minute" plans and decide which plan is cheaper for you. &lt;/p&gt;
&lt;p&gt;I recently switched my family to one of the new companies. My mother used to pay 100-110 NIS per month for her calls. Now she pays 10 NIS for her plan that grants her 60 minutes and 60 sms per month and on average she pays additional 20 NIS for the extra minutes she talks. That is an instant 70 NIS saving. &lt;/p&gt;
&lt;h4&gt;Telephone Bills&lt;/h4&gt;
&lt;p&gt;My family still keeps a Bezeq land-line at our home, but in my opinion there is absolutely no reason for this. Landlines are rarely used these days and 50 NIS just for the subscription is a too high price to pay when you have mobile unlimited plans. Also notice that contrary to a common belief, according to a new law, if you cancel your land-line you will still be able to keep Bezeq as your Internet infrastructure.&lt;/p&gt;
&lt;p&gt;For those that want to keep the phone number so people will be able to call, there is a light subscription plan that is called "Kav Kal" ("&lt;a href="http://www.bezeq.co.il/Telephony/PhoneLines/KavKal/Pages/kavkal.aspx"&gt;קו קל&lt;/a&gt;") and it costs 25 NIS per month.&lt;/p&gt;
&lt;h4&gt;Television&lt;/h4&gt;
&lt;p&gt;Nowadays we do not spend as much time watching TV as we used to. The Internet and Smartphones/Tablets have taken over the entertainment spot in our life. If you still want to be able to watch the news on the Israeli channels, you can buy an &lt;a href="http://idanplus.tv/"&gt;Idan+&lt;/a&gt; receiver with one time investment of ~200NIS. With most Idan+ receivers you will also be able to play movies from a plugged-in disk on key. &lt;/p&gt;
&lt;h4&gt;Internet&lt;/h4&gt;
&lt;p&gt;The key idea here is to hassle. First, research on the Internet for the market price of the speed you are interested to subscribe to. There are several sites (for example &lt;a href="http://www.kamaze.co.il"&gt;kamaze.co.il&lt;/a&gt;) on which people share the price they got from their company (either infrastructure or provider). You will notice that the lowest price for each speed is shared among all companies. Next, call for your company and stick to that price you want. When they tell you that &lt;em&gt;X&lt;/em&gt; is the price they can give you and nothing can be done to lower it, tell them that you did your research and know the "market price". Then they will probably bounce you from one representative to a more "senior" representative which will offer a lower price and maybe some "extras". Do not be tempted to take the "extras", stick to your price and if they will not bounce you any more, ask to disconnect immediately. They will bounce you one last time to thing called "customer retention" (&lt;em&gt;shimur lakohot&lt;/em&gt;) and there you will get the price you want. &lt;/p&gt;
&lt;h4&gt;Credit Cards&lt;/h4&gt;
&lt;p&gt;Some big chain stores offer a consumer club cards in a form of credit card. These card are usually free for the first year, but after that you have to pay a monthly fee. If you use these cards infrequently, it is good to reevaluate their benefit and maybe cancel some of them. On the other hand, if you use such card frequently it is good idea to cancel the ordinary credit card you got from your bank.&lt;/p&gt;
&lt;h4&gt;Groceries&lt;/h4&gt;
&lt;p&gt;Comparing prices is time consuming and not always worth the money that can be saved. My advice here is to compare prices on line. There are several sites (for example &lt;a href="http://mysupermarket.co.il/"&gt;mysupermarket.co.il&lt;/a&gt;) available that will allow you to input your desired basket of groceries and they will show you the cheapest chain store for your basket. Some will even recommend similar products of cheaper brand to help you save more money.&lt;/p&gt;
&lt;h4&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;It is hard to asses the savings that can be gained for the average family, but for amusement lets wildly guesstimate it:&lt;/p&gt;
&lt;p&gt;Here is what a family of 3 that did not have any of the bundle subscriptions (ie. TV + Phone + Internet bundles) can save a month:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Switching cellphone plans:&lt;/strong&gt; 3 &amp;#215; 70 NIS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Canceling landline:&lt;/strong&gt; 50 NIS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Canceling television plan:&lt;/strong&gt; 200 NIS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hassling over the Internet price:&lt;/strong&gt; 20 NIS + 40 NIS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Canceling 2 credit cards:&lt;/strong&gt; 2 &amp;#215; 10 NIS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Saving 10% on groceries:&lt;/strong&gt; 0.1 &amp;#215; 1500 NIS&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Total:&lt;/strong&gt; 690 NIS  &lt;/p&gt;</content><category term="Economics"></category><category term="Tips"></category></entry><entry><title>Spartanization Plug-In For Eclipse</title><link href="http://www.nihamkin.com/2013/03/09/spartanization-plug-in-for-eclipse" rel="alternate"></link><published>2013-03-09T02:00:00+02:00</published><updated>2013-03-09T02:00:00+02:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2013-03-09:/2013/03/09/spartanization-plug-in-for-eclipse</id><summary type="html">&lt;p&gt;I would like to share an Eclipse plug-in that I have recently developed. It possible to install it from the following  update site: &lt;a href="http://update.nihamkin.com/spartan/"&gt;http://update.nihamkin.com/spartan/&lt;/a&gt;. &lt;/p&gt;
&lt;!--&lt;p align="center"&gt;
&lt;script type="text/javascript"&gt;
       url_site = 'http://marketplace.eclipse.org/node/722342';
&lt;/script&gt;
&lt;script src="http://marketplace.eclipse.org/sites/all/modules/custom/eclipse_drigg_external/js/button.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;br&gt;
&lt;a href="http://marketplace.eclipse.org/marketplace-client-intro?mpc_install=722342" title="Drag and drop into a running Eclipse Indigo workspace to install Spartan Refactoring"&gt;
  &lt;img src="http://marketplace.eclipse.org/sites/all/modules/custom/marketplace/images/installbutton.png"/&gt;
&lt;/a&gt;
&lt;/p&gt;--&gt;

&lt;p&gt;If you are not familiar with "spartan programming", you can read about it on &lt;a href="http://www.codinghorror.com/blog/2008/07/spartan-programming.html"&gt;this&lt;/a&gt; Jeff Atwood's post or &lt;a href="http://ssdl-wiki.cs.technion.ac.il/wiki/index.php/Spartan_programming"&gt;here&lt;/a&gt; for more …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I would like to share an Eclipse plug-in that I have recently developed. It possible to install it from the following  update site: &lt;a href="http://update.nihamkin.com/spartan/"&gt;http://update.nihamkin.com/spartan/&lt;/a&gt;. &lt;/p&gt;
&lt;!--&lt;p align="center"&gt;
&lt;script type="text/javascript"&gt;
       url_site = 'http://marketplace.eclipse.org/node/722342';
&lt;/script&gt;
&lt;script src="http://marketplace.eclipse.org/sites/all/modules/custom/eclipse_drigg_external/js/button.js" type="text/javascript"&gt;&lt;/script&gt;
&lt;br&gt;
&lt;a href="http://marketplace.eclipse.org/marketplace-client-intro?mpc_install=722342" title="Drag and drop into a running Eclipse Indigo workspace to install Spartan Refactoring"&gt;
  &lt;img src="http://marketplace.eclipse.org/sites/all/modules/custom/marketplace/images/installbutton.png"/&gt;
&lt;/a&gt;
&lt;/p&gt;--&gt;

&lt;p&gt;If you are not familiar with "spartan programming", you can read about it on &lt;a href="http://www.codinghorror.com/blog/2008/07/spartan-programming.html"&gt;this&lt;/a&gt; Jeff Atwood's post or &lt;a href="http://ssdl-wiki.cs.technion.ac.il/wiki/index.php/Spartan_programming"&gt;here&lt;/a&gt; for more detailed description.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Refactoring Example" src="/files/spartanization_refactoring.png"&gt;&lt;/p&gt;
&lt;p&gt;My plug-in makes it possible to perform some of the spartanizations automatically. The following refactorings will be added into the Eclipse's refactor menu:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Convert Conditional to Ternary -&lt;/strong&gt; when possible, this refactoring will convert short if-else statements into ternary statements thus reducing the number of lines.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Eliminate Redundant Equalities -&lt;/strong&gt; will remove &lt;em&gt;true&lt;/em&gt; or &lt;em&gt;false&lt;/em&gt; from expressions which explicitly compare a Boolean with &lt;em&gt;true&lt;/em&gt; or with &lt;em&gt;false&lt;/em&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Shortest Conditional Branch First -&lt;/strong&gt; will switch between &lt;em&gt;if&lt;/em&gt; and &lt;em&gt;else&lt;/em&gt; branches of &lt;em&gt;if-else&lt;/em&gt; statements to make sure that the shortest branch is always first.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;There are two ways to apply the refactoring; either on the selected text, or if no text is selected, on a whole project (depends on the file active in the editor).&lt;/p&gt;
&lt;p&gt;The plug in is not polished yet. Some edge cases should be included. For example it is desirable that "Eliminate Redundant Equality" will also eliminate comparisons to &lt;em&gt;null&lt;/em&gt; or that all refactoring that add parentheses will add them only when needed (currently "&lt;em&gt;a != b&lt;/em&gt;" will be refactored into "&lt;em&gt;!(a)&lt;/em&gt;" ).&lt;/p&gt;
&lt;p&gt;Until I find time to fix these, feel free to take a look at the &lt;a href="https://bitbucket.org/alkhimey/spartanrefactoring"&gt;source code&lt;/a&gt; and maybe fork it and adjust it for your own needs. You can use it as an example of how to work with the refactoring framework of Eclipse.&lt;/p&gt;</content><category term="Eclipse"></category><category term="Software Engineering"></category><category term="Spartanization Plugin"></category></entry><entry><title>Start New Blogofile Post With a Single Command</title><link href="http://www.nihamkin.com/2013/02/22/start-new-blogofile-post-with-a-single-command" rel="alternate"></link><published>2013-02-22T20:00:00+02:00</published><updated>2013-02-22T20:00:00+02:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2013-02-22:/2013/02/22/start-new-blogofile-post-with-a-single-command</id><summary type="html">&lt;p&gt;I wrote a bash script which should allow starting blogofile blog posts more conveniently. This will set up everything needed with a single command.&lt;/p&gt;
&lt;p&gt;This script will perform:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a file in the &lt;em&gt;_posts&lt;/em&gt; directory. The file name will be prefixed with the next number in the sequence (personal choice …&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;</summary><content type="html">&lt;p&gt;I wrote a bash script which should allow starting blogofile blog posts more conveniently. This will set up everything needed with a single command.&lt;/p&gt;
&lt;p&gt;This script will perform:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create a file in the &lt;em&gt;_posts&lt;/em&gt; directory. The file name will be prefixed with the next number in the sequence (personal choice to enumerate the markdown files for better organization)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The file will contain a starting template for a markdown blog post (a header with placeholders for title, date etc.)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add the file to source control.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Open the file in emacs.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The script is:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="ch"&gt;#!/bin/bash&lt;/span&gt;


&lt;span class="nv"&gt;POSTS_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;_posts
&lt;span class="nv"&gt;FILE_EXT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;markdown
&lt;span class="nv"&gt;TEXT_EDITOR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;emacs
&lt;span class="nv"&gt;SOURCE_CONTROL_CMD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;git add&amp;quot;&lt;/span&gt;

&lt;span class="nb"&gt;read&lt;/span&gt; -d &lt;span class="s1"&gt;&amp;#39;&amp;#39;&lt;/span&gt; TEMPLATE &amp;lt;&amp;lt;&lt;span class="s2"&gt;&amp;quot;EOF&amp;quot;&lt;/span&gt;
Tags: 
date: 
title: 
draft: True

EOF


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$#&lt;/span&gt; -le &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Usage: &lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;&lt;span class="s2"&gt; postfix-name&amp;quot;&lt;/span&gt;
    &lt;span class="nb"&gt;exit&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$#&lt;/span&gt; -ge &lt;span class="m"&gt;2&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; 
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Warning: whitespaces in the name will be ignored&amp;quot;&lt;/span&gt; 
&lt;span class="k"&gt;fi&lt;/span&gt;


&lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="nv"&gt;$POSTS_DIR&lt;/span&gt;
&lt;span class="nv"&gt;last&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;ls *.&lt;span class="nv"&gt;$FILE_EXT&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sed &lt;span class="s1"&gt;&amp;#39;s/^\([0-9]*\).*/\1/g&amp;#39;&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; sort -n &lt;span class="p"&gt;|&lt;/span&gt; tail -1&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;span class="nv"&gt;next&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;expr &lt;span class="nv"&gt;$last&lt;/span&gt; + &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;span class="nv"&gt;next_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;next&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;-&lt;span class="nv"&gt;$1&lt;/span&gt;.&lt;span class="nv"&gt;$FILE_EXT&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Creating new file (&lt;/span&gt;&lt;span class="nv"&gt;$next_name&lt;/span&gt;&lt;span class="s2"&gt;)...&amp;quot;&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="nv"&gt;$TEMPLATE&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt; &amp;gt; &lt;span class="nv"&gt;$next_name&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Adding file to source control&amp;quot;&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$SOURCE_CONTROL_CMD&lt;/span&gt; &lt;span class="nv"&gt;$next_name&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Opening file in &lt;/span&gt;&lt;span class="nv"&gt;$TEXT_EDITOR&lt;/span&gt;&lt;span class="s2"&gt;...&amp;quot;&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="nv"&gt;$TEXT_EDITOR&lt;/span&gt; &lt;span class="nv"&gt;$next_name&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The way it is currently written, it supposed to work from the main directory (one above "&lt;em&gt;_posts&lt;/em&gt;"), but feel free to tweak it for your needs. &lt;/p&gt;
&lt;p&gt;Do not forget to add a "_" prefix, otherwise when you build, blogofile will copy it into "&lt;em&gt;_site&lt;/em&gt;".&lt;/p&gt;</content><category term="Blogofile"></category></entry><entry><title>How to Add Items Into Eclipse's Refactor Menu</title><link href="http://www.nihamkin.com/2013/02/16/how-to-add-items-into-eclipse-s-refactor-menu" rel="alternate"></link><published>2013-02-16T17:00:00+02:00</published><updated>2013-02-16T17:00:00+02:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2013-02-16:/2013/02/16/how-to-add-items-into-eclipse-s-refactor-menu</id><summary type="html">&lt;p&gt;Recently, I was writing a plug-in that performs some refactoring (of which I will write in a separate post). &lt;/p&gt;
&lt;p&gt;Writing the refactoring was not too complicated, but figuring out how add the menu items correctly into the Refactor menu took a lot of time.&lt;/p&gt;
&lt;p&gt;I tried to figure this from …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Recently, I was writing a plug-in that performs some refactoring (of which I will write in a separate post). &lt;/p&gt;
&lt;p&gt;Writing the refactoring was not too complicated, but figuring out how add the menu items correctly into the Refactor menu took a lot of time.&lt;/p&gt;
&lt;p&gt;I tried to figure this from the documentation and examples that I dug from google (some of which were incorrect), and finally &lt;em&gt;paulweb515&lt;/em&gt; from #elicpse-dev channel explained me how it should be done. &lt;/p&gt;
&lt;p&gt;Here is the correct plugin.xml snippet:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;&amp;lt;?eclipse version=&amp;quot;3.2&amp;quot;?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;plugin&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;extension&lt;/span&gt;
         &lt;span class="na"&gt;point=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;org.eclipse.ui.actionSets&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;actionSet&lt;/span&gt;
            &lt;span class="na"&gt;description=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Spartan Refactoring Actions&amp;quot;&lt;/span&gt;
            &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;il.ac.technion.cs.ssdl.spartan.refactoring.actionSet&amp;quot;&lt;/span&gt;
            &lt;span class="na"&gt;label=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Spartanization&amp;quot;&lt;/span&gt;
            &lt;span class="na"&gt;visible=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;true&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;menu&lt;/span&gt;
               &lt;span class="na"&gt;label=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Refactor&amp;quot;&lt;/span&gt;
               &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;edit&amp;quot;&lt;/span&gt;
               &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;org.eclipse.jdt.ui.refactoring.menu&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;separator&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;undoRedoGroup&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;separator&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;reorgGroup&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;separator&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;codingGroup&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;separator&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;reorgGroup2&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;separator&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;typeGroup&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;separator&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;typeGroup2&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;separator&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;codingGroup2&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;separator&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;typeGroup3&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;separator&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;spartanGroup&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;separator&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;scriptGroup&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/menu&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;menu&lt;/span&gt;
               &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;il.ac.technion.cs.ssdl.spartan.refactoring.menu&amp;quot;&lt;/span&gt;
               &lt;span class="na"&gt;label=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Spartanization&amp;quot;&lt;/span&gt;
               &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;org.eclipse.jdt.ui.refactoring.menu/spartanGroup&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;separator&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;group&amp;quot;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;    
        &lt;span class="nt"&gt;&amp;lt;/menu&amp;gt;&lt;/span&gt;

         &lt;span class="nt"&gt;&amp;lt;action&lt;/span&gt;
               &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;il.ac.technion.cs.ssdl.spartan.refactoring.ShortestBranchAction&amp;quot;&lt;/span&gt;
               &lt;span class="na"&gt;enablesFor=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;*&amp;quot;&lt;/span&gt;
               &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;il.ac.technion.cs.ssdl.spartan.refactoring.actions.ShortestBranchAction&amp;quot;&lt;/span&gt;
               &lt;span class="na"&gt;label=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Shortest Conditional Branch First...&amp;quot;&lt;/span&gt;  
               &lt;span class="na"&gt;menubarPath=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;org.eclipse.jdt.ui.refactoring.menu/il.ac.technion.cs.ssdl.spartan.refactoring.menu/group&amp;quot;&lt;/span&gt;
               &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;push&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
         &lt;span class="nt"&gt;&amp;lt;/action&amp;gt;&lt;/span&gt;

        &lt;span class="c"&gt;&amp;lt;!-- More actions --&amp;gt;&lt;/span&gt;

      &lt;span class="nt"&gt;&amp;lt;/actionSet&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;/extension&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/plugin&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The Refactor &lt;em&gt;menu&lt;/em&gt; tag is a copy of the original "Refactor" menu definition from &lt;em&gt;org.eclipse.jdt.ui&lt;/em&gt;. It is important to copy all the separator definitions. For my plug-in, I have also added a new separator called &lt;em&gt;spartanGroup&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The path for the Refactor menu is &lt;strong&gt;org.eclipse.jdt.ui.refactoring.menu&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;It is possible to figure this information by looking at &lt;em&gt;plugin.xml&lt;/em&gt; of the &lt;em&gt;org.eclipse.jdt.ui&lt;/em&gt; plug-in. You can find it online (for example &lt;a href="http://grepcode.com/file_/repository.grepcode.com/java/eclipse.org/3.6.1/org.eclipse.jdt/ui/3.6.1/plugin.xml/?v=source"&gt;here&lt;/a&gt;) or you can import the source code of your eclipse build following these steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;File -&amp;gt; Import&lt;/li&gt;
&lt;li&gt;Select &lt;em&gt;Plug-ins and Fragments&lt;/em&gt; and click next.&lt;/li&gt;
&lt;li&gt;In the "&lt;em&gt;Import From&lt;/em&gt;" section choose "&lt;em&gt;The active target platform&lt;/em&gt;". &lt;/li&gt;
&lt;li&gt;In the "&lt;em&gt;Import As&lt;/em&gt;" section choose "&lt;em&gt;Project with source folders&lt;/em&gt;"&lt;/li&gt;
&lt;li&gt;In the next screen, locate your plug-in (&lt;em&gt;org.eclipse.jdt.ui&lt;/em&gt;) and add it.&lt;/li&gt;
&lt;li&gt;Click finish and the source code of the plug-in will be imported into your workspace.&lt;/li&gt;
&lt;/ol&gt;</content><category term="Eclipse"></category><category term="Plug-In"></category><category term="JDT"></category></entry><entry><title>How to Install an Acer Scanner Under Linux</title><link href="http://www.nihamkin.com/2012/11/12/how-to-install-an-acer-scanner-under-linux" rel="alternate"></link><published>2012-11-12T14:00:00+02:00</published><updated>2012-11-12T14:00:00+02:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2012-11-12:/2012/11/12/how-to-install-an-acer-scanner-under-linux</id><summary type="html">&lt;p&gt;I own an old Acer szw4300U scanner. Making it work with Linux is not exactly a plug and play, but not very complex either. Here is how it is done.&lt;/p&gt;
&lt;h4&gt;Drivers&lt;/h4&gt;
&lt;p&gt;An easy way is to use &lt;a href="http://www.sane-project.org/"&gt;SANE&lt;/a&gt; which is a framework that connects scanning software (frontends) with the scanners' …&lt;/p&gt;</summary><content type="html">&lt;p&gt;I own an old Acer szw4300U scanner. Making it work with Linux is not exactly a plug and play, but not very complex either. Here is how it is done.&lt;/p&gt;
&lt;h4&gt;Drivers&lt;/h4&gt;
&lt;p&gt;An easy way is to use &lt;a href="http://www.sane-project.org/"&gt;SANE&lt;/a&gt; which is a framework that connects scanning software (frontends) with the scanners' drivers (backends). &lt;/p&gt;
&lt;p&gt;On the &lt;a href="http://www.sane-project.org/sane-mfgs.html"&gt;following page&lt;/a&gt; you can find a list of supported scanners with reference to their drivers. My scanner uses a "snapscan" driver.&lt;/p&gt;
&lt;p&gt;Both SANE and the drivers are already installed by default on most Linux distributions. To verify that SANE is installed use the following command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;~$ scanimage -V
scanimage &lt;span class="o"&gt;(&lt;/span&gt;sane-backends&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;.0.22&lt;span class="p"&gt;;&lt;/span&gt; backend version &lt;span class="m"&gt;1&lt;/span&gt;.0.22
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;&lt;em&gt;scanimage&lt;/em&gt; is a defualt frontend that is bundled with SANE. Let's try to scan something with it. Do not forget to plug your scanner into the computer:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;~$ scanimage
&lt;span class="o"&gt;[&lt;/span&gt;snapscan&lt;span class="o"&gt;]&lt;/span&gt; Cannot open firmware file /usr/share/sane/snapscan/your-firmwarefile.bin.
&lt;span class="o"&gt;[&lt;/span&gt;snapscan&lt;span class="o"&gt;]&lt;/span&gt; Edit the firmware file entry in snapscan.conf.
scanimage: open of device snapscan:libusb:006:002 failed: Invalid argument
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;The issue here is that my driver is a generic one, meaning it can handle different models of scanners depending on a provided firmware file. A firmware file has .bin extension and can be found on the windows driver installation disc. The disc usually contains several firmware files, to find out which is the firmware file for your scanner model please refer to this &lt;a href="http://snapscan.sourceforge.net/#supported"&gt;table at the snapscan homepage&lt;/a&gt;. Notice that the number after the V in the name of the file is the version number, so you might find that your disc contains an older version than the one listed on the website. Nevertheless, the firmware will still fit.&lt;/p&gt;
&lt;h4&gt;Configuration&lt;/h4&gt;
&lt;p&gt;The next step is to configure snapscan to use the firmware. For example my file is 
&lt;em&gt;U176V042.BIN&lt;/em&gt;. We need to copy it into /usr/share/sane/snapscan/ (create the directory if it does not exist). &lt;/p&gt;
&lt;p&gt;Now open &lt;em&gt;/etc/sane.d/snapscan.conf&lt;/em&gt; and do the following:&lt;/p&gt;
&lt;p&gt;Uncomment the line &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;/dev/usb/scanner0 &lt;span class="nv"&gt;bus&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;usb
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;and then replace&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;firmware /usr/share/sane/snapscan/your-firmware.bin
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;with&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;firmware /usr/share/sane/snapscan/U176V042.BIN
&lt;/pre&gt;&lt;/div&gt;


&lt;h4&gt;Frontend&lt;/h4&gt;
&lt;p&gt;Finally we can test the scanner:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;~$ scanimage &amp;gt; test.pnm
&lt;span class="o"&gt;[&lt;/span&gt;snapscan&lt;span class="o"&gt;]&lt;/span&gt; Scanner warming up - waiting &lt;span class="m"&gt;20&lt;/span&gt; seconds.
&lt;span class="o"&gt;[&lt;/span&gt;snapscan&lt;span class="o"&gt;]&lt;/span&gt; Scanner warming up - waiting &lt;span class="m"&gt;20&lt;/span&gt; seconds.
~$ pnmtojpeg test.pnm &amp;gt; test.jpeg
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;If you want a GUI frontend you can see the &lt;a href="http://www3.sane-project.org/sane-frontends.html"&gt;list here&lt;/a&gt;. I personaly use XSane and it is quite good.&lt;/p&gt;
&lt;h4&gt;Common Problems&lt;/h4&gt;
&lt;p&gt;If you get an error similar to &lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;snapscan&lt;span class="o"&gt;]&lt;/span&gt; Cannot open firmware file /usr/share/sane/snapscan/U176V042.BIN
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;And absolutely sure that there are no typos in the conf file, I would suggest to look into the permissions of &lt;em&gt;U176V042.BIN&lt;/em&gt; file. The permissions should allow reading for "all". Here is a reminder of how to do it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;/usr/share/sane/snapscan$ sudo chmod a+r U176V042.BIN
&lt;/pre&gt;&lt;/div&gt;</content><category term="Linux"></category></entry><entry><title>Strange Blogofile IO Error</title><link href="http://www.nihamkin.com/2012/10/13/strange-blogofile-io-error" rel="alternate"></link><published>2012-10-13T15:00:00+02:00</published><updated>2012-10-13T15:00:00+02:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2012-10-13:/2012/10/13/strange-blogofile-io-error</id><summary type="html">&lt;p&gt;Sometimes when building a blogofile site I encounter "No such file or directory" IO error. In this article I will explain the cause of the error as well as how to prevent it.&lt;/p&gt;</summary><content type="html">&lt;p&gt;Sometimes when building a blogofile site I encounter the following IO error:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="n"&gt;Traceback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;/usr/local/bin/blogofile&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="n"&gt;load_entry_point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Blogofile==0.7.1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;console_scripts&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;blogofile&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)()&lt;/span&gt;
  &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;/usr/local/lib/python2.7/dist-packages/Blogofile-0.7.1-py2.7.egg/blogofile/main.py&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;135&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;
    &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;/usr/local/lib/python2.7/dist-packages/Blogofile-0.7.1-py2.7.egg/blogofile/main.py&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;201&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;do_build&lt;/span&gt;
    &lt;span class="n"&gt;writer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;write_site&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;/usr/local/lib/python2.7/dist-packages/Blogofile-0.7.1-py2.7.egg/blogofile/writer.py&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;53&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;write_site&lt;/span&gt;
    &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__write_files&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;/usr/local/lib/python2.7/dist-packages/Blogofile-0.7.1-py2.7.egg/blogofile/writer.py&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mi"&gt;103&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;__write_files&lt;/span&gt;
    &lt;span class="n"&gt;t_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t_fn_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="ne"&gt;IOError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Errno&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="n"&gt;No&lt;/span&gt; &lt;span class="n"&gt;such&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;./.#index.html.mako&amp;#39;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;This error was a bit confusing. Why does it say that index.html.mako does not exist when it is open right here in my editor? &lt;/p&gt;
&lt;p&gt;Well the editor, specifically Emacs is the cause of problem here. If you do not save your files immediately before running &lt;em&gt;blogofile build&lt;/em&gt; there is a chance that an Emacs auto-save file will appear in your directory. The file looks like &lt;em&gt;#index.html.mako#&lt;/em&gt; and blogofile probably have problems with the unusual file name. Once you save your files with &lt;em&gt;C-x C-s&lt;/em&gt; the file will be gone.&lt;/p&gt;
&lt;p&gt;Alternatively you can make Emacs save the auto-save files in one dedicated directory. Here is an &lt;a href="http://emacswiki.org/emacs/AutoSave"&gt;emacswiki article&lt;/a&gt; that explains how to achieve this.&lt;/p&gt;</content><category term="Blogofile"></category><category term="Emacs"></category></entry><entry><title>Highlighting Special Posts in Blogofile</title><link href="http://www.nihamkin.com/2012/09/25/highlighting-special-posts-in-blogofile" rel="alternate"></link><published>2012-09-25T17:00:00+02:00</published><updated>2012-09-25T17:00:00+02:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2012-09-25:/2012/09/25/highlighting-special-posts-in-blogofile</id><summary type="html">&lt;p&gt;This simple but use-full blogofile hack will allow you to alter the style of posts which are marked as special. 
For example the post you are reading belongs to the "Special" category and therefore has a golden background instead of the gray default one.&lt;/p&gt;
&lt;p&gt;This is quite straightforward hack, all …&lt;/p&gt;</summary><content type="html">&lt;p&gt;This simple but use-full blogofile hack will allow you to alter the style of posts which are marked as special. 
For example the post you are reading belongs to the "Special" category and therefore has a golden background instead of the gray default one.&lt;/p&gt;
&lt;p&gt;This is quite straightforward hack, all you have to do is to modify the "_templates/site.mako" template (assuming version 0.7.1). &lt;/p&gt;
&lt;p&gt;Replace the line:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;&amp;lt;div class=&amp;quot;blog_post&amp;quot;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;with the following snippet:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;%&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Special&amp;quot;&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;categories&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;&amp;lt;div class=&amp;quot;blog_post&amp;quot; style=&amp;quot;background-color: gold;&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;%&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;span class="x"&gt;&amp;lt;div class=&amp;quot;blog_post&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;%&lt;/span&gt;&lt;span class="k"&gt; endif&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;As can be seen, we check for the existence of the category name "Style" in a list that contains the names of all the categories of the current post. 
If this name exists we output the div element with custom style.&lt;/p&gt;
&lt;p&gt;This is enough for simple usage, but the idea can be extended for multiple category names and styles, allowing us to style each category differently.&lt;/p&gt;
&lt;p&gt;Add the following code at the top of "_templates/site.mako":&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="cp"&gt;&amp;lt;%&lt;/span&gt;
&lt;span class="n"&gt;category_styles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Special&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;background-color: gold;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                   &lt;span class="s2"&gt;&amp;quot;Another Example&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;border: 3px dashed black;&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;category_names&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;categories&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;style&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;category_styles&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;category_names&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="cp"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;As you can see, it is possible to add more category-style pairs into the "category_styles" dictionary. Ideally we would like to put this into the _config.py file , but currently I do not know how to do it.&lt;/p&gt;
&lt;p&gt;And finally, we need to update the div element to look like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="x"&gt;&amp;lt;div class=&amp;quot;blog_post&amp;quot; style=&amp;quot;&lt;/span&gt;&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;style&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;&lt;span class="x"&gt;&amp;quot;&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;</content><category term="Blogofile"></category><category term="Special"></category></entry><entry><title>Why I Chose Blogofile as my Blogging Platform</title><link href="http://www.nihamkin.com/2012/09/02/why-i-chose-blogofile-as-my-blogging-platform" rel="alternate"></link><published>2012-09-02T01:00:00+03:00</published><updated>2012-09-02T01:00:00+03:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2012-09-02:/2012/09/02/why-i-chose-blogofile-as-my-blogging-platform</id><summary type="html">&lt;p&gt;Blogofile is the blogging engine behind this blog.&lt;/p&gt;
&lt;p&gt;First of all, what is "Blogofile"? The definition from the original &lt;a href="http://www.blogofile.com/"&gt;website&lt;/a&gt; says:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Definition: Blogofile (n):&lt;/strong&gt; A static website compiler and blog engine, written and extended in Python.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Blogofile creates a static, full featured blog out of posts that are stored in …&lt;/p&gt;</summary><content type="html">&lt;p&gt;Blogofile is the blogging engine behind this blog.&lt;/p&gt;
&lt;p&gt;First of all, what is "Blogofile"? The definition from the original &lt;a href="http://www.blogofile.com/"&gt;website&lt;/a&gt; says:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Definition: Blogofile (n):&lt;/strong&gt; A static website compiler and blog engine, written and extended in Python.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Blogofile creates a static, full featured blog out of posts that are stored in text files. This static website then can be copied to any web server capable of serving static content. No need for PHP, python, .NET or CGI installed.
This is contrary to blogs that use dynamic platforms. In these platform, pages are generated on demand, each time a user tries to access them (caching may apply).&lt;/p&gt;
&lt;p&gt;There are some pros/cons for using static website generator for blogging. These have already been discussed on many blog posts by bloggers that switched to Blogofile. If you are interested in reading more just google it.&lt;/p&gt;
&lt;p&gt;I will provide several reasons that bought me in. Please excuse me if those are duplicates of things that others have already noticed.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Currently this website is hosted as a personal home page my university provides for students. For security reasons, students can host only static content, so using static content is the only option I have.&lt;/li&gt;
&lt;li&gt;When I will not be able to host my blog on my university's server, I will be able to move to any other server independently of available technology, eventually making the hosting cheaper.&lt;/li&gt;
&lt;li&gt;Because there is no "code behind", I do not have worry about security. &lt;/li&gt;
&lt;li&gt;Bologofile can be easily customized. It is easy to learn and setup and beginner friendly.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Hopefully in the future I will costumize Blogofile and share some experience with the readers.&lt;/p&gt;</content><category term="Blogofile"></category><category term="Web Development"></category><category term="About"></category></entry><entry><title>About this Blog</title><link href="http://www.nihamkin.com/2012/09/01/about-this-blog" rel="alternate"></link><published>2012-09-01T17:00:00+03:00</published><updated>2012-09-01T17:00:00+03:00</updated><author><name>Artium Nihamkin</name></author><id>tag:www.nihamkin.com,2012-09-01:/2012/09/01/about-this-blog</id><summary type="html">&lt;div class="section" id="welcome"&gt;
&lt;h2&gt;Welcome!&lt;/h2&gt;
&lt;p&gt;My name is Artium Nihamkin and I am a software engineer from Israel.&lt;/p&gt;
&lt;p&gt;This is my personal blog where I plan to publish interesting and useful stuff
that I encounter during my endeavor in my professional and personal life.&lt;/p&gt;
&lt;p&gt;Some of the things you might find here are:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Articles …&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</summary><content type="html">&lt;div class="section" id="welcome"&gt;
&lt;h2&gt;Welcome!&lt;/h2&gt;
&lt;p&gt;My name is Artium Nihamkin and I am a software engineer from Israel.&lt;/p&gt;
&lt;p&gt;This is my personal blog where I plan to publish interesting and useful stuff
that I encounter during my endeavor in my professional and personal life.&lt;/p&gt;
&lt;p&gt;Some of the things you might find here are:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;Articles related to software developer.&lt;/li&gt;
&lt;li&gt;Problems and solutions for various technical problems that I have personally encountered.&lt;/li&gt;
&lt;li&gt;Philosophical monologues.&lt;/li&gt;
&lt;li&gt;Discoveries in the world of hobby robotics.&lt;/li&gt;
&lt;li&gt;Links to interesting information in other blogs.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I do not expect people to follow my blog closely. My expectations are that
individual posts will be discovered through various google searches.&lt;/p&gt;
&lt;a href="http://stackexchange.com/users/204340"&gt;
&lt;img src="http://stackexchange.com/users/flair/204340.png?theme=dark" width="208" height="58" alt="profile for Artium on Stack Exchange, a network of free, community-driven Q&amp;amp;A sites" title="profile for Artium on Stack Exchange, a network of free, community-driven Q&amp;amp;A sites"&gt;
&lt;/a&gt;&lt;a href="https://projecteuler.net/progress=Artium"&gt;
&lt;img src="https://projecteuler.net/profile/Artium.png" width="208" height="58" alt="Project Euler flair"&gt;
&lt;/a&gt;&lt;p&gt;You always can reach me by the following email:&lt;/p&gt;
&lt;img src="/files/email3.gif" alt="email captcha"&gt;&lt;/div&gt;
</content><category term="About"></category></entry></feed>