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