···11<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
22 <channel>
33 <title>nerdypepper's μblog</title>
44- <link>https://peppe.rs</link>
44+ <link>https://oppi.li</link>
55 <description>programming, design, software</description>
66- <atom:link href="https://peppe.rs/index.xml" rel="self" type="application/rss+xml" />
66+ <atom:link href="https://oppi.li/index.xml" rel="self" type="application/rss+xml" />
77 <image>
88- <title>nerdypepper's μblog</title>
99- <url>https://u.peppe.rs/n.png</url>
1010- <link>https://peppe.rs</link>
88+ <title>oppiliappan's μblog</title>
99+ <url>https://cdn.oppi.li/n.png</url>
1010+ <link>https://oppi.li</link>
1111 </image>
1212 <language>en-us</language>
1313 <copyright>Creative Commons BY-NC-SA 4.0</copyright>
1414 <item>
1515+<title>Tales From Mainframe Modernization</title>
1616+<description><p>At my last workplace, I wrote transpilers (or just <a
1717+href="https://people.csail.mit.edu/rachit/post/transpiler/">compilers</a>
1818+if you prefer) from mainframe languages (COBOL, JCL, BASIC etc.) to Java
1919+(in Rust!).</p>
2020+<p>Legacy code is full of surprises. In the roughly 200k lines of COBOL
2121+that I had the (dis)pleasure of working with, I saw some wonderful hacks
2222+to get around the limitations of the system. Mainframes are also chock
2323+full of history.</p>
2424+<h3 id="base-2-numerics">Base-2 numerics</h3>
2525+<p>This is the first thing that stood out to me when I looked at COBOL
2626+code, a data-definition (the phrase for “variable”) in COBOL is declared
2727+like so:</p>
2828+<pre><code> ,-- name
2929+ | ,- type
3030+ __|___ __|_
3131+ 01 HEIGHT PIC 9(3).
3232+ -- ---
3333+ | |
3434+ | `- picture clause (keyword)
3535+ `- level number </code></pre>
3636+<p>That statement declares a variable called <code>HEIGHT</code> with
3737+type <code>9(3)</code>, which is shorthand for <code>999</code>, which
3838+indicates “3-digit number”. Similarly <code>A(5)</code> indicates
3939+5-character alphabetic string.</p>
4040+<h3 id="internationalisation">Internationalisation</h3>
4141+<p>Below is another data-definition in COBOL, declaring 3 variables:</p>
4242+<pre class="cobol"><code>01 FOO-PERSON.
4343+ 05 FOO-NAME PIC X(5).
4444+ 05 FOO-HEIGHT PIC 9(3).</code></pre>
4545+<p>What that means is:</p>
4646+<ul>
4747+<li><code>FOO-PERSON</code>: a “group” variable consisting of two other
4848+variables</li>
4949+<li><code>FOO-NAME</code>: an alphanumeric type with 5 characters</li>
5050+<li><code>FOO-HEIGHT</code>: a numeric type with 3 digits (remember,
5151+base 10 and not base 2)</li>
5252+</ul>
5353+<p>COBOL has an interesting construct called “REDEFINES”:</p>
5454+<pre class="cobol"><code>01 FOO-PERSON.
5555+ 05 FOO-NAME PIC X(5).
5656+ 05 FOO-HEIGHT PIC 9(3).
5757+5858+01 FOO-PERSONNE REDEFINES FOO-PERSON.
5959+ 05 FOO-NOM PIC X(5).
6060+ 05 FOO-TAILLE PIC 9(3).</code></pre>
6161+<p><code>FOO-PERSON</code> and <code>FOO-PERSONNE</code> refer to the
6262+same region of memory.</p>
6363+<p>I helped modernise a codebase that had clearly been worked on by a
6464+Spanish consultancy at some point, and they had decided to redefine all
6565+data definitions in Spanish.</p>
6666+<h3 id="string-parsing">String parsing</h3>
6767+<p>Here’s another fun one:</p>
6868+<pre class="cobol"><code> 01 FOO-PERSON.
6969+ 05 FOO-NAME PIC X(5).
7070+ 05 FOO-HEIGHT PIC 9(3).
7171+ .
7272+ .
7373+ .
7474+7575+ MOVE &quot;PETER&quot; TO FOO-NAME.
7676+ MOVE 175 TO FOO-HEIGHT.
7777+7878+ *&gt; display the entire memory region
7979+ DISPLAY FOO-PERSON.
8080+ *&gt; PETER175
8181+8282+ *&gt; subscripting the first 7 bytes...
8383+ DISPLAY FOO-PERSON (1:7)
8484+ *&gt; PETER17</code></pre>
8585+<p>So data-definitions simply describe names for regions. Which enables
8686+a clever way to parse strings:</p>
8787+<pre class="cobol"><code> 01 DATE.
8888+ 05 DD PIC 9(2).
8989+ 05 FILLER PIC X.
9090+ 05 MM PIC 9(2).
9191+ 05 FILLER PIC X.
9292+ 05 YYYY PIC 9(4).
9393+9494+ .
9595+ .
9696+ .
9797+9898+ MOVE &quot;03/04/2025&quot; TO DATE.
9999+ DISPLAY &quot;DAY: &quot; DD. *&gt; DAY: 03
100100+ DISPLAY &quot;MONTH: &quot; MM. *&gt; MONTH: 04
101101+ DISPLAY &quot;YEAR: &quot; YYYY. *&gt; YEAR: 2025
102102+103103+ *&gt; also works:
104104+ MOVE &quot;03.04.2025&quot; TO DATE.</code></pre>
105105+<h3 id="early-exit">Early exit</h3>
106106+<p>I’d see this peppered around in a few places; which I later realized
107107+was a way to trigger an abnormal end to a batch job (possibly triggering
108108+an error handling routine in the outer job control system):</p>
109109+<pre class="cobol"><code> 01 CONSTANT-ZERO S9(9)V9 VALUE 0.
110110+ 01 ABEND S9(9)V9.
111111+112112+ .
113113+ .
114114+ .
115115+116116+ COMPUTE ABEND = CONSTANT-ZERO / CONSTANT-ZERO.</code></pre>
117117+<h3 id="all-the-numbers">All the numbers</h3>
118118+<p>I have yet to find an explanation for this one, but I once found a
119119+file with just the first 800 natural numbers defined as string
120120+constants:</p>
121121+<pre class="cobol"><code> 01 TC0001 X(5) &quot;00001&quot;.
122122+ 01 TC0002 X(5) &quot;00002&quot;.
123123+ 01 TC0003 X(5) &quot;00003&quot;.
124124+ .
125125+ .
126126+ *&gt; .... 800 lines later ....
127127+ .
128128+ .
129129+ 01 TC0800 X(5) &quot;00800&quot;.</code></pre>
130130+<h3 id="dd---disk-destroyer"><code>dd</code> - disk destroyer</h3>
131131+<p>The <code>DD</code> statement in the JCL subsystem stands for “data
132132+definition”, which is largely used to describe files and IO streams used
133133+by a batch job. The <code>dd</code> command <a href="#fn1"
134134+class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a> on
135135+UNIX is named after this statement!</p>
136136+<section id="footnotes" class="footnotes footnotes-end-of-document"
137137+role="doc-endnotes">
138138+<hr />
139139+<ol>
140140+<li id="fn1"><p><a
141141+href="https://en.wikipedia.org/wiki/Dd_%28Unix%29#History">Wikipedia -
142142+dd (Unix)</a><a href="#fnref1" class="footnote-back"
143143+role="doc-backlink">↩︎</a></p></li>
144144+</ol>
145145+</section></description>
146146+<link>https://oppi.li/posts/tales_from_mainframe_modernization/</link>
147147+<pubDate>Wed, 21 May 2025 21:54:00 +0000</pubDate>
148148+<guid>https://oppi.li/posts/tales_from_mainframe_modernization/</guid>
149149+</item>
150150+<item>
15151<title>OSC-52</title>
16152<description><p>I use <code>ssh</code> a lot. Copying text from the remote machine to
17153the host machine always sucked. But OSC-52 makes that easy.</p>
···60196above tweaks. <code>nvim</code> will pass the contents around to
61197<code>tmux</code>, which in turn will pass the contents to
62198<code>st</code>, which should pass it to your system clipboard.</p></description>
6363-<link>https://peppe.rs/posts/OSC-52/</link>
199199+<link>https://oppi.li/posts/OSC-52/</link>
64200<pubDate>Wed, 27 Nov 2024 22:56:00 +0000</pubDate>
6565-<guid>https://peppe.rs/posts/OSC-52/</guid>
201201+<guid>https://oppi.li/posts/OSC-52/</guid>
66202</item>
67203<item>
68204<title>Introducing Tablespoon</title>
···205341 └╴fn file
206342 └╴fn try_consume_stdin
207343 └╴fn main</code></pre></description>
208208-<link>https://peppe.rs/posts/introducing_tablespoon/</link>
344344+<link>https://oppi.li/posts/introducing_tablespoon/</link>
209345<pubDate>Thu, 01 Aug 2024 19:18:00 +0000</pubDate>
210210-<guid>https://peppe.rs/posts/introducing_tablespoon/</guid>
346346+<guid>https://oppi.li/posts/introducing_tablespoon/</guid>
211347</item>
212348<item>
213349<title>Snip Snap</title>
···278414<code>&lt;prefix&gt;+shift+L</code>.</p>
279415<h4 id="qutebrowser">qutebrowser</h4>
280416<p>Switch to the last active tab with <code>g$</code>.</p></description>
281281-<link>https://peppe.rs/posts/snip_snap/</link>
417417+<link>https://oppi.li/posts/snip_snap/</link>
282418<pubDate>Wed, 29 May 2024 17:48:00 +0000</pubDate>
283283-<guid>https://peppe.rs/posts/snip_snap/</guid>
419419+<guid>https://oppi.li/posts/snip_snap/</guid>
284420</item>
285421<item>
286422<title>Plain Text Journaling</title>
···519655though.</p>
520656<p><a href="https://u.peppe.rs/ZCK.png"><img
521657src="https://u.peppe.rs/ZCK.png" /></a></p></description>
522522-<link>https://peppe.rs/posts/plain_text_journaling/</link>
658658+<link>https://oppi.li/posts/plain_text_journaling/</link>
523659<pubDate>Sun, 18 Jun 2023 19:40:00 +0000</pubDate>
524524-<guid>https://peppe.rs/posts/plain_text_journaling/</guid>
660660+<guid>https://oppi.li/posts/plain_text_journaling/</guid>
525661</item>
526662<item>
527663<title>Curing A Case Of Git-UX</title>
···779915<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a><span class="kw">}</span></span>
780916<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a></span>
781917<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a><span class="bu">alias</span> gwls=<span class="st">&quot;git worktree list&quot;</span></span></code></pre></div></description>
782782-<link>https://peppe.rs/posts/curing_a_case_of_git-UX/</link>
918918+<link>https://oppi.li/posts/curing_a_case_of_git-UX/</link>
783919<pubDate>Sat, 03 Sep 2022 03:18:00 +0000</pubDate>
784784-<guid>https://peppe.rs/posts/curing_a_case_of_git-UX/</guid>
920920+<guid>https://oppi.li/posts/curing_a_case_of_git-UX/</guid>
785921</item>
786922<item>
787923<title>Programming On 34 Keys</title>
···9431079accomodate special characters from their grammars (angled brackets and
9441080hyphens, specifically). If you are on a similar journey, I would suggest
9451081focusing on accuracy and comfort over speed. Speed comes with time.</p></description>
946946-<link>https://peppe.rs/posts/programming_on_34_keys/</link>
10821082+<link>https://oppi.li/posts/programming_on_34_keys/</link>
9471083<pubDate>Sun, 28 Aug 2022 13:51:00 +0000</pubDate>
948948-<guid>https://peppe.rs/posts/programming_on_34_keys/</guid>
10841084+<guid>https://oppi.li/posts/programming_on_34_keys/</guid>
9491085</item>
9501086<item>
9511087<title>A Reference Counted Afterlife</title>
···9891125garbage-collection models a program’s memory.</p>
9901126<p>Perhaps some cheeky Egyptian has attained immortality by creating a
9911127<em>ren</em>-cycle.</p></description>
992992-<link>https://peppe.rs/posts/a_reference_counted_afterlife/</link>
11281128+<link>https://oppi.li/posts/a_reference_counted_afterlife/</link>
9931129<pubDate>Tue, 02 Aug 2022 16:47:00 +0000</pubDate>
994994-<guid>https://peppe.rs/posts/a_reference_counted_afterlife/</guid>
11301130+<guid>https://oppi.li/posts/a_reference_counted_afterlife/</guid>
9951131</item>
9961132<item>
9971133<title>Lotus58</title>
···11041240<img src="https://u.peppe.rs/XM3.jpg" alt="The Lotus58 in action" />
11051241<figcaption aria-hidden="true">The Lotus58 in action</figcaption>
11061242</figure></description>
11071107-<link>https://peppe.rs/posts/lotus58/</link>
12431243+<link>https://oppi.li/posts/lotus58/</link>
11081244<pubDate>Mon, 13 Jun 2022 13:55:00 +0000</pubDate>
11091109-<guid>https://peppe.rs/posts/lotus58/</guid>
12451245+<guid>https://oppi.li/posts/lotus58/</guid>
11101246</item>
11111247<item>
11121248<title>Lightweight Linting</title>
···14231559<span id="cb34-2"><a href="#cb34-2" aria-hidden="true" tabindex="-1"></a> name: (identifier) @fn</span>
14241560<span id="cb34-3"><a href="#cb34-3" aria-hidden="true" tabindex="-1"></a> !parameters)</span>
14251561<span id="cb34-4"><a href="#cb34-4" aria-hidden="true" tabindex="-1"></a> (<span class="sc">#i</span>s? @fn <span class="st">&quot;to_json&quot;</span>))</span></code></pre></div></description>
14261426-<link>https://peppe.rs/posts/lightweight_linting/</link>
15621562+<link>https://oppi.li/posts/lightweight_linting/</link>
14271563<pubDate>Wed, 26 Jan 2022 12:52:00 +0000</pubDate>
14281428-<guid>https://peppe.rs/posts/lightweight_linting/</guid>
15641564+<guid>https://oppi.li/posts/lightweight_linting/</guid>
14291565</item>
14301566<item>
14311567<title>Novice Nix: Flake Templates</title>
···16201756from the <code>biscuits</code> registry as well as the ones from
16211757<code>NixOS/templates</code>. Ensure that the names don’t collide
16221758though.</p></description>
16231623-<link>https://peppe.rs/posts/novice_nix:_flake_templates/</link>
17591759+<link>https://oppi.li/posts/novice_nix:_flake_templates/</link>
16241760<pubDate>Tue, 05 Oct 2021 16:49:00 +0000</pubDate>
16251625-<guid>https://peppe.rs/posts/novice_nix:_flake_templates/</guid>
17611761+<guid>https://oppi.li/posts/novice_nix:_flake_templates/</guid>
16261762</item>
16271763<item>
16281764<title>SDL2 Devlog</title>
···19072043<img src="https://u.peppe.rs/Ma.png" alt="Day 1" />
19082044<figcaption aria-hidden="true">Day 1</figcaption>
19092045</figure></description>
19101910-<link>https://peppe.rs/posts/SDL2_devlog/</link>
20462046+<link>https://oppi.li/posts/SDL2_devlog/</link>
19112047<pubDate>Sun, 11 Apr 2021 10:46:00 +0000</pubDate>
19121912-<guid>https://peppe.rs/posts/SDL2_devlog/</guid>
20482048+<guid>https://oppi.li/posts/SDL2_devlog/</guid>
19132049</item>
19142050<item>
19152051<title>Self-hosting Git</title>
···2072220820732209remote=$(git remote get-url --push origin)
20742210scp .git/description &quot;$remote/description&quot;</code></pre></description>
20752075-<link>https://peppe.rs/posts/self-hosting_git/</link>
22112211+<link>https://oppi.li/posts/self-hosting_git/</link>
20762212<pubDate>Sat, 17 Oct 2020 07:04:00 +0000</pubDate>
20772077-<guid>https://peppe.rs/posts/self-hosting_git/</guid>
22132213+<guid>https://oppi.li/posts/self-hosting_git/</guid>
20782214</item>
20792215<item>
20802216<title>NixOS</title>
···21502286current system</a>.</p>
21512287<p><a href="https://u.peppe.rs/6m.png"><img
21522288src="https://u.peppe.rs/6m.png" /></a></p></description>
21532153-<link>https://peppe.rs/posts/nixOS/</link>
22892289+<link>https://oppi.li/posts/nixOS/</link>
21542290<pubDate>Tue, 01 Sep 2020 07:08:00 +0000</pubDate>
21552155-<guid>https://peppe.rs/posts/nixOS/</guid>
22912291+<guid>https://oppi.li/posts/nixOS/</guid>
21562292</item>
21572293<item>
21582294<title>Gripes With Go</title>
···22982434lack of metaprogramming, bizzare export rules, but, I am too busy
22992435converting my <code>interface{}</code> types into actual generic code
23002436for Go v2.</p></description>
23012301-<link>https://peppe.rs/posts/gripes_with_go/</link>
24372437+<link>https://oppi.li/posts/gripes_with_go/</link>
23022438<pubDate>Sat, 01 Aug 2020 11:55:00 +0000</pubDate>
23032303-<guid>https://peppe.rs/posts/gripes_with_go/</guid>
24392439+<guid>https://oppi.li/posts/gripes_with_go/</guid>
23042440</item>
23052441<item>
23062442<title>Turing Complete Type Systems</title>
···23272463compiling your Rust program! I lied, <code>rustc</code> stops after a
23282464while, after hitting the recursion limit.</p>
23292465<p>I understand that this post lacks content.</p></description>
23302330-<link>https://peppe.rs/posts/turing_complete_type_systems/</link>
24662466+<link>https://oppi.li/posts/turing_complete_type_systems/</link>
23312467<pubDate>Wed, 17 Jun 2020 18:30:00 +0000</pubDate>
23322332-<guid>https://peppe.rs/posts/turing_complete_type_systems/</guid>
24682468+<guid>https://oppi.li/posts/turing_complete_type_systems/</guid>
23332469</item>
23342470<item>
23352471<title>Auto-currying Rust Functions</title>
···30593195class="footnote-back" role="doc-backlink">↩︎</a></p></li>
30603196</ol>
30613197</section></description>
30623062-<link>https://peppe.rs/posts/auto-currying_rust_functions/</link>
31983198+<link>https://oppi.li/posts/auto-currying_rust_functions/</link>
30633199<pubDate>Fri, 08 May 2020 18:30:00 +0000</pubDate>
30643064-<guid>https://peppe.rs/posts/auto-currying_rust_functions/</guid>
32003200+<guid>https://oppi.li/posts/auto-currying_rust_functions/</guid>
30653201</item>
30663202<item>
30673203<title>Pixel Art In GIMP</title>
···31653301<code>Quality &gt; Interpolation</code> to <code>None</code> and scale
31663302it up to 700x700, et voilà!</p>
31673303<p><img src="https://u.peppe.rs/CH.png" /></p></description>
31683168-<link>https://peppe.rs/posts/pixel_art_in_GIMP/</link>
33043304+<link>https://oppi.li/posts/pixel_art_in_GIMP/</link>
31693305<pubDate>Wed, 08 Apr 2020 18:30:00 +0000</pubDate>
31703170-<guid>https://peppe.rs/posts/pixel_art_in_GIMP/</guid>
33063306+<guid>https://oppi.li/posts/pixel_art_in_GIMP/</guid>
31713307</item>
31723308<item>
31733309<title>Rapid Refactoring With Vim</title>
···33233459class="footnote-back" role="doc-backlink">↩︎</a></p></li>
33243460</ol>
33253461</section></description>
33263326-<link>https://peppe.rs/posts/rapid_refactoring_with_vim/</link>
34623462+<link>https://oppi.li/posts/rapid_refactoring_with_vim/</link>
33273463<pubDate>Tue, 31 Mar 2020 18:30:00 +0000</pubDate>
33283328-<guid>https://peppe.rs/posts/rapid_refactoring_with_vim/</guid>
34643464+<guid>https://oppi.li/posts/rapid_refactoring_with_vim/</guid>
33293465</item>
33303466<item>
33313467<title>Font Size Fallacies</title>
···34003536href="#fnref4" class="footnote-back" role="doc-backlink">↩︎</a></p></li>
34013537</ol>
34023538</section></description>
34033403-<link>https://peppe.rs/posts/font_size_fallacies/</link>
35393539+<link>https://oppi.li/posts/font_size_fallacies/</link>
34043540<pubDate>Mon, 16 Mar 2020 18:30:00 +0000</pubDate>
34053405-<guid>https://peppe.rs/posts/font_size_fallacies/</guid>
35413541+<guid>https://oppi.li/posts/font_size_fallacies/</guid>
34063542</item>
34073543<item>
34083544<title>Termux Tandem</title>
···34393575<code>cmus</code> is a viable option:</p>
34403576<p><a href="https://u.peppe.rs/CP.jpg"><img
34413577src="https://u.peppe.rs/CP.jpg" /></a></p></description>
34423442-<link>https://peppe.rs/posts/termux_tandem/</link>
35783578+<link>https://oppi.li/posts/termux_tandem/</link>
34433579<pubDate>Sat, 07 Mar 2020 18:30:00 +0000</pubDate>
34443444-<guid>https://peppe.rs/posts/termux_tandem/</guid>
35803580+<guid>https://oppi.li/posts/termux_tandem/</guid>
34453581</item>
34463582<item>
34473583<title>Call To ARMs</title>
···34993635<h3 id="editing">Editing</h3>
35003636<p>Vim, with <code>syntax off</code> because it dosen’t handle GNU ARM
35013637syntax too well.</p></description>
35023502-<link>https://peppe.rs/posts/call_to_ARMs/</link>
36383638+<link>https://oppi.li/posts/call_to_ARMs/</link>
35033639<pubDate>Fri, 07 Feb 2020 18:30:00 +0000</pubDate>
35043504-<guid>https://peppe.rs/posts/call_to_ARMs/</guid>
36403640+<guid>https://oppi.li/posts/call_to_ARMs/</guid>
35053641</item>
35063642<item>
35073643<title>Color Conundrum</title>
···35313667text) are dimmed further.</p>
35323668<p>I’ll stop myself before I rant about color contrast and
35333669combinations.</p></description>
35343534-<link>https://peppe.rs/posts/color_conundrum/</link>
36703670+<link>https://oppi.li/posts/color_conundrum/</link>
35353671<pubDate>Mon, 30 Dec 2019 18:30:00 +0000</pubDate>
35363536-<guid>https://peppe.rs/posts/color_conundrum/</guid>
36723672+<guid>https://oppi.li/posts/color_conundrum/</guid>
35373673</item>
35383674<item>
35393675<title>Static Sites With Bash</title>
···35823718avoid javascript). It uses <code>sed</code> to produce nice titles from
35833719the file names (removes underscores, title-case), and
35843720<code>date(1)</code> to add the date to each post listing!</p></description>
35853585-<link>https://peppe.rs/posts/static_sites_with_bash/</link>
37213721+<link>https://oppi.li/posts/static_sites_with_bash/</link>
35863722<pubDate>Fri, 22 Nov 2019 18:30:00 +0000</pubDate>
35873587-<guid>https://peppe.rs/posts/static_sites_with_bash/</guid>
37233723+<guid>https://oppi.li/posts/static_sites_with_bash/</guid>
35883724</item>
35893725<item>
35903726<title>My Setup</title>
···36113747<p>Most of my academic typesetting is done with TeX, and compiled with
36123748<code>xelatex</code>. Other <em>fun</em> documents are made with GIMP
36133749:).</p></description>
36143614-<link>https://peppe.rs/posts/my_setup/</link>
37503750+<link>https://oppi.li/posts/my_setup/</link>
36153751<pubDate>Wed, 06 Nov 2019 18:30:00 +0000</pubDate>
36163616-<guid>https://peppe.rs/posts/my_setup/</guid>
37523752+<guid>https://oppi.li/posts/my_setup/</guid>
36173753</item>
36183754<item>
36193755<title>WPA Woes</title>
···36463782$ sudo ln -s /etc/sv/dhcpcd /var/service/
36473783$ sudo sv restart wpa_supplicant
36483784$ sudo sv restart dhcpcd</code></pre></description>
36493649-<link>https://peppe.rs/posts/WPA_woes/</link>
37853785+<link>https://oppi.li/posts/WPA_woes/</link>
36503786<pubDate>Sat, 12 Oct 2019 16:23:00 +0000</pubDate>
36513651-<guid>https://peppe.rs/posts/WPA_woes/</guid>
37873787+<guid>https://oppi.li/posts/WPA_woes/</guid>
36523788</item>
36533789<item>
36543790<title>Bye Bye BDFs</title>
···36763812href="https://github.com/nerdypepper/scientifica">scientifica</a> and <a
36773813href="https://github.com/nerdypepper/curie">curie</a> will soon ship
36783814with bitmap-only OpenType font formats.</p></description>
36793679-<link>https://peppe.rs/posts/bye_bye_BDFs/</link>
38153815+<link>https://oppi.li/posts/bye_bye_BDFs/</link>
36803816<pubDate>Wed, 07 Aug 2019 17:26:00 +0000</pubDate>
36813681-<guid>https://peppe.rs/posts/bye_bye_BDFs/</guid>
38173817+<guid>https://oppi.li/posts/bye_bye_BDFs/</guid>
36823818</item>
36833819<item>
36843820<title>Onivim Sucks</title>
···37143850pricing which is 80% off the final price! If you are on the lookout for
37153851an editor, I would suggest using <a href="https://vim.org">Vim</a>,
37163852charity ware that actually works, and costs $100 lesser.</p></description>
37173717-<link>https://peppe.rs/posts/onivim_sucks/</link>
38533853+<link>https://oppi.li/posts/onivim_sucks/</link>
37183854<pubDate>Fri, 02 Aug 2019 16:32:00 +0000</pubDate>
37193719-<guid>https://peppe.rs/posts/onivim_sucks/</guid>
38553855+<guid>https://oppi.li/posts/onivim_sucks/</guid>
37203856</item>
37213857<item>
37223858<title>Bash Harder With Vim</title>
···37623898<pre><code>$ vim
37633899New Post # output
37643900Press ENTER or type command to continue</code></pre></description>
37653765-<link>https://peppe.rs/posts/bash_harder_with_vim/</link>
39013901+<link>https://oppi.li/posts/bash_harder_with_vim/</link>
37663902<pubDate>Tue, 30 Jul 2019 18:30:00 +0000</pubDate>
37673767-<guid>https://peppe.rs/posts/bash_harder_with_vim/</guid>
39033903+<guid>https://oppi.li/posts/bash_harder_with_vim/</guid>
37683904</item>
37693905<item>
37703906<title>Hold Position!</title>
···37863922<p>It might seem a little overkill in the above example, just use ``
37873923(double backticks) instead, but it comes in handy when you run your file
37883924through heavier filtering.</p></description>
37893789-<link>https://peppe.rs/posts/hold_position!/</link>
39253925+<link>https://oppi.li/posts/hold_position!/</link>
37903926<pubDate>Tue, 30 Jul 2019 14:45:00 +0000</pubDate>
37913791-<guid>https://peppe.rs/posts/hold_position!/</guid>
39273927+<guid>https://oppi.li/posts/hold_position!/</guid>
37923928</item>
37933929<item>
37943930<title>Get Better At Yanking And Putting In Vim</title>
···38103946<pre><code>]p &quot; put (p) and adjust indent to current line
38113947]P &quot; put the text before the cursor (P) and adjust indent to current line</code></pre></li>
38123948</ol></description>
38133813-<link>https://peppe.rs/posts/get_better_at_yanking_and_putting_in_vim/</link>
39493949+<link>https://oppi.li/posts/get_better_at_yanking_and_putting_in_vim/</link>
38143950<pubDate>Tue, 30 Jul 2019 08:43:00 +0000</pubDate>
38153815-<guid>https://peppe.rs/posts/get_better_at_yanking_and_putting_in_vim/</guid>
39513951+<guid>https://oppi.li/posts/get_better_at_yanking_and_putting_in_vim/</guid>
38163952</item>
3817395338183954
···11+<!DOCTYPE html>
22+<html lang="en">
33+ <head>
44+ <link rel="stylesheet" href="/style.css">
55+ <link rel="stylesheet" href="/syntax.css">
66+ <meta charset="UTF-8">
77+ <meta name="viewport" content="initial-scale=1">
88+ <meta content="#ffffff" name="theme-color">
99+ <meta name="HandheldFriendly" content="true">
1010+ <meta property="og:title" content="Tales From Mainframe Modernization">
1111+ <meta property="og:type" content="website">
1212+ <meta property="og:description" content="a static site {for, by, about} me ">
1313+ <meta property="og:url" content="https://oppi.li">
1414+ <link rel="icon" type="image/x-icon" href="/favicon.png">
1515+ <title>Tales From Mainframe Modernization · oppi.li</title>
1616+ <body>
1717+ <div class="posts">
1818+ <div class="post">
1919+ <a href="/" class="post-end-link">Home</a>
2020+ <span>/</span>
2121+ <a href="/posts" class="post-end-link">Posts</a>
2222+ <span>/</span>
2323+ <a class="post-end-link">Tales From Mainframe Modernization</a>
2424+ <a class="stats post-end-link" href="https://tangled.sh/@oppi.li/site/raw/master/posts/tales_from_mainframe_modernization.md
2525+">View Raw</a>
2626+ <div class="separator"></div>
2727+ <div class="date">
2828+ 21/05 — 2025
2929+ <div class="stats">
3030+ <span class="stats-number">
3131+ 64.74
3232+ </span>
3333+ <span class="stats-unit">cm</span>
3434+  
3535+ <span class="stats-number">
3636+ 3.8
3737+ </span>
3838+ <span class="stats-unit">min</span>
3939+ </div>
4040+ </div>
4141+ <h1>
4242+ Tales From Mainframe Modernization
4343+ </h1>
4444+ <div class="post-text">
4545+ <p>At my last workplace, I wrote transpilers (or just <a
4646+href="https://people.csail.mit.edu/rachit/post/transpiler/">compilers</a>
4747+if you prefer) from mainframe languages (COBOL, JCL, BASIC etc.) to Java
4848+(in Rust!).</p>
4949+<p>Legacy code is full of surprises. In the roughly 200k lines of COBOL
5050+that I had the (dis)pleasure of working with, I saw some wonderful hacks
5151+to get around the limitations of the system. Mainframes are also chock
5252+full of history.</p>
5353+<h3 id="base-2-numerics">Base-2 numerics</h3>
5454+<p>This is the first thing that stood out to me when I looked at COBOL
5555+code, a data-definition (the phrase for “variable”) in COBOL is declared
5656+like so:</p>
5757+<pre><code> ,-- name
5858+ | ,- type
5959+ __|___ __|_
6060+ 01 HEIGHT PIC 9(3).
6161+ -- ---
6262+ | |
6363+ | `- picture clause (keyword)
6464+ `- level number </code></pre>
6565+<p>That statement declares a variable called <code>HEIGHT</code> with
6666+type <code>9(3)</code>, which is shorthand for <code>999</code>, which
6767+indicates “3-digit number”. Similarly <code>A(5)</code> indicates
6868+5-character alphabetic string.</p>
6969+<h3 id="internationalisation">Internationalisation</h3>
7070+<p>Below is another data-definition in COBOL, declaring 3 variables:</p>
7171+<pre class="cobol"><code>01 FOO-PERSON.
7272+ 05 FOO-NAME PIC X(5).
7373+ 05 FOO-HEIGHT PIC 9(3).</code></pre>
7474+<p>What that means is:</p>
7575+<ul>
7676+<li><code>FOO-PERSON</code>: a “group” variable consisting of two other
7777+variables</li>
7878+<li><code>FOO-NAME</code>: an alphanumeric type with 5 characters</li>
7979+<li><code>FOO-HEIGHT</code>: a numeric type with 3 digits (remember,
8080+base 10 and not base 2)</li>
8181+</ul>
8282+<p>COBOL has an interesting construct called “REDEFINES”:</p>
8383+<pre class="cobol"><code>01 FOO-PERSON.
8484+ 05 FOO-NAME PIC X(5).
8585+ 05 FOO-HEIGHT PIC 9(3).
8686+8787+01 FOO-PERSONNE REDEFINES FOO-PERSON.
8888+ 05 FOO-NOM PIC X(5).
8989+ 05 FOO-TAILLE PIC 9(3).</code></pre>
9090+<p><code>FOO-PERSON</code> and <code>FOO-PERSONNE</code> refer to the
9191+same region of memory.</p>
9292+<p>I helped modernise a codebase that had clearly been worked on by a
9393+Spanish consultancy at some point, and they had decided to redefine all
9494+data definitions in Spanish.</p>
9595+<h3 id="string-parsing">String parsing</h3>
9696+<p>Here’s another fun one:</p>
9797+<pre class="cobol"><code> 01 FOO-PERSON.
9898+ 05 FOO-NAME PIC X(5).
9999+ 05 FOO-HEIGHT PIC 9(3).
100100+ .
101101+ .
102102+ .
103103+104104+ MOVE "PETER" TO FOO-NAME.
105105+ MOVE 175 TO FOO-HEIGHT.
106106+107107+ *> display the entire memory region
108108+ DISPLAY FOO-PERSON.
109109+ *> PETER175
110110+111111+ *> subscripting the first 7 bytes...
112112+ DISPLAY FOO-PERSON (1:7)
113113+ *> PETER17</code></pre>
114114+<p>So data-definitions simply describe names for regions. Which enables
115115+a clever way to parse strings:</p>
116116+<pre class="cobol"><code> 01 DATE.
117117+ 05 DD PIC 9(2).
118118+ 05 FILLER PIC X.
119119+ 05 MM PIC 9(2).
120120+ 05 FILLER PIC X.
121121+ 05 YYYY PIC 9(4).
122122+123123+ .
124124+ .
125125+ .
126126+127127+ MOVE "03/04/2025" TO DATE.
128128+ DISPLAY "DAY: " DD. *> DAY: 03
129129+ DISPLAY "MONTH: " MM. *> MONTH: 04
130130+ DISPLAY "YEAR: " YYYY. *> YEAR: 2025
131131+132132+ *> also works:
133133+ MOVE "03.04.2025" TO DATE.</code></pre>
134134+<h3 id="early-exit">Early exit</h3>
135135+<p>I’d see this peppered around in a few places; which I later realized
136136+was a way to trigger an abnormal end to a batch job (possibly triggering
137137+an error handling routine in the outer job control system):</p>
138138+<pre class="cobol"><code> 01 CONSTANT-ZERO S9(9)V9 VALUE 0.
139139+ 01 ABEND S9(9)V9.
140140+141141+ .
142142+ .
143143+ .
144144+145145+ COMPUTE ABEND = CONSTANT-ZERO / CONSTANT-ZERO.</code></pre>
146146+<h3 id="all-the-numbers">All the numbers</h3>
147147+<p>I have yet to find an explanation for this one, but I once found a
148148+file with just the first 800 natural numbers defined as string
149149+constants:</p>
150150+<pre class="cobol"><code> 01 TC0001 X(5) "00001".
151151+ 01 TC0002 X(5) "00002".
152152+ 01 TC0003 X(5) "00003".
153153+ .
154154+ .
155155+ *> .... 800 lines later ....
156156+ .
157157+ .
158158+ 01 TC0800 X(5) "00800".</code></pre>
159159+<h3 id="dd---disk-destroyer"><code>dd</code> - disk destroyer</h3>
160160+<p>The <code>DD</code> statement in the JCL subsystem stands for “data
161161+definition”, which is largely used to describe files and IO streams used
162162+by a batch job. The <code>dd</code> command <a href="#fn1"
163163+class="footnote-ref" id="fnref1" role="doc-noteref"><sup>1</sup></a> on
164164+UNIX is named after this statement!</p>
165165+<section id="footnotes" class="footnotes footnotes-end-of-document"
166166+role="doc-endnotes">
167167+<hr />
168168+<ol>
169169+<li id="fn1"><p><a
170170+href="https://en.wikipedia.org/wiki/Dd_%28Unix%29#History">Wikipedia -
171171+dd (Unix)</a><a href="#fnref1" class="footnote-back"
172172+role="doc-backlink">↩︎</a></p></li>
173173+</ol>
174174+</section>
175175+176176+ </div>
177177+178178+ <div class="intro">
179179+ Hi.
180180+ <div class="hot-links">
181181+ <a href="/index.xml" class="feed-button">Subscribe</a>
182182+ </div>
183183+ <p>I'm Akshay, programmer, pixel-artist & programming-language enthusiast.</p>
184184+ <p>I am currently building <a href="https://tangled.sh">tangled.sh</a> — a decentralized code-collaboration platform.</p>
185185+ <p>Reach out at oppili@libera.chat.</p>
186186+ </div>
187187+188188+ <a href="/" class="post-end-link">Home</a>
189189+ <span>/</span>
190190+ <a href="/posts" class="post-end-link">Posts</a>
191191+ <span>/</span>
192192+ <a class="post-end-link">Tales From Mainframe Modernization</a>
193193+ <a class="stats post-end-link" href="https://tangled.sh/@oppi.li/site/raw/master/posts/tales_from_mainframe_modernization.md
194194+">View Raw</a>
195195+ </div>
196196+ </div>
197197+ </body>
198198+</html>
···11+At my last workplace, I wrote transpilers (or just
22+[compilers](https://people.csail.mit.edu/rachit/post/transpiler/)
33+if you prefer) from mainframe languages (COBOL, JCL, BASIC etc.) to
44+Java (in Rust!).
55+66+Legacy code is full of surprises. In the roughly 200k lines
77+of COBOL that I had the (dis)pleasure of working with, I saw
88+some wonderful hacks to get around the limitations of the
99+system. Mainframes are also chock full of history.
1010+1111+### Base-2 numerics
1212+1313+This is the first thing that stood out to me when I looked
1414+at COBOL code, a data-definition (the phrase for "variable")
1515+in COBOL is declared like so:
1616+1717+```
1818+ ,-- name
1919+ | ,- type
2020+ __|___ __|_
2121+ 01 HEIGHT PIC 9(3).
2222+ -- ---
2323+ | |
2424+ | `- picture clause (keyword)
2525+ `- level number
2626+```
2727+2828+That statement declares a variable called `HEIGHT` with type
2929+`9(3)`, which is shorthand for `999`, which indicates
3030+"3-digit number". Similarly `A(5)` indicates 5-character
3131+alphabetic string.
3232+3333+### Internationalisation
3434+3535+Below is another data-definition in COBOL, declaring 3
3636+variables:
3737+3838+```cobol
3939+01 FOO-PERSON.
4040+ 05 FOO-NAME PIC X(5).
4141+ 05 FOO-HEIGHT PIC 9(3).
4242+```
4343+4444+What that means is:
4545+4646+- `FOO-PERSON`: a "group" variable consisting of two other
4747+ variables
4848+- `FOO-NAME`: an alphanumeric type with 5 characters
4949+- `FOO-HEIGHT`: a numeric type with 3 digits (remember, base 10
5050+ and not base 2)
5151+5252+COBOL has an interesting construct called "REDEFINES":
5353+5454+```cobol
5555+01 FOO-PERSON.
5656+ 05 FOO-NAME PIC X(5).
5757+ 05 FOO-HEIGHT PIC 9(3).
5858+5959+01 FOO-PERSONNE REDEFINES FOO-PERSON.
6060+ 05 FOO-NOM PIC X(5).
6161+ 05 FOO-TAILLE PIC 9(3).
6262+```
6363+6464+`FOO-PERSON` and `FOO-PERSONNE` refer to the same region of
6565+memory.
6666+6767+I helped modernise a codebase that had clearly been worked
6868+on by a Spanish consultancy at some point, and they had
6969+decided to redefine all data definitions in Spanish.
7070+7171+### String parsing
7272+7373+Here's another fun one:
7474+7575+```cobol
7676+ 01 FOO-PERSON.
7777+ 05 FOO-NAME PIC X(5).
7878+ 05 FOO-HEIGHT PIC 9(3).
7979+ .
8080+ .
8181+ .
8282+8383+ MOVE "PETER" TO FOO-NAME.
8484+ MOVE 175 TO FOO-HEIGHT.
8585+8686+ *> display the entire memory region
8787+ DISPLAY FOO-PERSON.
8888+ *> PETER175
8989+9090+ *> subscripting the first 7 bytes...
9191+ DISPLAY FOO-PERSON (1:7)
9292+ *> PETER17
9393+```
9494+9595+So data-definitions simply describe names for regions. Which
9696+enables a clever way to parse strings:
9797+9898+```cobol
9999+ 01 DATE.
100100+ 05 DD PIC 9(2).
101101+ 05 FILLER PIC X.
102102+ 05 MM PIC 9(2).
103103+ 05 FILLER PIC X.
104104+ 05 YYYY PIC 9(4).
105105+106106+ .
107107+ .
108108+ .
109109+110110+ MOVE "03/04/2025" TO DATE.
111111+ DISPLAY "DAY: " DD. *> DAY: 03
112112+ DISPLAY "MONTH: " MM. *> MONTH: 04
113113+ DISPLAY "YEAR: " YYYY. *> YEAR: 2025
114114+115115+ *> also works:
116116+ MOVE "03.04.2025" TO DATE.
117117+```
118118+119119+### Early exit
120120+121121+I'd see this peppered around in a few places; which I later
122122+realized was a way to trigger an abnormal end to a batch job
123123+(possibly triggering an error handling routine in the outer
124124+job control system):
125125+126126+```cobol
127127+ 01 CONSTANT-ZERO S9(9)V9 VALUE 0.
128128+ 01 ABEND S9(9)V9.
129129+130130+ .
131131+ .
132132+ .
133133+134134+ COMPUTE ABEND = CONSTANT-ZERO / CONSTANT-ZERO.
135135+```
136136+137137+### All the numbers
138138+139139+I have yet to find an explanation for this one, but I once
140140+found a file with just the first 800 natural numbers defined
141141+as string constants:
142142+143143+```cobol
144144+ 01 TC0001 X(5) "00001".
145145+ 01 TC0002 X(5) "00002".
146146+ 01 TC0003 X(5) "00003".
147147+ .
148148+ .
149149+ *> .... 800 lines later ....
150150+ .
151151+ .
152152+ 01 TC0800 X(5) "00800".
153153+```
154154+155155+The file was definitely not generated, and I can't imagine
156156+text editors on the mainframe were all that advanced either.
157157+158158+### `dd` - disk destroyer
159159+160160+The `DD` statement in the JCL subsystem stands for "data
161161+definition", which is largely used to describe files and IO
162162+streams used by a batch job. The `dd` command [^dd] on UNIX is
163163+named after this statement!
164164+165165+[^dd]: [Wikipedia - dd (Unix)](https://en.wikipedia.org/wiki/Dd_%28Unix%29#History)