IOCCC image by Matt Zucker

The International Obfuscated C Code Contest

2000/dlowe - Worst abuse of the rules

A dc-style calculator that uses embedded Perl

Author:

To build:

    make

The following bit of perl may help determine the values you need:

    perl -MConfig -e 'print "$Config{archlibexp}/CORE\n"'

… just in case the Makefile does not figure this out for you.

Bugs and (Mis)features:

The current status of this entry is:

STATUS: known bug - please help us fix
STATUS: INABIAF - please DO NOT fix

For more detailed information see 2000/dlowe in bugs.html.

To use:

    ./dlowe [file ...]

Try:

    ./try.sh

Judges’ remarks:

When this entry was submitted the rules of the IOCCC did not prohibit the use of embedded language interpreters. The judges considered disqualifying this entry because of the use of perl, but on the other hand it qualifies as the Worst Abuse of the Rules. As a previous author, David Lowe continues to inflict the highest quality “poot” on the Judges.

The program also contains an undocumented command for Chad and Chongo (Landon). The judges’ remarks contain a clue to the hidden command :-).

Author’s remarks:

Usage

    ./dlowe [file ...]

Synopsis

This is a Reverse Polish calculator, loosely based on the dc(1) unix calculator.

Syntax

This program understands the following dc(1) commands:

And the following arithmetic operators are supported:

The precision and range are double, like it or not, except that the modulus operator actually returns (p1 - (p2 * (p1 / p2))), but with the innermost division calculated at integer precision. This is usually what you expect (e.g. echo "12 8 % p" | ./dlowe == 4)

Commands are read from stdin or from a list of files named on the command line. Unlike dc(1), multiple commands on the same line must be space separated. Commands are only executed when a newline or EOF is encountered.

Diagnostics:

Examples:

    $ echo '12 13 14 15 16 + + + + f' | ./dlowe
    70
    $ echo '12 13 14 15 16 17 + - * / p' | ./dlowe
    -0.0515873015873016
    $ echo '+' | ./dlowe
    stack empty
    $ echo '999999999999999 1 + p' | ./dlowe
    1e+15
    $ echo '99999999999999 1 + p' | ./dlowe
    100000000000000
    $ echo '12.5 9 % 10 * 15 + f' | ./dlowe
    50
    $ echo '7 P 6 d P P 8 p' | ./dlowe | tr 876 tpo
    poot

Code Concept:

We all know that Perl and other VHLLs (very high level languages) are particularly well-suited for (among other things) string handling, I/O, and powerful built-in data types, and (relatively) poorly suited for number crunching and other processor-intensive tasks - areas where C is strongest. This program takes this knowledge to its extreme conclusion, using each language for its strengths. Thus, it uses Perl to read and parse input, for output, and for the easy-to-use list primitive, and uses C for mathematical operations. Since the rules of this contest state that the program must be generated by an ANSI C compiler, of course, the outer Perl layer is wrapped with a thin layer of C.

In case that wasn’t clear, in a nutshell: this program is C, calling embedded Perl (contained in a C string), which in turn calls back to C, which performs math on Perl data types and calls Perl functions for error reporting.

Requirements:

Unfortunately, Perl is an evolving beast - that includes the embedding API and the XS API. The code was developed under Perl 5.005_03, successfully tested against Perl 5.6.0, Perl 5.005_02 and Perl 5.004_04, and according to the version delta documentation, should work as-is with Perl 5.002 and later (which has been around since February 1996). To clarify - it’s not the Perl code itself that may be non-portable, it’s the C code for embedding Perl and for calling C from Perl.

It is also important that Perl be installed cleanly and correctly. You may have problems linking if, for example, you have multiple overlapping versions of Perl installed (which might not be a problem for scripts, but causes problems with embedding the interpreter). More commonly, you may get non-fatal warnings from the linker, caused by slight mis-configurations of Perl on your system.

Some compilers also complain that “third argument of main() is deprecated” or something to that effect. But in Perl prior to 5.6.0, the header file “proto.h” actually had a prototype for main(), so applications which embed Perl must use the three argument form of main().

Aside: history…

Larry Wall wrote the original Perl in 1986-87, the same two successive years he won the IOCCC. I hope this program helps you to realize that this was no fluke - that Perl and Obfuscation are as inseparable as, say, camels and humps.

Obfuscated?

Aside: on unobfuscated Perl

My original intent was to write obfuscated C and crystal-clear Perl, to highlight my bending of the rules. Unfortunately, Perl really doesn’t lend itself to crystal-clear code…

Bending the rules?

Well, the rules never state that you can’t embed another programming language, but on the other hand, knowing Perl probably isn’t high on the list of qualifications for judges… Oh dear, I guess your C beautifier won’t help too much, either ;)

If you don’t change the rules, it’ll be embedded Ada next year!

Auto defend

  1. Isn’t this the obfuscated C contest? What’s this Perl $#_&&$_?

  2. Hey, this program is 100% C, and does not exec an external Perl interpreter. It simply links against the Perl language library. The “Perl code” is just a C string constant.

  3. Perl isn’t portable enough, or ubiquitous enough.

  4. I’d argue that it is more portable than X. According to the Perl folks, it runs on the following platforms: Acorn, AIX, Amiga, AS/400, BeOS, Concurrent, Debian, DEC OSF/1, Digital UNIX, EPOC, FreeBSD, Guardian, HP-UX, IRIX, LinuxPPC, LynxOS, MacOS, MachTen, Minix, MPE/iX, MS-DOS, MVS, NetBSD, Netware, NextStep, OpenBSD, OpenLinux, ODT, OpenVMS, OS/2, OS390, OSR, PowerMAX, Psion, QNX, Redhat, Reliant UNIX, RISCOS, SCO, SGI, SINIX, Slackware, Solaris, Sun, SuSE, Tandem, Tru64, UNIX, U/WIN, Unixware, VMS, Win31, Win32, Windows 3.1, and Windows 95/98/NT/2K. Granted, embeddable Perl isn’t quite so portable, but still…

Also, Perl 5 is bundled with the following OS distributions: AIX 4.3.3+, FreeBSD 3.0+, IRIX 6.4+, every Linux distribution, NetBSD, OpenBSD, and DEC Tru64 5.0+, again according to the Perl people.

Inventory for 2000/dlowe

Primary files

Secondary files


Jump to: top