<?xml version="1.0" encoding="UTF-8" ?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><atom:link href="https://raphgl.github.io/rss.xml" rel="self" type="application/rss+xml" /><title>RaphGL</title><link>https://raphgl.github.io</link><description>RaphGL's Blog</description><pubDate>Sun, 05 Jul 2026 10:22:56 +0000</pubDate><item><title>The case for custom static site generators</title><link>https://raphgl.github.io/blog/2026/07/the_case_for_custom_ssgs.html</link><guid>https://raphgl.github.io/blog/2026/07/the_case_for_custom_ssgs.html</guid><pubDate>Sat, 04 Jul 2026 00:00:00 +0000</pubDate><description>Some reasons to ditch static site generators and write your own</description><content:encoded><![CDATA[<p>Static site generators (SSGs) are fairly popular. Some of the most common ones out there are:
<a href="https://gohugo.io/">Hugo</a>, <a href="https://jekyllrb.com/">Jekyll</a>, <a href="https://www.gatsbyjs.com/">Gatsby</a>, <a href="https://www.getzola.org/">Zola</a></p>

<p>These generators usually rely on some form of directory structure to make sense of your website.
They also try to be very generic and provide as much functionality as possible out of the box.
In this quest for broad utility they all end up making generating a static site more complicated than it should be.
There&rsquo;s many functions, many taxonomies, you need to learn <em>their</em> templating language (or use a javascript frontend framework which is then prerendered),
know which block thingy to wrap your html around, etc.</p>

<p>All this rigmarole is simply a waste of time. All you wanted to do was render some html and display some information but now you&rsquo;re forced to understand all this machinery,
possibly debug why you can&rsquo;t get it to do exactly what you wanted, and they might&rsquo;ve broken the API and now you&rsquo;re forced
to go and update your website&rsquo;s template just because of someone else&rsquo;s whims.</p>

<h2>You do not need a general purpose static site generator</h2>

<p>What you want is to be able to write some markdown or some other format of your choice and have it be translated to the verbose html equivalent with a little bit of styling.
Static site generators are glorified string appenders. You can write your own in half an hour and just add more functionality as you need them.</p>

<p>The initial set up might be slightly annoying but once you have the base built, building on top of it is way easier.
There&rsquo;s no more arbitrary breaking changes because of things you never even cared about.
You no longer have to spend time digging documentation and forums for answers on how to do something, you can just do it. You&rsquo;re in total control.</p>
]]></content:encoded></item><item><title>Stop (ab)using regex</title><link>https://raphgl.github.io/blog/stop-abusing-regex.html</link><guid>https://raphgl.github.io/blog/stop-abusing-regex.html</guid><pubDate>Sun, 23 Nov 2025 00:00:00 +0000</pubDate><description>Stop it, get some help!</description><content:encoded><![CDATA[<p>Due to how widespread support for regex is in many languages, people feel like regex is a good tool to reach out for when you need to match over some text.
Whether it be while writing a parser, validating some input or whatever else. I&rsquo;m here to argue that while there are some small valid uses for regex that are very useful,
most uses of regex are an abuse of them. This is because people writing regex usually don&rsquo;t really know how to parse themselves.
So they just use whatever tool they know how to use.</p>

<h3>How your regex is ran</h3>

<p>To be run, your regex first goes through a few steps:</p>

<ol>
<li>Tokenizing - the regex is read and converted into tokens</li>
<li>Parsing - the tokens are converted into a syntax tree that can be walked through and more easily worked with by code</li>
<li>Compilation - the syntax tree is read and compiled into instructions for a regex virtual machine</li>
<li>Optimization (optional) - the instructions are ran through an optimizer and then turned into more efficient code</li>
</ol>

<p>By the time all of this is done your program has run through a couple thousand lines of code.
Now you have a compiled regex expression and can run it through the regex virtual machine.</p>

<h2>Regex is bad</h2>

<p>From a performance standpoint, doing all those steps already is much slower than calling any small function. Running through a virtual machine means at least a few levels
of indirection which is likely to thrash the cache and just runs a lot more code to do the same thing. So just by using regex, you&rsquo;re letting go of performance.
But ok, you don&rsquo;t care about performance. I get it, no one cares about performance anymore. So let&rsquo;s look at the other reason why regex is bad.</p>

<h4>Regex is unmaintainable</h4>

<p>Comprehending any reasonable complex regex expression is a huge waste of time. Let&rsquo;s look at this example
I copied <a href="https://stackoverflow.com/questions/19605150/regex-for-password-must-contain-at-least-eight-characters-at-least-one-number-a">from stackoverflow</a>:</p>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="s2">&#34;^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$&#34;</span>
</span></span></code></pre>
<p>Can you guess what it does at a glance without opening the link, seeing a comment or using one of those regex explainer tools? Probably not.
Here&rsquo;s what it does:</p>

<blockquote>
<p>Minimum eight characters, at least one letter and one number</p>
</blockquote>

<p>Now look at what the alternative is:</p>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="c1">// note: isAlphanumeric, isNumber and isAlpha are not real javascript functions
</span></span></span><span class="line"><span class="cl"><span class="c1">// but they&#39;re here to prove a point not to write absolutely correct code
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">function</span> <span class="nx">isValidPassword</span><span class="p">(</span><span class="nx">password</span>: <span class="kt">string</span><span class="p">)</span><span class="o">:</span> <span class="kt">bool</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">if</span> <span class="p">(</span><span class="nx">password</span><span class="p">.</span><span class="nx">length</span> <span class="o">&lt;</span> <span class="mi">8</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="kd">let</span> <span class="nx">charCount</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="kd">let</span> <span class="nx">numCount</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">for</span> <span class="p">(</span><span class="kr">const</span> <span class="nx">c</span> <span class="k">of</span> <span class="nx">password</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">c</span><span class="p">.</span><span class="nx">isAlphanumeric</span><span class="p">())</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nx">c</span><span class="p">.</span><span class="nx">isNumber</span><span class="p">())</span> <span class="nx">numCount</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nx">c</span><span class="p">.</span><span class="nx">isAlpha</span><span class="p">())</span> <span class="nx">charCount</span> <span class="o">+=</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">return</span> <span class="nx">charCount</span> <span class="o">&gt;=</span> <span class="mi">1</span> <span class="o">&amp;&amp;</span> <span class="nx">numCount</span> <span class="o">&gt;=</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre>
<p>It is more &ldquo;verbose&rdquo; but you can actually understand what it&rsquo;s doing and if you wanted to update the validation you can easily change it and reason about it.
Meanwhile for the regex version it might take you a couple tries and you might even need to completely scrap your current implementation. Even if you were a regex wizard,
other people aren&rsquo;t. So your regex is just objectively harder to understand and maintain.</p>

<h4>Regex can&rsquo;t give good error messages</h4>

<p>The only thing you get from using a regex is a match or not a match. You can&rsquo;t really give good error messages with it.
If you write the parser yourself and you know what is and isn&rsquo;t expected, you can give more meaningful error messages than &ldquo;password doesn&rsquo;t match regex&rdquo; or whatever.</p>

<h4>Regex is good actually</h4>

<p>Regex is not a good tool for validation and parsing. People use them as such but they&rsquo;re not a good tool for that. It&rsquo;s not a replacement for knowing how to parse.
If your program requires user interactivity to do matches, then regex is a good tool. Things like search functionality in text editors,
the find tool on browsers and so on are good use cases, for a regex engine in your program.</p>

