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