|
|
1.1 root 1: /*
2: * This file has all the code for the option command.
3: * I would rather this command were not necessary, but
4: * it is the only way to keep the wolves off of my back.
5: *
6: * @(#)options.c 3.3 (Berkeley) 5/25/81
7: */
8:
9: #include <curses.h>
10: #include <ctype.h>
11: #include "rogue.h"
12:
13: #define NUM_OPTS (sizeof optlist / sizeof (OPTION))
14:
15: /*
16: * description of an option and what to do with it
17: */
18: struct optstruct {
19: char *o_name; /* option name */
20: char *o_prompt; /* prompt for interactive entry */
21: int *o_opt; /* pointer to thing to set */
22: int (*o_putfunc)(); /* function to print value */
23: int (*o_getfunc)(); /* function to get value interactively */
24: };
25:
26: typedef struct optstruct OPTION;
27:
28: int put_bool(), get_bool(), put_str(), get_str();
29:
30: OPTION optlist[] = {
31: {"terse", "Terse output: ",
32: (int *) &terse, put_bool, get_bool },
33: {"flush", "Flush typeahead during battle: ",
34: (int *) &fight_flush, put_bool, get_bool },
35: {"jump", "Show position only at end of run: ",
36: (int *) &jump, put_bool, get_bool },
37: {"step", "Do inventories one line at a time: ",
38: (int *) &slow_invent, put_bool, get_bool },
39: {"askme", "Ask me about unidentified things: ",
40: (int *) &askme, put_bool, get_bool },
41: {"name", "Name: ",
42: (int *) whoami, put_str, get_str },
43: {"fruit", "Fruit: ",
44: (int *) fruit, put_str, get_str },
45: {"file", "Save file: ",
46: (int *) file_name, put_str, get_str }
47: };
48:
49: /*
50: * print and then set options from the terminal
51: */
52: option()
53: {
54: register OPTION *op;
55: register int retval;
56:
57: wclear(hw);
58: touchwin(hw);
59: /*
60: * Display current values of options
61: */
62: for (op = optlist; op < &optlist[NUM_OPTS]; op++)
63: {
64: waddstr(hw, op->o_prompt);
65: (*op->o_putfunc)(op->o_opt);
66: waddch(hw, '\n');
67: }
68: /*
69: * Set values
70: */
71: wmove(hw, 0, 0);
72: for (op = optlist; op < &optlist[NUM_OPTS]; op++)
73: {
74: waddstr(hw, op->o_prompt);
75: if ((retval = (*op->o_getfunc)(op->o_opt, hw)))
76: if (retval == QUIT)
77: break;
78: else if (op > optlist) { /* MINUS */
79: wmove(hw, (op - optlist) - 1, 0);
80: op -= 2;
81: }
82: else /* trying to back up beyond the top */
83: {
84: putchar('\007');
85: wmove(hw, 0, 0);
86: op--;
87: }
88: }
89: /*
90: * Switch back to original screen
91: */
92: mvwaddstr(hw, LINES-1, 0, "--Press space to continue--");
93: draw(hw);
94: wait_for(' ');
95: clearok(cw, TRUE);
96: touchwin(cw);
97: after = FALSE;
98: }
99:
100: /*
101: * put out a boolean
102: */
103: put_bool(b)
104: bool *b;
105: {
106: waddstr(hw, *b ? "True" : "False");
107: }
108:
109: /*
110: * put out a string
111: */
112: put_str(str)
113: char *str;
114: {
115: waddstr(hw, str);
116: }
117:
118: /*
119: * allow changing a boolean option and print it out
120: */
121:
122: get_bool(bp, win)
123: bool *bp;
124: WINDOW *win;
125: {
126: register int oy, ox;
127: register bool op_bad;
128:
129: op_bad = TRUE;
130: getyx(win, oy, ox);
131: waddstr(win, *bp ? "True" : "False");
132: while(op_bad)
133: {
134: wmove(win, oy, ox);
135: draw(win);
136: switch (readchar())
137: {
138: case 't':
139: case 'T':
140: *bp = TRUE;
141: op_bad = FALSE;
142: break;
143: case 'f':
144: case 'F':
145: *bp = FALSE;
146: op_bad = FALSE;
147: break;
148: case '\n':
149: case '\r':
150: op_bad = FALSE;
151: break;
152: case '\033':
153: case '\007':
154: return QUIT;
155: case '-':
156: return MINUS;
157: default:
158: mvwaddstr(win, oy, ox + 10, "(T or F)");
159: }
160: }
161: wmove(win, oy, ox);
162: waddstr(win, *bp ? "True" : "False");
163: waddch(win, '\n');
164: return NORM;
165: }
166:
167: /*
168: * set a string option
169: */
170: get_str(opt, win)
171: register char *opt;
172: WINDOW *win;
173: {
174: register char *sp;
175: register int c, oy, ox;
176: char buf[80];
177:
178: draw(win);
179: getyx(win, oy, ox);
180: /*
181: * loop reading in the string, and put it in a temporary buffer
182: */
183: for (sp = buf;
184: (c = readchar()) != '\n' && c != '\r' && c != '\033' && c != '\007';
185: wclrtoeol(win), draw(win))
186: {
187: if (c == -1)
188: continue;
189: #if USG==1
190: else if (c == _tty.c_cc[VERASE]) /* process erase character */
191: #else
192: else if (c == _tty.sg_erase) /* process erase character */
193: #endif
194: {
195: if (sp > buf)
196: {
197: register int i;
198:
199: sp--;
200: for (i = strlen(unctrl(*sp)); i; i--)
201: waddch(win, '\b');
202: }
203: continue;
204: }
205: #if USG==1
206: else if (c == _tty.c_cc[VKILL]) /* process kill character */
207: #else
208: else if (c == _tty.sg_kill) /* process kill character */
209: #endif
210: {
211: sp = buf;
212: wmove(win, oy, ox);
213: continue;
214: }
215: else if (sp == buf)
216: if (c == '-')
217: break;
218: else if (c == '~')
219: {
220: strcpy(buf, home);
221: waddstr(win, home);
222: sp += strlen(home);
223: continue;
224: }
225: *sp++ = c;
226: waddstr(win, unctrl(c));
227: }
228: *sp = '\0';
229: if (sp > buf) /* only change option if something has been typed */
230: strucpy(opt, buf, strlen(buf));
231: wmove(win, oy, ox);
232: waddstr(win, opt);
233: waddch(win, '\n');
234: draw(win);
235: if (win == cw)
236: mpos += sp - buf;
237: if (c == '-')
238: return MINUS;
239: else if (c == '\033' || c == '\007')
240: return QUIT;
241: else
242: return NORM;
243: }
244:
245: /*
246: * parse options from string, usually taken from the environment.
247: * the string is a series of comma seperated values, with booleans
248: * being stated as "name" (true) or "noname" (false), and strings
249: * being "name=....", with the string being defined up to a comma
250: * or the end of the entire option string.
251: */
252:
253: parse_opts(str)
254: register char *str;
255: {
256: register char *sp;
257: register OPTION *op;
258: register int len;
259:
260: while (*str)
261: {
262: /*
263: * Get option name
264: */
265: for (sp = str; isalpha(*sp); sp++)
266: continue;
267: len = sp - str;
268: /*
269: * Look it up and deal with it
270: */
271: for (op = optlist; op < &optlist[NUM_OPTS]; op++)
272: if (EQSTR(str, op->o_name, len))
273: {
274: if (op->o_putfunc == put_bool) /* if option is a boolean */
275: *(bool *)op->o_opt = TRUE;
276: else /* string option */
277: {
278: register char *start;
279: /*
280: * Skip to start of string value
281: */
282: for (str = sp + 1; *str == '='; str++)
283: continue;
284: if (*str == '~')
285: {
286: strcpy((char *) op->o_opt, home);
287: start = (char *) op->o_opt + strlen(home);
288: while (*++str == '/')
289: continue;
290: }
291: else
292: start = (char *) op->o_opt;
293: /*
294: * Skip to end of string value
295: */
296: for (sp = str + 1; *sp && *sp != ','; sp++)
297: continue;
298: strucpy(start, str, sp - str);
299: }
300: break;
301: }
302: /*
303: * check for "noname" for booleans
304: */
305: else if (op->o_putfunc == put_bool
306: && EQSTR(str, "no", 2) && EQSTR(str + 2, op->o_name, len - 2))
307: {
308: *(bool *)op->o_opt = FALSE;
309: break;
310: }
311:
312: /*
313: * skip to start of next option name
314: */
315: while (*sp && !isalpha(*sp))
316: sp++;
317: str = sp;
318: }
319: }
320:
321: /*
322: * copy string using unctrl for things
323: */
324: strucpy(s1, s2, len)
325: register char *s1, *s2;
326: register int len;
327: {
328: register char *sp;
329:
330: while (len--)
331: {
332: strcpy(s1, (sp = unctrl(*s2++)));
333: s1 += strlen(sp);
334: }
335: *s1 = '\0';
336: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.