<p>But if you already know the shape of the thing you want to match against and it&rsquo;s not supplied by the user,
then you&rsquo;re probably better off writing your own validation/parser.
You&rsquo;ll get better performance, better errors and more understandable and maintainable code.</p>
]]></content:encoded></item><item><title>C compiler flags you ought to know</title><link>https://raphgl.github.io/blog/recommended-c-compiler-flags.html</link><guid>https://raphgl.github.io/blog/recommended-c-compiler-flags.html</guid><pubDate>Mon, 17 Nov 2025 00:00:00 +0000</pubDate><description>A compiled list of compiler flags that make development and catching errors easier</description><content:encoded><![CDATA[<p>C compilers have bad defaults due to the need to be &ldquo;backwards compatible&rdquo;.
This means that despite improvements in C compilers, you just have to know what to use.
If you&rsquo;re not in the know, you might subject yourself to pain needlessly.</p>

<p>This is a compiled list of flags you might want to use.
Heavily inspired by <a href="https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html">Compiler Options Hardening Guide for C and C++</a>.
I felt that this adaptation was needed because that post suffered from &ldquo;too much yapping&rdquo;.</p>

<h2>The Essentials</h2>

<p>No matter what you do, always enable <code>-Wall -Wextra -pedantic</code>, these flags are actually a group of other flags that enable other errors.
If you want to see what they can do you can check the manpage for them:</p>
<pre class="chroma"><code><span class="line"><span class="cl">-Wall
</span></span><span class="line"><span class="cl">  This enables all the warnings about constructions that some users consider questionable, and that are easy to avoid (or modify to prevent the warning), even in conjunction with
</span></span><span class="line"><span class="cl">  macros.  This also enables some language-specific warnings described in C++ Dialect Options and Objective-C and Objective-C++ Dialect Options.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  -Wall turns on the following warning flags:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  -Waddress -Waligned-new (C++ and Objective-C++ only) -Warray-bounds=1 (only with -O2) -Warray-compare -Warray-parameter=2 -Wbool-compare -Wbool-operation -Wc++11-compat
</span></span><span class="line"><span class="cl">  -Wc++14-compat  -Wc++17compat  -Wc++20compat -Wcatch-value (C++ and Objective-C++ only) -Wchar-subscripts -Wclass-memaccess (C++ and Objective-C++ only) -Wcomment -Wdangling-else
</span></span><span class="line"><span class="cl">  -Wdangling-pointer=2 -Wdelete-non-virtual-dtor (C++ and Objective-C++ only) -Wduplicate-decl-specifier (C and Objective-C only) -Wenum-compare (in C/ObjC; this is on by default in
</span></span><span class="line"><span class="cl">  C++) -Wenum-int-mismatch (C and Objective-C only) -Wformat=1 -Wformat-contains-nul -Wformat-diag -Wformat-extra-args -Wformat-overflow=1 -Wformat-truncation=1 -Wformat-zero-length
</span></span><span class="line"><span class="cl">  -Wframe-address -Wimplicit (C and Objective-C only) -Wimplicit-function-declaration (C and Objective-C only) -Wimplicit-int (C and Objective-C only) -Winfinite-recursion
</span></span><span class="line"><span class="cl">  -Winit-self (C++ and Objective-C++ only) -Wint-in-bool-context -Wlogical-not-parentheses -Wmain (only for C/ObjC and unless -ffreestanding) -Wmaybe-uninitialized -Wmemset-elt-size
</span></span><span class="line"><span class="cl">  -Wmemset-transposed-args -Wmisleading-indentation (only for C/C++) -Wmismatched-dealloc -Wmismatched-new-delete (C++ and Objective-C++ only) -Wmissing-attributes -Wmissing-braces
</span></span><span class="line"><span class="cl">  (only for C/ObjC) -Wmultistatement-macros -Wnarrowing  (C++ and Objective-C++ only) -Wnonnull -Wnonnull-compare -Wopenmp-simd (C and C++ only) -Woverloaded-virtual=1 (C++ and
</span></span><span class="line"><span class="cl">  Objective-C++ only) -Wpacked-not-aligned -Wparentheses -Wpessimizing-move (C++ and Objective-C++ only) -Wpointer-sign (only for C/ObjC) -Wrange-loop-construct (C++ and
</span></span><span class="line"><span class="cl">  Objective-C++ only) -Wreorder (C++ and Objective-C++ only) -Wrestrict -Wreturn-type -Wself-move (C++ and Objective-C++ only) -Wsequence-point -Wsign-compare (C++ and Objective-C++
</span></span><span class="line"><span class="cl">  only) -Wsizeof-array-div -Wsizeof-pointer-div -Wsizeof-pointer-memaccess -Wstrict-aliasing -Wstrict-overflow=1 -Wswitch -Wtautological-compare -Wtrigraphs -Wuninitialized
</span></span><span class="line"><span class="cl">  -Wunknown-pragmas -Wunused -Wunused-but-set-variable -Wunused-const-variable=1 (only for C/ObjC) -Wunused-function -Wunused-label -Wunused-local-typedefs -Wunused-value
</span></span><span class="line"><span class="cl">  -Wunused-variable -Wuse-after-free=2 -Wvla-parameter -Wvolatile-register-var -Wzero-length-bounds
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  Note that some warning flags are not implied by -Wall.  Some of them warn about constructions that users generally do not consider questionable, but which occasionally you might
</span></span><span class="line"><span class="cl">  wish to check for; others warn about constructions that are necessary or hard to avoid in some cases, and there is no simple way to modify the code to suppress the warning. Some of
</span></span><span class="line"><span class="cl">  them are enabled by -Wextra but many of them must be enabled individually.
</span></span></code></pre><pre class="chroma"><code><span class="line"><span class="cl">-Wextra
</span></span><span class="line"><span class="cl">  This enables some extra warning flags that are not enabled by -Wall. (This option used to be called -W.  The older name is still supported, but the newer name is more descriptive.)
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  -Wabsolute-value (only for C/ObjC) -Walloc-size -Wcalloc-transposed-args -Wcast-function-type -Wclobbered -Wdangling-reference (C++ only) -Wdeprecated-copy (C++ and Objective-C++
</span></span><span class="line"><span class="cl">  only) -Wempty-body -Wenum-conversion (only for C/ObjC) -Wexpansion-to-defined -Wignored-qualifiers  (only for C/C++) -Wimplicit-fallthrough=3 -Wmaybe-uninitialized
</span></span><span class="line"><span class="cl">  -Wmissing-field-initializers -Wmissing-parameter-name (C/ObjC only) -Wmissing-parameter-type (C/ObjC only) -Wold-style-declaration (C/ObjC only) -Woverride-init (C/ObjC only)
</span></span><span class="line"><span class="cl">  -Wredundant-move (C++ and Objective-C++ only) -Wshift-negative-value (in C++11 to C++17 and in C99 and newer) -Wsign-compare (C++ and Objective-C++ only) -Wsized-deallocation (C++
</span></span><span class="line"><span class="cl">  and Objective-C++ only) -Wstring-compare -Wtype-limits -Wuninitialized -Wunterminated-string-initialization -Wunused-parameter (only with -Wunused or -Wall)
</span></span><span class="line"><span class="cl">  -Wunused-but-set-parameter (only with -Wunused or -Wall)
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  The option -Wextra also prints warning messages for the following cases:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  *   A pointer is compared against integer zero with &#34;&lt;&#34;, &#34;&lt;=&#34;, &#34;&gt;&#34;, or &#34;&gt;=&#34;.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  *   (C++ only) An enumerator and a non-enumerator both appear in a conditional expression.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  *   (C++ only) Ambiguous virtual bases.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  *   (C++ only) Subscripting an array that has been declared &#34;register&#34;.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  *   (C++ only) Taking the address of a variable that has been declared &#34;register&#34;.
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  *   (C++ only) A base class is not initialized in the copy constructor of a derived class.
</span></span></code></pre><pre class="chroma"><code><span class="line"><span class="cl">-pedantic
</span></span><span class="line"><span class="cl">  Issue all the warnings demanded by strict ISO C and ISO C++; diagnose all programs that use forbidden extensions, and some other programs that do not follow ISO C and ISO C++.
</span></span><span class="line"><span class="cl">  This follows the version of the ISO C or C++ standard specified by any -std option used.
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  Valid ISO C and ISO C++ programs should compile properly with or without this option (though a rare few require -ansi or a -std option specifying the version of the standard).
</span></span><span class="line"><span class="cl">  However, without this option, certain GNU extensions and traditional C and C++ features are supported as well.  With this option, they are diagnosed (or rejected with
</span></span><span class="line"><span class="cl">  -pedantic-errors).
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  -Wpedantic does not cause warning messages for use of the alternate keywords whose names begin and end with __.  This alternate format can also be used to disable warnings for
</span></span><span class="line"><span class="cl">  non-ISO __intN types, i.e. __intN__.  Pedantic warnings are also disabled in the expression that follows &#34;__extension__&#34;.  However, only system header files should use these escape
</span></span><span class="line"><span class="cl">  routes; application programs should avoid them.
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  Some warnings about non-conforming programs are controlled by options other than -Wpedantic; in many cases they are implied by -Wpedantic but can be disabled separately by their
</span></span><span class="line"><span class="cl">  specific option, e.g. -Wpedantic -Wno-pointer-sign.
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  Where the standard specified with -std represents a GNU extended dialect of C, such as gnu90 or gnu99, there is a corresponding base standard, the version of ISO C on which the GNU
</span></span><span class="line"><span class="cl">  extended dialect is based.  Warnings from -Wpedantic are given where they are required by the base standard.  (It does not make sense for such warnings to be given only for
</span></span><span class="line"><span class="cl">  features not in the specified GNU C dialect, since by definition the GNU dialects of C include all features the compiler supports with the given option, and there would be nothing
</span></span><span class="line"><span class="cl">  to warn about.)
</span></span></code></pre>
<p>Some people recommend adding <code>-Werror</code> which turns every warning into an error, but I don&rsquo;t really think that&rsquo;s reasonable. When you&rsquo;re iterating on a project, being forced to
fix any minutia slows you down. If you&rsquo;re going to enable it at all, I suggest you enable it for release builds.</p>

