1 /* $OpenBSD: bcd.c,v 1.13 2009/10/27 23:59:24 deraadt Exp $ */ 2 /* $NetBSD: bcd.c,v 1.6 1995/04/24 12:22:23 cgd Exp $ */ 3 4 /* 5 * Copyright (c) 1989, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * This code is derived from software contributed to Berkeley by 9 * Steve Hayman of the Indiana University Computer Science Dept. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 /* 37 * bcd -- 38 * 39 * Read one line of standard input and produce something that looks like a 40 * punch card. An attempt to reimplement /usr/games/bcd. All I looked at 41 * was the man page. 42 * 43 * I couldn't find a BCD table handy so I wrote a shell script to deduce what 44 * the patterns were that the old bcd was using for each possible 8-bit 45 * character. These are the results -- the low order 12 bits represent the 46 * holes. (A 1 bit is a hole.) These may be wrong, but they match the old 47 * program! 48 * 49 * Steve Hayman 50 * sahayman@iuvax.cs.indiana.edu 51 * 1989 11 30 52 * 53 * 54 * I found an error in the table. The same error is found in the SunOS 4.1.1 55 * version of bcd. It has apparently been around a long time. The error caused 56 * 'Q' and 'R' to have the same punch code. I only noticed the error due to 57 * someone pointing it out to me when the program was used to print a cover 58 * for an APA! The table was wrong in 4 places. The other error was masked 59 * by the fact that the input is converted to upper case before lookup. 60 * 61 * Dyane Bruce 62 * db@diana.ocunix.on.ca 63 * Nov 5, 1993 64 */ 65 66 #include <sys/types.h> 67 #include <stdio.h> 68 #include <stdlib.h> 69 #include <string.h> 70 #include <ctype.h> 71 #include <unistd.h> 72 73 u_short holes[256] = { 74 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 75 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 76 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 77 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 78 0x0, 0x206, 0x20a, 0x042, 0x442, 0x222, 0x800, 0x406, 79 0x812, 0x412, 0x422, 0xa00, 0x242, 0x400, 0x842, 0x300, 80 0x200, 0x100, 0x080, 0x040, 0x020, 0x010, 0x008, 0x004, 81 0x002, 0x001, 0x012, 0x40a, 0x80a, 0x212, 0x00a, 0x006, 82 0x022, 0x900, 0x880, 0x840, 0x820, 0x810, 0x808, 0x804, 83 0x802, 0x801, 0x500, 0x480, 0x440, 0x420, 0x410, 0x408, 84 0x404, 0x402, 0x401, 0x280, 0x240, 0x220, 0x210, 0x208, 85 0x204, 0x202, 0x201, 0x082, 0x822, 0x600, 0x282, 0x30f, 86 0x900, 0x880, 0x840, 0x820, 0x810, 0x808, 0x804, 0x802, 87 0x801, 0x500, 0x480, 0x440, 0x420, 0x410, 0x408, 0x404, 88 0x402, 0x401, 0x280, 0x240, 0x220, 0x210, 0x208, 0x204, 89 0x202, 0x201, 0x082, 0x806, 0x822, 0x600, 0x282, 0x0, 90 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 91 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 92 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 93 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 94 0x206, 0x20a, 0x042, 0x442, 0x222, 0x800, 0x406, 0x812, 95 0x412, 0x422, 0xa00, 0x242, 0x400, 0x842, 0x300, 0x200, 96 0x100, 0x080, 0x040, 0x020, 0x010, 0x008, 0x004, 0x002, 97 0x001, 0x012, 0x40a, 0x80a, 0x212, 0x00a, 0x006, 0x022, 98 0x900, 0x880, 0x840, 0x820, 0x810, 0x808, 0x804, 0x802, 99 0x801, 0x500, 0x480, 0x440, 0x420, 0x410, 0x408, 0x404, 100 0x402, 0x401, 0x280, 0x240, 0x220, 0x210, 0x208, 0x204, 101 0x202, 0x201, 0x082, 0x806, 0x822, 0x600, 0x282, 0x30f, 102 0x900, 0x880, 0x840, 0x820, 0x810, 0x808, 0x804, 0x802, 103 0x801, 0x500, 0x480, 0x440, 0x420, 0x410, 0x408, 0x404, 104 0x402, 0x401, 0x280, 0x240, 0x220, 0x210, 0x208, 0x204, 105 0x202, 0x201, 0x082, 0x806, 0x822, 0x600, 0x282, 0x0 106 }; 107 108 /* 109 * i'th bit of w. 110 */ 111 #define bit(w,i) ((w)&(1<<(i))) 112 113 void printcard(char *); 114 115 int 116 main(int argc, char *argv[]) 117 { 118 char cardline[80]; 119 120 /* 121 * The original bcd prompts with a "%" when reading from stdin, 122 * but this seems kind of silly. So this one doesn't. 123 */ 124 125 if (argc > 1) { 126 while (--argc) 127 printcard(*++argv); 128 } else 129 while (fgets(cardline, sizeof(cardline), stdin)) 130 printcard(cardline); 131 exit(0); 132 } 133 134 #define COLUMNS 48 135 136 void 137 printcard(char *str) 138 { 139 static const char rowchars[] = " 123456789"; 140 int i, row; 141 char *p; 142 143 /* ruthlessly remove newlines and truncate at 48 characters. */ 144 str[strcspn(str, "\n")] = '\0'; 145 146 if (strlen(str) > COLUMNS) 147 str[COLUMNS] = '\0'; 148 149 /* make string upper case. */ 150 for (p = str; *p; ++p) 151 if (isascii(*p) && islower(*p)) 152 *p = toupper(*p); 153 154 /* top of card */ 155 putchar(' '); 156 for (i = 1; i <= COLUMNS; ++i) 157 putchar('_'); 158 putchar('\n'); 159 160 /* 161 * line of text. Leave a blank if the character doesn't have 162 * a hole pattern. 163 */ 164 p = str; 165 putchar('/'); 166 for (i = 1; *p; i++, p++) 167 if (holes[(int)*p]) 168 putchar(*p); 169 else 170 putchar(' '); 171 while (i++ <= COLUMNS) 172 putchar(' '); 173 putchar('|'); 174 putchar('\n'); 175 176 /* 177 * 12 rows of potential holes; output a ']', which looks kind of 178 * like a hole, if the appropriate bit is set in the holes[] table. 179 * The original bcd output a '[', a backspace, five control A's, 180 * and then a ']'. This seems a little excessive. 181 */ 182 for (row = 0; row <= 11; ++row) { 183 putchar('|'); 184 for (i = 0, p = str; *p; i++, p++) { 185 if (bit(holes[(int)*p], 11 - row)) 186 putchar(']'); 187 else 188 putchar(rowchars[row]); 189 } 190 while (i++ < COLUMNS) 191 putchar(rowchars[row]); 192 putchar('|'); 193 putchar('\n'); 194 } 195 196 /* bottom of card */ 197 putchar('|'); 198 for (i = 1; i <= COLUMNS; i++) 199 putchar('_'); 200 putchar('|'); 201 putchar('\n'); 202 } 203