| 61 | } |
| 62 | |
| 63 | const char *configvar_parse(struct configvar *cv, |
| 64 | bool early, |
| 65 | bool full_knowledge, |
| 66 | bool developer) |
| 67 | { |
| 68 | const struct opt_table *ot; |
| 69 | |
| 70 | ot = configvar_unparsed(cv); |
| 71 | if (!ot) { |
| 72 | /* Do we ignore unknown entries? */ |
| 73 | if (!full_knowledge) |
| 74 | return NULL; |
| 75 | return "unknown option"; |
| 76 | } |
| 77 | |
| 78 | if ((ot->type & OPT_DEV) && !developer) |
| 79 | return "requires --developer"; |
| 80 | |
| 81 | /* If we're early and we want late, or vv, ignore. */ |
| 82 | if (!!(ot->type & OPT_EARLY) != early) |
| 83 | return NULL; |
| 84 | |
| 85 | if (ot->type & OPT_NOARG) { |
| 86 | /* MULTI doesn't make sense with single args */ |
| 87 | assert(!(ot->type & OPT_MULTI)); |
| 88 | if (cv->optarg) |
| 89 | return "doesn't allow an argument"; |
| 90 | return ot->cb(ot->u.arg); |
| 91 | } else { |
| 92 | if (!cv->optarg) |
| 93 | return "requires an argument"; |
| 94 | if (!(ot->type & OPT_KEEP_WHITESPACE)) |
| 95 | trim_whitespace(cv->optarg); |
| 96 | return ot->cb_arg(cv->optarg, ot->u.arg); |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | /* This is O(N^2) but nobody cares */ |
| 101 | void configvar_finalize_overrides(struct configvar **cvs) |
no test coverage detected