[alt.tv.twin-peaks] Owls

phillip@soda.Berkeley.EDU (Phillip "Edward" Nunez) (01/19/91)

The following program may be of vast interest to many of you out there.
It was written by me.  It is the second version, the eagerly-awaited
re-release, of the Owlspeak program everyone was so extatic about!

It is a filter program, much like the rather infamous 'jive'.

  How to make the program:
  -----------------------

Save this article to disk, and then delete all of the lines up to (and
including) the "CUT HERE" line.  Then you need to compile it.  For the
examples below, the filename is "owlspeak.c".

If you are using the Nunez C Compiler, simply enter the command line:

Phillip [17]:  philcc -cool owlspeak.c -o owlspeak

If you are using something like gcc, you should type something like:

  gcc owlspeak.c -o owlspeak -O -Dphillip

But if you don't compile it with philcc, it won't be as good.  And in any
case, you need a compiler able to grok ANSI C.

Run the program by piping operations through it.  For example, to read
the message of the day, use "cat /etc/motd | owlspeak".

Have some fun.  Pipe your friend's .forward through owlspeak.  Rlogin to
your favorite machine through owlspeak.  The possibilities are endless.

Send all bug reports, comments, and suggestions to phillip@soda.berkeley.edu.

---------- CUT HERE ---------
/* Owlspeak, by Phillip "Edward" Nunez (phillip@soda.berkeley.edu) */

static char *VERSION = "/OWLSPEAK/VERSION/V002/PHILLIP/PHILLIP/PHILLIP\n";

                          /* Phillip in the above refers to phillip@soda,
                             Phillip "Edward" Nunez.                      */

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

#ifdef X11
  #include <X11/X.h>
#endif                          /* So I can post this to comp.sources.x */

#define USAGE "/USAGE/U000/CAT/FILE/PIPE/OWLSPEAK/OPTION/V/OPTIONAL\n"
#define PUNCT "@#$%^&*()_+|~-=\\`{}[]:\";'<>?,./"
#define MESSINESS 6
#define MAXNUM 01000                    /* In octal, of course */

#define PROBABILITY 9                   /* Chances are 1 in PROBABILITY
                                           (decimal) that a strange message
                                           will appear per random slashed
                                           octal number generated and per
                                           line of text.          */

/*  You might want to nazi the source code since you don't want stupid
        users to know everything that the program might do to their
        messages unless they run it a lot.                              */

char *quotes[] = {
        "/THE/OWLS/ARE/NOT/WHAT/THEY/SEEM",
        "/COOPER/COOPER/COOPER",
        "/DAMN/GOOD/COFFEE",
        "/I/LIKE/WHALES",
        "//APPETITE//SATISFACTION/",
        "/CIRCLE/OF/GOLD",
        "/HUMAN/HOST",
        "/WILL/NOT/BE/WRONG",
        "/SMILING/BAG",
        "/DEATH/BAG",
        "/ANOTHER/PLACE",
        "/THE/BIRDS/SING/A/PRETTY/SONG",
        "/ALWAYS/MUSIC/IN/THE/AIR",
        "/THROUGH/THE/DARKNESS/OF/FUTURE/PAST",
        "/FIRE/WALK/WITH/ME",
        "/WORK/RELATED",
        "/MILK/WILL/GET/COLD/ON/YOU",
        "/HEARD/ABOUT/YOU",
        "/ADHERENCE/TO/FANTASY",
        "/MULTIPLE/SHALLOW/WOUNDS",
        "/WHEN/YOU/LEAST/EXPECT/IT",
        "/GOOD/VEHICLE",
        "/LETS/ROCK",
        "/DANCE",
        "/BEND/BACK",
        "/LEO/NO/R000/LEO/NO",
        "/HAPPY/GENERATION",
        "/PAWNS/WILL/BE/EXPENDABLE",
        "/WHITE/LODGE",
        "/WHAT/A/WONDERFUL/WORLD",
        "/SMOKED/CHEESE/PIG",
        "/WHOLE/DAMN/TOWN",
        "/WOOD/TICK",
        "/FISH/IN/THE/PERCOLATOR",
        "/FULL/OF/SECRETS",
        "/WOODEN/SHOE",
        "/ONE/LEG/AT/A/TIME",
        "/WHOLE/DAMN/TOWN",
        "/LET/A/SMILE/BE/YOUR/UMBRELLA",
        "/MAIRZY",
        "/POOR/CHET"
};

#define QUOTECOUNT (sizeof(quotes) / sizeof(int))

const char *nums[] = {                          /* viva INTERCAL */

        "/OH", "/ONE", "/TWO", "/THREE", "/FOUR", "/FIVE", "/SIX", "/SEVEN",
        "/EIGHT", "/NINER"
};

int pindex(char c) {            /* Written because I was having problems
        char *s = PUNCT;                with strchr() and subtraction and
        while (*s)                      getting negative numbers on some
                if (c == *s++)          systems.                          */
                        return c;
        return -1;
}

void Printnum(char c, int n) {
        fprintf(stdout, "/%c%03o", c, n);
}

char *cutspace(char *c) {
        while ((*c == ' ') || (*c == '\t')) c++;
        return c;
}

void qstatic(void) {
        int i;

        i = random() % QUOTECOUNT;
        fprintf(stdout, quotes[i]);
}

void sstatic(void) {
        int i;

        i = random() % MESSINESS;
        while (i-- > 0)
                Printnum(random() % 26 + 'A', random() % MAXNUM);
        if (random() % PROBABILITY) return;
        qstatic();
        sstatic();
}

void number(int n) {                    /* viva INTERCAL again */

        if (n == 0) {
                fprintf(stdout, (random() % 2) ? "/ZERO" : "/OH");
                return;
        } else if (n == 9) {
                fprintf(stdout, (random() % 2) ? "/NINE" : "/NINER");
                return;
        }
        fprintf(stdout, nums[n]);
}

char *process(char *c) {
        int d;
        static int nline = 0;

        if (*c == '\n') {
                if (nline) sstatic();
                fprintf(stdout, "/C000");
                if (!(random() % PROBABILITY)) {
                        qstatic();
                        fprintf(stdout, "/C000");
                }
                nline = 1;
                return ++c;
        }

        nline = 0;
        if (isdigit(*c)) {
                number(*c - '0');
                return ++c;
        }
        if (isalpha(*c)) {
                fputc('/', stdout);
                while (isalpha(*c))
                        fputc(isupper(*c) ? *c++ : toupper(*c++), stdout);
                return c;
        }

        if (random() % 2) return ++c;       /* Don't copy 100% of punctuation,
                                                because it starts to get
                                                messy if you do.            */

        d = pindex(*c);
        if (d == -1) fprintf(stdout, "/C000");
                else Printnum('C', d);
        return ++c;
}

void main(int argc, char *argv[]) {
        char *s, *t = (char *)malloc(BUFSIZ);

        srandom(time(0));
        if (argc > 1) {
                fprintf(stdout, *(argv[1] + 1) == 'v' ? VERSION : USAGE);
                exit(0);
        }
        sstatic();
        while (fgets((s = t), BUFSIZ - 1, stdin) != NULL)
                while (*s) s = process(cutspace(s));
        sstatic();
        fprintf(stdout, "\n");
}