force use of pandoc version >= 3.1.12.2

The `bin/pandoc-wrapper.sh` tool will verify that the ssytem
has a recent enough version of `pandoc(1)`.

We explain why we insist on `pandoc(1)`. version >= 3.1.12.2
in comments where the $PANDOC_MIN_VERSION is set.

Added `--wrap=preserve` as a default argument to `pandoc(1)`.
While this change will impact every HTML file generated,
we believe this will improve the ability of someone to look
at the generated HTML and correlate with the original markdown.

Changed `bin/pandoc-wrapper.sh` VERSION from "1.4.2 2024-03-17"
to "1.4.3 2024-03-18".

Performed `make www` to achieve all of the above and to generate
HTML using the new  `--wrap=preserve` `pandoc(1)` mode.
This commit is contained in:
Landon Curt Noll committed 2024-03-18 01:26:39 -07:00
1 parent 9eb7a54e9f
commit b0b212acb1
402 files changed
+37061 -55132

No files matched your search

+109 -180
View File
@@ -130,8 +130,8 @@
<h2 id="author"><a name="author"></a>Author:</h2>
<ul>
<li>Name: <a href="../../authors.html#Dave_Burton">Dave Burton</a><br>
Location: <a href="../../location.html#US">US</a> - <em>United States of
America</em> (<em>United States</em>) <br><br></li>
Location: <a href="../../location.html#US">US</a> - <em>United States of America</em> (<em>United States</em>)
<br><br></li>
</ul>
<!-- END: next line ends content generated by: bin/output-index-author.sh -->
@@ -154,231 +154,160 @@ America</em> (<em>United States</em>) <br><br></li>
<p>Finally, if you wish to read the man page:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a><span class="fu">man</span> ./calc.1</span></code></pre></div>
<h2 id="alternate-code">Alternate code:</h2>
<p>An alternate version of this entry, <a
href="prog.alt.c">prog.alt.c</a>, is provided. This alternate code is
discussed in the “prog.c vs prog.alt.c” section of the author’s remarks
below.</p>
<p>An alternate version of this entry, <a href="prog.alt.c">prog.alt.c</a>, is provided.
This alternate code is discussed in the “prog.c vs prog.alt.c” section of the
author’s remarks below.</p>
<h3 id="alternate-build">Alternate build:</h3>
<div class="sourceCode" id="cb7"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="fu">make</span> alt</span></code></pre></div>
<h3 id="alternate-use">Alternate use:</h3>
<p>Use <code>prog.alt</code> as you would <code>prog</code> above.</p>
<h2 id="judges-remarks">Judges’ remarks:</h2>
<p>“Look, Ma, no <del>hands</del> digits!”</p>
<p>The place where some arithmetic operations are done, for example,
division or modulo, are easy to find. Where are addition and
subtraction?</p>
<p>We were impressed with the level of detail the author “blogged” the
obfuscation process.</p>
<p>The place where some arithmetic operations are done, for example, division or
modulo, are easy to find. Where are addition and subtraction?</p>
<p>We were impressed with the level of detail the author “blogged” the obfuscation
process.</p>
<h2 id="authors-remarks">Author’s remarks:</h2>
<h3
id="calc---an-integer-expression-calculator-that-outputs-in-both-hex-and-decimal">calc
- an integer expression calculator that outputs in both hex and
decimal</h3>
<p>All useful tools should include sufficient documentation. See the
included man page. ;-)</p>
<h3 id="calc---an-integer-expression-calculator-that-outputs-in-both-hex-and-decimal">calc - an integer expression calculator that outputs in both hex and decimal</h3>
<p>All useful tools should include sufficient documentation.
See the included man page. ;-)</p>
<h3 id="notes">Notes</h3>
<p>This program is named <code>calc</code>. Onomatopoeia of sorts, in
the visual realm. The formatting was easier: Form Follows Function
(although <a href="../../2011/hou/hint.html" title="Hou Qiming">Hou</a>
did this better). It was tempting to call it iCalc, with <code>i</code>
for integer (and it was written on an <code>iDevice</code>), but sanity
prevailed.</p>
<p>Printed in 8 pt Courier, it makes aesthetically pleasing 8.5 x 11
wall art.</p>
<p>This program is named <code>calc</code>. Onomatopoeia of sorts, in the visual realm. The
formatting was easier: Form Follows Function (although <a href="../../2011/hou/hint.html" title="Hou Qiming">Hou</a> did this
better). It was tempting to call it iCalc, with <code>i</code> for integer (and it was
written on an <code>iDevice</code>), but sanity prevailed.</p>
<p>Printed in 8 pt Courier, it makes aesthetically pleasing 8.5 x 11 wall art.</p>
<h3 id="prog.c-vs-prog.alt.c">prog.c vs prog.alt.c</h3>
<p><a href="../../authors.html#Dominik_Muth">Dominik Muth</a> observed a
syntax error on <code>1+1</code>, <code>1-1</code>, <code>1|1</code>,
and <code>1^1</code> when using an ARM based computer, although
<code>1*1</code> and others worked correctly. This occurs because some
platforms by default treat <code>char</code> as
<code>unsigned char</code>. The original code has this weakness, which
can be corrected by adding <code>-fsigned-char</code> to the compile
line.</p>
<p><a href="../../authors.html#Dominik_Muth">Dominik Muth</a> observed a syntax error on <code>1+1</code>,
<code>1-1</code>, <code>1|1</code>, and <code>1^1</code> when using an ARM based computer, although <code>1*1</code> and
others worked correctly. This occurs because some platforms by default treat
<code>char</code> as <code>unsigned char</code>. The original code has this weakness, which can be
corrected by adding <code>-fsigned-char</code> to the compile line.</p>
<p>The modified code is agnostic to <code>char</code> signedness.</p>
<h3 id="why-is-this-entry-obfuscatedinteresting">Why is this entry
obfuscated/interesting?</h3>
<h3 id="why-is-this-entry-obfuscatedinteresting">Why is this entry obfuscated/interesting?</h3>
<p>Yes, this is another calculator program.</p>
<p>However, unlike any other calculator source code the author is aware
of, this one contains no digits. At all. Anywhere. As in</p>
<p>However, unlike any other calculator source code the author is aware of,
this one contains no digits. At all. Anywhere. As in</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="fu">grep</span> <span class="st">&#39;[0-9]&#39;</span> prog.c <span class="kw">||</span> <span class="bu">echo</span> no digits!</span></code></pre></div>
<p>Nor are the digits simply obfuscated. There are no character
constants. There is only one single, short string, and it does not
contain any obfuscated digits. And yet the output is in decimal and
hexadecimal, and it accepts octal, decimal, and hex input.</p>
<p>Flow control is by <code>for</code> and <code>return</code>. It is
<code>if</code>-less, <code>switch</code>-less, <code>while</code>-less,
and hopeless. Literally, if not figuratively. ;-)</p>
<p>The code size is intentionally 2015, as stated by
<code>iocccsize -i</code>, and can be reformatted without changes (as in
<a href="rule2.c">rule2.c</a>) to exactly 4096 octets.</p>
<p>Finally, <code>calc</code> is interesting, if for no other reason
than it is practically useful: Hex/decimal conversion, arithmetic,
byte-swapping, bit-shifting, and logical operations with memory, on the
command line, or interactively.</p>
<h3 id="but-the-question-is-why-is-the-entry-obfuscated">But the
question is why is the entry obfuscated?</h3>
<p>Nor are the digits simply obfuscated. There are no character constants. There
is only one single, short string, and it does not contain any obfuscated digits.
And yet the output is in decimal and hexadecimal, and it accepts octal, decimal,
and hex input.</p>
<p>Flow control is by <code>for</code> and <code>return</code>. It is <code>if</code>-less, <code>switch</code>-less,
<code>while</code>-less, and hopeless. Literally, if not figuratively. ;-)</p>
<p>The code size is intentionally 2015, as stated by <code>iocccsize -i</code>, and can be
reformatted without changes (as in <a href="rule2.c">rule2.c</a>) to exactly 4096 octets.</p>
<p>Finally, <code>calc</code> is interesting, if for no other reason than it is practically
useful: Hex/decimal conversion, arithmetic, byte-swapping, bit-shifting, and
logical operations with memory, on the command line, or interactively.</p>
<h3 id="but-the-question-is-why-is-the-entry-obfuscated">But the question is why is the entry obfuscated?</h3>
<p>The code follows many industry best-practices:</p>
<ul>
<li><p>You know what it does just by looking at it.</p></li>
<li><p>Numbers and digits have often been used for obfuscation, so in a
bid for better clarity, this code has no digits at all.</p></li>
<li><p>In the spirit of clarity, most of the variables are declared
before use, so they are readily visible, with single letter names that
don’t clutter the screen, in a tautological arrangement.</p></li>
<li><p>More helpful is the use of <code>typedef</code>s instead of
<code>#define</code>, so the types remain useful even in the debugger,
and source code beautifiers will not undo careful presentation.</p></li>
<li><p><code>#defines</code> are used here in the best spirit of the
preprocessor: to shorten repetitive constructs, not for
obscurity.</p></li>
<li><p>All functions are short (and therefore easy to understand?) and
do only one thing, well, ….</p></li>
<li><p>Curly braces invite endless holy wars over readability. This code
only uses them for function definitions, thereby greatly improving
readability, and reducing arguments about said readability.</p></li>
<li><p>One of C’s many blessings (until recently) is a modicum of
keywords, of which only 8 are used: <code>for</code>,
<code>return</code>, <code>typedef</code>, <code>void</code>,
<code>char</code>, <code>short</code>, <code>unsigned</code> and
<code>long</code>; 10 if <code>#include</code> and <code>#define</code>
are counted.</p></li>
<li><p>The code helpfully declares <code>"syntax_error!"</code> right up
front, filling the reader with confidence.</p></li>
<li><p>In spite of its inherent clarity, the code was presented to both
<code>indent(1)</code> and <code>clang-format(1)</code>, after running
it through the preprocessor, sustaining its better qualities.</p></li>
<li><p>That the code is obfuscated is spelled out two different ways in
the source; it helps to reformat the code to see the second
spelling.</p></li>
<li><p>The author is overly fond of the code that handles input. There
is no memory allocation, nor pre-allocation of arrays, so where does the
memory come from? The multi-base <code>strtol(3)</code> code is pretty
tricky. No special attempt was made to replace operations with obscure
mathematical relations, as the (lack of) beauty is in the parsing – ask
not where is the modulus operation, but how does it know when to mod –
okay, but where is add and subtract? And really, who doesn’t enjoy a
<code>setjmp(3)</code> in the argument list?</p></li>
<li><p>Finally, documentation of the source code structure is helpfully
provided in rot13 format. But isn’t it unsportsmanlike to rely upon it?
However, even with this helpful guide, things like reading input lines
remain as tricky to read as they are to write.</p></li>
<li><p>Numbers and digits have often been used for obfuscation,
so in a bid for better clarity, this code has no digits at all.</p></li>
<li><p>In the spirit of clarity, most of the variables are declared before use, so
they are readily visible, with single letter names that don’t clutter the
screen, in a tautological arrangement.</p></li>
<li><p>More helpful is the use of <code>typedef</code>s instead of <code>#define</code>, so the types
remain useful even in the debugger, and source code beautifiers will not undo
careful presentation.</p></li>
<li><p><code>#defines</code> are used here in the best spirit of the preprocessor: to shorten
repetitive constructs, not for obscurity.</p></li>
<li><p>All functions are short (and therefore easy to understand?) and do only one
thing, well, ….</p></li>
<li><p>Curly braces invite endless holy wars over readability. This code only uses
them for function definitions, thereby greatly improving readability, and
reducing arguments about said readability.</p></li>
<li><p>One of C’s many blessings (until recently) is a modicum of keywords, of which
only 8 are used: <code>for</code>, <code>return</code>, <code>typedef</code>, <code>void</code>, <code>char</code>, <code>short</code>, <code>unsigned</code>
and <code>long</code>; 10 if <code>#include</code> and <code>#define</code> are counted.</p></li>
<li><p>The code helpfully declares <code>"syntax_error!"</code> right up front, filling the
reader with confidence.</p></li>
<li><p>In spite of its inherent clarity, the code was presented to both <code>indent(1)</code>
and <code>clang-format(1)</code>, after running it through the preprocessor, sustaining its
better qualities.</p></li>
<li><p>That the code is obfuscated is spelled out two different ways in the source;
it helps to reformat the code to see the second spelling.</p></li>
<li><p>The author is overly fond of the code that handles input. There is no memory
allocation, nor pre-allocation of arrays, so where does the memory come from?
The multi-base <code>strtol(3)</code> code is pretty tricky. No special attempt was made to
replace operations with obscure mathematical relations, as the (lack of) beauty
is in the parsing – ask not where is the modulus operation, but how does it
know when to mod – okay, but where is add and subtract? And really, who
doesn’t enjoy a <code>setjmp(3)</code> in the argument list?</p></li>
<li><p>Finally, documentation of the source code structure is helpfully provided in
rot13 format. But isn’t it unsportsmanlike to rely upon it? However, even with
this helpful guide, things like reading input lines remain as tricky to read as
they are to write.</p></li>
</ul>
<h3 id="compiler-warnings">Compiler warnings</h3>
<p><code>calc</code> is C99 compliant, and is ANSI/C90 compliant except
for wanting 64-bit <code>long long</code>. Changing the two
<code>long long</code> typedefs to <code>long</code>, and compiling with
<code>gcc -m32</code> yields a program that operates on 32-bit values,
with wrap-around of shifts mod 32:</p>
<p><code>calc</code> is C99 compliant, and is ANSI/C90 compliant except for wanting 64-bit <code>long long</code>. Changing the two <code>long long</code> typedefs to <code>long</code>, and compiling with <code>gcc -m32</code> yields a program that operates on 32-bit values, with wrap-around of
shifts mod 32:</p>
<pre><code>1&lt;&lt;48
65536 0x00010000</code></pre>
<p>gcc 4.2.1 without arguments compiles cleanly
(e.g. <code>cc prog.c -o prog</code>). This is my workaday compiler. gcc
is also clean with <code>-ansi</code>, and <code>-std=c99</code>.</p>
<p>clang 3.6.0 lives up to its namesake, resounding on non-problems. To
stifle these complaints:</p>
<p>gcc 4.2.1 without arguments compiles cleanly (e.g. <code>cc prog.c -o prog</code>).
This is my workaday compiler. gcc is also clean with <code>-ansi</code>, and <code>-std=c99</code>.</p>
<p>clang 3.6.0 lives up to its namesake, resounding on non-problems.
To stifle these complaints:</p>
<pre><code>-Wno-return-type -Wno-parentheses -Wno-empty-body</code></pre>
<p>When invoked with <code>-ansi -pedantic</code>, there are two
warnings, which can be ignored:</p>
<p>When invoked with <code>-ansi -pedantic</code>, there are two warnings, which can be ignored:</p>
<ul>
<li><code>ISO C90 does not support 'long long'</code></li>
</ul>
<p>With <code>-Wall -std=c99</code>, both are quite noisy, and all can
be ignored:</p>
<p>With <code>-Wall -std=c99</code>, both are quite noisy, and all can be ignored:</p>
<ul>
<li><code>array subscript has type 'char' [-Wchar-subscripts]</code></li>
<li><code>value computed is not used [-Wunused-value]</code></li>
<li><code>operation on 'j' may be undefined [-Wsequence-point]</code></li>
</ul>
<h3 id="test-suite">Test Suite:</h3>
<p>If the program name begins with an <code>e</code>, it echoes
<code>stdin</code> to <code>stdout</code>. This allows for a convenient
test suite:</p>
<div class="sourceCode" id="cb11"><pre
class="sourceCode sh"><code class="sourceCode bash"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="fu">ln</span> <span class="at">-sf</span> prog eprog</span>
<p>If the program name begins with an <code>e</code>, it echoes <code>stdin</code> to <code>stdout</code>.
This allows for a convenient test suite:</p>
<div class="sourceCode" id="cb11"><pre class="sourceCode sh"><code class="sourceCode bash"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a><span class="fu">ln</span> <span class="at">-sf</span> prog eprog</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true" tabindex="-1"></a><span class="va">PATH</span><span class="op">=</span>. <span class="ex">eprog</span> <span class="op">&lt;</span> test.in <span class="kw">|</span> <span class="fu">diff</span> <span class="at">-</span> test.out</span></code></pre></div>
<h3 id="spoilers">Spoilers:</h3>
<p>If you do not want to puzzle out how it works, see <a
href="spoilers.html">spoilers.html</a>.</p>
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0
License:</h2>
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights
Reserved. You are free to share and adapt this file under the terms of
this license:</p>
<p>If you do not want to puzzle out how it works, see <a href="spoilers.html">spoilers.html</a>.</p>
<h2 id="copyright-and-cc-by-sa-4.0-license">Copyright and CC BY-SA 4.0 License:</h2>
<p>This file is Copyright (c) 2023 by Landon Curt Noll. All Rights Reserved.
You are free to share and adapt this file under the terms of this license:</p>
<pre><code>Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)</code></pre>
<p>For more information, see:
https://creativecommons.org/licenses/by-sa/4.0/</p>
<p>For more information, see: https://creativecommons.org/licenses/by-sa/4.0/</p>
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<!-- START: this line starts content for HTML phase 22 by: bin/output-index-inventory.sh via bin/md2html.sh -->
<!-- START: this line starts content generated by: bin/output-index-inventory.sh -->
<h1 id="inventory-for-2015burton"><a name="inventory"></a>Inventory for
2015/burton</h1>
<h1 id="inventory-for-2015burton"><a name="inventory"></a>Inventory for 2015/burton</h1>
<p><a href="#top">Jump to top</a></p>
<h2 id="primary-files">Primary files</h2>
<ul>
<li><a
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/prog.c">prog.c</a>
- entry source</li>
<li><a
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/Makefile">Makefile</a>
- entry Makefile</li>
<li><a
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/prog.alt.c">prog.alt.c</a>
- alternative source</li>
<li><a
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/prog.orig.c">prog.orig.c</a>
- original source</li>
<li><a
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/try.sh">try.sh</a>
- how to run</li>
<li><a
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/try.this.txt">try.this.txt</a>
- try.sh input</li>
<li><a
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/calc.1">calc.1</a>
- man page for integer expression calculator</li>
<li><a href="road.to.obscurity.html">road.to.obscurity.html</a> -
obfuscated calculator development notes</li>
<li><a
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/rule2.c">rule2.c</a>
- iocccsize reformatted to exactly 4096 octets</li>
<li><a
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/test.in">test.in</a>
- test suite input data</li>
<li><a
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/test.out">test.out</a>
- test suite comparison data</li>
<li><a
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/test32.out">test32.out</a>
- test suite comparison data for 32-bit systems</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/prog.c">prog.c</a> - entry source</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/Makefile">Makefile</a> - entry Makefile</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/prog.alt.c">prog.alt.c</a> - alternative source</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/prog.orig.c">prog.orig.c</a> - original source</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/try.sh">try.sh</a> - how to run</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/try.this.txt">try.this.txt</a> - try.sh input</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/calc.1">calc.1</a> - man page for integer expression calculator</li>
<li><a href="road.to.obscurity.html">road.to.obscurity.html</a> - obfuscated calculator development notes</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/rule2.c">rule2.c</a> - iocccsize reformatted to exactly 4096 octets</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/test.in">test.in</a> - test suite input data</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/test.out">test.out</a> - test suite comparison data</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/test32.out">test32.out</a> - test suite comparison data for 32-bit systems</li>
<li><a href="spoilers.html">spoilers.html</a> - SPOILER WARNING</li>
<li><a
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/src.doc.txt">src.doc.txt</a>
- SPOILER WARNING hints about the source</li>
<li><a href="2015_burton.tar.bz2">2015_burton.tar.bz2</a> - download
entry source</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/src.doc.txt">src.doc.txt</a> - SPOILER WARNING hints about the source</li>
<li><a href="2015_burton.tar.bz2">2015_burton.tar.bz2</a> - download entry source</li>
</ul>
<h2 id="secondary-files">Secondary files</h2>
<ul>
<li><a href="index.html">index.html</a> - entry home page</li>
<li><a
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/.entry.json">.entry.json</a>
- description of entry in JSON</li>
<li><a
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/.gitignore">.gitignore</a>
- list of files that should not be committed under git</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/.entry.json">.entry.json</a> - description of entry in JSON</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/.gitignore">.gitignore</a> - list of files that should not be committed under git</li>
<li><a href=".path">.path</a> - directory path from top directory</li>
<li><a
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/README.md">README.md</a>
- markdown source for index.html</li>
<li><a
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/road.to.obscurity.md">road.to.obscurity.md</a>
- markdown source for road.to.obscurity.html</li>
<li><a
href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/spoilers.md">spoilers.md</a>
- markdown source for spoilers.html</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/README.md">README.md</a> - markdown source for index.html</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/road.to.obscurity.md">road.to.obscurity.md</a> - markdown source for road.to.obscurity.html</li>
<li><a href="https://github.com/ioccc-src/temp-test-ioccc/blob/master/2015/burton/spoilers.md">spoilers.md</a> - markdown source for spoilers.html</li>
</ul>
<!-- END: next line ends content generated by: bin/output-index-inventory.sh -->
+132 -161
View File
@@ -120,28 +120,26 @@
<!-- END: this line ends content from: inc/before-content.default.html -->
<!-- START: this line starts content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<h1 id="development-of-the-obfuscated-calculator.">Development of the
obfuscated calculator.</h1>
<h1 id="development-of-the-obfuscated-calculator.">Development of the obfuscated calculator.</h1>
<p>I wanted to enter the IOCCC….</p>
<p>I think I can write something clever. Possibly even obscure. The
competition is fierce, but not a closed door.</p>
<p>I needed an interesting program, that had a reasonable chance of
being shrunk within 4096 bytes, and lent itself to obfuscation. I had
been revisiting utilities I’ve written over the years. One useful
program was <code>calc</code>, a simple recursive descent signed integer
expression parser I developed from first principles as a demonstration
of how computers work for my son. That program did the basic four
operations, but as a programmer, I needed more, so those were added over
time.</p>
<p><code>calc</code> is a useful, functioning utility. The operators
before the obfuscation dance began (this is called foreshadowing):</p>
<p>I think I can write something clever. Possibly even obscure. The competition
is fierce, but not a closed door.</p>
<p>I needed an interesting program, that had a reasonable chance of being shrunk
within 4096 bytes, and lent itself to obfuscation. I had been revisiting
utilities I’ve written over the years. One useful program was <code>calc</code>, a simple
recursive descent signed integer expression parser I developed from first
principles as a demonstration of how computers work for my son. That program
did the basic four operations, but as a programmer, I needed more, so those
were added over time.</p>
<p><code>calc</code> is a useful, functioning utility. The operators before the obfuscation
dance began (this is called foreshadowing):</p>
<pre><code>() forced precedence
- ~ ? unary minus, compl, byteswap
* / % &amp; &lt;&lt; &gt;&gt; mul, div, mod, bitand, shift: left, right
+ - | ^ add, sub, bitor, xor
NUM 0-9</code></pre>
<p>This seemed like a reasonable candidate to experiment with
obfuscation; perhaps it might yield good results.</p>
<p>This seemed like a reasonable candidate to experiment with obfuscation; perhaps
it might yield good results.</p>
<h2 id="principle-of-operation">Principle of operation</h2>
<p>The algorithm was and is rather straightforward:</p>
<pre><code>expr() {
@@ -180,8 +178,8 @@ factor() {
error()
}</code></pre>
<h2 id="obfuscation-is-a-process">Obfuscation is a process</h2>
<p>Within the above algorithm, there are many details unmentioned, all
ripe for obfuscation:</p>
<p>Within the above algorithm, there are many details unmentioned, all ripe for
obfuscation:</p>
<ul>
<li>input</li>
<li>tokenization</li>
@@ -191,164 +189,137 @@ ripe for obfuscation:</p>
<li>swapping bytes</li>
<li>user interface (command line vs <code>stdin</code>)</li>
</ul>
<p>Uncertain as to how this would progress, I started
obfuscating/condensing everything except the conversion operations,
leaving those to <code>sprintf(3)</code> and <code>strtol(3)</code>. The
first version of the obfuscated code used an homage to 1984 anon for
I/O, and it featured a <code>#define</code> for <code>else</code>s and
the types, to help minimize the repetition. And of course, most
functions were renamed with one or two letters, and most of the
variables became single letter globals. Tokenization was rather easy
with a declared array, just initialized with unique values for each.</p>
<p>This was when the obfuscation took a turn for the better (worse): it
was easy to hide the operations via a simple transformation. The code
now dealt with small integer values instead of direct ASCII
representation of the operations. And the strings were collapsed into a
single combined error message and operator tokenization table. This was
relatively obscure.</p>
<p>Next, <code>sprintf(3)</code> was replaced with a custom formatter.
This was rather simple, but at least the formatting was not obvious.
Formatting and printing were split early. <code>strtol(3)</code> was
replaced with custom logic, limited to 3 practical bases: octal,
decimal, and hex. The last result was remembered in a special variable,
dot.</p>
<p>By this time, I had a version which I considered obscure, and shared
this early version with a couple of colleagues for comments. I suggested
I could improve the obfuscation of a <code>term()</code> and
<code>factor()</code>, and would like to have assignable memories.</p>
<p>This code was pretty dense, but inspired by previous IOCCC entries, I
thought I might get rid of all the <code>else</code>s, which showed the
structure of the parser rather clearly. Investing in the ternary
operator, the code got quite a bit more difficult to follow, used only
<code>for</code> loops, and I had to start taking notes to follow it.
This was a good sign! ;-)</p>
<p>I started testing the code. I wrote a test suite to ensure the
changes I made did not corrupt the processing (oh so easy to do with
this obfuscated mess). Why does <code>-1&gt;&gt;32</code> yield
<code>-1</code>? Oh, yeah: signed arithmetic. Enter Java’s
<code>unsigned</code> shift: <code>&gt;&gt;&gt;</code>. Better. But with
more features, more to get wrong, and harder to know which expression is
causing the error. The easy solution: if the name begins with
<code>e</code>, echo the input. Now I can see the failing expression.
<p>Uncertain as to how this would progress, I started obfuscating/condensing
everything except the conversion operations, leaving those to <code>sprintf(3)</code> and
<code>strtol(3)</code>. The first version of the obfuscated code used an homage to 1984 anon
for I/O, and it featured a <code>#define</code> for <code>else</code>s and the types, to help minimize
the repetition. And of course, most functions were renamed with one or two
letters, and most of the variables became single letter globals. Tokenization
was rather easy with a declared array, just initialized with unique values for
each.</p>
<p>This was when the obfuscation took a turn for the better (worse): it was easy
to hide the operations via a simple transformation. The code now dealt with
small integer values instead of direct ASCII representation of the operations.
And the strings were collapsed into a single combined error message and
operator tokenization table. This was relatively obscure.</p>
<p>Next, <code>sprintf(3)</code> was replaced with a custom formatter. This was rather simple,
but at least the formatting was not obvious. Formatting and printing were
split early. <code>strtol(3)</code> was replaced with custom logic, limited to 3 practical
bases: octal, decimal, and hex. The last result was remembered in a special
variable, dot.</p>
<p>By this time, I had a version which I considered obscure, and shared this early
version with a couple of colleagues for comments. I suggested I could improve
the obfuscation of a <code>term()</code> and <code>factor()</code>, and would like to have assignable
memories.</p>
<p>This code was pretty dense, but inspired by previous IOCCC entries, I thought I
might get rid of all the <code>else</code>s, which showed the structure of the parser
rather clearly. Investing in the ternary operator, the code got quite a bit
more difficult to follow, used only <code>for</code> loops, and I had to start taking notes
to follow it. This was a good sign! ;-)</p>
<p>I started testing the code. I wrote a test suite to ensure the changes I made
did not corrupt the processing (oh so easy to do with this obfuscated mess).
Why does <code>-1&gt;&gt;32</code> yield <code>-1</code>? Oh, yeah: signed arithmetic. Enter Java’s
<code>unsigned</code> shift: <code>&gt;&gt;&gt;</code>. Better. But with more features, more to get wrong,
and harder to know which expression is causing the error. The easy solution: if
the name begins with <code>e</code>, echo the input. Now I can see the failing expression.
Wait, what is this test expression supposed to be testing?</p>
<p>Wouldn’t it be nice to have comments?</p>
<p>Adding new functionality to an obscure program is … going about it
backwards. Get the functionality correct and complete, THEN obscure.
Sounds obvious, but that did not happen. I got comments working, then
desired to have multiple statements on a single line (read: semicolon
expression terminators). This involved quite a bit of rework of the
input code, but now allowed very convenient user interaction.</p>
<h2 id="better-obscurity-is-a-laborious-process">Better Obscurity is a
laborious process</h2>
<p>Satisfied with the functionality, but unsatisfied with the obscurity,
I pondered if I could get rid of all the constants? This had not been
done before (to my knowledge), and I was able to work out the how-tos
and the compromises. Now I can no longer declare my arrays, I have to
allocate them. Obscurity now increased!</p>
<p>Adding new functionality to an obscure program is … going about it backwards.
Get the functionality correct and complete, THEN obscure. Sounds obvious, but
that did not happen. I got comments working, then desired to have multiple
statements on a single line (read: semicolon expression terminators). This
involved quite a bit of rework of the input code, but now allowed very
convenient user interaction.</p>
<h2 id="better-obscurity-is-a-laborious-process">Better Obscurity is a laborious process</h2>
<p>Satisfied with the functionality, but unsatisfied with the obscurity, I
pondered if I could get rid of all the constants? This had not been done
before (to my knowledge), and I was able to work out the how-tos and the
compromises. Now I can no longer declare my arrays, I have to allocate them.
Obscurity now increased!</p>
<p>But wouldn’t it be nice to have assignable memories?</p>
<p>Around this time, the formatted code no longer fit with the 2053
limit (due to a lack of comprehension of the significance of the
space-after-brace-and-semi rule, and a layout program that did not know
how to do this). Frustrated, I wrote another program to reformat this
code into <a href="rule2.c">rule2.c</a>, which was a single C token per
line. This solved the formatting problem, but intriguingly introduced
another. Now I was faced with the 4096 rule as well as the 2053 rule.
But this was a challenge!</p>
<p>I wrote a de-obfuscator, and worked on both the unobfuscated version
and the master code. I worked on the template formatter to make this as
automated as possible, and worked to achieve both a perfectly presented
picture AND the single-line exactly-at-4096 <a
href="rule2.c">rule2.c</a>.</p>
<p>Finally, “perfection”, with assignable memories! Where perfection is
defined as a nicely formatted picture at less than 2053, and exactly
4096 token-per-line <a href="rule2.c">rule2.c</a>.</p>
<p>Around this time, the formatted code no longer fit with the 2053 limit (due to a
lack of comprehension of the significance of the space-after-brace-and-semi
rule, and a layout program that did not know how to do this). Frustrated, I
wrote another program to reformat this code into <a href="rule2.c">rule2.c</a>, which was a
single C token per line. This solved the formatting problem, but intriguingly
introduced another. Now I was faced with the 4096 rule as well as the 2053
rule. But this was a challenge!</p>
<p>I wrote a de-obfuscator, and worked on both the unobfuscated version and the
master code. I worked on the template formatter to make this as automated as
possible, and worked to achieve both a perfectly presented picture AND the
single-line exactly-at-4096 <a href="rule2.c">rule2.c</a>.</p>
<p>Finally, “perfection”, with assignable memories! Where perfection is defined
as a nicely formatted picture at less than 2053, and exactly 4096
token-per-line <a href="rule2.c">rule2.c</a>.</p>
<h2 id="testing-testing-testing">Testing Testing Testing</h2>
<p>Cross platform, it works on Mac OSX, fails on Linux. It works if
<code>#include &lt;stdlib.h&gt;</code>, but it dumps core without it
(the only change!)?. 64-bits without proper declaration of
<code>int</code>s in syscalls yields unpredictable results. 32-bit
<p>Cross platform, it works on Mac OSX, fails on Linux. It works if <code>#include &lt;stdlib.h&gt;</code>, but it dumps core without it (the only change!)?. 64-bits without
proper declaration of <code>int</code>s in syscalls yields unpredictable results. 32-bit
compilation showed problems with byte-swapping in using addition versus
bitwise-or. In 32-bit land, <code>x&lt;&lt;32 == x</code>, so
<code>x&lt;&lt;32 + x&gt;&gt;32</code> does not yield the desired
result, but <code>x&lt;&lt;32 | x&gt;&gt;32</code> does (with
appropriate care and feeding). And the different compilers on different
hosts complained loudly and differently, although all produced correct
bits in spite of the noise.</p>
<p>Further, the program did not do UNIX pipelines well, due to the
unbuffered homage code (byte-at-a-time I/O), of which
<code>write(2)</code> was also the source of the portability problem.
Replace <code>write(2)</code> with
<code>getchar(3)</code>/<code>putchar(3)</code>, and it piped well but
lost some obscurity and no longer paid (direct) homage to history.</p>
<p>Another problem: only one expression at a time was allowed on the
command line, no semis, no comments, and it turns out <code>$2</code>,
<code>$3</code>, … were not handled correctly. Given the new I/O code,
it was now possible to copy the command line arguments into a buffer,
and write a small routine to retrieve bytes from this buffer like
<code>getchar(3)</code>. Voila! Better obfuscation with much better
functionality!</p>
bitwise-or. In 32-bit land, <code>x&lt;&lt;32 == x</code>, so <code>x&lt;&lt;32 + x&gt;&gt;32</code> does not yield the
desired result, but <code>x&lt;&lt;32 | x&gt;&gt;32</code> does (with appropriate care and feeding).
And the different compilers on different hosts complained loudly and
differently, although all produced correct bits in spite of the noise.</p>
<p>Further, the program did not do UNIX pipelines well, due to the unbuffered
homage code (byte-at-a-time I/O), of which <code>write(2)</code> was also the source of the
portability problem. Replace <code>write(2)</code> with <code>getchar(3)</code>/<code>putchar(3)</code>, and it
piped well but lost some obscurity and no longer paid (direct) homage to
history.</p>
<p>Another problem: only one expression at a time was allowed on the command line,
no semis, no comments, and it turns out <code>$2</code>, <code>$3</code>, … were not handled correctly.
Given the new I/O code, it was now possible to copy the command line arguments
into a buffer, and write a small routine to retrieve bytes from this buffer
like <code>getchar(3)</code>. Voila! Better obfuscation with much better functionality!</p>
<p>But wouldn’t it be nice to show what the current variables hold?</p>
<p>Bytes are now hard to find to keep exactly at 4096, and adding
functionality to obscured code is not easy. Restructuring the logic to
gain the bytes necessary, code to display the variables was added.</p>
<p>Test. Test. Test. Oh, noes! More bugs! Typing “<code>1 + 2 5</code>”
yields <code>3</code>, but no syntax error. “<code>g = 1</code>” yields
a syntax error, and “<code>0xg</code>” does not! “<code>)</code>” causes
a segfault! Why didn’t I test these before I started obfuscating?! By
this point, everything I did to the code perturbed the 4096 bytes, all
variables were already a single character, and it was really difficult
to follow the logic in a debugger (single-stepping an expression did the
entire line of code, even if it involved multiple statements – and it
did, everywhere, even in the unobfuscated version; think: a complex
chain of ternary expressions is a single statement). This involved
careful examination of all the expressions within the logic, trying to
find a different way of getting the same result, but typically within
fewer bytes than before to allow for the added logic to fix the
bugs.</p>
<p>The bugs were fixed, the code re-formatted, and <a
href="rule2.c">rule2.c</a> was again 4096 bytes.</p>
<p>Bytes are now hard to find to keep exactly at 4096, and adding functionality to
obscured code is not easy. Restructuring the logic to gain the bytes
necessary, code to display the variables was added.</p>
<p>Test. Test. Test. Oh, noes! More bugs! Typing “<code>1 + 2 5</code>” yields <code>3</code>, but
no syntax error. “<code>g = 1</code>” yields a syntax error, and “<code>0xg</code>” does not! “<code>)</code>”
causes a segfault! Why didn’t I test these before I started obfuscating?! By
this point, everything I did to the code perturbed the 4096 bytes, all variables
were already a single character, and it was really difficult to follow the logic
in a debugger (single-stepping an expression did the entire line of code, even
if it involved multiple statements – and it did, everywhere, even in the
unobfuscated version; think: a complex chain of ternary expressions is a single
statement). This involved careful examination of all the expressions within the
logic, trying to find a different way of getting the same result, but typically
within fewer bytes than before to allow for the added logic to fix the bugs.</p>
<p>The bugs were fixed, the code re-formatted, and <a href="rule2.c">rule2.c</a> was again
4096 bytes.</p>
<p>But wouldn’t it be nice for unary plus to work?</p>
<p>Add unary plus, re-balance. Little things now take a fair bit of
work. Adding anything requires taking away in others, but since all the
logic is functional, this means rewriting the logic to be more concise.
After several rounds of this, bytes are scarce to come by.</p>
<p>Add unary plus, re-balance. Little things now take a fair bit of work. Adding
anything requires taking away in others, but since all the logic is functional,
this means rewriting the logic to be more concise. After several rounds of
this, bytes are scarce to come by.</p>
<p>But wouldn’t it be nice for assignments to be silent?</p>
<p>Made them silent (easier said than done!). Why does
“<code>1 + 2 5</code>” print a syntax error, but
“<code>a = 1 + 2 5</code>” does not? Rewrite(!) the assignment logic –
and this requires more bytes!</p>
<h2 id="better-obscurity-through-simplification">Better Obscurity
Through Simplification</h2>
<p>Except there were not enough bytes to do this, unless
<code>#include &lt;unistd.h&gt;</code> is removed. But then
<code>sbrk()</code> must be declared, eating into the savings. If only
there were 512 bytes of memory already allocated that could be portably
touched for free….</p>
<p>Light bulb! Memory allocation was excised, and the code became more
obscure.</p>
<p>It was working again! It formats beautifully, it compiled cleanly
(with apropos <code>-Wno-guards</code>), it remains obscure after
<code>cpp(1)</code> and <code>clang-format(1)</code>, it measures within
the limits and exactly at 4096 (this latter was really getting
<p>Made them silent (easier said than done!). Why does “<code>1 + 2 5</code>” print a syntax
error, but “<code>a = 1 + 2 5</code>” does not? Rewrite(!) the assignment logic – and
this requires more bytes!</p>
<h2 id="better-obscurity-through-simplification">Better Obscurity Through Simplification</h2>
<p>Except there were not enough bytes to do this, unless <code>#include &lt;unistd.h&gt;</code> is
removed. But then <code>sbrk()</code> must be declared, eating into the savings. If only
there were 512 bytes of memory already allocated that could be portably touched
for free….</p>
<p>Light bulb! Memory allocation was excised, and the code became more obscure.</p>
<p>It was working again! It formats beautifully, it compiled cleanly (with apropos
<code>-Wno-guards</code>), it remains obscure after <code>cpp(1)</code> and <code>clang-format(1)</code>, it
measures within the limits and exactly at 4096 (this latter was really getting
challenging to maintain). No more bugs known, it is feature complete,
documentation written.</p>
<p>But wouldn’t it be nice to have a logical not?</p>
<p>Sigh. This was the last operation added. Another round of code churn,
expressions are difficult to rewrite because they are both obscure and
relatively tight. But changing around the stable initialization code –
by now the largest piece of logic – yielded the necessary bytes, and
improved obscurity by double duty encoding of the operations
initialization.</p>
<p>The utility is now truly functional, and feature complete, and
obscure. Without <a href="src.doc.txt">src.doc.txt</a> (basic
documentation of the code structure), and some commented expanded logic
stashed away, and the familiarity I have with the code having written
and revised it repeatedly, I would not even want to attempt to decipher
the logic. Many times in the debugging, I was thwarted by my own
relatively tight. But changing around the stable initialization code – by now
the largest piece of logic – yielded the necessary bytes, and improved
obscurity by double duty encoding of the operations initialization.</p>
<p>The utility is now truly functional, and feature complete, and obscure. Without
<a href="src.doc.txt">src.doc.txt</a> (basic documentation of the code structure), and some
commented expanded logic stashed away, and the familiarity I have with the code
having written and revised it repeatedly, I would not even want to attempt to
decipher the logic. Many times in the debugging, I was thwarted by my own
obfuscations, and went down blind paths in trying to fix a bug or add
functionality. Now I think I have a good entry.</p>
<p>But wouldn’t it be nice to import pre-set definitions from a
file?</p>
<p>But wouldn’t it be nice to import pre-set definitions from a file?</p>
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<!-- START: this line starts content from: inc/after-content.default.html -->
+23 -30
View File
@@ -121,41 +121,34 @@
<!-- START: this line starts content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->
<h3 id="spoilers">Spoilers</h3>
<p><code>calc</code> is a recursive-descent parser. It allocates from
the stack deep enough that all expressions are exhausted before the
recursion stack depth reaches the allocations. The memory map and source
is documented in <a href="src.doc.txt">src.doc.txt</a>. Tokens are
encoded using values 0-20, where 0 is an invalid token, 1 is minus, 2 is
space, 3 is plus, etc. The necessary constants are derived at the start
of the program, using the guarantee that globals are initialized to
zero; so a correct NULL pointer is obtained from an uninitialized global
pointer variable, and the integers from uninitialized global
<code>int</code> variables. If <code>x</code> is a global
<code>int</code>, then <code>!x</code> is <code>1</code>, and the
derivation proceeds from there, using some identities that are
confusingly similar and interestingly combined (increasing
obfuscation):</p>
<p><code>calc</code> is a recursive-descent parser. It allocates from the stack deep enough
that all expressions are exhausted before the recursion stack depth reaches the
allocations. The memory map and source is documented in
<a href="src.doc.txt">src.doc.txt</a>. Tokens are encoded using values 0-20, where 0 is an
invalid token, 1 is minus, 2 is space, 3 is plus, etc. The necessary constants
are derived at the start of the program, using the guarantee that globals are
initialized to zero; so a correct NULL pointer is obtained from an uninitialized
global pointer variable, and the integers from uninitialized global <code>int</code>
variables. If <code>x</code> is a global <code>int</code>, then <code>!x</code> is <code>1</code>, and the derivation
proceeds from there, using some identities that are confusingly similar and
interestingly combined (increasing obfuscation):</p>
<pre><code>obc clr
--- ---
-~x x+1
~-x x-1
y-~x y+x+1</code></pre>
<p>The derived constants are a compromise between simple expressions,
maximum utility, and minimum number of variables used.</p>
<p>Command line arguments are copied into the upper half of the input
buffer, separated by a space. This allows the code to have a single
input parser by using a pointer-to-func to either
<code>getchar(3)</code> if live, or a <code>getchar(3)</code>
simulator.</p>
<p>A small amount of obfuscation comes from <code>void</code> functions
declared <code>int</code>, but missing <code>return</code>. This is
necessary to allow these functions in ternary <code>?:</code>
expressions and paired with <code>&amp;&amp;</code> and <code>||</code>;
but the requisite returns would add symbol count at no benefit to
obscurity or functionality. Function decomposition was mostly chosen to
avoid curly braces: if a <code>for</code>-loop required multiple
statements, the body became a new function. Last, but not least: sharing
state via global variables is an ancient and honored form of
<p>The derived constants are a compromise between simple expressions, maximum utility,
and minimum number of variables used.</p>
<p>Command line arguments are copied into the upper half of the input buffer,
separated by a space. This allows the code to have a single input parser by using
a pointer-to-func to either <code>getchar(3)</code> if live, or a <code>getchar(3)</code> simulator.</p>
<p>A small amount of obfuscation comes from <code>void</code> functions declared <code>int</code>, but
missing <code>return</code>. This is necessary to allow these functions in ternary <code>?:</code>
expressions and paired with <code>&amp;&amp;</code> and <code>||</code>; but the requisite returns would add
symbol count at no benefit to obscurity or functionality. Function
decomposition was mostly chosen to avoid curly braces: if a <code>for</code>-loop required
multiple statements, the body became a new function. Last, but not least:
sharing state via global variables is an ancient and honored form of
obfuscation, and remarkably effective.</p>
<!-- END: this line ends content for HTML phase 21 by: bin/pandoc-wrapper.sh via bin/md2html.sh -->