https://log.vasilvv.org/Victor's Weblog2015-01-08T14:17:18ZVictor Vasilievhttps://log.vasilvv.org/post/where-am-iWhere am I? Locating yourself on different platforms2015-01-08T14:17:18Z<p>It happens every so often that a program needs to figure out where its
executable file is located. A common situation is when you are writing a unit
test, and your test data is located in the same directory as your binary.</p>
<p>Unfortunately, POSIX does not provide any interface to do that, so if you
are writing portable C/C++ code, you are in for an adventure. Below are short
code snippets which do that on various platforms. Try to guess which ones work
with which platform.</p>
<p><small><b>Disclaimer:</b> those are the snippets which I have collected from
various API references, StackOverflow answers and SDL source code. I have not
tested them, and you should not assume they actually always work correctly.
</small></p>
<p><b>Variant 1</b>
<div class="highlight"><pre><span class="n">GetModuleFileName</span><span class="p">(</span><span class="nb">NULL</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">path</span><span class="p">));</span>
</pre></div>
<p><b>Variant 2</b></p>
<div class="highlight"><pre><span class="n">path</span> <span class="o">=</span> <span class="n">getexecname</span><span class="p">();</span>
</pre></div>
<p><b>Variant 3</b></p>
<div class="highlight"><pre><span class="cm">/* This is, of course, an oversimplification. In practice, you would want to</span>
<span class="cm"> * do the link expansion recursively, or at least one level more deep than</span>
<span class="cm"> * this. */</span>
<span class="n">readlink</span><span class="p">(</span><span class="s">"/proc/self/exe"</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">path</span><span class="p">))</span>
</pre></div>
<p><b>Variant 4(a)</b></p>
<div class="highlight"><pre><span class="n">readlink</span><span class="p">(</span><span class="s">"/proc/curproc/file"</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">path</span><span class="p">))</span>
</pre></div>
<p><b>Variant 4(b)</b>, from the same platform as above</p>
<div class="highlight"><pre><span class="k">const</span> <span class="kt">int</span> <span class="n">mib</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span> <span class="n">CTL_KERN</span><span class="p">,</span> <span class="n">KERN_PROC</span><span class="p">,</span> <span class="n">KERN_PROC_PATHNAME</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">};</span>
<span class="n">sysctl</span><span class="p">(</span><span class="n">mib</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">mib</span><span class="p">),</span> <span class="n">path</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">path</span><span class="p">),</span> <span class="nb">NULL</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
</pre></div>
<p><b>Variant 5</b></p>
<div class="highlight"><pre><span class="n">_NSGetExecutablePath</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="o">&</span><span class="n">path_size</span><span class="p">);</span>
</pre></div>
<p>As a bonus, here is the same problem solved in higher-level languages.</p>
<p><b>Variant 6</b> <small>(used in multiple languages)</small></p>
<div class="highlight"><pre><span class="n">__FILE__</span>
</pre></div>
<p><b>Variant 7</b> <small>(strictly speaking, returns the directory instead of the file)</small></p>
<div class="highlight"><pre><span class="n">AppDomain</span><span class="p">.</span><span class="n">CurrentDomain</span><span class="p">.</span><span class="n">BaseDirectory</span>
</pre></div>
<p><b>Variant 8</b></p>
<div class="highlight"><pre><span class="n">SomeClass</span><span class="p">.</span><span class="n">class</span><span class="p">.</span><span class="n">getProtectionDomain</span><span class="p">().</span><span class="n">getCodeSource</span><span class="p">().</span><span class="n">getLocation</span><span class="p">().</span><span class="n">getPath</span><span class="p">();</span>
</pre></div>
<p>The answers here are (highlight to show): <span class="spoiler">#1 is
Windows, #2 is Solaris, #3 is Linux, #4 is FreeBSD, #5 is OS X, #6 could be
Python, Perl, PHP, Ruby (and probably others as well), #7 is C# and #8 is
Java</span>.</p>
<p>In practice, many frameworks (like SDL or Qt) have already solved that
problem once, and you can just call <code>SDL_GetBasePath</code> or
<code>QCoreApplication::applicationFilePath()</code> to get the path you
need.</p>https://log.vasilvv.org/post/this-blog-finally-existsPrologue2014-10-18T19:11:45Z<p>I finally decided to start writing a blog.</p>
<p>I've wanted to do that for quite a while; the issue was that I could not
find a platform I liked. WordPress seemed like an overkill, many of more
minimalist solutions were written in Ruby, which I can't speak... In short, I
ended up writing my own blogging engine using Flask.</p>
<p>I am baffled by how well-developed web frameworks for Python are
these days. You see, even though I've spent quite a while improving various
parts of MediaWiki (which is decidedly a webapp), I've never actually worked
with any <i>real</i> web frameworks, even for PHP. MediaWiki was written
in vanilla PHP, back when it was an actual improvement over Perl. Over
time it grew its very own supporting framework-library; it includes
some quite crazy features, like a reverse-engineered IE6 content sniffer and a
Lua sandbox. At the same time it is missing some things which you would
normally consider vital, like an HTML templating system. So when I discovered
that I made a blog in just 300 lines of code, only ~100 of which were Python, I
was very confused and tried hard to figure out which important part I am
missing.</p>
<p>Most of the time I spent on this was debugging CSS to make sure that website
is responsive and works well on some reasonable subset of browsers. I still
have a feeling that I actually have no idea how CSS works (that is apparently
<a href="https://i.imgur.com/Q3cUg29.gif">a somewhat widespread sentiment</a>),
so if you find that something is broken for a browser/screen size combination
you use, please tell me.</p>