1// Copyright 2016 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "option.h"
6#include "util.h"
7
8#pragma GCC visibility push(hidden)
9
10#include <string.h>
11
12#pragma GCC visibility pop
13
14#define OPTION_DEFAULT(option) \
15    case OPTION_##option: value = OPTION_##option##_DEFAULT; break
16
17static void initialize_options(struct options* o) {
18    for (enum option i = 0; i < OPTION_MAX; ++i) {
19        const char* value = NULL;
20        switch (i) {
21            OPTION_DEFAULT(FILENAME);
22            OPTION_DEFAULT(SHUTDOWN);
23            OPTION_DEFAULT(REBOOT);
24        case OPTION_MAX:
25            __builtin_unreachable();
26        }
27        o->value[i] = value;
28    }
29}
30
31#define OPTION_STRING(option)                               \
32    case OPTION_##option:                                   \
33        string = OPTION_##option##_STRING;                  \
34        string_len = sizeof(OPTION_##option##_STRING) - 1;  \
35        break
36
37static void apply_option(struct options* o, const char* arg) {
38    size_t len = strlen(arg);
39    for (enum option i = 0; i < OPTION_MAX; ++i) {
40        const char* string = NULL;
41        size_t string_len = 0;
42        switch (i) {
43            OPTION_STRING(FILENAME);
44            OPTION_STRING(SHUTDOWN);
45            OPTION_STRING(REBOOT);
46        case OPTION_MAX:
47            __builtin_unreachable();
48        }
49        if (len > string_len &&
50            arg[string_len] == '=' &&
51            !strncmp(arg, string, string_len)) {
52            o->value[i] = &arg[string_len + 1];
53        }
54    }
55}
56
57void parse_options(zx_handle_t log, struct options *o, char** strings) {
58    initialize_options(o);
59    for (char** sp = strings; *sp != NULL; ++sp) {
60        const char* arg = *sp;
61        printl(log, "option \"%s\"", arg);
62        apply_option(o, arg);
63    }
64}
65