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.2 (Berkeley) 03/20/94"; 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 * I found an error in the table. The same error is found in the SunOS 4.1.1 40 * version of bcd. It has apparently been around a long time. The error caused 41 * 'Q' and 'R' to have the same punch code. I only noticed the error due to 42 * someone pointing it out to me when the program was used to print a cover 43 * for an APA! The table was wrong in 4 places. The other error was masked 44 * by the fact that the input is converted to upper case before lookup. 45 * 46 * Dyane Bruce 47 * db@diana.ocunix.on.ca 48 * Nov 5, 1993 49 */ 50 51 #include <sys/types.h> 52 53 #include <stdio.h> 54 #include <ctype.h> 55 56 u_short holes[256] = { 57 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 58 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 59 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 60 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 61 0x0, 0x206, 0x20a, 0x042, 0x442, 0x222, 0x800, 0x406, 62 0x812, 0x412, 0x422, 0xa00, 0x242, 0x400, 0x842, 0x300, 63 0x200, 0x100, 0x080, 0x040, 0x020, 0x010, 0x008, 0x004, 64 0x002, 0x001, 0x012, 0x40a, 0x80a, 0x212, 0x00a, 0x006, 65 0x022, 0x900, 0x880, 0x840, 0x820, 0x810, 0x808, 0x804, 66 0x802, 0x801, 0x500, 0x480, 0x440, 0x420, 0x410, 0x408, 67 0x404, 0x402, 0x401, 0x280, 0x240, 0x220, 0x210, 0x208, 68 0x204, 0x202, 0x201, 0x082, 0x822, 0x600, 0x282, 0x30f, 69 0x900, 0x880, 0x840, 0x820, 0x810, 0x808, 0x804, 0x802, 70 0x801, 0x500, 0x480, 0x440, 0x420, 0x410, 0x408, 0x404, 71 0x402, 0x401, 0x280, 0x240, 0x220, 0x210, 0x208, 0x204, 72 0x202, 0x201, 0x082, 0x806, 0x822, 0x600, 0x282, 0x0, 73 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 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 0x206, 0x20a, 0x042, 0x442, 0x222, 0x800, 0x406, 0x812, 78 0x412, 0x422, 0xa00, 0x242, 0x400, 0x842, 0x300, 0x200, 79 0x100, 0x080, 0x040, 0x020, 0x010, 0x008, 0x004, 0x002, 80 0x001, 0x012, 0x40a, 0x80a, 0x212, 0x00a, 0x006, 0x022, 81 0x900, 0x880, 0x840, 0x820, 0x810, 0x808, 0x804, 0x802, 82 0x801, 0x500, 0x480, 0x440, 0x420, 0x410, 0x408, 0x404, 83 0x402, 0x401, 0x280, 0x240, 0x220, 0x210, 0x208, 0x204, 84 0x202, 0x201, 0x082, 0x806, 0x822, 0x600, 0x282, 0x30f, 85 0x900, 0x880, 0x840, 0x820, 0x810, 0x808, 0x804, 0x802, 86 0x801, 0x500, 0x480, 0x440, 0x420, 0x410, 0x408, 0x404, 87 0x402, 0x401, 0x280, 0x240, 0x220, 0x210, 0x208, 0x204, 88 0x202, 0x201, 0x082, 0x806, 0x822, 0x600, 0x282, 0x0 89 }; 90 91 /* 92 * i'th bit of w. 93 */ 94 #define bit(w,i) ((w)&(1<<(i))) 95 96 int 97 main(argc, argv) 98 int argc; 99 char **argv; 100 { 101 char cardline[80]; 102 103 /* 104 * The original bcd prompts with a "%" when reading from stdin, 105 * but this seems kind of silly. So this one doesn't. 106 */ 107 108 if (argc > 1) { 109 while (--argc) 110 printcard(*++argv); 111 } else 112 while (fgets(cardline, sizeof(cardline), stdin)) 113 printcard(cardline); 114 exit(0); 115 } 116 117 #define COLUMNS 48 118 119 printcard(str) 120 register char *str; 121 { 122 static char rowchars[] = " 123456789"; 123 register int i, row; 124 register char *p; 125 char *index(); 126 127 /* ruthlessly remove newlines and truncate at 48 characters. */ 128 if ((p = index(str, '\n'))) 129 *p = '\0'; 130 131 if (strlen(str) > COLUMNS) 132 str[COLUMNS] = '\0'; 133 134 /* make string upper case. */ 135 for (p = str; *p; ++p) 136 if (isascii(*p) && islower(*p)) 137 *p = toupper(*p); 138 139 /* top of card */ 140 putchar(' '); 141 for (i = 1; i <= COLUMNS; ++i) 142 putchar('_'); 143 putchar('\n'); 144 145 /* 146 * line of text. Leave a blank if the character doesn't have 147 * a hole pattern. 148 */ 149 p = str; 150 putchar('/'); 151 for (i = 1; *p; i++, p++) 152 if (holes[*p]) 153 putchar(*p); 154 else 155 putchar(' '); 156 while (i++ <= COLUMNS) 157 putchar(' '); 158 putchar('|'); 159 putchar('\n'); 160 161 /* 162 * 12 rows of potential holes; output a ']', which looks kind of 163 * like a hole, if the appropriate bit is set in the holes[] table. 164 * The original bcd output a '[', a backspace, five control A's, 165 * and then a ']'. This seems a little excessive. 166 */ 167 for (row = 0; row <= 11; ++row) { 168 putchar('|'); 169 for (i = 0, p = str; *p; i++, p++) { 170 if (bit(holes[*p], 11 - row)) 171 putchar(']'); 172 else 173 putchar(rowchars[row]); 174 } 175 while (i++ < COLUMNS) 176 putchar(rowchars[row]); 177 putchar('|'); 178 putchar('\n'); 179 } 180 181 /* bottom of card */ 182 putchar('|'); 183 for (i = 1; i <= COLUMNS; i++) 184 putchar('_'); 185 putchar('|'); 186 putchar('\n'); 187 } 188