139662Sbostic /*
260752Sbostic * Copyright (c) 1989, 1993
360752Sbostic * The Regents of the University of California. All rights reserved.
439662Sbostic *
539662Sbostic * This code is derived from software contributed to Berkeley by
658187Sbostic * Steve Hayman of the Indiana University Computer Science Dept.
739662Sbostic *
842567Sbostic * %sccs.include.redist.c%
939662Sbostic */
108857Smckusick
1139662Sbostic #ifndef lint
1260752Sbostic static char copyright[] =
1360752Sbostic "@(#) Copyright (c) 1989, 1993\n\
1460752Sbostic The Regents of the University of California. All rights reserved.\n";
1539662Sbostic #endif /* not lint */
168857Smckusick
1739662Sbostic #ifndef lint
18*66408Sbostic static char sccsid[] = "@(#)bcd.c 8.2 (Berkeley) 03/20/94";
1939662Sbostic #endif /* not lint */
2039662Sbostic
2139662Sbostic /*
2239662Sbostic * bcd --
2339662Sbostic *
2439662Sbostic * Read one line of standard input and produce something that looks like a
2539662Sbostic * punch card. An attempt to reimplement /usr/games/bcd. All I looked at
2639662Sbostic * was the man page.
2739662Sbostic *
2839662Sbostic * I couldn't find a BCD table handy so I wrote a shell script to deduce what
2939662Sbostic * the patterns were that the old bcd was using for each possible 8-bit
3039662Sbostic * character. These are the results -- the low order 12 bits represent the
3139662Sbostic * holes. (A 1 bit is a hole.) These may be wrong, but they match the old
3239662Sbostic * program!
3339662Sbostic *
3439662Sbostic * Steve Hayman
3539662Sbostic * sahayman@iuvax.cs.indiana.edu
3639662Sbostic * 1989 11 30
37*66408Sbostic *
38*66408Sbostic *
39*66408Sbostic * I found an error in the table. The same error is found in the SunOS 4.1.1
40*66408Sbostic * version of bcd. It has apparently been around a long time. The error caused
41*66408Sbostic * 'Q' and 'R' to have the same punch code. I only noticed the error due to
42*66408Sbostic * someone pointing it out to me when the program was used to print a cover
43*66408Sbostic * for an APA! The table was wrong in 4 places. The other error was masked
44*66408Sbostic * by the fact that the input is converted to upper case before lookup.
45*66408Sbostic *
46*66408Sbostic * Dyane Bruce
47*66408Sbostic * db@diana.ocunix.on.ca
48*66408Sbostic * Nov 5, 1993
4939662Sbostic */
5039662Sbostic
5139662Sbostic #include <sys/types.h>
52*66408Sbostic
5339662Sbostic #include <stdio.h>
5439662Sbostic #include <ctype.h>
5539662Sbostic
5639662Sbostic u_short holes[256] = {
5739662Sbostic 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
5839662Sbostic 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
5939662Sbostic 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
6039662Sbostic 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
6139662Sbostic 0x0, 0x206, 0x20a, 0x042, 0x442, 0x222, 0x800, 0x406,
6239662Sbostic 0x812, 0x412, 0x422, 0xa00, 0x242, 0x400, 0x842, 0x300,
6339662Sbostic 0x200, 0x100, 0x080, 0x040, 0x020, 0x010, 0x008, 0x004,
6439662Sbostic 0x002, 0x001, 0x012, 0x40a, 0x80a, 0x212, 0x00a, 0x006,
6539662Sbostic 0x022, 0x900, 0x880, 0x840, 0x820, 0x810, 0x808, 0x804,
6639662Sbostic 0x802, 0x801, 0x500, 0x480, 0x440, 0x420, 0x410, 0x408,
67*66408Sbostic 0x404, 0x402, 0x401, 0x280, 0x240, 0x220, 0x210, 0x208,
6839662Sbostic 0x204, 0x202, 0x201, 0x082, 0x822, 0x600, 0x282, 0x30f,
6939662Sbostic 0x900, 0x880, 0x840, 0x820, 0x810, 0x808, 0x804, 0x802,
7039662Sbostic 0x801, 0x500, 0x480, 0x440, 0x420, 0x410, 0x408, 0x404,
71*66408Sbostic 0x402, 0x401, 0x280, 0x240, 0x220, 0x210, 0x208, 0x204,
7239662Sbostic 0x202, 0x201, 0x082, 0x806, 0x822, 0x600, 0x282, 0x0,
7339662Sbostic 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
7439662Sbostic 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
7539662Sbostic 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
7639662Sbostic 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
7739662Sbostic 0x206, 0x20a, 0x042, 0x442, 0x222, 0x800, 0x406, 0x812,
7839662Sbostic 0x412, 0x422, 0xa00, 0x242, 0x400, 0x842, 0x300, 0x200,
7939662Sbostic 0x100, 0x080, 0x040, 0x020, 0x010, 0x008, 0x004, 0x002,
8039662Sbostic 0x001, 0x012, 0x40a, 0x80a, 0x212, 0x00a, 0x006, 0x022,
8139662Sbostic 0x900, 0x880, 0x840, 0x820, 0x810, 0x808, 0x804, 0x802,
8239662Sbostic 0x801, 0x500, 0x480, 0x440, 0x420, 0x410, 0x408, 0x404,
83*66408Sbostic 0x402, 0x401, 0x280, 0x240, 0x220, 0x210, 0x208, 0x204,
8439662Sbostic 0x202, 0x201, 0x082, 0x806, 0x822, 0x600, 0x282, 0x30f,
8539662Sbostic 0x900, 0x880, 0x840, 0x820, 0x810, 0x808, 0x804, 0x802,
8639662Sbostic 0x801, 0x500, 0x480, 0x440, 0x420, 0x410, 0x408, 0x404,
87*66408Sbostic 0x402, 0x401, 0x280, 0x240, 0x220, 0x210, 0x208, 0x204,
8839662Sbostic 0x202, 0x201, 0x082, 0x806, 0x822, 0x600, 0x282, 0x0
898857Smckusick };
9039662Sbostic
9139662Sbostic /*
9239662Sbostic * i'th bit of w.
9339662Sbostic */
9439662Sbostic #define bit(w,i) ((w)&(1<<(i)))
9539662Sbostic
96*66408Sbostic int
main(argc,argv)978857Smckusick main(argc, argv)
9839662Sbostic int argc;
9939662Sbostic char **argv;
1008857Smckusick {
10139662Sbostic char cardline[80];
1028857Smckusick
10339662Sbostic /*
10439662Sbostic * The original bcd prompts with a "%" when reading from stdin,
10539662Sbostic * but this seems kind of silly. So this one doesn't.
10639662Sbostic */
10739662Sbostic
10839662Sbostic if (argc > 1) {
10939662Sbostic while (--argc)
11039662Sbostic printcard(*++argv);
1118857Smckusick } else
11239662Sbostic while (fgets(cardline, sizeof(cardline), stdin))
11339662Sbostic printcard(cardline);
11439662Sbostic exit(0);
11539662Sbostic }
11639662Sbostic
11739662Sbostic #define COLUMNS 48
11839662Sbostic
printcard(str)11939662Sbostic printcard(str)
12039662Sbostic register char *str;
12139662Sbostic {
12239662Sbostic static char rowchars[] = " 123456789";
12339662Sbostic register int i, row;
12439662Sbostic register char *p;
12539662Sbostic char *index();
12639662Sbostic
12739662Sbostic /* ruthlessly remove newlines and truncate at 48 characters. */
12839662Sbostic if ((p = index(str, '\n')))
12939662Sbostic *p = '\0';
13039662Sbostic
13139662Sbostic if (strlen(str) > COLUMNS)
13239662Sbostic str[COLUMNS] = '\0';
13339662Sbostic
13439662Sbostic /* make string upper case. */
13539662Sbostic for (p = str; *p; ++p)
13639662Sbostic if (isascii(*p) && islower(*p))
13739662Sbostic *p = toupper(*p);
13839662Sbostic
13939662Sbostic /* top of card */
14039662Sbostic putchar(' ');
14139662Sbostic for (i = 1; i <= COLUMNS; ++i)
14239662Sbostic putchar('_');
14339662Sbostic putchar('\n');
14439662Sbostic
14539662Sbostic /*
14639662Sbostic * line of text. Leave a blank if the character doesn't have
14739662Sbostic * a hole pattern.
14839662Sbostic */
14939662Sbostic p = str;
1508857Smckusick putchar('/');
15139662Sbostic for (i = 1; *p; i++, p++)
15239662Sbostic if (holes[*p])
15339662Sbostic putchar(*p);
15439662Sbostic else
15539662Sbostic putchar(' ');
15639662Sbostic while (i++ <= COLUMNS)
15739662Sbostic putchar(' ');
15839662Sbostic putchar('|');
15939662Sbostic putchar('\n');
16039662Sbostic
16139662Sbostic /*
16239662Sbostic * 12 rows of potential holes; output a ']', which looks kind of
16339662Sbostic * like a hole, if the appropriate bit is set in the holes[] table.
16439662Sbostic * The original bcd output a '[', a backspace, five control A's,
16539662Sbostic * and then a ']'. This seems a little excessive.
16639662Sbostic */
16739662Sbostic for (row = 0; row <= 11; ++row) {
1688857Smckusick putchar('|');
16939662Sbostic for (i = 0, p = str; *p; i++, p++) {
17039662Sbostic if (bit(holes[*p], 11 - row))
17139662Sbostic putchar(']');
1728857Smckusick else
17339662Sbostic putchar(rowchars[row]);
1748857Smckusick }
17539662Sbostic while (i++ < COLUMNS)
17639662Sbostic putchar(rowchars[row]);
17739662Sbostic putchar('|');
17839662Sbostic putchar('\n');
1798857Smckusick }
18039662Sbostic
18139662Sbostic /* bottom of card */
1828857Smckusick putchar('|');
18339662Sbostic for (i = 1; i <= COLUMNS; i++)
18439662Sbostic putchar('_');
18539662Sbostic putchar('|');
18639662Sbostic putchar('\n');
1878857Smckusick }
188