]> thyrsus.com Git - morse-classic.git/commitdiff
Save the released 2.0 version.
authorEric S. Raymond <esr@thyrsus.com>
Mon, 24 Jan 2005 20:48:23 +0000 (20:48 +0000)
committerEric S. Raymond <esr@thyrsus.com>
Mon, 24 Jan 2005 20:48:23 +0000 (20:48 +0000)
alarm.c [deleted file]
alarm.h [deleted file]
beep.h [deleted file]
beepLinux.c [deleted file]
beepOSS.c [deleted file]
beepX11.c [deleted file]
morse.c [deleted file]

diff --git a/alarm.c b/alarm.c
deleted file mode 100644 (file)
index 25eb9cf..0000000
--- a/alarm.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/* alarm.c -- wakeup calls */
-
-/*
--- Implementation of alarm.h
-*/
-
-#include <stdio.h>
-#include <signal.h>
-#include <sys/time.h>
-
-static int alarmPending = 0;  /* Nonzero when the alarm is set. */
-
-static void ualarm();
-static void AlarmHandler();
-
-void AlarmSet(time)
-    int time;
-{
-    alarmPending = 1;
-    sigset(SIGALRM, AlarmHandler);
-    ualarm(1000 * time, 0);
-}
-
-/*
--- If an alarm signal is lurking (due to a prior call to SetAlarm), then
--- pause until it arrives.  This procedure could have simply been written:
---   if (alarmPending) pause();
--- but that allows a potential race condition.
-*/
-void AlarmWait()
-{
-    sighold(SIGALRM);
-    if (alarmPending)
-      sigpause(SIGALRM);
-    sigrelse(SIGALRM);
-}
-
-
-static void ualarm(us)
-    unsigned us;
-{
-    struct itimerval rttimer, old_rttimer;
-
-    rttimer.it_value.tv_sec  = us / 1000000;
-    rttimer.it_value.tv_usec = us % 1000000;
-    rttimer.it_interval.tv_sec  = 0;
-    rttimer.it_interval.tv_usec = 0;
-    if (setitimer(ITIMER_REAL, &rttimer, &old_rttimer)) {
-       perror("ualarm");
-       exit(1);
-    }
-}
-
-
-static void AlarmHandler()
-{
-    alarmPending = 0;
-}
diff --git a/alarm.h b/alarm.h
deleted file mode 100644 (file)
index 33a5fb1..0000000
--- a/alarm.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/* alarm.h -- wakeup call interface */
-
-/*
--- Routines for using the system interval timer to time beeps.  Useful
--- for implementing the functions in beep.h on systems that don't provide
--- a more straightforward BeepWait() equivalent.
---
--- These routines use the ALRM signal.
-*/
-
-
-/*
--- Set the alarm for a time specified in ms.
-*/
-void AlarmSet(time_t);
-
-/*
--- Wait for the alarm, or return immediately if the alarm isn't set.
-*/
-void AlarmWait(void);
diff --git a/beep.h b/beep.h
deleted file mode 100644 (file)
index 7e1796b..0000000
--- a/beep.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/* beep.h -- seligman 5/92 */
-
-/*
--- Machine-dependent code for sounding a beep.
-*/
-
-#ifndef _BEEP_H
-#define _BEEP_H
-
-
-/*
--- Called exactly once, before any other function in this interface.
--- Returns nonzero on error.
-*/
-int BeepInit(void);
-
-
-/*
--- Sound a beep for a time specified in ms.
--- The volume is in the range [0..100], and the pitch is in Hz.
---
--- May return immediately, after the sounding of the beep is completed,
--- or any time in between.  May be called while a previous beep is still
--- sounding, in which case the previous beep finishes before the new one
--- begins. Overall timing will be much better if this routine can return
--- during the sounding of the beep, especially if it's a "zero-volume beep",
--- meaning it's really just the timed pause of silence between tones.
--- ("morse.c" tries to do all its thinking during the pauses between beeps,
--- mostly in the longer ones between words.)
---
--- May use the ALRM signal for timing.
---
--- Returns nonzero on error.
-*/
-int Beep(int time, int volume, int pitch);
-
-
-/*
--- Wait until any currently sounding beeps have completed.
--- Returns nonzero on error.
-*/
-int BeepWait(void);
-
-
-/*
--- Clean up any altered state before exiting or suspending the program.
--- Returns nonzero on error.
-*/
-int BeepCleanup(void);
-
-
-/*
--- Restore the world when program is resumed after having been suspended.
--- Returns nonzero on error.
-*/
-int BeepResume(void);
-
-
-#endif /* _BEEP_H */
diff --git a/beepLinux.c b/beepLinux.c
deleted file mode 100644 (file)
index add29bb..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * From: jmorriso@bogomips.ee.ubc.ca (John Paul Morrison)
- * Subject: beepLinux.c
- * To: joe@montebello.soest.hawaii.edu
- * Date: Fri, 18 Nov 1994 15:32:33 -0800 (PST)
- * X-Linux: watch for it: Linux 94 aka "Helsinki"
- * 
- * beepLinux.c for morse (lightly tested, seems to work fine)
- */
-
-/*
- * beep for the Linux console (PC Speaker) 
- *
- * (beepSun.c might work if you have a sound card installed and /dev/audio)
- *
- * by John Paul Morrison <jmorriso@ve7jpm.ampr.org>
- *
- */
-
-/* beepLinux.c -- 11/94 */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/kd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include "alarm.h"
-#include "beep.h"
-
-
-static int fd;
-
-int BeepInit()
-{
-  if ((fd = open("/dev/console",O_WRONLY)) == -1)
-    {
-      fprintf(stderr,"You have no permissions to use /dev/console (chmod a+w).\n");
-      return 1;
-    }
-  return 0;
-}
-
-int Beep(time, volume, pitch)
-int time, volume, pitch;
-{
-    int count;
-
-    AlarmWait();
-    if (volume == 0)
-       count = 0;
-    else
-       count = (1193180 / pitch) & 0xffff;
-
-    ioctl(fd, KDMKTONE, (time << 16) | count);
-    AlarmSet(time); 
-    return 0;
-}
-
-int BeepWait()
-{
-    AlarmWait();
-    return 0;
-}
-
-int BeepCleanup()
-{
-    close(fd);
-    return 0;
-}
-
-int BeepResume()
-{
-    return 0;
-}
-
-/*
- * ---------------------------------------------------------------------------
- * BogoMIPS Research Labs  --  bogosity research & simulation  --  VE7JPM  -- 
- * jmorriso@bogomips.ee.ubc.ca ve7jpm@ve7jpm.ampr.org jmorriso@ve7ubc.ampr.org
- * ---------------------------------------------------------------------------
- */
diff --git a/beepOSS.c b/beepOSS.c
deleted file mode 100644 (file)
index 6573539..0000000
--- a/beepOSS.c
+++ /dev/null
@@ -1,207 +0,0 @@
-/* beepOSS.c -- Jacek M. Holeczek 3/2000 */
-/* A lot of code taken from the beepSun.c */
-
-/*
-  Implementation of beep for the Open Sound System /dev/dsp device.
-*/
-
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <sys/soundcard.h>
-#include <math.h>
-
-#include "beep.h"
-
-#define DEVICE_NAME "/dev/dsp"
-#define RATE   (8000)  /* 8 K samples = 1 second */
-#define RAMP   (RATE * 5 / 1000)       /* 5 millisecond ramp */
-#define MAXTIME        (2 * RATE)      /* 2 seconds max tone time */
-
-static int audio = 0;
-static int channels = 0; /* 1=mono, 2=stereo */
-static unsigned char silence[2*MAXTIME];
-static unsigned char soundbuf[2*(MAXTIME - RAMP)];
-static unsigned char ramp_down[2*RAMP];
-
-int BeepInit (void)
-{
-  int i;
-  
-  /*
-   * Initialize the sound of silence
-   */
-  for (i = 0; i < 2*MAXTIME; i++)
-    silence[i] = 128;
-  
-  audio = open(DEVICE_NAME, O_WRONLY, 0);
-  if (audio < 0)
-    {
-      return 1; /* not o.k. */
-    } else {
-      
-      i = 0x00ff0008; /* 255 fragments, 256 bytes each */
-      if (ioctl(audio, SNDCTL_DSP_SETFRAGMENT, &i))
-       {
-         fprintf(stderr, "SNDCTL_DSP_SETFRAGMENT error : 0x%08x\n", i);
-         return 2;
-       }
-      
-      channels = 1; /* 1 channel = mono */
-      if (ioctl(audio, SNDCTL_DSP_CHANNELS, &channels)==-1)
-       {
-         fprintf(stderr, "SNDCTL_DSP_CHANNELS error : %i\n", channels);
-         return 3;
-       }
-      if (channels != 1)
-       {
-         channels = 2; /* 2 channels = stereo */
-         if (ioctl(audio, SNDCTL_DSP_CHANNELS, &channels)==-1)
-           {
-             fprintf(stderr, "SNDCTL_DSP_CHANNELS error : %i\n", channels);
-             return 4;
-           }
-       }
-      if (!(channels == 1 || channels == 2))
-       {
-         fprintf(stderr, "Neither mono nor stereo mode could be set.\n");
-         return 5;
-       }
-      
-      i = AFMT_U8; /* standard unsigned 8 bit audio encoding */
-      if (ioctl(audio, SNDCTL_DSP_SETFMT, &i)==-1)
-       {
-         fprintf(stderr, "SNDCTL_DSP_SETFMT error : %i\n", i);
-         return 6;
-       }
-      
-      i = RATE; /* sampling rate RATE */
-      if (ioctl(audio, SNDCTL_DSP_SPEED, &i)==-1)
-       {
-         fprintf(stderr, "SNDCTL_DSP_SPEED error : %i\n", i);
-         return 7;
-       }
-      
-      write (audio, silence, channels*2);
-      BeepWait();
-      return 0; /* o.k. */
-    }
-}
-
-int Beep (int time, int volume, int pitch)
-{
-  static int      last_pitch = -1, last_n = -1, last_volume = -1;
-  int             i, n, first_len, down_len, cycle;
-  double          dt;
-  
-  /*
-   * Finagle the number of samples
-   */
-  n = (time / 1000.) * RATE;   /* Number samples in tone time */
-  n = n < MAXTIME ? n : MAXTIME;       /* clip to buffer size */
-  n = n < 2 * RAMP ? 2 * RAMP : n;     /* leave room for ramps */
-  
-  /*
-   * Catch stupidity
-   */
-  if (pitch <= 0)
-    volume = 0;
-  
-  if (volume <= 0)
-    {
-      write (audio, silence, channels*n);
-    }
-  else
-    {
-      /*
-       * clip to Nyquist
-       * (Of course this means that if you ask for too high a frequency you
-       * just get silence, since you sample all the zero-crossings of the
-       * sine wave.)
-       */
-      pitch = pitch < RATE / 2 ? pitch : RATE / 2;
-      cycle = ((RATE + 1.e-6) / pitch); /* samples per cycle */
-      
-      if (cycle > MAXTIME / 2)
-       cycle = MAXTIME / 2;
-      
-      /* round down length of (rampup + mesa top) to integral cycle */
-      first_len = ((n - RAMP) / cycle) * cycle;
-      if (first_len < cycle)
-       first_len = cycle;
-      if (first_len > MAXTIME - RAMP)
-       first_len = MAXTIME - RAMP;
-      
-      /* round down length of (rampdown) to integral cycle */
-      down_len = ((RAMP) / cycle) * cycle;
-      if (down_len < cycle)
-       down_len = cycle;
-      if (down_len > RAMP)
-       down_len = RAMP;
-      
-      /*
-       * Can we just reuse what we had before?
-       */
-      if (pitch != last_pitch || n > last_n || volume != last_volume)
-       {
-         last_pitch = pitch;
-         last_n = n;
-         last_volume = volume;
-         
-         dt = 2. * M_PI / cycle;       /* sine scale factor */
-         
-         /* Ramp up; begin with silence */
-         
-         for (i = 0; i < RAMP; i++)
-           {
-             soundbuf[i*channels] = rint( 128. +
-                                          ((float) i / RAMP) * (volume * 1.26) * sin (i * dt)
-                                          );
-             if (channels == 2)
-               soundbuf[i*channels+1] = soundbuf[i*channels];
-           }
-         
-         /* Mesa top */
-         for (i = RAMP; i < first_len; i++)
-           {
-             soundbuf[i*channels] = rint( 128. +
-                                          1. * (volume * 1.26) * sin (i * dt)
-                                          );
-             if (channels == 2)
-               soundbuf[i*channels+1] = soundbuf[i*channels];
-           }
-         
-         /* Ramp down; end with silence */
-         for (i = 0; i < down_len; i++)
-           {
-             ramp_down[i*channels] = rint( 128. +
-                                           (1. - (float) (i + 1) / down_len) * (volume * 1.26) * sin (i * dt)
-                                           );
-             if (channels == 2)
-               ramp_down[i*channels+1] = ramp_down[i*channels];
-           }
-       }
-      
-      write (audio, soundbuf, channels*first_len);
-      write (audio, ramp_down, channels*down_len);
-    }
-  
-  return 0;
-}
-
-int BeepWait (void)
-{
-  ioctl (audio, SNDCTL_DSP_SYNC, 0);
-  return 0;
-}
-
-int BeepCleanup (void)
-{
-  return 0;
-}
-
-int BeepResume (void)
-{
-  return 0;
-}
diff --git a/beepX11.c b/beepX11.c
deleted file mode 100644 (file)
index dc9c444..0000000
--- a/beepX11.c
+++ /dev/null
@@ -1,81 +0,0 @@
-/* beepX11.c -- seligman 5/92 */
-
-/*
--- Implementation of beep.h for X11.
---
--- Compile with the library "-lX11".
-*/
-
-#include <stdio.h>
-#include <X11/Xlib.h>
-#include "alarm.h"
-#include "beep.h"
-
-static Display *dpy = 0;
-static XKeyboardControl initialState;
-
-#define BellFlags (KBBellPercent | KBBellPitch | KBBellDuration)
-
-
-int BeepInit()
-{
-    XKeyboardState state;
-
-    if (! (dpy = XOpenDisplay(0))) {
-       perror("Couldn't open display");
-       return 1;
-    }
-
-    /* Save initial state so it can be restored later. */
-    XGetKeyboardControl(dpy, &state);
-    initialState.bell_duration = state.bell_duration;
-    initialState.bell_percent  = state.bell_percent;
-    initialState.bell_pitch    = state.bell_pitch;
-
-    return 0;
-}
-
-
-int Beep(time, volume, pitch)
-    int time, volume, pitch;
-{
-    XKeyboardControl values;
-
-    AlarmWait();
-
-    if (volume != 0  &&  pitch != 0) {
-       values.bell_duration = time;
-       values.bell_percent  = 100;
-       values.bell_pitch    = pitch;
-
-       XChangeKeyboardControl(dpy, BellFlags, &values);
-       XBell(dpy, volume - 100);
-       XFlush(dpy);
-    }
-
-    AlarmSet(time);
-    return 0;
-}
-
-
-int BeepWait()
-{
-    AlarmWait();
-    return 0;
-}
-
-
-int BeepCleanup()
-{
-    if (dpy != 0) {
-       XChangeKeyboardControl(dpy, BellFlags, &initialState);
-       XFlush(dpy);
-    }
-    return 0;
-}
-
-
-int BeepResume()
-{
-    return 0;
-}
diff --git a/morse.c b/morse.c
deleted file mode 100644 (file)
index 29af690..0000000
--- a/morse.c
+++ /dev/null
@@ -1,1935 +0,0 @@
-/*
- * Copyright (c) 1988 Regents of the University of California.
- * Copyright (c) 1992 Joe Dellinger, University of Hawaii at Manoa
- * Copyright (c) 2005 Eric S. Raymond.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-/*
- * A morse code practice utility. (Contains those characters that can appear
- * on the FCC ham license exam.)
- *
- * Running "morse" without arguments or input gives self-doc.
- *
- * It doesn't keep PERFECT time, but it seems reasonably close
- * for reasonable word speeds on my slow SUN IPC!
- *
- * This code is (ridiculously) heavily modified from morse.c from the Reno UNIX
- * distribution. I (Joe) also used slightly modified versions of a subroutine
- * from Richard Ottolini at Unocal for Sun workstation tone generation.
- * Scott Seligman at Stanford added support for other sorts of devices and
- * made several other changes. John Shalamskas helped test and made comments.
- *
- * For a more detailed history, see the HISTORY file
- */
-
-/*
- * Useful for seeing what the interleaved reading and writing loops are
- * really up to.
- *
- * #define DEBUG
- *
- * If you want to be overwhelmed with information about the probabilities
- * of each letter being chosen.
- *
- * #define DEBUGG
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <ctype.h>
-#include <signal.h>
-#include "beep.h"
-
-#define FREQUENCY      800.0
-#define FREQUENCY2     602.0
-#define VOLUME         0.5
-#define ERROR_VOLUME           0.5
-#define WORDS_PER_MINUTE       20.0
-#define MAX_BEHINDNESS 0
-#define ERROR_FREQUENCY        2000.0
-
-static int      whichfrequ = 0;
-static float    frequency1 = FREQUENCY;
-static float    frequency2 = FREQUENCY2;
-static float    frequency;
-static float    volume = VOLUME;
-static float    dot_time;
-static float    dash_time;
-static float    intra_char_time;
-static float    inter_char_time;
-static float    inter_word_time;
-static float    catchup_time;
-static int      showletters = 0;
-static int      showmorse = 0;
-static int      wordsbefore = 0;
-static int      wordsafter = 0;
-static int      fancyending = 1;
-static int      noticebad = 0;
-static int      testing = 0;
-static int      showtesting = 0;
-static int      keepquiet = 0;
-static int      dynamicspeed = 0;
-static int      charbychar = 0;
-static int     international = 0;
-static int     allprosigns = 0;
-static int     allpunctuation = 1;
-static int      tryagaincount = 1;
-static float    words_per_minute = WORDS_PER_MINUTE;
-static float   error_frequency = ERROR_FREQUENCY;
-static float   error_volume = ERROR_VOLUME;
-static float    fwords_per_minute;
-static int      randomletters = 0;
-#define LETMESEE 2
-static int      typeaway = 0;
-
-static int      totalhitcount = 0;
-static int      totalmisscount = 0;
-static int      helpmeflag = 0;
-
-#define MAXWORDLEN     20
-#define TESTBUFSZ ((MAXWORDLEN+1)*10)
-static int      wordlen = MAXWORDLEN;
-static int      wordcount = -1;
-static time_t   starttime;
-static int      timeout = -1;
-static int      testpointer = -1;
-static int      testlength = 0;
-static int      behindness = 0;
-static int      max_behindness = MAX_BEHINDNESS;
-static char     teststring[TESTBUFSZ];
-static int      yourpointer = -1;
-static int      yourlength = 0;
-static char     yourstring[TESTBUFSZ];
-static int      linepos = 0;
-
-/*
- * How many times can a given character not be asked before
- * kicking up the probability of asking that one by one randomfactor unit.
- */
-#define RIPECOUNT      64
-
-#define TWOFIFTYSIX 256
-static char    *(code[TWOFIFTYSIX]);
-static int      errorlog[TWOFIFTYSIX];
-static int      randomfactor[TWOFIFTYSIX];
-static int      randomripe[TWOFIFTYSIX];
-static int      testterminal (void);
-static int      randomletter (void);
-
-/*
- * Pointers to termcap/terminfo "smso/so" (enter_standout_mode) and "rmso/se"
- * (exit_standout_mode) terminal string capabilities (initialized respectively
- * with ANSI sequences "\E[7m" to turn the inverse video mode on and "\E[0m"
- * to turn all video attributes off).
- */
-static const char           *enter_standout_mode = "\033[7m";
-static const char           *exit_standout_mode = "\033[0m";
-
-/*
- * Value of (Wrong - Right), which, if exceeded, will cause the program
- * to start prompting you. Above MAX_ERROR_THRESHOLD it will never prompt.
- * Don't let the user bank too much credit for past correct answers;
- * limit it by min(ERROR_FLOOR, error_threshold).
- */
-#define MAX_ERROR_THRESHOLD            1000
-#define ERROR_FLOOR                    -3
-static int      error_threshold = MAX_ERROR_THRESHOLD;
-static int      error_floor = ERROR_FLOOR;
-
-/*
- * How many characters behind before it decides you're having
- * trouble keeping up.
- */
-#define BEHIND         1
-#define WAYBEHIND      3
-#define TOOFARBEHIND   6
-/*
- * If SLOWPOKE or more wpm ticks go by, then it decides you are having lots
- * of trouble remembering this character, and need to be asked it more
- * often.
- */
-#define SLOWPOKE       10
-/* You aren't slow -- you left and came back! */
-#define SLOWPOKEMAX    (50 * SLOWPOKE)
-/*
- * If FASTPOKE or less wpm ticks go by, then it decides you are good at this
- * character, and need to be asked it less often.
- */
-#define FASTPOKE       4
-
-/*
- * These control how quickly the dynamicspeed option acts when you are
- * fast or slow. Easier to slow down than speed up!
- */
-#define ERRORSLOWER    1.04
-#define ALOTSLOWER     1.15
-#define ALITTLESLOWER  1.02
-#define ALITTLEFASTER  1.02
-
-/*
- * How many inter_char_time's to give you to answer after the end of
- * a word before considering that you are not keeping up.
- * Maximum of 2.3, minimum of 0.
- * The bigger the value, the easier it is to kick in the "automatic
- * speedup" when using the "-d" option. The maximum means you have (almost)
- * right up to the beginning of the next word to answer and still have it
- * count as keeping up.
- */
-#define SPORTING_RATIO 1.5
-
-/*
- * The bigger, the more evenly things start out.
- * (Must be at least 2)
- */
-#define RANDOMBASELEVEL        7
-/*
- * RANDOMINCWORSE scales how badly you are punished for being wrong
- * or taking too long. RANDOMINCBETTER scales how you are rewarded for
- * answering quickly or being right.
- */
-#define RANDOMINCWORSE 6
-#define RANDOMINCBETTER        7
-#define RANDOMMAX      (30 * RANDOMBASELEVEL)
-/*
- * The average length of a random word (chosen using exponential distribution).
- * After implementing this I'm not so sure an exponential distribution
- * actually models the distribution of real word lengths in English very well.
- * It's not too bad, though, and the words themselves are all garbage anyway,
- * so what the heck.
- */
-#define RANDWORDLEN    3.5
-
-/* Put in a newline instead of a space when past this column */
-#define LINELENGTH     78
-
-/* An EOF without the EOF (%) sound */
-#define SILENTEOF -2
-/* Toggle tone frequency on control-G within input file */
-#define FREQU_TOGGLE ((int)'\007')
-
-/*
- * If you want the morse code to come out synchronized with the printing
- * of dots and dashes with the -m option, then define this. The problem
- * is that then the morse code sounds ratty on slower CPU's.
- * John Shalamskas (KJ9U) suggested turning the precise morse-code printing
- * synching off because he didn't like the resulting code quality!
- */
-#undef FLUSHCODE
-
-static void            new_words_per_minute (void);
-static void            dowords (int c);
-static void            morse (int c);
-static void            show (char *s);
-static void            testaddchar (char c);
-static void            youraddchar (char c);
-static void            pollyou (void);
-static void            tone (float hertz, float duration, float amplitude);
-static void            toneflush (void);
-static void            openterminal (void);
-static int             readterminal (char **string);
-static void            closeterminal (void);
-static void            report (void);
-
-static void            die (), suspend ();
-static void            cleanup ();
-
-int
-main (int argc, char **argv)
-{
-extern char    *optarg;
-extern int      optind;
-int             ch;
-char           *p;
-int             ii, jj;
-int             firsttime, notdoneyet;
-int             yourchar;
-float           randexp, randnum;
-extern time_t   time ();
-
-    if (argc == 1 && isatty (fileno (stdin)))
-    {
-/*
- * SELF DOC
- */
-       printf ("Usage:\n");
-       printf ("morse [options] < text_file\n");
-       printf ("morse [options] words words words\n");
-       printf ("morse [options] -r\n");
-       printf ("morse [options] -i\n");
-       printf ("Options:\n");
-       printf ("-i    Play what you type.\n");
-       printf ("-I    Like -i but don't turn off keyboard echoing.\n");
-       printf ("-r    Generate random text. Starts out slanted towards easy\n");
-       printf ("      letters, then slants towards ones you get wrong.\n");
-       printf ("-n NUM (default %d means random length)\n", MAXWORDLEN);
-       printf ("      Make words (groups) NUM characters long.\n");
-       printf ("      Valid values are between %d and %d.\n", 1, MAXWORDLEN);
-       printf ("-R NUM (default 0 means unlimited)\n");
-       printf ("      Set the total time (in minutes) to generate text.\n");
-       printf ("-N NUM (default 0 means unlimited)\n");
-       printf ("      Set the total number of words (groups) to generate.\n");
-       printf ("-C \'STRING\' (default all available characters)\n");
-       printf ("      Select characters to send from this STRING only.\n");
-       printf ("-w words_per_minute (default %g)\n-f frequency_in_hertz (default %g)\n-v volume (zero to one, rather nonlinear, default %g)\n",
-               WORDS_PER_MINUTE, FREQUENCY, VOLUME);
-       printf ("-g alternate_frequency (default %g)\n      (toggles via control-G in input FILE at a word break)\n", FREQUENCY2);
-       printf ("-F Farnsworth_character_words_per_minute\n");
-       printf ("-e    leave off the <SK> sound at the end\n");
-       printf ("-c    complain about illegal characters instead of just ignoring them\n");
-       printf ("-b    print each word before doing it\n");
-       printf ("-a    print each word after doing it\n");
-       printf ("-l    print each letter just before doing it\n");
-       printf ("-m    print morse dots and dashes as they sound\n");
-#ifdef FLUSHCODE
-       printf ("      (this printing-intensive option slows the wpm down!)\n");
-#endif
-       printf ("-t    Type along with the morse, but don't see what\n");
-       printf ("      you're typing (unless you make a mistake).\n");
-       printf ("      You are allowed to get ahead as much as you want.\n");
-       printf ("      If you get too far behind it will stop and resync with you.\n");
-       printf ("      You can force it to resync at the next word end by hitting control-H.\n");
-       printf ("      Hit ESC to see how you are doing, control-D to end.\n");
-       printf ("      (The rightmost space in the printout marks where the average is.\n");
-       printf ("      Farther left spaces separate off blocks of letters that are\n");
-       printf ("      about twice as probable as the average to occur, three times, etc.)\n");
-       printf ("-T    Like -t but see your characters (after they are played).\n");
-       printf ("-s    Stop after each character and make sure you get it right. (implies -t)\n");
-       printf ("-q    Quietly resyncs with your input (after you make a mistake).\n");
-       printf ("-p NUM (default 0)\n");
-       printf ("      Make you get it right NUM times, for penance. (implies -s)\n");
-       printf ("      (Yes, NUM = 0 means you can sin all you want.)\n");
-       printf ("-E NUM (default %d)\n", MAX_ERROR_THRESHOLD);
-       printf ("      If your count of wrong answers minus right answers for a given character\n");
-       printf ("      exceeds this, the program will start prompting you.\n");
-       printf ("      If %d or above, it will never prompt. (implies -t)\n", MAX_ERROR_THRESHOLD);
-       printf ("-M NUM (default %d)\n", MAX_BEHINDNESS);
-       printf ("      If you get more than this number of characters behind, pause until you\n");
-       printf ("      do your next letter. (1 behind is normal, 0 behind means never pause.)\n");
-       printf ("      (implies -t)\n");
-       printf ("-d    Dynamically speed up or slow down depending on how you are doing.\n");
-       printf ("      (if also -s, then -d _only speeds up_!)\n");
-       printf ("-A    Add ISO 8850-1 (Latin-1) signs to test set.\n");
-       printf ("-B    Add uncommon punctuation to test set.\n");
-       printf ("-S    Add uncommon prosigns to test set.\n");
-       printf ("-X    Set error volume. Defaults to %g.\n", ERROR_VOLUME);
-       printf ("      Error volume 0 means use console speaker.\n");
-       printf ("-x    Set frequency of error tone, default 2000.0Hz\n");
-       exit (0);
-    }
-
-    for (ii = 0; ii < TWOFIFTYSIX; ii++)
-       code[ii] = NULL;
-
-/* Load in the morse code code */
-    code[(int) 'a'] = ".-";
-    code[(int) 'b'] = "-...";
-    code[(int) 'c'] = "-.-.";
-    code[(int) 'd'] = "-..";
-    code[(int) 'e'] = ".";
-    code[(int) 'f'] = "..-.";
-    code[(int) 'g'] = "--.";
-    code[(int) 'h'] = "....";
-    code[(int) 'i'] = "..";
-    code[(int) 'j'] = ".---";
-    code[(int) 'k'] = "-.-";
-    code[(int) 'l'] = ".-..";
-    code[(int) 'm'] = "--";
-    code[(int) 'n'] = "-.";
-    code[(int) 'o'] = "---";
-    code[(int) 'p'] = ".--.";
-    code[(int) 'q'] = "--.-";
-    code[(int) 'r'] = ".-.";
-    code[(int) 's'] = "...";
-    code[(int) 't'] = "-";
-    code[(int) 'u'] = "..-";
-    code[(int) 'v'] = "...-";
-    code[(int) 'w'] = ".--";
-    code[(int) 'x'] = "-..-";
-    code[(int) 'y'] = "-.--";
-    code[(int) 'z'] = "--..";
-
-    code[(int) '1'] = ".----";
-    code[(int) '2'] = "..---";
-    code[(int) '3'] = "...--";
-    code[(int) '4'] = "....-";
-    code[(int) '5'] = ".....";
-    code[(int) '6'] = "-....";
-    code[(int) '7'] = "--...";
-    code[(int) '8'] = "---..";
-    code[(int) '9'] = "----.";
-    code[(int) '0'] = "-----";
-
-    /* Punctuation marks */
-    code[(int) '.'] = ".-.-.-";
-    code[(int) ','] = "--..--";
-    code[(int) '?'] = "..--..";
-    code[(int) '/'] = "-..-.";
-    code[(int) '-'] = "-....-";
-
-    if (allpunctuation) {
-    /* Not so commonly used punctuation marks */
-    code[(int) ')'] = "-.--.-";
-    code[(int) '\"'] = ".-..-.";
-    code[(int) '_'] = "..--.-";
-    code[(int) '\''] = ".----.";
-    code[(int) ':'] = "---...";
-    code[(int) ';'] = "-.-.-.";
-    code[(int) '$'] = "...-..-";
-    code[(int) '!'] = "-.-.--";
-    }
-
-    /* Commonly used procedure signs ("prosigns") */
-    code[(int) '+'] = ".-.-.";  /* <AR> end of message */
-    code[(int) '*'] = ".-...";  /* <AS> wait, stand-by */
-    code[(int) '='] = "-...-";  /* <BT> (double dash) pause, break for text */
-    code[(int) '('] = "-.--.";  /* <KN> over-specified station only */
-    code[(int) '%'] = "...-.-"; /* <SK> end of contact, known also as <VA> */
-
-    if (allprosigns) {
-    /* Not so commonly used procedure signs ("prosigns") */
-    code[(int) '^'] = ".-.-";   /* <AA> new line, the same as :a, ae */
-    code[(int) '#'] = "-...-.-";/* <BK> invite receiving station to transmit */
-    code[(int) '&'] = "-.-.-";  /* <KA> attention */
-    code[(int) '@'] = "...-.";  /* <SN> understood */
-    }
-
-    if (international) {
-    /* Not so commonly used international extensions (ISO 8859-1) */
-    code[(int) ((unsigned char)'\344')] = ".-.-";   /* :a (also for ae), the same as <AA> */
-    if (code[(int) '^'] != NULL) code[(int) '^'] = NULL;
-    code[(int) ((unsigned char)'\340')] = ".--.-";  /* `a, oa (danish a with ring over it) */
-    code[(int) ((unsigned char)'\347')] = "----";   /* ch (bar-ch) */
-    code[(int) ((unsigned char)'\360')] = "..--.";  /* -d (eth, overstrike d with -) */
-    code[(int) ((unsigned char)'\350')] = "..-..";  /* `e */
-    code[(int) ((unsigned char)'\361')] = "--.--";  /* ~n */
-    code[(int) ((unsigned char)'\366')] = "---.";   /* :o (also for oe) */
-    code[(int) ((unsigned char)'\374')] = "..--";   /* :u (also for ue) */
-    code[(int) ((unsigned char)'\376')] = ".--..";  /* ]p (thorn, overstrike ] with p) */
-    code[(int) ((unsigned char)'\247')] = ".-.-.."; /* paragraph */
-    }
-
-    for (ii = 0; ii < TWOFIFTYSIX; ii++)
-    {
-       /* Everything starts equally fresh */
-       randomripe[ii] = 0;
-       /* Start out assuming you know how everything sounds */
-       errorlog[ii] = 0;
-
-       if (code[ii] == NULL)
-       {
-           /* Ensures these will never be chosen */
-           randomfactor[ii] = 0;
-       }
-       else
-       {
-           /* Start out favoring easy ones */
-           randomfactor[ii] = RANDOMBASELEVEL - strlen (code[ii]);
-           if (randomfactor[ii] < 1)
-               randomfactor[ii] = 1;
-       }
-    }
-
-    words_per_minute = WORDS_PER_MINUTE;
-    fwords_per_minute = -1.;
-
-    /* DGHJKLMOPQUVWYZhjkouyz are still available */
-    while ((ch = getopt (argc, argv, "ABC:E:F:IM:N:R:STXabcdef:g:ilmn:p:qrstv:w:x:")) != EOF)
-       switch ((char) ch)
-       {
-       case 'A':
-           international = 1;
-           break;
-       case 'B':
-           allpunctuation = 1;
-           break;
-       case 'C':
-           for (ii = 0; ii < strlen(optarg); ii++)
-             {
-               *(optarg+ii) = tolower(*(optarg+ii));
-             }
-           for (ii = 0; ii < TWOFIFTYSIX; ii++)
-             {
-               if (code[ii] != NULL)
-                 {
-                   if (strchr(optarg, ii) != NULL)
-                     {
-                       randomfactor[ii] = RANDOMBASELEVEL - 1;
-                     } else {
-                       code[ii] = NULL;
-                       randomfactor[ii] = 0;
-                     }
-                 }
-             }
-           break;
-       case 'E':
-           testing = 1;
-           sscanf (optarg, "%d", &error_threshold);
-           if (error_threshold < error_floor)
-               error_floor = error_threshold;
-           break;
-       case 'F':
-           sscanf (optarg, "%f", &fwords_per_minute);
-           break;
-       case 'I':
-           typeaway = LETMESEE;
-           break;
-       case 'M':
-           testing = 1;
-           sscanf (optarg, "%d", &max_behindness);
-           if (max_behindness < 1)
-               max_behindness = 0;
-           break;
-       case 'N':
-           sscanf (optarg, "%d", &wordcount);
-           if (wordcount < 1) wordcount = -1;
-           break;
-       case 'R':
-           sscanf (optarg, "%d", &timeout);
-           timeout *= 60;
-           if (timeout < 1) timeout = -1;
-           break;
-       case 'S':
-           allprosigns = 1;
-           break;
-       case 'T':
-           testing = 1;
-           showtesting = 1;
-           break;
-       case 'X':
-           sscanf (optarg, "%f", &error_volume);
-           break;
-       case 'a':
-           wordsafter = 1;
-           break;
-       case 'b':
-           wordsbefore = 1;
-           break;
-       case 'c':
-           noticebad = 1;
-           break;
-       case 'd':
-           dynamicspeed = 1;
-           break;
-       case 'e':
-           fancyending = 0;
-           break;
-       case 'f':
-           sscanf (optarg, "%f", &frequency1);
-           break;
-       case 'g':
-           sscanf (optarg, "%f", &frequency2);
-           break;
-       case 'i':
-           typeaway = 1;
-           break;
-       case 'l':
-           showletters = 1;
-           break;
-       case 'm':
-           showmorse = 1;
-           break;
-       case 'n':
-           sscanf (optarg, "%d", &wordlen);
-           if (wordlen < 1) wordlen = 1;
-           if (wordlen > MAXWORDLEN) wordlen = MAXWORDLEN;
-           break;
-       case 'p':
-           charbychar = 1;
-           testing = 1;
-           sscanf (optarg, "%d", &tryagaincount);
-           break;
-       case 'q':
-           keepquiet = 1;
-           break;
-       case 'r':
-           randomletters = 1;
-           break;
-       case 's':
-           charbychar = 1;
-           testing = 1;
-           break;
-       case 't':
-           testing = 1;
-           break;
-       case 'v':
-           sscanf (optarg, "%f", &volume);
-           if (volume < 0.)
-               volume = 0.;
-           if (volume > 1.)
-               volume = 1.;
-           break;
-       case 'w':
-           sscanf (optarg, "%f", &words_per_minute);
-           break;
-       case 'x':
-           sscanf (optarg, "%f", &error_frequency);
-           break;
-       default:
-           fprintf (stderr, "Type \"morse\" without arguments to get self-doc!\n");
-           exit (1);
-           break;
-       }
-    argc -= optind;
-    argv += optind;
-
-    if (fwords_per_minute <= 0.)
-       fwords_per_minute = words_per_minute;
-    new_words_per_minute ();
-
-    frequency = frequency1;
-
-    if (BeepInit () != 0)
-    {
-       fprintf (stderr, "Can't access speaker.\n");
-       exit (1);
-    }
-
-    time(&starttime);
-
-    sigset (SIGINT, die);
-    sigset (SIGTERM, die);
-    sigset (SIGQUIT, die);
-    sigset (SIGTSTP, suspend);
-
-    if (testing || typeaway)
-    {
-       openterminal ();
-    }
-
-/*
- * Do .25 seconds of silence initially to give the workstation time to
- * get settled after the stress of starting this program and opening
- * up everything.
- */
-    tone (frequency, .25, 0.);
-    toneflush ();
-
-    if (typeaway)
-    {
-       testing = 0;
-       showtesting = 0;
-       charbychar = 0;
-       wordsbefore = 0;
-       wordsafter = 0;
-       randomletters = 0;
-
-       notdoneyet = 1;
-
-       while (notdoneyet)
-       {
-           pollyou ();
-
-           for (jj = 0; jj < yourlength; jj++)
-           {
-               yourchar = yourstring[(yourpointer - yourlength + 1 + jj + TESTBUFSZ) % TESTBUFSZ];
-
-               /* Control-D: finished */
-               if (yourchar == (int) '\004')
-               {
-                   toneflush ();
-                   notdoneyet = 0;
-                   break;
-               }
-
-               if (isspace (yourchar))
-               {
-                   if (showletters)
-                   {
-                       toneflush ();
-                       printf ("%c", yourchar);
-                       fflush (stdout);
-                   }
-
-                   tone (frequency, inter_word_time, 0.);
-
-                   continue;
-               }
-
-               morse (yourchar);
-           }
-           yourlength -= jj;
-
-           if (timeout > 0)
-             if (difftime(time(NULL),starttime) > (double)timeout)
-               break;
-       }
-    }
-    else if (randomletters)
-    {
-       srand48(time (NULL));
-       randexp = 1. / (1. - 1. / (float) (RANDWORDLEN));
-       while (1)
-       {
-           if ((wordcount == 0) || timeout == 0) break;
-
-           dowords (randomletter ());
-
-           if (wordlen == MAXWORDLEN)
-             {
-               /* Knock a few bits off the top so we're sure it won't overflow */
-               /* Shift a few bits because the lower bits stink */
-               /* Add in the time so it doesn't repeat from run to run */
-               randnum = (float) (
-                                  (((lrand48() >> 9) + (long) (time (NULL))) >> 4)
-                                  & 0x00FFFFFF);
-               randnum = randnum - randexp * (int) (randnum / randexp);
-               if ((randnum >= 1.) && (linepos != 0)) dowords ((int) ' ');
-             }
-       }
-    }
-    else
-    {
-       if (*argv)
-       {
-           firsttime = 1;
-
-           do
-           {
-               if (!firsttime)
-               {
-                   dowords ((int) ' ');
-               }
-               else
-                   firsttime = 0;
-
-               if ((wordcount == 0) || timeout == 0) break;
-
-               for (p = *argv; *p; ++p)
-                 {
-                   dowords ((int) *p);
-                   if ((wordcount == 0) || timeout == 0) break;
-                 }
-               if ((wordcount == 0) || timeout == 0) break;
-
-           } while (*++argv);
-       }
-       else
-       {
-           while ((ch = getchar ()) != EOF)
-             {
-               dowords (ch);
-               if ((wordcount == 0) || timeout == 0) break;
-             }
-       }
-    }
-
-    if (fancyending)
-       dowords (EOF);
-    else
-       dowords (SILENTEOF);
-
-    fflush (stdout);
-
-    if (testing)
-    {
-       /*
-        * WE'RE completely done, and YOU aren't! Force catch up. (Note if
-        * charbychar = YES we won't get here, since we're always caught up
-        * after each character as it comes out.)
-        */
-       while (testlength > 0)
-       {
-           tone (frequency, catchup_time, 0.);
-           toneflush ();
-           testterminal ();
-       }
-    }
-
-    /* Just to be sure! */
-    toneflush ();
-
-    if (showmorse || wordsbefore || wordsafter || showletters || showtesting)
-       printf ("\n");
-    fflush (stdout);
-
-    if (testing)
-       report ();
-
-/* If you make any mistakes exit with a return code! */
-    cleanup ();
-    return (totalmisscount > 0);
-}
-
-static void
-new_words_per_minute ()
-{
-float           wtick, ftick, tick;
-
-    tick = 60. / (words_per_minute * 50);
-
-    /*
-     * In the limit as wpm goes past fwpm, Farnsworth becomes kosher PARIS
-     */
-    if (fwords_per_minute <= words_per_minute)
-       ftick = 60. / (words_per_minute * 50);
-    else
-       ftick = 60. / (fwords_per_minute * 50);
-
-    wtick = (50. * tick - 31. * ftick) / 19.;
-
-    /*
-     * This time is used when the computer is waiting on you to hit a key; it
-     * is useful to scale the granularity with the real overrall words per
-     * minute. This also serves as a measuring rod to see if you are
-     * responding "fast enough". If you are too slow, then obviously you are
-     * having trouble with that character, and should be given it more OFTEN.
-     * Heh heh heh...
-     */
-    catchup_time = tick;
-
-    /*
-     * Things between characters and words go at the "remainder" speed,
-     * whatever space you need to make the sped-up Farnsworth characters come
-     * out with the correct overall words per minute.
-     */
-    inter_char_time = wtick * 3.;
-    inter_word_time = wtick * 7.;
-
-    /* Things within the character go at the Farnsworth speed */
-    intra_char_time = ftick;
-    dot_time = ftick;
-    dash_time = ftick * 3.;
-}
-
-static int      tryingagain = 0, slowpoke = 0;
-
-static void
-dowords (int c)
-{
-static int      wordc = 0;
-static char     word[MAXWORDLEN+1];
-char           *wordp;
-int             ii;
-int             againcount = 0;
-int             are_we_repeating;
-
-/*
- * Increment the line position counter.
- * If a line gets too long, just cut it off by inserting a new line.
- */
-    if (c != EOF && c != SILENTEOF && c != FREQU_TOGGLE) linepos++;
-    if (isspace (c) && ((linepos + wordlen) >= LINELENGTH)) c = '\n';
-    if (c == '\n') linepos = 0;
-
-    if (isspace (c) || c == EOF || c == SILENTEOF || c == FREQU_TOGGLE)
-    {
-       if (wordc > 0)
-       {
-           if (wordcount > 0) wordcount--;
-           if (timeout > 0)
-             if (difftime(time(NULL),starttime) > (double)timeout)
-               timeout = 0;
-
-           word[wordc] = '\0';
-
-/*
- * We have just read in a new complete word from the input, (hopefully)
- * during the time of an inter-word space minus an inter-char space.
- * Now let's go back and see what happened with the PREVIOUS word,
- * the one that we had just finished playing. Did the user keep
- * up with us?
- */
-#ifdef DEBUG
-           fprintf (stderr, " [%d] ", behindness);
-#endif
-           if (testing && dynamicspeed && !charbychar)
-           {
-               /*
-                * (If charbychar then behindness is ALWAYS 0 at this
-                * point...)
-                */
-               if (behindness == 0)
-               {
-                   /* You're a speed demon! Speed up a bit, then! */
-                   words_per_minute *= ALITTLEFASTER;
-                   new_words_per_minute ();
-               }
-               else if (behindness > WAYBEHIND)
-               {
-                   /* You're way behind! Slow way down. */
-                   words_per_minute /= ALOTSLOWER;
-                   new_words_per_minute ();
-               }
-               else if (behindness > BEHIND)
-               {
-                   /* You're behind! Slow down a bit. */
-                   words_per_minute /= ALITTLESLOWER;
-                   new_words_per_minute ();
-               }
-           }
-
-
-/*
- * If the user was WAY too far behind stop and catch up with
- * the "new" word as the first one.
- */
-           if (testing && (behindness > TOOFARBEHIND || helpmeflag))
-           {
-               if (helpmeflag)
-                   printf ("\nOK, let's restart.\n");
-               else
-                   printf ("\nYou are too far behind! Let's restart.\n");
-               fflush (stdout);
-
-               toneflush ();
-
-               /* Flush the keyboard buffer */
-               pollyou ();
-
-               /* Forget the past */
-               helpmeflag = 0;
-               behindness = 0;
-               testlength = 0;
-               yourlength = 0;
-
-               /* Give the user a little rest. */
-               sleep (2);
-               printf ("\nWPM now %d\n", (int) (words_per_minute + .5));
-               fflush (stdout);
-               sleep (2);
-               printf ("\nREADY?\n");
-               fflush (stdout);
-               sleep (1);
-               printf ("\nSET\n");
-               fflush (stdout);
-               sleep (1);
-               printf ("\nGO!\n");
-               fflush (stdout);
-               linepos = 0;
-           }
-
-/*
- * Start treating the new word.
- */
-           if (wordsbefore)
-           {
-               /* Try to keep your out-of-sync text from getting swirled in */
-               if (showtesting)
-                 {
-                   printf ("\n");
-                   linepos = 0;
-                 }
-
-               printf ("%s", word);
-
-               if (showmorse || showletters || wordsafter || showtesting)
-               {
-                   printf ("  ");
-                   for (ii = 0; ii < 16 - (wordc + 2); ii++)
-                   {
-                       printf (" ");
-                   }
-               }
-
-               fflush (stdout);
-           }
-
-           if (testing && charbychar)
-           {
-               againcount = 0;
-           }
-
-           for (wordp = word; *wordp != '\0'; wordp++)
-           {
-               tryingagain = 0;
-
-       tryagain:
-               if (testing && !tryingagain && !showletters &&
-                   error_threshold < MAX_ERROR_THRESHOLD &&
-                   errorlog[(int) *wordp] > error_threshold)
-               {
-                   toneflush ();
-                   /* Give them a quick hint */
-                   printf ("[%c]", *wordp);
-                   fflush (stdout);
-
-                   morse (*wordp);
-
-                   toneflush ();
-                   if (!showmorse)
-                   {
-                       /* Erase the hint */
-                       printf ("\b\b\b   \b\b\b");
-                       fflush (stdout);
-                   }
-               }
-               else
-               {
-                   morse (*wordp);
-               }
-
-               if (testing)
-               {
-                   if (charbychar)
-                   {
-                       toneflush ();
-                       /* Force catchup */
-                       slowpoke = 0;
-                       while (behindness > 0)
-                       {
-                           if (testterminal () && tryagaincount > 0)
-                           {
-                               /*
-                                * OOPS! They got it WRONG! MAKE THEM TRY
-                                * AGAIN!
-                                */
-                               printf ("Try again.\n");
-                               linepos = 0;
-                               /*
-                                * Yeah I know gotos are inelegant but I
-                                * don't feel like figuring out the "elegant"
-                                * way to do this right now.
-                                */
-                               againcount = tryagaincount - 1;
-                               tryingagain = 1;
-                               goto tryagain;
-                           }
-                           else
-                           {
-                               /*
-                                * They got it right, or they didn't answer
-                                * yet.
-                                */
-                               if (behindness > 0)
-                               {
-                                   /*
-                                    * They are STILL thinking, the
-                                    * slowpokes. Wait a bit before trying
-                                    * again.
-                                    */
-                                   tone (frequency, catchup_time, 0.);
-                                   /*
-                                    * Keep track of how long they're taking
-                                    * to answer!
-                                    */
-                                   if (slowpoke < SLOWPOKEMAX)
-                                       slowpoke++;
-                                   toneflush ();
-                               }
-                               else if (dynamicspeed && !slowpoke && !tryingagain)
-                               {
-                                   /*
-                                    * They got it right without errors the
-                                    * first time and we didn't have to wait
-                                    * for them! A speed demon! Speed up a
-                                    * bit, then!
-                                    */
-                                   words_per_minute *= ALITTLEFASTER;
-                                   new_words_per_minute ();
-                               }
-                           }
-                       }
-
-                       /* Insufficient penance? */
-                       if (againcount > 0)
-                       {
-                           againcount--;
-                           goto tryagain;
-                       }
-                   }
-                   else
-                   {
-                       testterminal ();
-                       /*
-                        * Stop if we get more than max_behindness ahead.
-                        * max_behindness == 0 means don't worry about them,
-                        * they can be as far behind as they want and we
-                        * won't stop!
-                        */
-                       if (max_behindness > 0)
-                       {
-                           are_we_repeating = 0;
-                           while (behindness >= max_behindness)
-                           {
-#ifdef DEBUG
-                               fprintf (stderr, " (%d) ", behindness);
-#endif
-                               if (are_we_repeating)
-                               {
-                                   /*
-                                    * Pause for a bit so we don't loop too
-                                    * fast
-                                    */
-                                   tone (frequency, catchup_time, 0.);
-                               }
-                               else
-                               {
-                                   are_we_repeating = 1;
-                               }
-                               /* Finish playing whatever we're playing */
-                               toneflush ();
-                               /* And give them another chance */
-                               testterminal ();
-                           }
-                       }
-                   }
-               }
-           }
-
-           toneflush ();
-           if (testing)
-               testterminal ();
-
-           if (wordsafter)
-           {
-               printf (" (%s)", word);
-           }
-
-           if (wordsbefore || wordsafter || showmorse)
-             {
-               if (!showmorse && !testing && linepos)
-                 {
-                   if (wordsafter)
-                     linepos += 3;
-                   else
-                     printf (" ");
-                 } else {
-                   printf ("\n");
-                   linepos = 0;
-                 }
-             }
-           else if (showletters || showtesting)
-           {
-               if (c != EOF && c != SILENTEOF && c != FREQU_TOGGLE)
-               {
-                   if (showletters)
-                       printf ("%c", c);
-
-                   if (showtesting)
-                       testaddchar (c);
-               }
-           }
-
-/*
- * WHEW! FINISHED QUEUEING THE WORD FOR PLAYING!
- * Now finish up all the other sundry details...
- */
-
-           /* Flush the output printing queue... */
-           fflush (stdout);
-           /*
-            * Pause for a bit; this gives the user a sporting chance at
-            * catching up with us.
-            */
-           tone (frequency, SPORTING_RATIO * inter_char_time, 0.);
-           toneflush ();
-           /* Start sounding an inter-word space */
-           tone (frequency, inter_word_time - SPORTING_RATIO * inter_char_time, 0.);
-
-           /* While that silence is playing check if the user has caught up. */
-           if (testing)
-               testterminal ();
-
-           /* We finished this word; reset the word character count */
-           wordc = 0;
-       }
-       else if (!(wordsbefore || wordsafter || showmorse)
-                &&
-                (showletters || showtesting))
-       {
-           if (c != EOF && c != SILENTEOF && c != FREQU_TOGGLE)
-           {
-               if (showletters)
-                   printf ("%c", c);
-
-               if (showtesting)
-                   testaddchar (c);
-           }
-       }
-
-       if (c == EOF)
-       {
-           morse (EOF);
-           toneflush ();
-       }
-       else if (c == SILENTEOF)
-       {
-           toneflush ();
-       }
-       else if (c == FREQU_TOGGLE)
-       {
-           /* Switch to the other frequency */
-           /* (Won't work from keyboard, only from a file.) */
-           whichfrequ = 1 - whichfrequ;
-           switch (whichfrequ)
-           {
-           case 1:
-               frequency = frequency2;
-               break;
-           case 0:
-           default:
-               frequency = frequency1;
-               break;
-           }
-       }
-    }
-    else
-    {
-       word[wordc++] = c;
-    }
-
-/*
- * If a word gets too long, just cut it off by inserting a space.
- * Just call ourselves with the character we wish we'd gotten...
- */
-    if (wordc == wordlen && !(isspace (c) || c == EOF || c == SILENTEOF || c == FREQU_TOGGLE))
-       dowords ((int) ' ');
-}
-
-/*
- * Don't try to test the person DURING the call into morse!
- */
-void
-morse (int c)
-{
-    if ((isalpha (c) && (code[tolower(c)] == NULL)) || ((code[(int) '%'] == NULL) && ((c == EOF) || (c == '\004'))))
-      c = ' ';
-
-    if (showletters)
-    {
-        if ((c == EOF) || (c == '\004'))
-         {
-           if (showmorse)
-             {
-               printf ("<SK>");
-             } else {
-               printf ("%%");
-             }
-         }
-       else if (c == '.' && showmorse)
-           printf ("<DOT>");
-       else if (c == '-' && showmorse)
-           printf ("<DASH>");
-       else if (c == '+' && showmorse)
-           printf ("<AR>");
-       else if (c == '*' && showmorse)
-           printf ("<AS>");
-       else if (c == '=' && showmorse)
-           printf ("<BT>");
-       else if (c == '(' && showmorse)
-           printf ("<KN>");
-       else if (c == '%' && showmorse)
-           printf ("<SK>");
-#ifdef ALLPROSIGNS
-       else if (c == '^' && (code[(int) '^'] != NULL) && showmorse)
-           printf ("<AA>");
-       else if (c == '#' && showmorse)
-           printf ("<BK>");
-       else if (c == '&' && showmorse)
-           printf ("<KA>");
-       else if (c == '@' && showmorse)
-           printf ("<SN>");
-#endif
-       else
-           printf ("%c", c);
-
-       fflush (stdout);
-    }
-
-    if (isalpha (c))
-    {
-       if (testing)
-           testaddchar (c - (isupper (c) ? 'A' : 'a') + 'a');
-       show (code[c - (isupper (c) ? 'A' : 'a') + 'a']);
-    }
-    else if ((c == EOF) || (c == '\004'))
-    {
-       show (code[(int) '%']);
-    }
-    else if (code[c] != NULL)
-    {
-       if (testing)
-           testaddchar (c);
-       show (code[c]);
-    }
-    else
-    {
-       /* Oops! This letter is junk! */
-
-       if (noticebad)
-       {
-           if (showletters)
-           {
-               fflush (stdout);
-           }
-
-           /* Simulate a stumble */
-           tone (frequency, 2. * inter_word_time, 0.);
-           toneflush ();
-       }
-
-       if (showletters)
-       {
-           /* Wipe out what we just printed */
-           fflush (stdout);
-           printf ("\b");
-           printf (" ");
-           printf ("\b");
-           fflush (stdout);
-       }
-
-       if (noticebad)
-       {
-           if (showletters)
-           {
-               /* And replace it with an error message */
-               printf ("<UNKNOWN_CHARACTER>");
-               fflush (stdout);
-           }
-
-           /* Give the error call */
-           show ("........");
-
-           /* Regroup */
-           tone (frequency, inter_word_time, 0.);
-       }
-    }
-
-    if (showmorse)
-       printf (" ");
-    fflush (stdout);
-    toneflush ();
-    tone (frequency, inter_char_time - intra_char_time, 0.);
-}
-
-
-/*
- * Don't try to test the person WHILE doing dots and dashes!
- */
-static void
-show (char *s)
-{
-char            c;
-
-    while ((c = *s++) != '\0')
-    {
-       tone (frequency, intra_char_time, 0.);
-
-#ifdef FLUSHCODE
-       if (showmorse)
-           toneflush ();
-#endif
-
-       switch (c)
-       {
-       case '.':
-           tone (frequency, dot_time, volume);
-           break;
-       case '-':
-           tone (frequency, dash_time, volume);
-           break;
-       }
-
-       if (showmorse)
-       {
-           printf ("%c", c);
-           fflush (stdout);
-#ifdef FLUSHCODE
-           toneflush ();
-#endif
-       }
-    }
-}
-
-/*
- * This only gets passed valid characters: ones
- * that have a morse code associated with them
- * or ones for which isspace(c) is true.
- */
-static void
-testaddchar (char c)
-{
-    testpointer = (testpointer + 1) % TESTBUFSZ;
-    teststring[testpointer] = c;
-#ifdef DEBUG
-    fprintf (stderr, " (%c,%d,%d) ", c, testlength, behindness);
-#endif
-    testlength++;
-    if (testlength > TESTBUFSZ)
-    {
-       fprintf (stderr, "\n\nInput buffer queue overflow! Make TESTBUFSZ bigger!\n");
-       fprintf (stderr, "(Or don't fall so far behind)\n");
-
-       die ();
-    }
-
-/*
- * Since you are never asked to type spaces (you can type them if
- * you want, but they are ignored) spaces in the input file don't
- * count against your "behindness".
- */
-    if (!isspace (c))
-       behindness++;
-}
-
-static void
-youraddchar (char c)
-{
-    yourpointer = (yourpointer + 1) % TESTBUFSZ;
-    yourstring[yourpointer] = c;
-#ifdef DEBUG
-    fprintf (stderr, " <%c,%d> ", c, yourlength);
-#endif
-    yourlength++;
-    if (yourlength > TESTBUFSZ)
-    {
-       fprintf (stderr, "\n\nKeyboard typeahead buffer queue overflow! Make TESTBUFSZ bigger!\n");
-       fprintf (stderr, "(Or don't type so far ahead... how did you expect to get them right anyway?)\n");
-
-       die ();
-    }
-}
-
-static void
-pollyou (void)
-{
-    int ii, num;
-    char *string;
-
-    num = readterminal (&string);
-
-    for (ii = 0; ii < num; ii++)
-       youraddchar (string[ii]);
-}
-
-static int
-testterminal (void)
-{
-int             testinc, yourinc;
-int             correctchar, yourchar, yourcharnocase;
-int             errorcount;
-int             resync;
-
-    errorcount = 0;
-
-/*
- * There is nothing in the input file queue right now,
- * so we can't process any of your keystrokes.
- * Defer processing until we can catch up with YOU!
- */
-    if (testlength == 0)
-       return errorcount;
-
-    /* We're ready for you; but are you ready for us? */
-    pollyou ();
-
-/*
- * Process your entries and the input queue entries in parallel
- */
-    if (yourlength > 0 && testlength > 0)
-    {
-       for (testinc = 0, yourinc = 0;
-            testinc < testlength && yourinc < yourlength;
-            testinc++, yourinc++)
-       {
-           correctchar = teststring[(testpointer - testlength + 1 + testinc + TESTBUFSZ) % TESTBUFSZ];
-
-           /*
-            * The latter half of this if shouldn't be necessary, but just in
-            * case...
-            */
-           if (isspace (correctchar) || code[correctchar] == NULL)
-           {
-               if (showtesting)
-               {
-                   printf ("%c", correctchar);
-                   fflush (stdout);
-               }
-
-               /* White space doesn't count for "behindness" */
-               behindness++;
-               /* The _other_ pointer wasn't used; don't increment it. */
-               yourinc--;
-
-               /* Short circuit the loop */
-               continue;
-           }
-
-
-           yourchar = yourstring[(yourpointer - yourlength + 1 + yourinc + TESTBUFSZ) % TESTBUFSZ];
-           if (isalpha (yourchar))
-               yourcharnocase = yourchar - (isupper (yourchar) ? 'A' : 'a') + 'a';
-           else
-               yourcharnocase = yourchar;
-
-           /* Did you type something rude? If so, just ignore it. */
-           if (isspace (yourchar) || code[yourcharnocase] == NULL)
-           {
-               /* ESCAPE: dump status info */
-               /* Control-D: dump status info and then bye bye */
-               /* Control-H: force restart */
-               if (yourchar == '\033' || yourchar == (int) '\004')
-               {
-                   report ();
-
-                   if (yourchar == (int) '\004')
-                       die ();
-               }
-               else if (yourchar == '\b')
-               {
-                   helpmeflag = 1;
-               }
-
-               /* The _other_ pointer wasn't used; don't increment it. */
-               testinc--;
-               /* Short circuit the loop */
-               continue;
-           }
-
-           if (keepquiet > 1)
-             {
-               for (resync = testinc; resync < testlength; resync++)
-                 if ( yourcharnocase == teststring[(testpointer - testlength + 1 + resync + TESTBUFSZ) % TESTBUFSZ])
-                   {
-                     for (; testinc < resync; testinc++)
-                       {
-                         correctchar = teststring[(testpointer - testlength + 1 + testinc + TESTBUFSZ) % TESTBUFSZ];
-                         if (isspace (correctchar) || code[correctchar] == NULL)
-                           {
-                             if (showtesting) printf ("%c", correctchar);
-                           } else {
-                             printf("%s%c%s", enter_standout_mode, correctchar, exit_standout_mode);
-                           }
-                       }
-                     fflush (stdout);
-                     correctchar = teststring[(testpointer - testlength + 1 + testinc + TESTBUFSZ) % TESTBUFSZ];
-                     keepquiet = 1;
-                     break;
-                   }
-             }
-
-           if (yourcharnocase != correctchar)
-           {
-               errorcount++;
-               totalmisscount++;
-
-               /*
-                * Record that you are having trouble with these.
-                */
-               errorlog[correctchar]++;
-               if (code[yourcharnocase] != NULL &&
-                   errorlog[yourcharnocase] < MAX_ERROR_THRESHOLD)
-                   errorlog[yourcharnocase]++;
-
-               if (keepquiet > 0)
-                 {
-                   printf("%s%c%s", enter_standout_mode, correctchar, exit_standout_mode);
-                   fflush (stdout);
-                   keepquiet++;
-                 } else {
-                   /*
-                    * Scold them for their mistake.
-                    */
-                   printf ("\n");
-
-                   if (error_volume) {
-                       /* Beep using the tone generator */
-                       toneflush ();
-                       tone (error_frequency, 0.1, error_volume);
-                   } else
-                       /* Beep using control-G */
-                       printf ("\007");
-                   printf ("%c (%s) for %c (%s)\n",
-                           yourchar, code[yourcharnocase],
-                           correctchar, code[correctchar]);
-                   fflush (stdout);
-                   linepos = 0;
-                 }
-
-               if (charbychar)
-               {
-                   /* Give them a bit of time to think about their error */
-                   tone (frequency, inter_word_time, 0.);
-                   toneflush ();
-               }
-               if (dynamicspeed && !charbychar)
-               {
-                   /*
-                    * Slow down. Doesn't make sense to slow down for errors,
-                    * though, if you've got all the time you want to think
-                    * about each one.
-                    */
-                   words_per_minute /= ERRORSLOWER;
-                   new_words_per_minute ();
-               }
-               if (randomletters && !tryingagain)
-               {
-                   /*
-                    * Ask ones that confused you more often!
-                    */
-                   if (code[yourcharnocase] != NULL)
-                   {
-                       randomfactor[yourcharnocase] += (3 * RANDOMINCWORSE / 2);
-                       if (randomfactor[yourcharnocase] > RANDOMMAX)
-                           randomfactor[yourcharnocase] = RANDOMMAX;
-                   }
-
-                   randomfactor[correctchar] += RANDOMINCWORSE * 2;
-                   if (randomfactor[correctchar] > RANDOMMAX)
-                       randomfactor[correctchar] = RANDOMMAX;
-               }
-           }
-           else
-           {
-               /*
-                * Record that you got this right.
-                */
-               if (!tryingagain)
-               {
-                   totalhitcount++;
-                   if (errorlog[correctchar] > error_floor)
-                       errorlog[correctchar]--;
-               }
-
-               if (showtesting)
-               {
-                   printf ("%c", yourchar);
-                   fflush (stdout);
-               }
-
-               if (randomletters && !tryingagain)
-               {
-                   if (slowpoke == SLOWPOKEMAX)
-                   {
-                       printf ("\nNice to have you back again, I was getting bored!\n");
-                       linepos = 0;
-                   }
-                   else if (slowpoke >= SLOWPOKE * 3)
-                   {
-                       /*
-                        * Did you take too long thinking about it? If so,
-                        * you probably need to be asked this one more
-                        * often...
-                        */
-                       randomfactor[correctchar] += (3 * RANDOMINCWORSE / 2);
-                       if (randomfactor[correctchar] > RANDOMMAX)
-                           randomfactor[correctchar] = RANDOMMAX;
-
-                       /*
-                        * Hits this slow shouldn't count! You were obviously
-                        * just guessing! (But it doesn't count as an error
-                        * either.)
-                        */
-                       totalhitcount--;
-                   }
-                   else if (slowpoke > FASTPOKE)
-                   {
-                       randomfactor[correctchar] +=
-                        (slowpoke * RANDOMINCWORSE) / (2 * SLOWPOKE);
-                       if (randomfactor[correctchar] > RANDOMMAX)
-                           randomfactor[correctchar] = RANDOMMAX;
-                   }
-                   else if (slowpoke <= (FASTPOKE / 2))
-                   {
-                       /*
-                        * Ask ones that you quickly answer correctly less
-                        * often!
-                        */
-                       randomfactor[correctchar] -= (3 * RANDOMINCBETTER / 2);
-                       /*
-                        * Don't let randomfactor hit 0, or you'll NEVER be
-                        * asked this one AGAIN!
-                        */
-                       if (randomfactor[correctchar] < 1)
-                           randomfactor[correctchar] = 1;
-                   }
-                   else if (slowpoke <= FASTPOKE)
-                   {
-                       randomfactor[correctchar] -= (RANDOMINCBETTER / 2);
-                       if (randomfactor[correctchar] < 1)
-                           randomfactor[correctchar] = 1;
-                   }
-               }
-           }
-
-       }
-       testlength -= testinc;
-       behindness -= testinc;
-       yourlength -= yourinc;
-    }
-
-/*
- * If there are some extra white space characters in the input queue
- * it's OK, we'll get to them next time or we'll clean them out at the
- * end.
- */
-    return errorcount;
-}
-
-
-/*----------------------------------------*/
-
-static void
-tone (float hertz, float duration, float amplitude)
-{
-    Beep ((int) (duration * 1000), (int) (amplitude * 100), (int) hertz);
-}
-
-
-static void
-toneflush (void)
-{
-    BeepWait ();
-}
-
-
-/*----------------------------------------*/
-
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <termio.h>
-struct termio   oldtermgtty;
-struct termio   termgtty;
-static char    *terminal = "/dev/tty";
-static int      termfd;
-static int      termopen = 0;
-static int      oldflgs, newflgs;
-
-static void
-openterminal (void)
-{
-    /* get parameters and open terminal */
-
-    termfd = open (terminal, O_RDWR | O_NDELAY, 0);
-    ioctl (termfd, TCGETA, &termgtty);
-    oldtermgtty = termgtty;
-    if (typeaway != LETMESEE)
-       termgtty.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
-    termgtty.c_lflag &= ~ICANON;
-    termgtty.c_cc[VMIN] = 1;
-    termgtty.c_cc[VTIME] = 0;
-    ioctl (termfd, TCSETAW, &termgtty);
-    termopen = 1;
-}
-
-static int
-readterminal (char **string)
-{
-/* This must be declared static! */
-static char     line[TESTBUFSZ];
-int             n;
-
-    n = read (termfd, line, sizeof (line) - 1);
-
-    if (n > 0)
-    {
-       line[n] = '\0';
-       *string = line;
-    }
-    else
-       *string = NULL;
-
-    return n;
-}
-
-static void
-closeterminal (void)
-{
-    ioctl (termfd, TCSETAW, &oldtermgtty);
-    close (termfd);
-}
-
-static void
-die (void)
-{
-    cleanup ();
-    exit (1);
-}
-
-static void
-cleanup (void)
-{
-    if (termopen)
-       closeterminal ();
-    BeepCleanup ();
-}
-
-static void
-suspend (int sig)
-{
-    sigset (SIGTSTP, suspend);
-    cleanup ();
-    kill (getpid (), SIGSTOP);
-    if (termopen)
-       openterminal ();
-    BeepResume ();
-}
-
-
-/*----------------------------------------*/
-
-static int
-randomletter (void)
-{
-int             ii;
-int             sum, sum2;
-long            ranspot;
-static int      lasttime = -1;
-static long     norepeat;
-
-/*
- * This keeps the not-so-random random number generator from ignoring
- * certain characters forever!
- */
-    norepeat = ((long) time (NULL) / 31) % 17291;
-
-/*
- * All the usable letters get one unit riper.
- */
-    for (ii = 0; ii < TWOFIFTYSIX; ii++)
-    {
-       if (randomfactor[ii] > 0)
-       {
-#ifdef DEBUGG
-           fprintf (stderr, "%c: %d %d\n",
-                    (char) ii, randomfactor[ii], randomripe[ii]);
-#endif
-           randomripe[ii]++;
-       }
-    }
-
-    sum = 0;
-    for (ii = 0; ii < TWOFIFTYSIX; ii++)
-       sum += (randomfactor[ii] + (int) (randomripe[ii] / RIPECOUNT));
-
-/*
- * The low bits of random aren't very random, I don't care WHAT
- * the manual claims.
- */
-    do
-    {
-       ranspot = ((lrand48() >> 4) % sum + norepeat) % sum;
-
-       sum2 = 0;
-       for (ii = 0; ii < TWOFIFTYSIX - 1; ii++)
-       {
-           sum2 += (randomfactor[ii] + (int) (randomripe[ii] / RIPECOUNT));
-
-           if (sum2 > ranspot)
-               break;
-       }
-       /* Do it again if you got the same as last time! */
-    } while (ii == lasttime);
-
-    /* This one is FRESH again. */
-    randomripe[ii] = 0;
-    /* Remember for next time. */
-    lasttime = ii;
-
-    return ii;
-}
-
-static int
-rancomp (const void *elem1, const void *elem2)
-{
-    register int *e1 = (int *)elem1;
-    register int *e2 = (int *)elem2;
-    float           a, b;
-
-
-    a = (randomfactor[(*e1)] + (randomripe[(*e1)] / (float) RIPECOUNT));
-    b = (randomfactor[(*e2)] + (randomripe[(*e2)] / (float) RIPECOUNT));
-
-    if (a == b)
-       return 0;
-    else if (a > b)
-       return -1;
-    else
-       return 1;
-}
-
-static void
-report (void)
-{
-    int ii, jj, count;
-    float sum; 
-    int randomstr[TWOFIFTYSIX];
-
-    printf ("\nCurrent words per minute: %.1f\n", words_per_minute);
-
-    printf ("Total hits %d, misses %d", totalhitcount, totalmisscount);
-    if (totalmisscount > 0)
-       printf (", hit per miss ratio %.1f\n", (float) totalhitcount / (float) totalmisscount);
-    else
-       printf ("\n");
-
-    if (randomletters)
-    {
-       printf ("Most to least frequent choices:\n");
-       count = 0;
-       sum = 0.;
-       for (ii = 0; ii < TWOFIFTYSIX; ii++)
-       {
-           if (randomfactor[ii] > 0)
-           {
-               sum += (randomfactor[ii] + (randomripe[ii] / (float) RIPECOUNT));
-               randomstr[count] = ii;
-               count++;
-           }
-       }
-
-       qsort ((char *) randomstr, count, sizeof (randomstr[0]), rancomp);
-
-       for (ii = 0; ii < count; ii++)
-       {
-/*
- * Insert a space for each jump across an integer.
- * The normalization (count/sum) ensures that if all
- * letters were equally probable, they would all have value 1.
- * Since they are not generally equally probable, then 1 is just the average.
- * Thus the rightmost space in the printout marks where the average is.
- * Further left spaces separate off blocks of letters that are approximately
- * twice as probable as the average, three times, etc.
- */
-           if (ii > 0)
-           {
-               for (jj = 0; jj <
-                    (int) (
-                           (randomfactor[randomstr[ii - 1]] + (randomripe[randomstr[ii - 1]] / (float) RIPECOUNT))
-                           * count / sum) -
-                    (int) (
-                           (randomfactor[randomstr[ii]] + (randomripe[randomstr[ii]] / (float) RIPECOUNT))
-                           * count / sum);
-                    jj++)
-                   printf (" ");
-           }
-           printf ("%c", (char) randomstr[ii]);
-       }
-       printf ("\n");
-    }
-
-    /*
-     * So you don't get penalized for being "slow" after this.
-     */
-    if (charbychar)
-       slowpoke = SLOWPOKEMAX + 1;
-
-    fflush (stdout);
-}