1 1.5 plunky /* $NetBSD: printching.c,v 1.5 2011/08/31 16:24:55 plunky Exp $ */ 2 1.1 perry 3 1.1 perry /* 4 1.1 perry * Copyright (c) 1988, 1993 5 1.1 perry * The Regents of the University of California. All rights reserved. 6 1.1 perry * 7 1.1 perry * This code is derived from software contributed to Berkeley by 8 1.1 perry * Guy Harris. 9 1.1 perry * 10 1.1 perry * Redistribution and use in source and binary forms, with or without 11 1.1 perry * modification, are permitted provided that the following conditions 12 1.1 perry * are met: 13 1.1 perry * 1. Redistributions of source code must retain the above copyright 14 1.1 perry * notice, this list of conditions and the following disclaimer. 15 1.1 perry * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 perry * notice, this list of conditions and the following disclaimer in the 17 1.1 perry * documentation and/or other materials provided with the distribution. 18 1.1 perry * 3. All advertising materials mentioning features or use of this software 19 1.1 perry * must display the following acknowledgement: 20 1.1 perry * This product includes software developed by the University of 21 1.1 perry * California, Berkeley and its contributors. 22 1.1 perry * 4. Neither the name of the University nor the names of its contributors 23 1.1 perry * may be used to endorse or promote products derived from this software 24 1.1 perry * without specific prior written permission. 25 1.1 perry * 26 1.1 perry * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 27 1.1 perry * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 1.1 perry * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 29 1.1 perry * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 30 1.1 perry * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 31 1.1 perry * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 1.1 perry * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 1.1 perry * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 1.1 perry * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 1.1 perry * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 1.1 perry * SUCH DAMAGE. 37 1.1 perry */ 38 1.1 perry 39 1.1 perry #include <sys/cdefs.h> 40 1.1 perry #ifndef lint 41 1.3 lukem __COPYRIGHT("@(#) Copyright (c) 1988, 1993\ 42 1.3 lukem The Regents of the University of California. All rights reserved."); 43 1.1 perry #endif /* not lint */ 44 1.1 perry 45 1.1 perry #ifndef lint 46 1.1 perry #if 0 47 1.1 perry static char sccsid[] = "@(#)ching.phx.c 8.1 (Berkeley) 5/31/93"; 48 1.1 perry #else 49 1.5 plunky __RCSID("$NetBSD: printching.c,v 1.5 2011/08/31 16:24:55 plunky Exp $"); 50 1.1 perry #endif 51 1.1 perry #endif /* not lint */ 52 1.1 perry 53 1.1 perry /* 54 1.1 perry * printching - Print NROFF/TROFF source of change, given the line values. 55 1.1 perry */ 56 1.1 perry #include <stdio.h> 57 1.1 perry #include <stdlib.h> 58 1.1 perry #include <string.h> 59 1.1 perry #include "ching.h" 60 1.1 perry #include "pathnames.h" 61 1.1 perry 62 1.4 dholland static int changes(void); 63 1.4 dholland static int codem(int a); 64 1.4 dholland static int doahex(void); 65 1.4 dholland static void phx(int hexagram, int flag); 66 1.1 perry 67 1.4 dholland static const struct { 68 1.1 perry int lines; /* encoded value of lines */ 69 1.1 perry int trinum; /* trigram number */ 70 1.1 perry } table[] = { 71 1.1 perry { 777, 0 }, /* 1 */ 72 1.1 perry { 887, 1 }, /* 4 */ 73 1.1 perry { 878, 2 }, /* 6 */ 74 1.1 perry { 788, 3 }, /* 7 */ 75 1.1 perry { 888, 4 }, /* 8 */ 76 1.1 perry { 778, 5 }, /* 5 */ 77 1.1 perry { 787, 6 }, /* 3 */ 78 1.1 perry { 877, 7 }, /* 2 */ 79 1.1 perry }; 80 1.1 perry 81 1.1 perry /* 82 1.1 perry * Gives hexagram number from two component trigrams. 83 1.1 perry */ 84 1.4 dholland static const int crosstab[8][8] = { 85 1.1 perry {1, 34, 5, 26, 11, 9, 14, 43}, 86 1.1 perry {25, 51, 3, 27, 24, 42, 21, 17}, 87 1.1 perry {6, 40, 29, 4, 7, 59, 64, 47}, 88 1.1 perry {33, 62, 39, 52, 15, 53, 56, 31}, 89 1.1 perry {12, 16, 8, 23, 2, 20, 35, 45}, 90 1.1 perry {44, 32, 48, 18, 46, 57, 50, 28}, 91 1.1 perry {13, 55, 63, 22, 36, 37, 30, 49}, 92 1.1 perry {10, 54, 60, 41, 19, 61, 38, 58} 93 1.1 perry }; 94 1.1 perry 95 1.4 dholland static int trigrams[6]; 96 1.4 dholland static int moving[6]; 97 1.1 perry 98 1.4 dholland static FILE *chingf; /* stream to read the hexagram file */ 99 1.1 perry 100 1.1 perry /*ARGSUSED*/ 101 1.1 perry int 102 1.1 perry main(int argc, char **argv) 103 1.1 perry { 104 1.1 perry char *hexptr; /* pointer to string of lines */ 105 1.1 perry char hexstr[6+1]; /* buffer for reading lines in */ 106 1.1 perry int i; 107 1.1 perry 108 1.1 perry if (argc < 2) 109 1.1 perry hexptr = fgets(hexstr, 6+1, stdin); 110 1.1 perry else 111 1.1 perry hexptr = argv[1]; 112 1.5 plunky if (hexptr == NULL || strlen(hexptr) != 6) { 113 1.1 perry fprintf(stderr, "What kind of a change is THAT?!?\n"); 114 1.1 perry exit(1); 115 1.1 perry } 116 1.1 perry for (i = 0; i < 6; i++) { 117 1.1 perry trigrams[i] = hexptr[i] - '0'; 118 1.1 perry if (trigrams[i] == 6 || trigrams[i] == 9) 119 1.1 perry moving[i] = 1; 120 1.1 perry else 121 1.1 perry moving[i] = 0; 122 1.1 perry } 123 1.5 plunky if ((chingf = fopen(_PATH_HEX, "r")) == NULL) { 124 1.1 perry fprintf(stderr, "ching: can't read %s\n", _PATH_HEX); 125 1.1 perry exit(2); 126 1.1 perry } 127 1.1 perry phx(doahex(), 0); 128 1.1 perry if (changes()) 129 1.1 perry phx(doahex(), 1); 130 1.1 perry exit(0); 131 1.1 perry } 132 1.1 perry 133 1.1 perry /* 134 1.1 perry * Compute the hexagram number, given the trigrams. 135 1.1 perry */ 136 1.4 dholland static int 137 1.1 perry doahex(void) 138 1.1 perry { 139 1.1 perry int lower, upper; /* encoded values of lower and upper trigrams */ 140 1.2 martin int lnum = 0, unum = 0; /* indices of upper and lower trigrams */ 141 1.1 perry int i; 142 1.1 perry 143 1.1 perry lower = codem(0); 144 1.1 perry upper = codem(3); 145 1.1 perry for (i = 0; i < 8; i++) { 146 1.1 perry if (table[i].lines == lower) 147 1.1 perry lnum = table[i].trinum; 148 1.1 perry if (table[i].lines == upper) 149 1.1 perry unum = table[i].trinum; 150 1.1 perry } 151 1.1 perry return(crosstab[lnum][unum]); 152 1.1 perry } 153 1.1 perry 154 1.1 perry /* 155 1.1 perry * Encode a trigram as a 3-digit number; the digits, from left to right, 156 1.1 perry * represent the lines. 7 is a solid (yang) line, 8 is a broken (yin) line. 157 1.1 perry */ 158 1.4 dholland static int 159 1.1 perry codem(int a) 160 1.1 perry { 161 1.1 perry int code, i; 162 1.1 perry int factor[3]; 163 1.1 perry 164 1.1 perry factor[0] = 1; 165 1.1 perry factor[1] = 10; 166 1.1 perry factor[2] = 100; 167 1.1 perry code = 0; 168 1.1 perry 169 1.1 perry for (i = a; i < a + 3; i++) { 170 1.1 perry switch(trigrams[i]) { 171 1.1 perry 172 1.1 perry case YYANG: 173 1.1 perry case OYANG: 174 1.1 perry code += factor[i%3]*7; 175 1.1 perry break; 176 1.1 perry 177 1.1 perry case OYIN: 178 1.1 perry case YYIN: 179 1.1 perry code += factor[i%3]*8; 180 1.1 perry break; 181 1.1 perry } 182 1.1 perry } 183 1.1 perry return(code); 184 1.1 perry } 185 1.1 perry 186 1.1 perry /* 187 1.1 perry * Compute the changes based on moving lines; return 1 if any lines moved, 188 1.1 perry * 0 if no lines moved. 189 1.1 perry */ 190 1.4 dholland static int 191 1.1 perry changes(void) 192 1.1 perry { 193 1.1 perry int cflag; 194 1.1 perry int i; 195 1.1 perry 196 1.1 perry cflag = 0; 197 1.1 perry for (i = 0; i < 6; i++) { 198 1.1 perry if (trigrams[i] == OYIN) { 199 1.1 perry trigrams[i] = YYANG; 200 1.1 perry cflag++; 201 1.1 perry } else if (trigrams[i] == OYANG) { 202 1.1 perry trigrams[i] = YYIN; 203 1.1 perry cflag++; 204 1.1 perry } 205 1.1 perry } 206 1.1 perry return(cflag); 207 1.1 perry } 208 1.1 perry 209 1.1 perry /* 210 1.1 perry * Print the NROFF/TROFF source of a hexagram, given the hexagram number; 211 1.1 perry * if flag is 0, print the entire source; if flag is 1, ignore the meanings 212 1.1 perry * of the lines. 213 1.1 perry */ 214 1.4 dholland static void 215 1.1 perry phx(int hexagram, int flag) 216 1.1 perry { 217 1.1 perry char textln[128+1]; /* buffer for text line */ 218 1.1 perry char *lp; /* pointer into buffer */ 219 1.1 perry int thishex; /* number of hexagram just read */ 220 1.1 perry int lineno; /* number of line read in */ 221 1.1 perry int allmoving; /* 1 if all lines are moving */ 222 1.1 perry int i; 223 1.1 perry 224 1.1 perry /* 225 1.1 perry * Search for the hexagram; it begins with a line of the form 226 1.1 perry * .H <hexagram number> <other data>. 227 1.1 perry */ 228 1.1 perry rewind(chingf); 229 1.1 perry for (;;) { 230 1.5 plunky if (fgets(textln, sizeof(textln), chingf) == NULL) { 231 1.1 perry fprintf(stderr, "ching: Hexagram %d missing\n", 232 1.1 perry hexagram); 233 1.1 perry exit(3); 234 1.1 perry } 235 1.1 perry lp = &textln[0]; 236 1.1 perry if (*lp++ != '.' || *lp++ != 'H') 237 1.1 perry continue; 238 1.1 perry while (*lp++ == ' ') 239 1.1 perry ; 240 1.1 perry lp--; 241 1.1 perry thishex = atoi(lp); 242 1.1 perry if (thishex < 1 || thishex > 64) 243 1.1 perry continue; 244 1.1 perry if (thishex == hexagram) 245 1.1 perry break; 246 1.1 perry } 247 1.1 perry 248 1.1 perry /* 249 1.1 perry * Print up to the line commentary, which ends with a line of the form 250 1.1 perry * .L <position> <value> 251 1.1 perry */ 252 1.1 perry fputs(textln, stdout); 253 1.1 perry for (;;) { 254 1.5 plunky if (fgets(textln, sizeof(textln), chingf) == NULL) { 255 1.1 perry fprintf(stderr, "ching: Hexagram %d malformed\n", 256 1.1 perry hexagram); 257 1.1 perry exit(3); 258 1.1 perry } 259 1.1 perry lp = &textln[0]; 260 1.1 perry if (*lp++ == '.') { 261 1.1 perry if (*lp++ == 'L') 262 1.1 perry break; 263 1.1 perry } 264 1.1 perry fputs(textln, stdout); 265 1.1 perry } 266 1.1 perry 267 1.1 perry /* 268 1.1 perry * Now print the line commentaries, if this is the first hexagram. 269 1.1 perry */ 270 1.1 perry if (flag) 271 1.1 perry return; 272 1.1 perry 273 1.1 perry /* 274 1.1 perry * If a line is moving, print its commentary. 275 1.1 perry * The text of the commentary ends with a line either of the form 276 1.1 perry * .L <position> <value> 277 1.1 perry * or of the form 278 1.1 perry * .LA <value> 279 1.1 perry * or of the form 280 1.1 perry * .H <hexagram number> <other arguments> 281 1.1 perry */ 282 1.1 perry allmoving = 1; 283 1.1 perry for (i = 0; i < 6; i++) { 284 1.1 perry while (*lp++ == ' ') 285 1.1 perry ; 286 1.1 perry lp--; 287 1.1 perry lineno = atoi(lp); 288 1.1 perry if (i + 1 != lineno) { 289 1.1 perry fprintf(stderr, "ching: Hexagram %d malformed\n", 290 1.1 perry hexagram); 291 1.1 perry exit(3); 292 1.1 perry } 293 1.1 perry if (moving[i]) 294 1.1 perry fputs(textln, stdout); 295 1.1 perry else 296 1.1 perry allmoving = 0; 297 1.1 perry for (;;) { 298 1.5 plunky if (fgets(textln, sizeof(textln), chingf) == NULL) 299 1.1 perry break; 300 1.1 perry lp = &textln[0]; 301 1.1 perry if (*lp++ == '.' && (*lp == 'L' || *lp == 'H')) { 302 1.1 perry lp++; 303 1.1 perry break; 304 1.1 perry } 305 1.1 perry if (moving[i]) 306 1.1 perry fputs(textln, stdout); 307 1.1 perry } 308 1.1 perry } 309 1.1 perry 310 1.1 perry /* 311 1.1 perry * If all the lines are moving, print the commentary for that; it 312 1.1 perry * ends with a line of the form 313 1.1 perry * .H <hexagram number> <other arguments> 314 1.1 perry */ 315 1.1 perry if (*lp == 'A' && allmoving) { 316 1.1 perry fputs(textln, stdout); 317 1.1 perry for (;;) { 318 1.5 plunky if (fgets(textln, sizeof(textln), chingf) == NULL) 319 1.1 perry break; 320 1.1 perry lp = &textln[0]; 321 1.1 perry if (*lp++ == '.' || *lp++ == 'H') 322 1.1 perry break; 323 1.1 perry fputs(textln, stdout); 324 1.1 perry } 325 1.1 perry } 326 1.1 perry } 327