Any line in the configuration file starting with `#' is treated as a comment.
Empty lines are ignored.
.pg
+Any line beginning with `[' and ending in `]' is considered a section
+marker. The text between the square brackets is the section name.
+Lines after a section marker belong to that section, and are
+ignored unless a CHOOSE -statement was used to select that section.
+Section names are case insensitive.
+.pg
You can use different configuration statements in the file, some
of which can be used multiple times. In general, the statements are
written in capital letters, followed by an equals sign, followed by
.sd
\fBBIND=^X:getpos.autodescribe\fP
.ed
+.lp CHOOSE
+Chooses at random one of the comma-separated parameters as an active
+section name. Lines in other sections are ignored.
+.pg
+Example:
+.sd
+\fBOPTIONS=color\fP
+\fBCHOOSE=char A,char B\fP
+\fB[char A]\fP
+\fBOPTIONS=role:arc,race:dwa,align:law,gender:fem\fP
+\fB[char B]\fP
+\fBOPTIONS=role:wiz,race:elf,align:cha,gender:mal\fP
+.ed
.lp MSGTYPE
Change the way messages are shown in the top status line.
See the ``Configuring Message Types`` section.
Any line in the configuration file starting with `{\tt \#}' is treated as a comment.
Empty lines are ignored.
+%.pg
+Any line beginning with `{\tt [}' and ending in `{\tt ]}' is considered a section
+marker. The text between the square brackets is the section name.
+Lines after a section marker belong to that section, and are
+ignored unless a CHOOSE -statement was used to select that section.
+Section names are case insensitive.
+
%.pg
You can use different configuration statements in the file, some
of which can be used multiple times. In general, the statements are
\end{verbatim}
%.ed
+%.lp
+\item[\bb{CHOOSE}]
+Chooses at random one of the comma-separated parameters as an active
+section name. Lines in other sections are ignored.
+
+%.pg
+Example:
+%.sd
+\begin{verbatim}
+ OPTIONS=color
+ CHOOSE=char A,char B
+ [char A]
+ OPTIONS=role:arc,race:dwa,align:law,gender:fem
+ [char B]
+ OPTIONS=role:wiz,race:elf,align:cha,gender:mal
+\end{verbatim}
+%.ed
+
%.lp
\item[\bb{MSGTYPE}]
Change the way messages are shown in the top status line.
#ifdef NOCWD_ASSUMPTIONS
STATIC_DCL void FDECL(adjust_prefix, (char *, int));
#endif
+STATIC_DCL void NDECL(free_config_sections);
+STATIC_DCL char *FDECL(choose_random_part, (char *, char));
+STATIC_DCL boolean FDECL(is_config_section, (const char *));
+STATIC_DCL boolean FDECL(handle_config_section, (char *));
#ifdef SELF_RECOVER
STATIC_DCL boolean FDECL(copy_bytes, (int, int));
#endif
STATIC_DCL int FDECL(open_levelfile_exclusively, (const char *, int, int));
#endif
+
+static char *config_section_chosen = (char *) 0;
+static char *config_section_current = (char *) 0;
+
/*
* fname_encode()
*
}
#endif
+/* Choose at random one of the sep separated parts from str. Mangles str. */
+STATIC_OVL char *
+choose_random_part(str,sep)
+char *str;
+char sep;
+{
+ int nsep = 1;
+ int csep;
+ int len = 0;
+ char *begin = str;
+
+ if (!str)
+ return (char *) 0;
+
+ while (*str) {
+ if (*str == sep) nsep++;
+ str++;
+ }
+ csep = rn2(nsep);
+ str = begin;
+ while ((csep > 0) && *str) {
+ str++;
+ if (*str == sep) csep--;
+ }
+ if (*str) {
+ if (*str == sep) str++;
+ begin = str;
+ while (*str && *str != sep) {
+ str++;
+ len++;
+ }
+ *str = '\0';
+ if (len)
+ return begin;
+ }
+ return (char *) 0;
+}
+
+STATIC_OVL void
+free_config_sections()
+{
+ if (config_section_chosen) {
+ free(config_section_chosen);
+ config_section_chosen = NULL;
+ }
+ if (config_section_current) {
+ free(config_section_current);
+ config_section_current = NULL;
+ }
+}
+
+STATIC_OVL boolean
+is_config_section(str)
+const char *str;
+{
+ const char *a = rindex(str, ']');
+
+ return (a && *str == '[' && *(a+1) == '\0' && (int)(a - str) > 0);
+}
+
+STATIC_OVL boolean
+handle_config_section(buf)
+char *buf;
+{
+ if (is_config_section(buf)) {
+ char *send;
+ if (config_section_current) {
+ free(config_section_current);
+ }
+ config_section_current = dupstr(&buf[1]);
+ send = rindex(config_section_current, ']');
+ *send = '\0';
+ debugpline1("set config section: '%s'", config_section_current);
+ return TRUE;
+ }
+
+ if (config_section_current) {
+ if (!config_section_chosen)
+ return TRUE;
+ if (strcmp(config_section_current, config_section_chosen))
+ return TRUE;
+ }
+ return FALSE;
+}
+
#define match_varname(INP, NAM, LEN) match_optname(INP, NAM, LEN, TRUE)
int
if (!*buf || *buf == '#' || !strcmp(buf, " "))
return 1;
+ if (src != SET_IN_SYS && handle_config_section(buf))
+ return 1;
+
/* find the '=' or ':' */
bufp = index(buf, '=');
altp = index(buf, ':');
++bufp; /* skip '='; parseoptions() handles spaces */
parseoptions(bufp, TRUE, TRUE);
+ } else if (match_varname(buf, "CHOOSE", 6)) {
+ char *section;
+ if (config_section_chosen)
+ free(config_section_chosen);
+ section = choose_random_part(bufp, ',');
+ if (section)
+ config_section_chosen = dupstr(section);
} else if (match_varname(buf, "AUTOPICKUP_EXCEPTION", 5)) {
add_autopickup_exception(bufp);
} else if (match_varname(buf, "BINDINGS", 4)) {
/* begin detection of duplicate configfile options */
set_duplicate_opt_detection(1);
+ free_config_sections();
while (fgets(buf, sizeof buf, fp)) {
#ifdef notyet
}
(void) fclose(fp);
+ free_config_sections();
/* turn off detection of duplicate configfile options */
set_duplicate_opt_detection(0);
return rv;