<h4>Sanitizers</h4>

<p>Sanitizers are your friend. They&rsquo;ll help you with detecting memory leaks, undefined behavior and other common bugs. They can be enabled with the <code>-fsanitize</code> flag.
Also don&rsquo;t forget to add <code>-g</code> when compiling to add debug symbols, otherwise the sanitization errors might not be as useful.
(You can also use valgrind but I won&rsquo;t get into it in this post).</p>

<p>There&rsquo;s many sanitizers you can use. I recommend looking at the manpage and seeing what sanitizers are available. Bear in mind that not all sanitizers can be used together.
So you might have to compile your code and test it with each sanitizer individually. As far as I know, you can use <code>-fsanitize=leak,undefined,address</code> and these 3 can work together just fine.
So I recommend using this at least on your debug builds. (do not that if you use a library that has many leaks and was never used with sanitizers, you might have to add an ignore list so that you
can sanitize your own code, it&rsquo;s just the state of things sadly)</p>

<h4>C Standard</h4>

<p>A lot of people swear by C89 but personally I&rsquo;m not a fan. I recommend C99+. C99 is a nice standard if you want to support as many compilers as possible and/or you don&rsquo;t need atomics.
If you do need atomics, C11 is fine, Linux for example defaults to it (technically gnu11, but still).</p>

<p>I recommend you always set your standard with <code>-std=c99</code> or whatever version you&rsquo;re using. GCC defaults to their own dialect which has a bunch of extensions. I&rsquo;d rather use the standard
and not a dialect, only use it if you know you need the extensions (for some reason).</p>

<h2>Compiler Flags</h2>

<p>The following are flags that you might benefit from, they either add compile-time or runtime checks to make the compiler/program even stricter.</p>

<p>Flags that enable compile-time checks:</p>

<table>
<thead>
<tr>
<th>Compiler Flag</th>
<th>Supported since</th>
<th>Description</th>
</tr>
</thead>

<tbody>
<tr>
<td>-Wformat <br/>-Wformat=2</td>
<td>GCC 2.95.3Clang 4.0.0</td>
<td>Enable additional format function warnings</td>
</tr>

<tr>
<td>-Wconversion <br/>-Wsign-conversion</td>
<td>GCC 2.95.3Clang 4.0.0</td>
<td>Enable implicit conversion warnings</td>
</tr>

<tr>
<td>-Wtrampolines</td>
<td>GCC 4.3.0</td>
<td>Enable warnings about trampolines that require executable stacks</td>
</tr>

<tr>
<td>-Wimplicit-fallthrough</td>
<td>GCC 7.0.0Clang 4.0.0</td>
<td>Warn when a switch case falls through</td>
</tr>

<tr>
<td>-Wbidi-chars=any</td>
<td>GCC 12.0.0</td>
<td>Enable warnings for possibly misleading Unicode bidirectional control characters</td>
</tr>

<tr>
<td>-Werror <br/>-Werror=<warning-flag></td>
<td>GCC 2.95.3Clang 2.6.0</td>
<td>Treat all or selected compiler warnings as errors. Use the blanket form  <br/>-Werror only during development, not in source distribution.</td>
</tr>

<tr>
<td>-Werror=format-security</td>
<td>GCC 2.95.3Clang 4.0.0</td>
<td>Treat format strings that are not string literals and used without arguments as errors</td>
</tr>

<tr>
<td>-Werror=implicit <br/>-Werror=incompatible-pointer-types <br/>-Werror=int-conversion</td>
<td>GCC 2.95.3Clang 2.6.0</td>
<td>Treat obsolete C constructs as errors</td>
</tr>
</tbody>
</table>
<p>Flags that enable runtime checks:</p>

<table>
<thead>
<tr>
<th>Compiler Flag</th>
<th>Supported since</th>
<th>Description</th>
</tr>
</thead>

<tbody>
<tr>
<td>-D_FORTIFY_SOURCE=3</td>
<td>GCC 12.0.0Clang 9.0.02</td>
<td>Fortify sources with compile- and run-time checks for unsafe libc usage and buffer overflows. Some fortification levels can impact performance. Requires -O1 or higher, may require prepending -U_FORTIFY_SOURCE.</td>
</tr>

<tr>
<td>-D_GLIBCXX_ASSERTIONS</td>
<td>libstdc++ 6.0.0</td>
<td>Precondition checks for C++ standard library calls. Can impact performance.</td>
</tr>

<tr>
<td>-fstrict-flex-arrays=3</td>
<td>GCC 13.0.0Clang 16.0.0</td>
<td>Consider a trailing array in a struct as a flexible array if declared as []</td>
</tr>

<tr>
<td>-fstack-clash-protection</td>
<td>GCC 8.0.0Clang 11.0.0</td>
<td>Enable run-time checks for variable-size stack allocation validity. Can impact performance.</td>
</tr>

<tr>
<td>-fstack-protector-strong</td>
<td>GCC 4.9.0Clang 6.0.0</td>
<td>Enable run-time checks for stack-based buffer overflows. Can impact performance.</td>
</tr>

<tr>
<td>-fcf-protection=full</td>
<td>GCC 8.0.0Clang 7.0.0</td>
<td>Enable control-flow protection against return-oriented programming (ROP) and jump-oriented programming (JOP) attacks on x86_64</td>
</tr>

<tr>
<td>-mbranch-protection=standard</td>
<td>GCC 9.0.0Clang 8.0.0</td>
<td>Enable branch protection against ROP and JOP attacks on AArch64</td>
</tr>

