The Boston Diaries

The ongoing saga of a programmer who doesn't live in Boston, nor does he even like Boston, but yet named his weblog/journal “The Boston Diaries.”

Go figure.

Monday, January 09, 2012

99 ways to program a hex, Part 1: The Standard

For Christmas, Hoade gave me 99 Ways To Tell A Story: Excercises in Style, an interesting book whereby the same story (an eight panel cartoon about a guy walking to the refrigerator and forgetting what he was going to look for) ninety-nine different ways; a different style, a different genre, different number of panels, whatever. Ninety-nine different ways.

It got me to thinking. While the book was about different ways to present a story, what about programming? Okay, other than sounding completely insane, could a program be written ninety-nine different ways?

An easy way is a different computer language for each version. Sure, there's CPL, BCPL, B, C (four variations there—K&R, C89, C99, C11), C++ (C++, C++9x, C++2x), Objective-C, D, Fortran (many versions over the years), BASIC (just about every computer made between 1975 and 1985 came with its own dialect of BASIC, along with the original Dartmouth version), Algol (Agol 60, Algol 68), Pascal (Pascal, Turbo Pascal, Delphi), Assembly (basically each CPU architecture has its own form, for instance the 6502, 6800, 6809, 68000 (which has variant), 8080, Z80, 8086 (all the way up to the latest Pentium 4), MIPS (which has variants), SPARC (and variants), ARM (and variants), PDP-1, PHP-7, PHP-8, PHP-10, PHP-11, VAX) Forth (just as many dialects as BASIC), Modula (Modula and Modula-II), SNOBOL, ICON, Hope, bash, sh, csh, ksh, VIth, Alice, Pilot, COBOL, Intercal, Perl (several major variations), Piet, Python (Python 1, Python 2, Python 3), PHP (practically every version ever released), awk, Ruby (nearly every version ever released), Lua (several versions), Malbolge, Java (several major revisions), Lisp (Lisp, Lisp 1.5, MACLISP, Common Lisp, Scheme (I know! I know! It's not Lisp, even though it has the same syntax and pretty much the same command set, it's a LISP1 and Common Lisp is a LISP2 (and if you have to ask, you'll have to take a few graduate programming courses to understand))), Erlang, Prolog, Haskel, ML, Oberon, LOLCODE, Befunge, Chef, BrainXXXX and that alone will probably get us to 99 versions right there.

But I don't have access to a lot of these languages. Heck, most of them are dead, obscure or esoteric and trying to even find examples would be difficult. Especially since what I want to do is more than just a simple “Hello World” program. I want to write a program that is actually useful, but not so long as to make this insane project … um … insaner.

So I'm going to try just a few languages (which still leaves me with plenty to choose from; my home system alone comes with C, Ruby 1.8, Perl 5.8, Python 2.3, Python 2.6, PHP 5.1, Lua 5.1, C++, sh, bash, awk, 68000 assembler, x86 assembler and probably a few I'm forgetting about. I might not hit all of these, or maybe I will. We'll see.

And the program I selected for this insanity silly treatment is a small utility I wrote back in the early 90s when I first learned C—it's a program that dumps data in hexadecimal:

/*************************************************************************
*
* Copyright 1991 by Sean Conner.  All Rights Reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*
* Comments, questions and criticisms can be sent to: sean@conman.org
*
*************************************************************************/

/* Style: Original Version, C89 */

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>

#define LINESIZE	  16

static void 	do_dump		(FILE *,FILE *);

/****************************************************************/

int main(int argc,char *argv[])
{
  if (argc == 1)
    do_dump(stdin,stdout);
  else
  {
    int i;
    
    for (i = 1 ; i < argc ; i++)
    {
      FILE *fp;
      
      fp = fopen(argv[i],"rb");
      if (fp == NULL)
      {
        perror(argv[i]);
        continue;
      }

      printf("-----%s-----\n",argv[i]);
      do_dump(fp,stdout);
      fclose(fp);
    }
  }

  return EXIT_SUCCESS;
}

/******************************************************************/

static void do_dump(FILE *fpin,FILE *fpout)
{
  unsigned char  buffer[BUFSIZ];
  unsigned char *pbyte;
  size_t         offset;
  size_t         bread;
  size_t         j;
  char           ascii[LINESIZE + 1];
  
  offset = 0;

  while((bread = fread(buffer,1,BUFSIZ,fpin)) > 0)
  {
    pbyte = buffer;
    while (bread > 0)
    {
      fprintf(fpout,"%08lX: ",(unsigned long)offset);
      j = 0;
      do
      {
        fprintf(fpout,"%02X ",*pbyte);
        if (isprint(*pbyte))
          ascii [j] = *pbyte;
        else
          ascii [j] = '.';
        pbyte  ++;
        offset ++;
        j      ++;
        bread  --;
      } while ((j < LINESIZE) && (bread > 0));
      ascii [j] = '\0';
      if (j < LINESIZE)
      {
	size_t i;

	for (i = j ; i < LINESIZE ; i++) fprintf(fpout,"   ");
      }
      fprintf(fpout,"%s\n",ascii);      
    }
    
    if (fflush(fpout) == EOF)
    {
      perror("output");
      exit(EXIT_FAILURE);
    }
  }
}

/***************************************************************/

This is the current version of the program, written in C89. There's not much to say about this—it's straight forward, does one thing, does it well, and we'll see just how far I can take this version.

Obligatory Picture

Trying to get into the festive mood this year

Obligatory Contact Info

Obligatory Feeds

Obligatory Links

Obligatory Miscellaneous

Obligatory AI Disclaimer

No AI was used in the making of this site, unless otherwise noted.

You have my permission to link freely to any entry here. Go ahead, I won't bite. I promise.

The dates are the permanent links to that day's entries (or entry, if there is only one entry). The titles are the permanent links to that entry only. The format for the links are simple: Start with the base link for this site: https://boston.conman.org/, then add the date you are interested in, say 2000/08/01, so that would make the final URL:

https://boston.conman.org/2000/08/01

You can also specify the entire month by leaving off the day portion. You can even select an arbitrary portion of time.

You may also note subtle shading of the links and that's intentional: the “closer” the link is (relative to the page) the “brighter” it appears. It's an experiment in using color shading to denote the distance a link is from here. If you don't notice it, don't worry; it's not all that important.

It is assumed that every brand name, slogan, corporate name, symbol, design element, et cetera mentioned in these pages is a protected and/or trademarked entity, the sole property of its owner(s), and acknowledgement of this status is implied.

Copyright © 1999-2024 by Sean Conner. All Rights Reserved.