I benefit immensely from code other people give away. Hopefully someone else can benefit from these offerings.
You're welcome to download, examine and use my work any way you feel like, bearing in mind that it might not do what I say it does. I do not guarantee this code works as I say it does, nor do I guarantee that you can even read it.
I run Unix-like operating systems at home, including Linux and NetBSD. The programs I write work under those operating systems. If you run anything else, this code may only interest you in an academic sense. I urge you to consider switching to Linux or NetBSD if you run anything else.
Email me
some comments
Return to my home page and read stimulating
articles I wrote.
My favorite awk scripts, right here, right now! No download necessary, just cut-n-paste!
#!/bin/sh
# This costs memory two ways: (1) sort has to buffer up everything somehow, and
# awk has to have a huge array in-memory.
sort -n |
awk 'BEGIN{c=0;sum=0;}/^[^#]/{a[c++]=$1;sum+=$1;}END{ave=sum/c;if((c%2)==1){median=a[int(c/2)];}else{median=(a[c/2]+a[c/2-1])/2;}print sum," ",c," ",ave," ",median," ",a[0]," ",a[c-1]}'
Source code for an assembler. It runs under the NetBSD/sparc 1.1 operating system. It assembles the "suggested assembly syntax" for SPARC instruction set architecture version 8. I wrote an article describing the assembler. This code may interest you if you think you need a parser and/or lexer for SPARC assembly language. It includes a YACC grammar and flex-based lexer for that language.
Source code for a program to print out the headers, relocation data and symbol table for a NetBSD/sparc 1.1 object file. You could probably get it to work on SunOS 4.1.x object files with only a small amount of work.
Source code for Solaris 2.3, SPARC V8 instruction set architecture disassembler.
This program stars in a technical report by Cristina Cifuentes and Norman Ramsey.
The paper is titled Measuring the Cost of Decoding Machine Instructions in Software - Hand-crafted vs Automatically-generated Decoders.
Cifuentes and Ramsey have this to say about elfdis:
This is a standalone disassembler that implements an ELF loader and a decoder of SPARC machine instructions; it does not handle flow of control or produce an intermediate representation [...] The code is clearly modularized, and 4 different modules ... deal with the decoding of the instructions.
Even though my disassembler is the "before" exhibit in this paper, it comes out a bit faster than Cifuentes & Ramsey's automatically generated disassembler. My disassembler takes 0.000368 seconds to disassemble a SPARC instruction, while theirs takes 0.000389 seconds.
You may find Norman Ramsey's SPARC disassembler more interesting. Ramsey based that disassembler on the NJ Machine code tool kit.
You may also find this SPARC disassembler interesting.
You can find disassemblers for other architectures (mostly Intel x86) at the Disassembler home page.
The files neccessary to get lcc version 3.6 running under NetBSD/sparc 1.1. Here's the README file. In addition to NetBSD/sparc 1.1, and this distribution, you'll need lcc-3.6 and Perl. This port is not perfect. It has a few problems.
New! Version 2.10 as of 2001-07-09.
I use this HTTP request generator to:
- Accurately time HTTP requests.
- Reproducibly generate arbitrary HTTP POST requests to trigger CGI-BIN program bugs.
- Generate incorrect HTTP requests to test an HTTP server's abilities.
- Collect the HTML a server gives back.
- Examine HTTP protocol headers returned by a server (a help in times of mime-type crises).
I tried to make this request generator very robust. It makes every effort to generate some output before exiting for every circumstance.
I composed tests specifically to exercise as much of the code as possible: of 227 basic blocks, my tests executed all but 40. I checked memory leaks using dmalloc and memory access using efence.
I've built this program under:
Jef Poskanzer wrote http_get, a program very similar to my HTTP request generator. Jef Poskanzer also wrote WebCat and WebPost, which do pretty much the same thing, but are written in Java.
WebCopy is a Perl program that can recursively retrieve the contents of any web page and its links.
SWebget "does nothing else but get you a webpage and prints it to stdout"
cURL - a client that groks URLs is said to be a similar program that understands HTTP, FTP and GOPHER protocols. Said to compile under Win32 as well as on most Unixes.
Snarf "is a command line resource grabber. It can transfer files through the http, gopher, finger, and ftp protocols without user interaction."
Greed connects to a web site or FTP site and downloads files for you and supports resuming.
Pagesucker is "a little program which will download a web page from a remote web server, from details you pass through the command line, of in a file, which is a list of webservers, paths and an output file name".
Laurent Demailly has quite a few WWW tools, including a tiny HTTP server and client in Tcl.
This sh script examines command lines, environment variables, HTTP methods and url-encoded data. It generates HTML that may inform you of the reasons why your CGI-BIN programs work the way they do. I find this script indispensable when working with HTML forms and the CGI-BIN programs that interact with them.
Tested under:
To install:
You probably don't want to install this program on a web server available to the entire Internet. It gives away a lot of information invaluable not only to the CGI-BIN programmer, but also to system crackers.
Serve File Not Found messages with the HTTP 404 server.
This program understands a very small part of the HTTP protocol (RFC 1945). It uses this knowledge to respond to every incoming HTTP request with the beloved "404 - File Not Found" error message.
This server complements the HTTP request generator above. It lets you view the HTTP request headers generated by browsers or Web Spiders, and record those headers along with the time of the request.
I've compiled and tried this program under:
The 404 Server is not terrifically well-tested on any of the platforms listed above. The distribution lacks any documentation, including only a ".c" file and a makefile. Consider it an alpha release.
Other people's small or limited scope HTTP servers:
This program reads a file containing concatenated usenet articles. For each usenet article it finds in the input file, it creates a headers file and a body file in separate directories. It puts the headers lines of the article it just found in one file, and the body text of the article in the other file. It names the two files after the "Message-ID:" line found in the that article's header lines.
It has problems with usenet articles that contain unquoted usenet articles. It will incorrectly break the unquoted included article into its own seperate file. I don't think this problem has a solution, though.
I believe that one could modify it to break up "mailbox" files, too. To do this, one would add another header line to the lex specification: the lexer should consider all lines beginning with From as header lines.
ANSI C allows a programmer to use any legal identifier in at least 5 different contexts in the same scope. This program illustrates the use of the identifier list in all those contexts. Works great under Solaris 2.5.1, NetBSD's gcc 2.4.5, 2.7.2.2, SuSE linux's GCC 2.95.3, lcc 4.27 under linux, and finer C compilers everywhere.
Please email me if you find or know of another way to use a particular, legal identifier.
I read M-J. Dominus' article Perl contains the λ-calculus right as I encountered Python's nested functions. It occurred to me that Python also contains the λ-calculus, in exactly the same way that Perl does, as well as actually having "lambda" to make anonymous functions. So, I wrote a script that proves it. This script creates Church Numerals, a Y-combinator, and an addition function, all without an explicity "lambda:" keyword.
This shell script prints an "evolved" version of itself on stdout. Use it like this:
| % chmod 555 replicate |
| % replicate > r2 |
| % chmod 555 r2 |
| % r2 > r3 |
| % diff replicate r2 |
| % diff r2 r3 |
This Python program rather imaginatively prints a version of itself on stdout. Use it like this:
| $ python ./self_replicating.py > r2.py |
| $ python ./r2.py > r3.py |
| $ diff self_replicating.py r2.py |
| $ diff r2.py r3.py |
No differences should appear. This code appears mainly as a Python transliteration of a self-replicating sh script. Not too modern, and not even very difficult. Therefore, I have written a most remarkably improved Object Oriented self-replicating python program.
In a most modern, object oriented way, this Python program prints a version of itself on stdout. Use it like this:
| $ python ./objectOrientedSelfReplication.py > r2.py |
| $ python ./r2.py > r3.py |
| $ diff objectOrientedSelfReplication.py r2.py |
| $ diff r2.py r3.py |
No differences should appear. This particular program should satisfy even the most pure of object oriented purists' need for a self-replicating program.
This wee curiosity emulates ferns that have alternation of generations.
| $ python ./self_rep_alternating.py > a.py |
| $ python ./a.py > b.py |
| $ python ./b.py > c.py |
| $ cksum self_rep_alternating.py [abc].py |
You should see checksums that indicate that files self_rep_alternating.py and b.py have the same contents, and that a.py and c.py have identical contents.
This doesn't truly match the way ferns alternate generations, but it does prove that art can imitate nature.
This curiosity, written in reasonably strict C, contains a function which relocates itself in memory.
This code started life under SunOS 4.0.3 on a M68020 based Sun 3/260. Since then, I have compiled and run it under quite a few Unix variants (at least SunOS, Solaris, Ultrix, NeXTStep, Irix, NetBSD). It works on hardware ranging from an M68010, SPARC, Mips R2000, R3000, R4000, and many others. It probably won't work on M68040 or Alpha CPUs without in-line assembly code to flush those CPU's instruction caches.
It will probably never work on Hewlett-Packard's ghastly HP-PA CPU because of that architecture's poorly-documented segmentation.
Amuse yourself with my SPARC assembler language "hello world" program.
This constitutes my efforts at producing the smallest possible "hello world" program. The program prints the phrase "Hello, World!" on stdout, then exits with a zero status.
It assembles and runs under:
The final executable varies between 88 bytes (SunOS and NetBSD) and 364 bytes (Solaris 2.5.1).
An example of how to use the SPARC V8 "ldstub" instruction to implement a mutex lock between two or more processes.
This compiles and runs under Solaris 2.6 on a 2-CPU SPARCStation 10. I think you could easily get it to work on any SPARC V8 machine that runs an OS that supports System V shared memory.
Edmund Ronald put out a puzzle called Quinto in 1991. He wrote it in Objective-C for the old NeXTStep GUI. I did a rework of that puzzle, transforming it into Tcl/Tk.
Edmund Ronald's original Readme:
QuintoQuinto is a game. The board is a 5*5 array of buttons, pressing one toggles its' state and that of its 4 neighbors.
The aim of the game is to highlight all the buttons.
My friend John Horton Conway, who knows some mathematics, took a few hours to solve this back in the early eighties. Other people tend to take slightly longer.
I hid one solution I found (almost certainly not the shortest) as comments in the source code.
I wrote the Tcl/Tk version under Red Hat Linux 5.0 for Alpha, which apparently means Tcl 8.0 and Tk 8.0. I also tested under NetBSD/Sparc 1.1, Tcl 7.6, Tk 4.2., and Solaris/Sparc 2.5.1. I tried it under twm, gwm, dtwm (ugh!) and fvwm-2 window managers. It seems to work the same for all permutations.
You may have to change the path to wish in the first line of the Tcl/Tk program.
I wrote a small, yacc and lex based programmer's calculator, along the lines of bc, but without variables or flow-of-control. Why do I call it a "programmer's" calculator? It accepts input in hex, octal, decimal or binary, and you can mix up the formats. It has a full set of bitwise operators, including left and right shift, and complement. Its has operator precedence identical to that of the C programming language, so that you can cut-n-paste a tricky expression from a C program into a "spine" instance to see what the expression evaluates to.
Spine should compile and work on any unix-like operating system that has yacc and lex (or byacc and flex), like Linux, Solaris or NetBSD.
These pages are designed to be informative and not to win any "cool site of the week" awards.
Last update: Tue Apr 8 14:44:28 MDT 2003