<tr>
<td><br/>-Wl,-z,nodlopen</td>
<td>Binutils 2.10.0</td>
<td>Restrict dlopen(3) calls to shared objects</td>
</tr>

<tr>
<td><br/>-Wl,-z,noexecstack</td>
<td>Binutils 2.14.0</td>
<td>Enable data execution prevention by marking stack memory as non-executable</td>
</tr>

<tr>
<td><br/>-Wl,-z,relro <br/>-Wl,-z,now</td>
<td>Binutils 2.15.0</td>
<td>Mark relocation table entries resolved at load-time as read-only.  <br/>-Wl,-z,now can impact startup performance.</td>
</tr>

<tr>
<td>-fPIE -pie</td>
<td>Binutils 2.16.0Clang 5.0.0</td>
<td>Build as position-independent executable. Can impact performance on 32-bit architectures.</td>
</tr>

<tr>
<td>-fPIC -shared</td>
<td>&lt; Binutils 2.6.0Clang 5.0.0</td>
<td>Build as position-independent code. Can impact performance on 32-bit architectures.</td>
</tr>

<tr>
<td>-fno-delete-null-pointer-checks</td>
<td>GCC 3.0.0Clang 7.0.0</td>
<td>Force retention of null pointer checks</td>
</tr>

<tr>
<td>-fno-strict-overflow</td>
<td>GCC 4.2.0</td>
<td>Define behavior for signed integer and pointer arithmetic overflows</td>
</tr>

<tr>
<td>-fno-strict-aliasing</td>
<td>GCC 2.95.3Clang 2.9.0</td>
<td>Do not assume strict aliasing</td>
</tr>

<tr>
<td>-ftrivial-auto-var-init</td>
<td>GCC 12.0.0Clang 8.0.0</td>
<td>Initialize automatic variables that lack explicit initializers</td>
</tr>

<tr>
<td>-fexceptions</td>
<td>GCC 2.95.3Clang 2.6.0</td>
<td>Enable exception propagation to harden multi-threaded C code</td>
</tr>

<tr>
<td>-fhardened</td>
<td>GCC 14.0.0</td>
<td>Enable pre-determined set of hardening options in GCC</td>
</tr>

<tr>
<td><br/>-Wl,&ndash;as-needed <br/>-Wl,&ndash;no-copy-dt-needed-entries</td>
<td>Binutils 2.20.0</td>
<td>Allow linker to omit libraries specified on the command line to link against if they are not used</td>
</tr>

<tr>
<td>-fzero-init-padding-bits=all</td>
<td>GCC 15.0.0</td>
<td>Guarantee zero initialization of padding bits in all automatic variable initializers</td>
</tr>
</tbody>
</table>
<p>I suggest you read the manpages and search online for the flags you&rsquo;re interested in using.</p>
]]></content:encoded></item><item><title>How to write generics in C</title><link>https://raphgl.github.io/blog/generics-in-c.html</link><guid>https://raphgl.github.io/blog/generics-in-c.html</guid><pubDate>Sat, 15 Nov 2025 00:00:00 +0000</pubDate><description>Implementing type-safe generics in C step by step</description><content:encoded><![CDATA[<p>C is barebones and &ldquo;doesn&rsquo;t support&rdquo; generics, but it&rsquo;s actually quite easy to implement with the tools we already have.
There&rsquo;s many ways you might find them being implemented in the wild. Some of the common ones are:</p>

<ul>
<li><strong>Using function-like macros</strong></li>
</ul>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="cp">#define vector_push(vector, item) vector.buf[vector.idx++] = item;
</span></span></span></code></pre>
<p>Con: This will cause everything to be inlined and loosely typed.</p>

<ul>
<li><strong>Using void pointers</strong></li>
</ul>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">vector_push</span><span class="p">(</span><span class="n">Vector</span> <span class="n">vec</span><span class="p">,</span> <span class="kt">void</span> <span class="o">*</span><span class="n">item</span><span class="p">);</span>
</span></span></code></pre>
<p>Con: You rely on type erasure to achieve generics, so you&rsquo;ll have to recast everything back to access them.
You might also run into UB.</p>

