hack.options.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /* $NetBSD: hack.options.c,v 1.7 2004/01/01 16:02:51 jsm Exp $ */
  2. /*
  3. * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
  4. * Amsterdam
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are
  9. * met:
  10. *
  11. * - Redistributions of source code must retain the above copyright notice,
  12. * this list of conditions and the following disclaimer.
  13. *
  14. * - Redistributions in binary form must reproduce the above copyright
  15. * notice, this list of conditions and the following disclaimer in the
  16. * documentation and/or other materials provided with the distribution.
  17. *
  18. * - Neither the name of the Stichting Centrum voor Wiskunde en
  19. * Informatica, nor the names of its contributors may be used to endorse or
  20. * promote products derived from this software without specific prior
  21. * written permission.
  22. *
  23. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  24. * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  25. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  26. * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
  27. * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  28. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  29. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  30. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  31. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  32. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  33. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  34. */
  35. /*
  36. * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
  37. * All rights reserved.
  38. *
  39. * Redistribution and use in source and binary forms, with or without
  40. * modification, are permitted provided that the following conditions
  41. * are met:
  42. * 1. Redistributions of source code must retain the above copyright
  43. * notice, this list of conditions and the following disclaimer.
  44. * 2. Redistributions in binary form must reproduce the above copyright
  45. * notice, this list of conditions and the following disclaimer in the
  46. * documentation and/or other materials provided with the distribution.
  47. * 3. The name of the author may not be used to endorse or promote products
  48. * derived from this software without specific prior written permission.
  49. *
  50. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
  51. * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
  52. * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  53. * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  54. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  55. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  56. * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  57. * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  58. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  59. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  60. */
  61. #include <sys/cdefs.h>
  62. #ifndef lint
  63. __RCSID("$NetBSD: hack.options.c,v 1.7 2004/01/01 16:02:51 jsm Exp $");
  64. #endif /* not lint */
  65. #include <stdlib.h>
  66. #include <unistd.h>
  67. #include "hack.h"
  68. #include "extern.h"
  69. void
  70. initoptions()
  71. {
  72. char *opts;
  73. flags.time = flags.nonews = flags.notombstone = flags.end_own =
  74. flags.standout = flags.nonull = FALSE;
  75. flags.no_rest_on_space = TRUE;
  76. flags.invlet_constant = TRUE;
  77. flags.end_top = 5;
  78. flags.end_around = 4;
  79. flags.female = FALSE; /* players are usually male */
  80. if ((opts = getenv("HACKOPTIONS")) != NULL)
  81. parseoptions(opts, TRUE);
  82. }
  83. void
  84. parseoptions(opts, from_env)
  85. char *opts;
  86. boolean from_env;
  87. {
  88. char *op, *op2;
  89. unsigned num;
  90. boolean negated;
  91. if ((op = strchr(opts, ',')) != NULL) {
  92. *op++ = 0;
  93. parseoptions(op, from_env);
  94. }
  95. if ((op = strchr(opts, ' ')) != NULL) {
  96. op2 = op;
  97. while (*op++)
  98. if (*op != ' ')
  99. *op2++ = *op;
  100. }
  101. if (!*opts)
  102. return;
  103. negated = FALSE;
  104. while ((*opts == '!') || !strncmp(opts, "no", 2)) {
  105. if (*opts == '!')
  106. opts++;
  107. else
  108. opts += 2;
  109. negated = !negated;
  110. }
  111. if (!strncmp(opts, "standout", 8)) {
  112. flags.standout = !negated;
  113. return;
  114. }
  115. if (!strncmp(opts, "null", 3)) {
  116. flags.nonull = negated;
  117. return;
  118. }
  119. if (!strncmp(opts, "tombstone", 4)) {
  120. flags.notombstone = negated;
  121. return;
  122. }
  123. if (!strncmp(opts, "news", 4)) {
  124. flags.nonews = negated;
  125. return;
  126. }
  127. if (!strncmp(opts, "time", 4)) {
  128. flags.time = !negated;
  129. flags.botl = 1;
  130. return;
  131. }
  132. if (!strncmp(opts, "restonspace", 4)) {
  133. flags.no_rest_on_space = negated;
  134. return;
  135. }
  136. if (!strncmp(opts, "fixinv", 4)) {
  137. if (from_env)
  138. flags.invlet_constant = !negated;
  139. else
  140. pline("The fixinvlet option must be in HACKOPTIONS.");
  141. return;
  142. }
  143. if (!strncmp(opts, "male", 4)) {
  144. flags.female = negated;
  145. return;
  146. }
  147. if (!strncmp(opts, "female", 6)) {
  148. flags.female = !negated;
  149. return;
  150. }
  151. /* name:string */
  152. if (!strncmp(opts, "name", 4)) {
  153. if (!from_env) {
  154. pline("The playername can be set only from HACKOPTIONS.");
  155. return;
  156. }
  157. op = strchr(opts, ':');
  158. if (!op)
  159. goto bad;
  160. (void) strncpy(plname, op + 1, sizeof(plname) - 1);
  161. return;
  162. }
  163. /* endgame:5t[op] 5a[round] o[wn] */
  164. if (!strncmp(opts, "endgame", 3)) {
  165. op = strchr(opts, ':');
  166. if (!op)
  167. goto bad;
  168. op++;
  169. while (*op) {
  170. num = 1;
  171. if (digit(*op)) {
  172. num = atoi(op);
  173. while (digit(*op))
  174. op++;
  175. } else if (*op == '!') {
  176. negated = !negated;
  177. op++;
  178. }
  179. switch (*op) {
  180. case 't':
  181. flags.end_top = num;
  182. break;
  183. case 'a':
  184. flags.end_around = num;
  185. break;
  186. case 'o':
  187. flags.end_own = !negated;
  188. break;
  189. default:
  190. goto bad;
  191. }
  192. while (letter(*++op));
  193. if (*op == '/')
  194. op++;
  195. }
  196. return;
  197. }
  198. bad:
  199. if (!from_env) {
  200. if (!strncmp(opts, "help", 4)) {
  201. pline("%s%s%s",
  202. "To set options use `HACKOPTIONS=\"<options>\"' in your environment, or ",
  203. "give the command 'O' followed by the line `<options>' while playing. ",
  204. "Here <options> is a list of <option>s separated by commas.");
  205. pline("%s%s%s",
  206. "Simple (boolean) options are rest_on_space, news, time, ",
  207. "null, tombstone, (fe)male. ",
  208. "These can be negated by prefixing them with '!' or \"no\".");
  209. pline("%s",
  210. "A string option is name, as in HACKOPTIONS=\"name:Merlin-W\".");
  211. pline("%s%s%s",
  212. "A compound option is endgame; it is followed by a description of what ",
  213. "parts of the scorelist you want to see. You might for example say: ",
  214. "`endgame:own scores/5 top scores/4 around my score'.");
  215. return;
  216. }
  217. pline("Bad option: %s.", opts);
  218. pline("Type `O help<cr>' for help.");
  219. return;
  220. }
  221. puts("Bad syntax in HACKOPTIONS.");
  222. puts("Use for example:");
  223. puts(
  224. "HACKOPTIONS=\"!restonspace,notombstone,endgame:own/5 topscorers/4 around me\""
  225. );
  226. getret();
  227. }
  228. int
  229. doset()
  230. {
  231. char buf[BUFSZ];
  232. pline("What options do you want to set? ");
  233. getlin(buf);
  234. if (!buf[0] || buf[0] == '\033') {
  235. (void) strcpy(buf, "HACKOPTIONS=");
  236. (void) strcat(buf, flags.female ? "female," : "male,");
  237. if (flags.standout)
  238. (void) strcat(buf, "standout,");
  239. if (flags.nonull)
  240. (void) strcat(buf, "nonull,");
  241. if (flags.nonews)
  242. (void) strcat(buf, "nonews,");
  243. if (flags.time)
  244. (void) strcat(buf, "time,");
  245. if (flags.notombstone)
  246. (void) strcat(buf, "notombstone,");
  247. if (flags.no_rest_on_space)
  248. (void) strcat(buf, "!rest_on_space,");
  249. if (flags.end_top != 5 || flags.end_around != 4 || flags.end_own) {
  250. (void) sprintf(eos(buf), "endgame: %u topscores/%u around me",
  251. flags.end_top, flags.end_around);
  252. if (flags.end_own)
  253. (void) strcat(buf, "/own scores");
  254. } else {
  255. char *eop = eos(buf);
  256. if (*--eop == ',')
  257. *eop = 0;
  258. }
  259. pline(buf);
  260. } else
  261. parseoptions(buf, FALSE);
  262. return (0);
  263. }