parse 'role' or 'race' or 'gender' or 'alignment' */
| 7902 | |
| 7903 | /* parse 'role' or 'race' or 'gender' or 'alignment' */ |
| 7904 | staticfn boolean |
| 7905 | parse_role_opt( |
| 7906 | int optidx, |
| 7907 | boolean negated, |
| 7908 | const char *fullname, |
| 7909 | char *opts, |
| 7910 | char **opp) |
| 7911 | { |
| 7912 | static char neg_opt[] = "!"; /* not 'const' but never modified */ |
| 7913 | char *preval, *op; |
| 7914 | int which = (optidx == opt_role) ? RS_ROLE |
| 7915 | : (optidx == opt_race) ? RS_RACE |
| 7916 | : (optidx == opt_gender) ? RS_GENDER |
| 7917 | : (optidx == opt_alignment) ? RS_ALGNMNT |
| 7918 | : RS_filter; /* none of the above */ |
| 7919 | boolean ok = FALSE; |
| 7920 | |
| 7921 | /* |
| 7922 | * Accepts multiple forms |
| 7923 | * role:priest -- play as priest |
| 7924 | * race:!orc -- any race other than orc |
| 7925 | * role:!cav !mon -- any role other than caveman/cavewoman or monk |
| 7926 | * !role:tour -- any role other than tourist |
| 7927 | * !role:tou rog wiz -- any role other than tourist or rogue or wizard |
| 7928 | * TODO: add support for |
| 7929 | * role:arc bar kni -- only role archeologist or barbarian or knight |
| 7930 | * Rejected: |
| 7931 | * role:sam !val -+ invalid; need either positive or negative subset |
| 7932 | * !role:!sam +- not a mixture of the two and not dual negation. |
| 7933 | */ |
| 7934 | if ((op = string_for_env_opt(fullname, opts, FALSE)) != empty_optstr) { |
| 7935 | char *sp; |
| 7936 | boolean val_negated, prev_negated = FALSE, first = TRUE; |
| 7937 | |
| 7938 | mungspaces(op); |
| 7939 | while (*op) { |
| 7940 | if (*op == ' ') |
| 7941 | ++op; |
| 7942 | val_negated = FALSE; |
| 7943 | while (*op == '!' || !strncmpi(op, "no", 2)) { |
| 7944 | val_negated = !val_negated; |
| 7945 | op += (*op == '!') ? 1 : (op[2] != '-') ? 2 : 3; |
| 7946 | } |
| 7947 | if (!*op || *op == ' ') { |
| 7948 | config_error_add("Negated nothing for '%s'", fullname); |
| 7949 | return FALSE; |
| 7950 | } |
| 7951 | if (!first) { |
| 7952 | if ((val_negated ^ prev_negated) |
| 7953 | || (negated && val_negated)) { |
| 7954 | config_error_add("Invalid mixed negation for '%s%s'", |
| 7955 | negated ? "!" : "", fullname); |
| 7956 | return FALSE; |
| 7957 | } else if (!negated && !val_negated) { |
| 7958 | config_error_add( |
| 7959 | "Multiple role values only allowed when list is negated"); |
| 7960 | return FALSE; |
| 7961 | } |
no test coverage detected