<ul>
<li><strong>Dispatch specializations through a function-like macro</strong></li>
</ul>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="cp">#define DECLARE_VECTOR(type) \
</span></span></span><span class="line"><span class="cl"><span class="cp">  void vector_push(Vector##_##type, type item) {\
</span></span></span><span class="line"><span class="cl"><span class="cp">    </span><span class="c1">// do stuff here \
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">DECLARE_VECTOR</span><span class="p">(</span><span class="kt">int</span><span class="p">)</span>
</span></span></code></pre>
<p>Con: Everything is wrapped in a macro and might break autocomplete</p>

<p><br>
</p>

<p>The approach I recommend is not really novel, but it&rsquo;s the one I&rsquo;ve found to be the nicest to use and to work better with existing tooling.
Since it doesn&rsquo;t rely on type erasure and everything isn&rsquo;t wrapped in macros.</p>

<p><br>
</p>

<p>Pros:</p>

<ul>
<li>Type safe</li>
<li>Doesn&rsquo;t have to use pointers</li>
<li>Minimal use of Macros</li>
<li>Can be deduplicated by linkers</li>
<li>Can be entirely put in a single file to reduce changes triggering compilation for multiple files</li>
</ul>

<p>Cons:</p>

<ul>
<li>Relies on a macro trick</li>
<li>Can be a bit verbose</li>
</ul>

<h2>Achieving generics through header instantiation</h2>

<p>The way this works is, you instantiate a specialization for a type by defining your type and possibly a suffix if that type is not a valid identifier name.
To do this, we&rsquo;ll have to rely on a small macro trick, but other than that, everything is quite straight forward. The header instantiation should look like this:</p>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="cp">#define VEC_ITEM_TYPE long long
</span></span></span><span class="line"><span class="cl"><span class="cp">#define VEC_SUFFIX num
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;vector.h&#34;</span><span class="cp">
</span></span></span></code></pre>
<p>With the <code>VEC_SUFFIX</code> being optional.</p>

<p>Once instantiated this would give you a <code>vector_push_num</code> function you could use.
To do this we need to be able to append <code>_num</code> to our symbol names. So we create a <code>G</code> function-like macro.</p>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="cp">#define G(name) name##_##VEC_ITEM_TYPE
</span></span></span></code></pre>
<p>Except, this doesn&rsquo;t work. You can&rsquo;t just expand and append them like that. We need to expand the definitions first and then append them, so we&rsquo;ll rely on the following trick:</p>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="cp">#define __G(name, type) name##_##type
</span></span></span><span class="line"><span class="cl"><span class="cp">#define _G(name, type) __G(name, type)
</span></span></span><span class="line"><span class="cl"><span class="cp">#define G(name) _G(name, VEC_ITEM_TYPE)
</span></span></span></code></pre>
<p>It works now! Now we can wrap our identifier names in a <code>G</code> macro so that they&rsquo;re <a href="https://en.wikipedia.org/wiki/Name_mangling"><em>name mangled</em></a> for the types they&rsquo;re for.<br>
We can use it to define our functions and structs like this: <code>struct G(something)</code>, <code>void G(do_something)()</code>.</p>

<h3>Enforcing type definition and allowing custom suffixes</h3>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="cp">#ifndef VEC_ITEM_TYPE
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>  <span class="cp">#error VEC_ITEM_TYPE was not defined
</span></span></span><span class="line"><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#ifndef VEC_SUFFIX
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>  <span class="cp">#define VEC_SUFFIX VEC_ITEM_TYPE
</span></span></span><span class="line"><span class="cl"><span class="cp">#endif
</span></span></span></code></pre>
<p>Now we can emit an error if <code>VEC_ITEM_TYPE</code> is not defined.</p>

<p>This fixes wrong uses of the header but what if we want to use something like <code>long long</code> or <code>atomic int</code>? It won&rsquo;t work.
So we have to introduce a way of programmatically overriding the suffix that&rsquo;s added to functions. So we&rsquo;ll introduce a <code>VEC_SUFFIX</code>:</p>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="cp">#ifndef VEC_ITEM_TYPE
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>  <span class="cp">#error VEC_ITEM_TYPE was not defined
</span></span></span><span class="line"><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#ifndef VEC_SUFFIX
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>  <span class="cp">#define VEC_SUFFIX VEC_ITEM_TYPE
</span></span></span><span class="line"><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#define __G(name, type) name##_##type
</span></span></span><span class="line"><span class="cl"><span class="cp">#define _G(name, type) __G(name, type)
</span></span></span><span class="line"><span class="cl"><span class="cp">#define G(name) _G(name, VEC_SUFFIX)
</span></span></span></code></pre>
<p>Now we&rsquo;re free to implement our library. For example, here&rsquo;s a generic <code>vec_pop</code> implementation:</p>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kt">bool</span> <span class="nf">G</span><span class="p">(</span><span class="n">vec_pop</span><span class="p">)(</span><span class="nf">G</span><span class="p">(</span><span class="n">Vector</span><span class="p">)</span> <span class="o">*</span><span class="n">vec</span><span class="p">,</span> <span class="n">VEC_ITEM_TYPE</span> <span class="o">*</span><span class="n">dest</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">   <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">vec</span><span class="o">-&gt;</span><span class="n">vec</span> <span class="o">||</span> <span class="n">vec</span><span class="o">-&gt;</span><span class="n">len</span> <span class="o">&lt;=</span> <span class="mi">0</span> <span class="o">||</span> <span class="n">vec</span><span class="o">-&gt;</span><span class="n">capacity</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">return</span> <span class="nb">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">   <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">   <span class="n">vec</span><span class="o">-&gt;</span><span class="n">len</span><span class="o">--</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">   <span class="k">if</span> <span class="p">(</span><span class="n">dest</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="o">*</span><span class="n">dest</span> <span class="o">=</span> <span class="n">vec</span><span class="o">-&gt;</span><span class="n">vec</span><span class="p">[</span><span class="n">vec</span><span class="o">-&gt;</span><span class="n">len</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">   <span class="p">}</span>
</span></span><span class="line"><span class="cl">   <span class="nf">G</span><span class="p">(</span><span class="n">vec_fit</span><span class="p">)(</span><span class="n">vec</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">   <span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre>
<p>As you can see, every time we call anything generic we need to wrap it in <code>G</code> so that it can properly call the generic function.</p>

<h3>The elephants in the room</h3>

<h4>Redeclaration error</h4>

<p>You can try and use this implementation but unless you only have one C file and nothing else, you&rsquo;re likely to eventually run into a redeclaration error especially if you&rsquo;re
using this generic library on <code>.c</code> and <code>.h</code> files.</p>

<p>A potential fix is to make everything <code>static</code> but then you would end up duplicating everything throughout many translation units in your program.</p>

<p>The actual fix is to be able to choose when to forward declare and when to use the implementation:</p>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="cp">#ifndef VEC_IMPLEMENTATION
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>  <span class="kt">bool</span> <span class="nf">G</span><span class="p">(</span><span class="n">vec_pop</span><span class="p">)(</span><span class="nf">G</span><span class="p">(</span><span class="n">Vector</span><span class="p">)</span> <span class="o">*</span><span class="n">vec</span><span class="p">,</span> <span class="n">VEC_ITEM_TYPE</span> <span class="o">*</span><span class="n">dest</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="cp">#else
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>  <span class="kt">bool</span> <span class="nf">G</span><span class="p">(</span><span class="n">vec_pop</span><span class="p">)(</span><span class="nf">G</span><span class="p">(</span><span class="n">Vector</span><span class="p">)</span> <span class="o">*</span><span class="n">vec</span><span class="p">,</span> <span class="n">VEC_ITEM_TYPE</span> <span class="o">*</span><span class="n">dest</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">     <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">vec</span><span class="o">-&gt;</span><span class="n">vec</span> <span class="o">||</span> <span class="n">vec</span><span class="o">-&gt;</span><span class="n">len</span> <span class="o">&lt;=</span> <span class="mi">0</span> <span class="o">||</span> <span class="n">vec</span><span class="o">-&gt;</span><span class="n">capacity</span> <span class="o">&lt;=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="nb">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">     <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">     <span class="n">vec</span><span class="o">-&gt;</span><span class="n">len</span><span class="o">--</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">     <span class="k">if</span> <span class="p">(</span><span class="n">dest</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="o">*</span><span class="n">dest</span> <span class="o">=</span> <span class="n">vec</span><span class="o">-&gt;</span><span class="n">vec</span><span class="p">[</span><span class="n">vec</span><span class="o">-&gt;</span><span class="n">len</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">     <span class="p">}</span>
</span></span><span class="line"><span class="cl">     <span class="nf">G</span><span class="p">(</span><span class="n">vec_fit</span><span class="p">)(</span><span class="n">vec</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">     <span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="cp">#endif
</span></span></span></code></pre>
<p>You can then just include the header in header files</p>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="c1">// included like any other header
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="cp">#define VEC_ITEM_TYPE int
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;vector.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;stdlib.h&gt;</span><span class="cp">
</span></span></span></code></pre>
<p>And then on your C files you can tell it that you need the implementations, not the declarations.</p>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="cp">#define VEC_IMPLEMENTATION
</span></span></span><span class="line"><span class="cl"><span class="cp">#define VEC_ITEM_TYPE int
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;vector.h&#34;</span><span class="cp">
</span></span></span></code></pre>
<hr>

<p>Side Note: if you include the header in another header, you can still just call <code>#define VEC_IMPLEMENTATION</code> without reincluding the generic header library to get the implementation.
Which is a nice side effect of this approach to generics, but it can end up looking a bit implicit because the include is hidden in another include.</p>

<p>Example:</p>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="cp">#define VEC_IMPLEMENTATION
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;flag.h&#34;</span><span class="cp">
</span></span></span></code></pre>
<h4>Multiple includes inheriting types</h4>

<p>Since we&rsquo;re relying on preprocessor definitions to define our types.
If we do:</p>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="cp">#define VEC_ITEM_TYPE int
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;vector.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;vector.h&#34;</span><span class="cp">
</span></span></span></code></pre>
<p>We&rsquo;ll have a redeclaration error, because both includes see <code>VEC_ITEM_TYPE</code> as <code>int</code>. We can fix it by undefining it at the end of our generic vector header:</p>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="cp">#undef VEC_ITEM_TYPE
</span></span></span><span class="line"><span class="cl"><span class="cp">#undef VEC_SUFFIX
</span></span></span></code></pre>
<p>This way we still get a &ldquo;VEC_ITEM_TYPE is not defined&rdquo; error if we include the vector again and forget to tell it what type we want instantiated.</p>

<p>NOTE: We don&rsquo;t undefine <code>VEC_IMPLEMENTATION</code> so that we can just declare it once in our <code>.c</code> files for convenience&rsquo;s sake.</p>

<h4>Include guards</h4>

<p>You might be asking about the missing include guard, but you don&rsquo;t need it! The reason is that we actually want to be able to include the same header multiple times.
Each time with a different type.</p>

<p>You might still want to have an include guard for a section of the header if you want to declare some types or code
that is not generic in the header. A good example of this would be if your allocator would receive an allocator context
which does not care about types. For example, you might want to have something like this:</p>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="cp">#ifndef VECTOR_H
</span></span></span><span class="line"><span class="cl"><span class="cp">#define VECTOR_H
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="k">typedef</span> <span class="k">struct</span> <span class="n">vec_allocator</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">   <span class="kt">void</span> <span class="o">*</span><span class="p">(</span><span class="o">*</span><span class="n">malloc</span><span class="p">)(</span><span class="kt">size_t</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">   <span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">free</span><span class="p">)(</span><span class="kt">void</span> <span class="o">*</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="n">VecAllocator</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cp">#endif
</span></span></span></code></pre>
<p>That way, every single vector could still share the same allocator type.</p>

<h2>Putting everything together</h2>

<p>The final header should look something like this:</p>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="cp">#ifndef VEC_ITEM_TYPE
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>   <span class="cp">#error VEC_ITEM_TYPE was not defined
</span></span></span><span class="line"><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#ifndef VEC_SUFFIX
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>   <span class="cp">#define VEC_SUFFIX VEC_ITEM_TYPE
</span></span></span><span class="line"><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#define __G(name, type) name##_##type
</span></span></span><span class="line"><span class="cl"><span class="cp">#define _G(name, type) __G(name, type)
</span></span></span><span class="line"><span class="cl"><span class="cp">#define G(name) _G(name, VEC_SUFFIX)
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;math.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;stdbool.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;stdint.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;stdlib.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;string.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#ifndef VEC_IMPLEMENTATION
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="k">typedef</span> <span class="k">struct</span> <span class="nf">G</span><span class="p">(</span><span class="n">vec_vector</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">   <span class="kt">size_t</span> <span class="n">capacity</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">   <span class="kt">size_t</span> <span class="n">len</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">   <span class="n">VEC_ITEM_TYPE</span> <span class="o">*</span><span class="n">vec</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="nf">G</span><span class="p">(</span><span class="n">Vector</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">G</span><span class="p">(</span><span class="n">Vector</span><span class="p">)</span> <span class="o">*</span> <span class="nf">G</span><span class="p">(</span><span class="n">vec_new</span><span class="p">)(</span><span class="kt">void</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="kt">bool</span> <span class="nf">G</span><span class="p">(</span><span class="n">vec_push</span><span class="p">)(</span><span class="nf">G</span><span class="p">(</span><span class="n">Vector</span><span class="p">)</span> <span class="o">*</span><span class="n">vec</span><span class="p">,</span> <span class="n">VEC_ITEM_TYPE</span> <span class="n">item</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cp">#else
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="c1">// Initializes a new vector with items of sizeof(T)
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="nf">G</span><span class="p">(</span><span class="n">Vector</span><span class="p">)</span> <span class="o">*</span> <span class="nf">G</span><span class="p">(</span><span class="n">vec_new</span><span class="p">)(</span><span class="kt">void</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">   <span class="nf">G</span><span class="p">(</span><span class="n">Vector</span><span class="p">)</span> <span class="o">*</span><span class="n">vector</span> <span class="o">=</span> <span class="nf">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="o">*</span><span class="n">vector</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">   <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">vector</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">   <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">   <span class="o">*</span><span class="n">vector</span> <span class="o">=</span> <span class="p">(</span><span class="nf">G</span><span class="p">(</span><span class="n">Vector</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="p">.</span><span class="n">capacity</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="p">.</span><span class="n">len</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="p">.</span><span class="n">vec</span> <span class="o">=</span> <span class="nb">NULL</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">   <span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">   <span class="k">return</span> <span class="n">vector</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Resizes vector to fit length
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kt">bool</span> <span class="nf">G</span><span class="p">(</span><span class="n">vec_fit</span><span class="p">)(</span><span class="nf">G</span><span class="p">(</span><span class="n">Vector</span><span class="p">)</span> <span class="o">*</span><span class="n">vec</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">   <span class="k">const</span> <span class="kt">size_t</span> <span class="n">power</span> <span class="o">=</span> <span class="nf">ceilf</span><span class="p">(</span><span class="nf">log2f</span><span class="p">(</span><span class="n">vec</span><span class="o">-&gt;</span><span class="n">len</span> <span class="o">+</span> <span class="mi">1</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">   <span class="k">const</span> <span class="kt">size_t</span> <span class="n">new_capacity</span> <span class="o">=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">vec</span><span class="o">-&gt;</span><span class="n">vec</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">*</span> <span class="nf">powf</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="n">power</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">   <span class="k">if</span> <span class="p">(</span><span class="n">new_capacity</span> <span class="o">&lt;</span> <span class="n">vec</span><span class="o">-&gt;</span><span class="n">capacity</span> <span class="o">||</span> <span class="n">new_capacity</span> <span class="o">&gt;</span> <span class="n">vec</span><span class="o">-&gt;</span><span class="n">capacity</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="kt">void</span> <span class="o">*</span><span class="n">tmp</span> <span class="o">=</span> <span class="nf">realloc</span><span class="p">(</span><span class="n">vec</span><span class="o">-&gt;</span><span class="n">vec</span><span class="p">,</span> <span class="n">new_capacity</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">      <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">tmp</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">         <span class="k">return</span> <span class="nb">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="n">vec</span><span class="o">-&gt;</span><span class="n">vec</span> <span class="o">=</span> <span class="n">tmp</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">      <span class="n">vec</span><span class="o">-&gt;</span><span class="n">capacity</span> <span class="o">=</span> <span class="n">new_capacity</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">   <span class="p">}</span>
</span></span><span class="line"><span class="cl">   <span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Pushes a value to vector
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kt">bool</span> <span class="nf">G</span><span class="p">(</span><span class="n">vec_push</span><span class="p">)(</span><span class="nf">G</span><span class="p">(</span><span class="n">Vector</span><span class="p">)</span> <span class="o">*</span><span class="n">vec</span><span class="p">,</span> <span class="n">VEC_ITEM_TYPE</span> <span class="n">item</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">   <span class="k">if</span> <span class="p">(</span><span class="n">vec</span><span class="o">-&gt;</span><span class="n">len</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">vec</span><span class="o">-&gt;</span><span class="n">capacity</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="n">vec</span><span class="o">-&gt;</span><span class="n">vec</span> <span class="o">=</span> <span class="nf">malloc</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">vec</span><span class="o">-&gt;</span><span class="n">vec</span><span class="p">[</span><span class="mi">0</span><span class="p">]));</span>
</span></span><span class="line"><span class="cl">      <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">vec</span><span class="o">-&gt;</span><span class="n">vec</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">         <span class="k">return</span> <span class="nb">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      <span class="n">vec</span><span class="o">-&gt;</span><span class="n">vec</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">item</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">      <span class="n">vec</span><span class="o">-&gt;</span><span class="n">len</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">      <span class="n">vec</span><span class="o">-&gt;</span><span class="n">capacity</span> <span class="o">=</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">vec</span><span class="o">-&gt;</span><span class="n">vec</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">      <span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">   <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">   <span class="nf">G</span><span class="p">(</span><span class="n">vec_fit</span><span class="p">)(</span><span class="n">vec</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">   <span class="n">vec</span><span class="o">-&gt;</span><span class="n">vec</span><span class="p">[</span><span class="n">vec</span><span class="o">-&gt;</span><span class="n">len</span><span class="p">]</span> <span class="o">=</span> <span class="n">item</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">   <span class="n">vec</span><span class="o">-&gt;</span><span class="n">len</span><span class="o">++</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">   <span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#undef VEC_ITEM_TYPE
</span></span></span><span class="line"><span class="cl"><span class="cp">#undef VEC_SUFFIX
</span></span></span></code></pre>]]></content:encoded></item><item><title>Helix tutorial for Vim plebs</title><link>https://raphgl.github.io/blog/helix-tutorial.html</link><guid>https://raphgl.github.io/blog/helix-tutorial.html</guid><pubDate>Mon, 21 Jul 2025 00:00:00 +0000</pubDate><description>A walk through vim and helix differences and the various helix modes for people that are familiar with vim motions</description><content:encoded><![CDATA[<p>(Neo)Vim has been one of the most popular editors for decades now and a lot of people have muscle memory for it.
So every time I suggest someone tries Helix, if they&rsquo;ve used or use (neo)vim or vim mode on other editors, they almost alway complain about
the different keybindings being an impediment to them using the editor. So this is my attempt at trying to make the transition less painful
by drawing parallels between Helix and Vim bindings.</p>

<h2>The low-hanging fruits</h2>

<h4>Basic Motions</h4>

<p>The main difference between Helix and Vim is that Helix is selection based and reverses the motions. A lot of the actions are actually the same.
So for example <code>de</code> in Vim is <code>ed</code> in Helix, <code>ce</code> is <code>ec</code> and so on. The reason for this is that Helix selects text before doing anything with it.</p>

<p>You can think of the Helix binding as just Vim but entering visual mode before doing anything. So <code>de</code> would be <code>ved</code> and <code>ce</code> would be <code>vec</code>, the end result on
Vim would be the exact same as what would happen on Helix.</p>

<h4>Doing selections</h4>

<p>A cursor in Helix is essentially a one character selection, so if you attempt to use <code>dd</code> or <code>cc</code> or <code>yy</code> or any other double verb to apply it to the entire line,
it just won&rsquo;t work. You have to do a selection before. Here&rsquo;s the most common selections:</p>

<ul>
<li><code>x</code>: select the current line (if you keep pressing it it&rsquo;ll keep adding more lines to the selection)</li>
<li><code>%</code>: select the entire file</li>
<li><code>e</code>, <code>E</code>, <code>b</code>, <code>B</code>, <code>w</code>, <code>W</code>: essentially the same as in vim, select from the current cursor position until where they stop</li>
</ul>

<h2>Helix modes and macros</h2>

<h4>Macros</h4>

<p>Macros can be recorded by pressing <code>Q</code>, then after you&rsquo;ve done whatever you wanted to record, you can press <code>Q</code> again to stop.
By default macros are recorded into the <code>@</code> register, you can change where your macros are recorded if you want to store and use multiple macros.
For example you could do <code>&quot;mQ</code> to record a macro in a custom register <code>m</code>. <code>&quot;&lt;register&gt;</code> is the syntax for changing registers.</p>

<p>You can also delete all macros by doing <code>:clear-register</code>.
Registers can also be used to save your selection (text) so if you use <code>d</code>, <code>y</code> and so on, they&rsquo;re also saved in registers.
This also allows you to have multiple things saved at once by just changing the register before doing something.
<br>
Helix also has a few special registers. If you want to know more about registers you can <a href="https://docs.helix-editor.com/registers.html">check the documentation</a>.</p>

<h4>Space mode</h4>

<p>Helix heavily relies on pickers to provide a lot of interactive features all of these can be accessed by pressing space:</p>

<ul>
<li><code>&lt;space&gt;b</code>: Buffer picker</li>
<li><code>&lt;space&gt;e</code>: File explorer</li>
<li><code>&lt;space&gt;s</code>: Symbol search</li>
<li><code>&lt;space&gt;/</code>: Global search</li>
<li><code>&lt;space&gt;d</code>: LSP diagnostics</li>
<li><code>&lt;space&gt;a</code>: Code actions</li>
</ul>

<p>Space mode has a few other features as well. You can check what else it can do <a href="https://docs.helix-editor.com/keymap.html?highlight=space%20mode#space-mode">here</a>.</p>

<h4>Goto mode</h4>

<p>Moving around the file is very common. Vim users are used to using <code>g</code> to move around. Helix also has this keybinding.</p>

<table>
<thead>
<tr>
<th align="center">Vim</th>
<th align="center">Helix</th>
</tr>
</thead>

<tbody>
<tr>
<td align="center">gg</td>
<td align="center">gg</td>
</tr>

<tr>
<td align="center">G</td>
<td align="center">ge</td>
</tr>

<tr>
<td align="center">$</td>
<td align="center">gl</td>
</tr>

<tr>
<td align="center">0</td>
<td align="center">gh</td>
</tr>
</tbody>
</table>
<p>Besides these, there&rsquo;s other ways to move around, for example jumping around references, definitions, or between buffers, they all happen through the goto mode.
One of the most useful ones for moving around is <code>gw</code>, this creates labels in your text that once you type them, your cursor jumps straight to where the label was.</p>

<p>If you want to learn more about gotos you can check the docs <a href="https://docs.helix-editor.com/keymap.html#goto-mode">here</a></p>

<h4>Window mode</h4>

<p>Window mode allows you to manage splits in  Helix, you can enter window mode with <code>&lt;space&gt;w</code>.
Once in window mode, to create the splits you can use <code>s</code> for vertical splits and <code>v</code> for vertical splits.
Then you can use window mode to manage your splits. Such as moving between them (using hjkl in window mode), swapping them (using HJKL),
<br>
You can change windows between vertical and horizontal using <code>t</code> (t stands for transpose), and you can quit the window with <code>q</code>.</p>

<h4>Match mode</h4>

<p>Match mode allows you to select text, in Vim you would usually use <code>gi</code> and <code>ga</code> for this, match mode is the Helix equivalent.
To enter the window mode you can press <code>m</code> while in normal mode.</p>

<p>For example <code>giw</code> would be <code>miw</code> in helix (though for this case going back and forth or the other way around with the <code>w</code>, <code>b</code> and <code>e</code> keys is one less keystroke).
If you&rsquo;re inside of a <code>()</code> or a <code>{}</code> or some other pair and you have an LSP configured you can do <code>mim</code> to select everything inside of a pair or <code>mam</code> to select everything including the pair.
If you don&rsquo;t have an LSP or you want to match something else you can just type one of the pairs for example you could do <code>mi(</code> to match everything inside of a parenthesis.
<br>
You can also swap a <code>()</code>, <code>{}</code> or any pair with the syntax <code>mr&lt;original_pair&gt;&lt;new_pair&gt;</code> so for <code>()</code> to <code>{}</code> you can do <code>mr({</code>. Or you could delete the pairs <code>md(</code>.</p>

<h4>Command mode</h4>

<p>Basic commands are mostly the same as in Vim. You can enter the command mode with <code>:</code>.</p>

<p>Common commands shared by Helix and Vim:</p>

<ul>
<li><code>:q</code>: quit</li>
<li><code>:q!</code>: force quit</li>
<li><code>:w</code>: save</li>
<li><code>:w!</code>: force save</li>
<li><code>:x</code>: save and quit</li>
<li><code>:|</code>: pipe selection to command and substitute with command output</li>
<li><code>:o</code>/<code>:open</code>: open file</li>
</ul>

<p>Common commands that are different:</p>

<ul>
<li><code>:!</code>: required a space in helix as it&rsquo;s an alias to <code>:sh</code></li>
<li><code>:lsp-restart</code>: (re)start LSP</li>
<li><code>:lsp-stop</code>: stop LSP</li>
<li><code>:log-open</code>: read logs</li>
<li><code>set-language</code>: equivalent to <code>:lang</code> in Vim</li>
<li><code>:format</code>: format text with language formatter</li>
</ul>

<h4>Multicursors</h4>

<p>Helix supports multiple cursors. These can be created by using <code>&lt;shift&gt;C</code> the cursors can be disabled with <code>,</code>.</p>

<p>But the most powerful thing about it is being to spawn multiple cursors on certain locations based on their content.
To do this you can do a selection of the region where you want the cursors to spawn then you press <code>s</code> and type what you&rsquo;re looking for,
after you&rsquo;ve matched the content you can press enter and continue editing.</p>

<p>To disable a selection you can use <code>;</code>.</p>

<hr/>

<p>If you want to learn more give the <a href="https://docs.helix-editor.com/">official docs</a> a try.
You might also want to try the helix tutor by running <code>helix --tutor</code>.</p>
]]></content:encoded></item><item><title>Error handling patterns in Rust</title><link>https://raphgl.github.io/blog/rust-error-handling-patterns.html</link><guid>https://raphgl.github.io/blog/rust-error-handling-patterns.html</guid><pubDate>Thu, 09 Jan 2025 00:00:00 +0000</pubDate><description>Common error handling patterns that help reduce verbosity in Rust</description><content:encoded><![CDATA[<p>These are some patterns I&rsquo;ve found in Rust that tend to make error handling code more legible/less noisy.</p>

<h2>Handling errors</h2>

<p>If you only care about one case in an error, instead of being forced to match against all errors, do this:</p>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="k">if</span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="n">val</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">returns_option</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// do something
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre>
<p>If the value that is returns doesn&rsquo;t matter, then you can do this:</p>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="k">if</span><span class="w"> </span><span class="n">returns_option</span><span class="p">().</span><span class="n">is_some</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// do something
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre>
<p>There&rsquo;s corresponding versions for the other values as well: <code>Result::{is_err, is_ok}</code>, <code>Option::{is_some, is_none}</code></p>

<p>If you expect the error to never happen, or if it happens you can&rsquo;t handle it, you can just <code>unwrap</code> or <code>expect</code> it.</p>

<ul>
<li><code>unwrap</code> just panics over an error. So if you do this:</li>
</ul>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">returns_option</span><span class="p">().</span><span class="n">unwrap</span><span class="p">();</span><span class="w">
</span></span></span></code></pre>
<p>that would be equivalent to this:</p>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">returns_option</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nb">Some</span><span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">x</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nb">None</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="fm">panic!</span><span class="p">(</span><span class="s">&#34;some reason why it errored here&#34;</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span><span class="w">
</span></span></span></code></pre>
<ul>
<li><code>expect</code> allows you to change the panic message, you should write there what your expectation was for that error</li>
</ul>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">retcode</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">execute_file</span><span class="p">(</span><span class="s">&#34;path/to/file&#34;</span><span class="p">).</span><span class="n">expect</span><span class="p">(</span><span class="s">&#34;file should be executable&#34;</span><span class="p">);</span><span class="w">
</span></span></span></code></pre>
<h2>Propagating errors</h2>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">func</span><span class="p">(</span><span class="n">x</span>: <span class="kp">&amp;</span><span class="kt">str</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Result</span><span class="o">&lt;&amp;</span><span class="kt">str</span><span class="p">,</span><span class="w"> </span><span class="n">Error</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// instead of:
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">returns_result</span><span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nb">Ok</span><span class="p">(</span><span class="n">other</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="n">other</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nb">Err</span><span class="p">(</span><span class="n">err</span><span class="p">)</span><span class="w"> </span><span class="o">=&gt;</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">err</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="c1">// do:
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">returns_result</span><span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="o">?</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre>
<p>Sometimes though, the Result or Option returns by the function might not be 1-to-1 with the functions you&rsquo;re propagating the error from, in those cases
you can either use <code>let else</code> idiom:</p>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="nb">Ok</span><span class="p">(</span><span class="n">other</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">returns_result</span><span class="p">(</span><span class="n">x</span><span class="p">)</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="k">return</span><span class="w"> </span><span class="nb">None</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre>
<p>Or you can also convert from a Result to an Option or vice versa with these methods: <code>Result::{ok, err}</code> and <code>Option::ok_or</code> to convert to the appropriate type</p>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="k">fn</span> <span class="nf">func</span><span class="p">(</span><span class="n">x</span>: <span class="kp">&amp;</span><span class="kt">str</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nb">Option</span><span class="o">&lt;&amp;</span><span class="kt">str</span><span class="o">&gt;</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="kd">let</span><span class="w"> </span><span class="n">other</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">returns_result</span><span class="p">().</span><span class="n">ok</span><span class="p">()</span><span class="o">?</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre>
<p>If these are not sufficient, you might want to change the Error or Ok values so you can &ldquo;massage&rdquo; it into working,
 these functions are <code>Result::{map_err, map_ok}</code> and <code>Option::map_or</code>. You can use them like this:</p>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="kd">let</span><span class="w"> </span><span class="n">other</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">returns_result</span><span class="p">().</span><span class="n">map_err</span><span class="p">(</span><span class="o">|</span><span class="n">e</span><span class="o">|</span><span class="w"> </span><span class="cm">/* massage the value here */</span><span class="p">)</span><span class="o">?</span><span class="p">;</span><span class="w">
</span></span></span></code></pre>]]></content:encoded></item><item><title>How base64 works</title><link>https://raphgl.github.io/blog/how_base64_works/index.html</link><guid>https://raphgl.github.io/blog/how_base64_works/index.html</guid><pubDate>Fri, 01 Nov 2024 00:00:00 +0000</pubDate><description>A step by step guide into implementing base64 in C</description><content:encoded><![CDATA[<p><center>
  <p>In this document I explain how base64 works and go step by step on how one would go about implementing it.</p>
  <h3>
    <a href="./index.pdf">Open PDF →</a>
  <h3/>
<center/></p>
]]></content:encoded></item><item><title>Setting up NeoVim for Godot</title><link>https://raphgl.github.io/blog/godot-with-nvim/index.html</link><guid>https://raphgl.github.io/blog/godot-with-nvim/index.html</guid><pubDate>Fri, 23 Sep 2022 00:00:00 +0000</pubDate><description></description><content:encoded><![CDATA[<p>Recently I&rsquo;ve been using Godot a bit to mess around with game development and I wanted to have autocompletion working with CoC. I looked around and there were no extensions for the Godot LSP. So, to use Godot with NeoVim I just had to connect to their LSP.</p>

<h2>Setting Up</h2>

<p>If you have CoC working correctly already, open NeoVim and run <code>:CocConfig</code>, it&rsquo;ll open the configuration file for your CoC, then just add this to the JSON config:</p>
<pre class="chroma"><code><span class="line"><span class="cl"><span class="s2">&#34;languageserver&#34;</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="s2">&#34;godot&#34;</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;host&#34;</span><span class="o">:</span> <span class="s2">&#34;127.0.0.1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;filetypes&#34;</span><span class="o">:</span> <span class="p">[</span><span class="s2">&#34;gdscript3&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">            <span class="s2">&#34;port&#34;</span><span class="o">:</span> <span class="mi">6005</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span></code></pre>
<p><strong>Note:</strong> If there&rsquo;s an error connecting to the LSP, open Godot and go on <code>Editor &gt; Editor Settings &gt; Network &gt; Language Server</code> and check that the port numbers and IP address match.</p>

<h2>Additional steps</h2>

<p>You probably want syntax highlighting, for that you have 2 options: you could install the <a href="https://github.com/sheerun/vim-polyglot"><code>sheerun/vim-polyglot</code></a> or use <a href="https://github.com/habamax/vim-godot"><code>habamax/vim-godot</code></a> (which provides syntax highlighting as well as a set of commands allows you to run scenes through NeoVim).</p>

<h4>Setting up the editor</h4>

<p>To set up the editor go to <code>Editor &gt; Editor Settings &gt; Text Editor</code> and change the <code>Exec Path</code> to the terminal of your liking (kitty in my case) and on <code>Exec Flags</code> put <code>nvim {file}</code>.</p>

<p><img src="./godot.png" alt="Editor settings &gt; External Editor" /></p>

<p>Now everything should be working correctly and when you click to open a script on the engine it should open nvim on the correct file.</p>

<p><img src="./vim.png" alt="Neovim opened with Godot" /></p>
]]></content:encoded></item></channel></rss>