xref: /original-bsd/games/bcd/bcd.c (revision 4405f301)
1 /*
2  * Copyright (c) 1989, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Steve Hayman of the Indiana University Computer Science Dept.
7  *
8  * %sccs.include.redist.c%
9  */
10 
11 #ifndef lint
12 static char copyright[] =
13 "@(#) Copyright (c) 1989, 1993\n\
14 	The Regents of the University of California.  All rights reserved.\n";
15 #endif /* not lint */
16 
17 #ifndef lint
18 static char sccsid[] = "@(#)bcd.c	8.1 (Berkeley) 05/31/93";
19 #endif /* not lint */
20 
21 /*
22  * bcd --
23  *
24  * Read one line of standard input and produce something that looks like a
25  * punch card.  An attempt to reimplement /usr/games/bcd.  All I looked at
26  * was the man page.
27  *
28  * I couldn't find a BCD table handy so I wrote a shell script to deduce what
29  * the patterns were that the old bcd was using for each possible 8-bit
30  * character.  These are the results -- the low order 12 bits represent the
31  * holes.  (A 1 bit is a hole.)  These may be wrong, but they match the old
32  * program!
33  *
34  * Steve Hayman
35  * sahayman@iuvax.cs.indiana.edu
36  * 1989 11 30
37  */
38 
39 #include <sys/types.h>
40 #include <stdio.h>
41 #include <ctype.h>
42 
43 u_short holes[256] = {
44     0x0,	 0x0,	  0x0,	   0x0,	    0x0,     0x0,     0x0,     0x0,
45     0x0,	 0x0,	  0x0,	   0x0,	    0x0,     0x0,     0x0,     0x0,
46     0x0,	 0x0,	  0x0,	   0x0,	    0x0,     0x0,     0x0,     0x0,
47     0x0,	 0x0,	  0x0,	   0x0,	    0x0,     0x0,     0x0,     0x0,
48     0x0,	 0x206,	  0x20a,   0x042,   0x442,   0x222,   0x800,   0x406,
49     0x812,	 0x412,	  0x422,   0xa00,   0x242,   0x400,   0x842,   0x300,
50     0x200,	 0x100,	  0x080,   0x040,   0x020,   0x010,   0x008,   0x004,
51     0x002,	 0x001,	  0x012,   0x40a,   0x80a,   0x212,   0x00a,   0x006,
52     0x022,	 0x900,	  0x880,   0x840,   0x820,   0x810,   0x808,   0x804,
53     0x802,	 0x801,	  0x500,   0x480,   0x440,   0x420,   0x410,   0x408,
54     0x404,	 0x402,	  0x402,   0x280,   0x240,   0x220,   0x210,   0x208,
55     0x204,	 0x202,	  0x201,   0x082,   0x822,   0x600,   0x282,   0x30f,
56     0x900,	 0x880,	  0x840,   0x820,   0x810,   0x808,   0x804,   0x802,
57     0x801,	 0x500,	  0x480,   0x440,   0x420,   0x410,   0x408,   0x404,
58     0x402,	 0x402,	  0x280,   0x240,   0x220,   0x210,   0x208,   0x204,
59     0x202,	 0x201,	  0x082,   0x806,   0x822,   0x600,   0x282,   0x0,
60     0x0,	 0x0,	  0x0,	   0x0,	    0x0,     0x0,     0x0,     0x0,
61     0x0,	 0x0,	  0x0,	   0x0,	    0x0,     0x0,     0x0,     0x0,
62     0x0,	 0x0,	  0x0,	   0x0,	    0x0,     0x0,     0x0,     0x0,
63     0x0,	 0x0,	  0x0,	   0x0,	    0x0,     0x0,     0x0,     0x0,
64     0x206,	 0x20a,	  0x042,   0x442,   0x222,   0x800,   0x406,   0x812,
65     0x412,	 0x422,	  0xa00,   0x242,   0x400,   0x842,   0x300,   0x200,
66     0x100,	 0x080,	  0x040,   0x020,   0x010,   0x008,   0x004,   0x002,
67     0x001,	 0x012,	  0x40a,   0x80a,   0x212,   0x00a,   0x006,   0x022,
68     0x900,	 0x880,	  0x840,   0x820,   0x810,   0x808,   0x804,   0x802,
69     0x801,	 0x500,	  0x480,   0x440,   0x420,   0x410,   0x408,   0x404,
70     0x402,	 0x402,	  0x280,   0x240,   0x220,   0x210,   0x208,   0x204,
71     0x202,	 0x201,	  0x082,   0x806,   0x822,   0x600,   0x282,   0x30f,
72     0x900,	 0x880,	  0x840,   0x820,   0x810,   0x808,   0x804,   0x802,
73     0x801,	 0x500,	  0x480,   0x440,   0x420,   0x410,   0x408,   0x404,
74     0x402,	 0x402,	  0x280,   0x240,   0x220,   0x210,   0x208,   0x204,
75     0x202,	 0x201,	  0x082,   0x806,   0x822,   0x600,   0x282,   0x0
76 };
77 
78 /*
79  * i'th bit of w.
80  */
81 #define	bit(w,i)	((w)&(1<<(i)))
82 
83 main(argc, argv)
84 	int argc;
85 	char **argv;
86 {
87 	char cardline[80];
88 
89 	/*
90 	 * The original bcd prompts with a "%" when reading from stdin,
91 	 * but this seems kind of silly.  So this one doesn't.
92 	 */
93 
94 	if (argc > 1) {
95 		while (--argc)
96 			printcard(*++argv);
97 	} else
98 		while (fgets(cardline, sizeof(cardline), stdin))
99 			printcard(cardline);
100 	exit(0);
101 }
102 
103 #define	COLUMNS	48
104 
105 printcard(str)
106 	register char *str;
107 {
108 	static char rowchars[] = "   123456789";
109 	register int i, row;
110 	register char *p;
111 	char *index();
112 
113 	/* ruthlessly remove newlines and truncate at 48 characters. */
114 	if ((p = index(str, '\n')))
115 		*p = '\0';
116 
117 	if (strlen(str) > COLUMNS)
118 		str[COLUMNS] = '\0';
119 
120 	/* make string upper case. */
121 	for (p = str; *p; ++p)
122 		if (isascii(*p) && islower(*p))
123 			*p = toupper(*p);
124 
125 	 /* top of card */
126 	putchar(' ');
127 	for (i = 1; i <= COLUMNS; ++i)
128 		putchar('_');
129 	putchar('\n');
130 
131 	/*
132 	 * line of text.  Leave a blank if the character doesn't have
133 	 * a hole pattern.
134 	 */
135 	p = str;
136 	putchar('/');
137 	for (i = 1; *p; i++, p++)
138 		if (holes[*p])
139 			putchar(*p);
140 		else
141 			putchar(' ');
142 	while (i++ <= COLUMNS)
143 		putchar(' ');
144 	putchar('|');
145 	putchar('\n');
146 
147 	/*
148 	 * 12 rows of potential holes; output a ']', which looks kind of
149 	 * like a hole, if the appropriate bit is set in the holes[] table.
150 	 * The original bcd output a '[', a backspace, five control A's,
151 	 * and then a ']'.  This seems a little excessive.
152 	 */
153 	for (row = 0; row <= 11; ++row) {
154 		putchar('|');
155 		for (i = 0, p = str; *p; i++, p++) {
156 			if (bit(holes[*p], 11 - row))
157 				putchar(']');
158 			else
159 				putchar(rowchars[row]);
160 		}
161 		while (i++ < COLUMNS)
162 			putchar(rowchars[row]);
163 		putchar('|');
164 		putchar('\n');
165 	}
166 
167 	/* bottom of card */
168 	putchar('|');
169 	for (i = 1; i <= COLUMNS; i++)
170 		putchar('_');
171 	putchar('|');
172 	putchar('\n');
173 }
174