hack.options.c revision 1.4 1 1.4 christos /* $NetBSD: hack.options.c,v 1.4 1997/10/19 16:58:42 christos Exp $ */
2 1.4 christos
3 1.2 mycroft /*
4 1.2 mycroft * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985.
5 1.2 mycroft */
6 1.2 mycroft
7 1.4 christos #include <sys/cdefs.h>
8 1.2 mycroft #ifndef lint
9 1.4 christos __RCSID("$NetBSD: hack.options.c,v 1.4 1997/10/19 16:58:42 christos Exp $");
10 1.4 christos #endif /* not lint */
11 1.1 cgd
12 1.4 christos #include <stdlib.h>
13 1.1 cgd #include "hack.h"
14 1.4 christos #include "extern.h"
15 1.1 cgd
16 1.4 christos void
17 1.1 cgd initoptions()
18 1.1 cgd {
19 1.4 christos char *opts;
20 1.1 cgd
21 1.1 cgd flags.time = flags.nonews = flags.notombstone = flags.end_own =
22 1.4 christos flags.standout = flags.nonull = FALSE;
23 1.1 cgd flags.no_rest_on_space = TRUE;
24 1.1 cgd flags.invlet_constant = TRUE;
25 1.1 cgd flags.end_top = 5;
26 1.1 cgd flags.end_around = 4;
27 1.4 christos flags.female = FALSE; /* players are usually male */
28 1.1 cgd
29 1.4 christos if ((opts = getenv("HACKOPTIONS")) != NULL)
30 1.4 christos parseoptions(opts, TRUE);
31 1.1 cgd }
32 1.1 cgd
33 1.4 christos void
34 1.1 cgd parseoptions(opts, from_env)
35 1.4 christos char *opts;
36 1.4 christos boolean from_env;
37 1.1 cgd {
38 1.4 christos char *op, *op2;
39 1.4 christos unsigned num;
40 1.4 christos boolean negated;
41 1.1 cgd
42 1.4 christos if ((op = strchr(opts, ',')) != NULL) {
43 1.1 cgd *op++ = 0;
44 1.1 cgd parseoptions(op, from_env);
45 1.1 cgd }
46 1.4 christos if ((op = strchr(opts, ' ')) != NULL) {
47 1.1 cgd op2 = op;
48 1.4 christos while (*op++)
49 1.4 christos if (*op != ' ')
50 1.4 christos *op2++ = *op;
51 1.1 cgd }
52 1.4 christos if (!*opts)
53 1.4 christos return;
54 1.1 cgd negated = FALSE;
55 1.4 christos while ((*opts == '!') || !strncmp(opts, "no", 2)) {
56 1.4 christos if (*opts == '!')
57 1.4 christos opts++;
58 1.4 christos else
59 1.4 christos opts += 2;
60 1.1 cgd negated = !negated;
61 1.1 cgd }
62 1.4 christos
63 1.4 christos if (!strncmp(opts, "standout", 8)) {
64 1.1 cgd flags.standout = !negated;
65 1.1 cgd return;
66 1.1 cgd }
67 1.4 christos if (!strncmp(opts, "null", 3)) {
68 1.1 cgd flags.nonull = negated;
69 1.1 cgd return;
70 1.1 cgd }
71 1.4 christos if (!strncmp(opts, "tombstone", 4)) {
72 1.1 cgd flags.notombstone = negated;
73 1.1 cgd return;
74 1.1 cgd }
75 1.4 christos if (!strncmp(opts, "news", 4)) {
76 1.1 cgd flags.nonews = negated;
77 1.1 cgd return;
78 1.1 cgd }
79 1.4 christos if (!strncmp(opts, "time", 4)) {
80 1.1 cgd flags.time = !negated;
81 1.1 cgd flags.botl = 1;
82 1.1 cgd return;
83 1.1 cgd }
84 1.4 christos if (!strncmp(opts, "restonspace", 4)) {
85 1.1 cgd flags.no_rest_on_space = negated;
86 1.1 cgd return;
87 1.1 cgd }
88 1.4 christos if (!strncmp(opts, "fixinv", 4)) {
89 1.4 christos if (from_env)
90 1.1 cgd flags.invlet_constant = !negated;
91 1.1 cgd else
92 1.1 cgd pline("The fixinvlet option must be in HACKOPTIONS.");
93 1.1 cgd return;
94 1.1 cgd }
95 1.4 christos if (!strncmp(opts, "male", 4)) {
96 1.1 cgd flags.female = negated;
97 1.1 cgd return;
98 1.1 cgd }
99 1.4 christos if (!strncmp(opts, "female", 6)) {
100 1.1 cgd flags.female = !negated;
101 1.1 cgd return;
102 1.1 cgd }
103 1.1 cgd /* name:string */
104 1.4 christos if (!strncmp(opts, "name", 4)) {
105 1.4 christos if (!from_env) {
106 1.4 christos pline("The playername can be set only from HACKOPTIONS.");
107 1.4 christos return;
108 1.1 cgd }
109 1.4 christos op = strchr(opts, ':');
110 1.4 christos if (!op)
111 1.4 christos goto bad;
112 1.4 christos (void) strncpy(plname, op + 1, sizeof(plname) - 1);
113 1.1 cgd return;
114 1.1 cgd }
115 1.1 cgd /* endgame:5t[op] 5a[round] o[wn] */
116 1.4 christos if (!strncmp(opts, "endgame", 3)) {
117 1.4 christos op = strchr(opts, ':');
118 1.4 christos if (!op)
119 1.4 christos goto bad;
120 1.1 cgd op++;
121 1.4 christos while (*op) {
122 1.1 cgd num = 1;
123 1.4 christos if (digit(*op)) {
124 1.4 christos /*###124 [cc] warning: implicit declaration of function `atoi'%%%*/
125 1.1 cgd num = atoi(op);
126 1.4 christos while (digit(*op))
127 1.4 christos op++;
128 1.4 christos } else if (*op == '!') {
129 1.1 cgd negated = !negated;
130 1.1 cgd op++;
131 1.1 cgd }
132 1.4 christos switch (*op) {
133 1.1 cgd case 't':
134 1.1 cgd flags.end_top = num;
135 1.1 cgd break;
136 1.1 cgd case 'a':
137 1.1 cgd flags.end_around = num;
138 1.1 cgd break;
139 1.1 cgd case 'o':
140 1.1 cgd flags.end_own = !negated;
141 1.1 cgd break;
142 1.1 cgd default:
143 1.1 cgd goto bad;
144 1.1 cgd }
145 1.4 christos while (letter(*++op));
146 1.4 christos if (*op == '/')
147 1.4 christos op++;
148 1.1 cgd }
149 1.1 cgd return;
150 1.1 cgd }
151 1.1 cgd bad:
152 1.4 christos if (!from_env) {
153 1.4 christos if (!strncmp(opts, "help", 4)) {
154 1.1 cgd pline("%s%s%s",
155 1.4 christos "To set options use `HACKOPTIONS=\"<options>\"' in your environment, or ",
156 1.4 christos "give the command 'o' followed by the line `<options>' while playing. ",
157 1.4 christos "Here <options> is a list of <option>s separated by commas.");
158 1.1 cgd pline("%s%s%s",
159 1.4 christos "Simple (boolean) options are rest_on_space, news, time, ",
160 1.4 christos "null, tombstone, (fe)male. ",
161 1.4 christos "These can be negated by prefixing them with '!' or \"no\".");
162 1.1 cgd pline("%s",
163 1.4 christos "A string option is name, as in HACKOPTIONS=\"name:Merlin-W\".");
164 1.1 cgd pline("%s%s%s",
165 1.4 christos "A compound option is endgame; it is followed by a description of what ",
166 1.4 christos "parts of the scorelist you want to see. You might for example say: ",
167 1.4 christos "`endgame:own scores/5 top scores/4 around my score'.");
168 1.1 cgd return;
169 1.1 cgd }
170 1.1 cgd pline("Bad option: %s.", opts);
171 1.1 cgd pline("Type `o help<cr>' for help.");
172 1.1 cgd return;
173 1.1 cgd }
174 1.1 cgd puts("Bad syntax in HACKOPTIONS.");
175 1.1 cgd puts("Use for example:");
176 1.1 cgd puts(
177 1.4 christos "HACKOPTIONS=\"!restonspace,notombstone,endgame:own/5 topscorers/4 around me\""
178 1.4 christos );
179 1.1 cgd getret();
180 1.1 cgd }
181 1.1 cgd
182 1.4 christos int
183 1.1 cgd doset()
184 1.1 cgd {
185 1.4 christos char buf[BUFSZ];
186 1.1 cgd
187 1.1 cgd pline("What options do you want to set? ");
188 1.1 cgd getlin(buf);
189 1.4 christos if (!buf[0] || buf[0] == '\033') {
190 1.4 christos (void) strcpy(buf, "HACKOPTIONS=");
191 1.4 christos (void) strcat(buf, flags.female ? "female," : "male,");
192 1.4 christos if (flags.standout)
193 1.4 christos (void) strcat(buf, "standout,");
194 1.4 christos if (flags.nonull)
195 1.4 christos (void) strcat(buf, "nonull,");
196 1.4 christos if (flags.nonews)
197 1.4 christos (void) strcat(buf, "nonews,");
198 1.4 christos if (flags.time)
199 1.4 christos (void) strcat(buf, "time,");
200 1.4 christos if (flags.notombstone)
201 1.4 christos (void) strcat(buf, "notombstone,");
202 1.4 christos if (flags.no_rest_on_space)
203 1.4 christos (void) strcat(buf, "!rest_on_space,");
204 1.4 christos if (flags.end_top != 5 || flags.end_around != 4 || flags.end_own) {
205 1.4 christos (void) sprintf(eos(buf), "endgame: %u topscores/%u around me",
206 1.4 christos flags.end_top, flags.end_around);
207 1.4 christos if (flags.end_own)
208 1.4 christos (void) strcat(buf, "/own scores");
209 1.4 christos } else {
210 1.4 christos char *eop = eos(buf);
211 1.4 christos if (*--eop == ',')
212 1.4 christos *eop = 0;
213 1.4 christos }
214 1.4 christos pline(buf);
215 1.1 cgd } else
216 1.4 christos parseoptions(buf, FALSE);
217 1.1 cgd
218 1.4 christos return (0);
219 1.1 cgd }
220